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 21 PlaylistItem::Listener::Listener() 22 { 23 } 24 25 PlaylistItem::Listener::~Listener() 26 { 27 } 28 29 void PlaylistItem::Listener::ItemChanged(const PlaylistItem* item) 30 { 31 } 32 33 34 // #pragma mark - 35 36 37 //#define DEBUG_INSTANCE_COUNT 38 #ifdef DEBUG_INSTANCE_COUNT 39 static vint32 sInstanceCount = 0; 40 #endif 41 42 43 PlaylistItem::PlaylistItem() 44 : 45 fPlaybackFailed(false), 46 fTrackSupplier(NULL) 47 { 48 #ifdef DEBUG_INSTANCE_COUNT 49 atomic_add(&sInstanceCount, 1); 50 printf("%p->PlaylistItem::PlaylistItem() (%ld)\n", this, sInstanceCount); 51 #endif 52 } 53 54 55 PlaylistItem::~PlaylistItem() 56 { 57 #ifdef DEBUG_INSTANCE_COUNT 58 atomic_add(&sInstanceCount, -1); 59 printf("%p->PlaylistItem::~PlaylistItem() (%ld)\n", this, sInstanceCount); 60 #endif 61 } 62 63 64 TrackSupplier* 65 PlaylistItem::GetTrackSupplier() 66 { 67 if (fTrackSupplier == NULL) 68 fTrackSupplier = _CreateTrackSupplier(); 69 70 return fTrackSupplier; 71 } 72 73 74 void 75 PlaylistItem::ReleaseTrackSupplier() 76 { 77 delete fTrackSupplier; 78 fTrackSupplier = NULL; 79 } 80 81 82 bool 83 PlaylistItem::HasTrackSupplier() const 84 { 85 return fTrackSupplier != NULL; 86 } 87 88 89 BString 90 PlaylistItem::Name() const 91 { 92 BString name; 93 if (GetAttribute(ATTR_STRING_NAME, name) != B_OK) 94 name = B_TRANSLATE_CONTEXT("<unnamed>", "PlaylistItem-name"); 95 return name; 96 } 97 98 99 BString 100 PlaylistItem::Author() const 101 { 102 BString author; 103 if (GetAttribute(ATTR_STRING_AUTHOR, author) != B_OK) 104 author = B_TRANSLATE_CONTEXT("<unknown>", "PlaylistItem-author"); 105 return author; 106 } 107 108 109 BString 110 PlaylistItem::Album() const 111 { 112 BString album; 113 if (GetAttribute(ATTR_STRING_ALBUM, album) != B_OK) 114 album = B_TRANSLATE_CONTEXT("<unknown>", "PlaylistItem-album"); 115 return album; 116 } 117 118 119 BString 120 PlaylistItem::Title() const 121 { 122 BString title; 123 if (GetAttribute(ATTR_STRING_TITLE, title) != B_OK) 124 title = B_TRANSLATE_CONTEXT("<untitled>", "PlaylistItem-title"); 125 return title; 126 } 127 128 129 int32 130 PlaylistItem::TrackNumber() const 131 { 132 int32 trackNumber; 133 if (GetAttribute(ATTR_INT32_TRACK, trackNumber) != B_OK) 134 trackNumber = 0; 135 return trackNumber; 136 } 137 138 139 bigtime_t 140 PlaylistItem::Duration() 141 { 142 bigtime_t duration; 143 if (GetAttribute(ATTR_INT64_DURATION, duration) != B_OK) { 144 duration = this->_CalculateDuration(); 145 SetAttribute(ATTR_INT64_DURATION, duration); 146 } 147 148 return duration; 149 } 150 151 152 void 153 PlaylistItem::SetPlaybackFailed() 154 { 155 fPlaybackFailed = true; 156 } 157 158 159 //! You must hold the Playlist lock. 160 bool 161 PlaylistItem::AddListener(Listener* listener) 162 { 163 if (listener && !fListeners.HasItem(listener)) 164 return fListeners.AddItem(listener); 165 return false; 166 } 167 168 169 //! You must hold the Playlist lock. 170 void 171 PlaylistItem::RemoveListener(Listener* listener) 172 { 173 fListeners.RemoveItem(listener); 174 } 175 176 177 void 178 PlaylistItem::_NotifyListeners() const 179 { 180 BList listeners(fListeners); 181 int32 count = listeners.CountItems(); 182 for (int32 i = 0; i < count; i++) { 183 Listener* listener = (Listener*)listeners.ItemAtFast(i); 184 listener->ItemChanged(this); 185 } 186 } 187 188 189 bigtime_t PlaylistItem::_CalculateDuration() 190 { 191 // To be overridden in subclasses with more efficient methods 192 TrackSupplier* supplier = GetTrackSupplier(); 193 194 AudioTrackSupplier* au = supplier->CreateAudioTrackForIndex(0); 195 VideoTrackSupplier* vi = supplier->CreateVideoTrackForIndex(0); 196 197 bigtime_t duration = max_c(au == NULL ? 0 : au->Duration(), 198 vi == NULL ? 0 : vi->Duration()); 199 200 delete vi; 201 delete au; 202 ReleaseTrackSupplier(); 203 204 return duration; 205 } 206 207