1/*
2 * Copyright 2009-2010 Stephan A��mus <superstippi@gmx.de>
3 * All rights reserved. Distributed under the terms of the MIT license.
4 */
5
6#include "PlaylistItem.h"
7
8#include <stdio.h>
9
10#include <Catalog.h>
11#include <Locale.h>
12
13#include "AudioTrackSupplier.h"
14#include "TrackSupplier.h"
15#include "VideoTrackSupplier.h"
16
17#undef B_TRANSLATION_CONTEXT
18#define B_TRANSLATION_CONTEXT "MediaPlayer-PlaylistItem"
19
20
21PlaylistItem::Listener::Listener()
22{
23}
24
25
26PlaylistItem::Listener::~Listener()
27{
28}
29
30
31void PlaylistItem::Listener::ItemChanged(const PlaylistItem* item)
32{
33}
34
35
36// #pragma mark -
37
38
39// #define DEBUG_INSTANCE_COUNT
40#ifdef DEBUG_INSTANCE_COUNT
41static vint32 sInstanceCount = 0;
42#endif
43
44
45PlaylistItem::PlaylistItem()
46	:
47	fPlaybackFailed(false),
48	fTrackSupplier(NULL),
49	fDuration(-1)
50{
51#ifdef DEBUG_INSTANCE_COUNT
52	atomic_add(&sInstanceCount, 1);
53	printf("%p->PlaylistItem::PlaylistItem() (%ld)\n", this, sInstanceCount);
54#endif
55}
56
57
58PlaylistItem::~PlaylistItem()
59{
60#ifdef DEBUG_INSTANCE_COUNT
61	atomic_add(&sInstanceCount, -1);
62	printf("%p->PlaylistItem::~PlaylistItem() (%ld)\n", this, sInstanceCount);
63#endif
64}
65
66
67TrackSupplier*
68PlaylistItem::GetTrackSupplier()
69{
70	if (fTrackSupplier == NULL)
71		fTrackSupplier = _CreateTrackSupplier();
72
73	return fTrackSupplier;
74}
75
76
77void
78PlaylistItem::ReleaseTrackSupplier()
79{
80	delete fTrackSupplier;
81	fTrackSupplier = NULL;
82}
83
84
85bool
86PlaylistItem::HasTrackSupplier() const
87{
88	return fTrackSupplier != NULL;
89}
90
91
92BString
93PlaylistItem::Name() const
94{
95	BString name;
96	if (GetAttribute(ATTR_STRING_NAME, name) != B_OK)
97		name = B_TRANSLATE_CONTEXT("<unnamed>", "PlaylistItem-name");
98	return name;
99}
100
101
102BString
103PlaylistItem::Author() const
104{
105	BString author;
106	if (GetAttribute(ATTR_STRING_AUTHOR, author) != B_OK)
107		author = B_TRANSLATE_CONTEXT("<unknown>", "PlaylistItem-author");
108	return author;
109}
110
111
112BString
113PlaylistItem::Album() const
114{
115	BString album;
116	if (GetAttribute(ATTR_STRING_ALBUM, album) != B_OK)
117		album = B_TRANSLATE_CONTEXT("<unknown>", "PlaylistItem-album");
118	return album;
119}
120
121
122BString
123PlaylistItem::Title() const
124{
125	BString title;
126	if (GetAttribute(ATTR_STRING_TITLE, title) != B_OK)
127		title = B_TRANSLATE_CONTEXT("<untitled>", "PlaylistItem-title");
128	return title;
129}
130
131
132int32
133PlaylistItem::TrackNumber() const
134{
135	int32 trackNumber;
136	if (GetAttribute(ATTR_INT32_TRACK, trackNumber) != B_OK)
137		trackNumber = 0;
138	return trackNumber;
139}
140
141
142bigtime_t
143PlaylistItem::Duration()
144{
145	bigtime_t duration;
146	if (GetAttribute(ATTR_INT64_DURATION, duration) != B_OK) {
147		if (fDuration == -1) {
148			duration = this->_CalculateDuration();
149			if (SetAttribute(ATTR_INT64_DURATION, duration) != B_OK) {
150				fDuration = duration;
151			}
152		} else {
153			duration = fDuration;
154		}
155	}
156
157	return duration;
158}
159
160
161int64
162PlaylistItem::LastFrame() const
163{
164	int64 lastFrame;
165	if (GetAttribute(ATTR_INT64_FRAME, lastFrame) != B_OK)
166		lastFrame = 0;
167	return lastFrame;
168}
169
170
171float
172PlaylistItem::LastVolume() const
173{
174	float lastVolume;
175	if (GetAttribute(ATTR_FLOAT_VOLUME, lastVolume) != B_OK)
176		lastVolume = -1;
177	return lastVolume;
178}
179
180
181status_t
182PlaylistItem::SetLastFrame(int64 value)
183{
184	return SetAttribute(ATTR_INT64_FRAME, value);
185}
186
187
188status_t
189PlaylistItem::SetLastVolume(float value)
190{
191	return SetAttribute(ATTR_FLOAT_VOLUME, value);
192}
193
194
195void
196PlaylistItem::SetPlaybackFailed()
197{
198	fPlaybackFailed = true;
199}
200
201
202//! You must hold the Playlist lock.
203bool
204PlaylistItem::AddListener(Listener* listener)
205{
206	if (listener && !fListeners.HasItem(listener))
207		return fListeners.AddItem(listener);
208	return false;
209}
210
211
212//! You must hold the Playlist lock.
213void
214PlaylistItem::RemoveListener(Listener* listener)
215{
216	fListeners.RemoveItem(listener);
217}
218
219
220void
221PlaylistItem::_NotifyListeners() const
222{
223	BList listeners(fListeners);
224	int32 count = listeners.CountItems();
225	for (int32 i = 0; i < count; i++) {
226		Listener* listener = (Listener*)listeners.ItemAtFast(i);
227		listener->ItemChanged(this);
228	}
229}
230
231
232bigtime_t PlaylistItem::_CalculateDuration()
233{
234	// To be overridden in subclasses with more efficient methods
235	TrackSupplier* supplier = GetTrackSupplier();
236
237	AudioTrackSupplier* au = supplier->CreateAudioTrackForIndex(0);
238	VideoTrackSupplier* vi = supplier->CreateVideoTrackForIndex(0);
239
240	bigtime_t duration = max_c(au == NULL ? 0 : au->Duration(),
241		vi == NULL ? 0 : vi->Duration());
242
243	delete vi;
244	delete au;
245	ReleaseTrackSupplier();
246
247	return duration;
248}
249
250