1 /* 2 * Copyright 2010-2011, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus <superstippi@gmx.de> 7 * SHINTA 8 */ 9 #include "MediaFileTrackSupplier.h" 10 11 #include <new> 12 13 #include <stdio.h> 14 #include <string.h> 15 16 #include <MediaFile.h> 17 #include <MediaTrack.h> 18 #include <String.h> 19 20 #include "MediaTrackAudioSupplier.h" 21 #include "MediaTrackVideoSupplier.h" 22 #include "ImageTrackVideoSupplier.h" 23 24 25 MediaFileTrackSupplier::MediaFileTrackSupplier() 26 : 27 TrackSupplier() 28 { 29 } 30 31 32 MediaFileTrackSupplier::~MediaFileTrackSupplier() 33 { 34 for (vector<BMediaFile*>::size_type i = fMediaFiles.size() - 1; 35 static_cast<int32>(i) >= 0; i--) { 36 delete fMediaFiles[i]; 37 // BMediaFile destructor will call ReleaseAllTracks() 38 } 39 40 for (vector<BBitmap*>::size_type i = fBitmaps.size() - 1; 41 static_cast<int32>(i) >= 0; i--) { 42 delete fBitmaps[i]; 43 } 44 45 for (int32 i = fSubTitleTracks.CountItems() - 1; i >= 0; i--) 46 delete reinterpret_cast<SubTitles*>(fSubTitleTracks.ItemAtFast(i)); 47 } 48 49 50 status_t 51 MediaFileTrackSupplier::InitCheck() 52 { 53 if (fMediaFiles.empty()) 54 return B_ERROR; 55 56 return fMediaFiles[0]->InitCheck(); 57 } 58 59 60 status_t 61 MediaFileTrackSupplier::GetFileFormatInfo(media_file_format* fileFormat) 62 { 63 if (fMediaFiles.empty()) 64 return B_ERROR; 65 66 return fMediaFiles[0]->GetFileFormatInfo(fileFormat); 67 } 68 69 70 status_t 71 MediaFileTrackSupplier::GetCopyright(BString* copyright) 72 { 73 if (fMediaFiles.empty()) 74 return B_ERROR; 75 76 *copyright = fMediaFiles[0]->Copyright(); 77 return B_OK; 78 } 79 80 81 status_t 82 MediaFileTrackSupplier::GetMetaData(BMessage* metaData) 83 { 84 if (fMediaFiles.empty()) 85 return B_ERROR; 86 87 return fMediaFiles[0]->GetMetaData(metaData); 88 } 89 90 91 int32 92 MediaFileTrackSupplier::CountAudioTracks() 93 { 94 return fAudioTracks.CountItems(); 95 } 96 97 98 int32 99 MediaFileTrackSupplier::CountVideoTracks() 100 { 101 return fVideoTracks.CountItems() + fBitmaps.size(); 102 } 103 104 105 int32 106 MediaFileTrackSupplier::CountSubTitleTracks() 107 { 108 return fSubTitleTracks.CountItems(); 109 } 110 111 112 status_t 113 MediaFileTrackSupplier::GetAudioMetaData(int32 index, BMessage* metaData) 114 { 115 BMediaTrack* track = (BMediaTrack*)fAudioTracks.ItemAt(index); 116 if (track == NULL) 117 return B_BAD_INDEX; 118 119 return track->GetMetaData(metaData); 120 } 121 122 123 status_t 124 MediaFileTrackSupplier::GetVideoMetaData(int32 index, BMessage* metaData) 125 { 126 BMediaTrack* track = (BMediaTrack*)fVideoTracks.ItemAt(index); 127 if (track == NULL) 128 return B_BAD_INDEX; 129 130 return track->GetMetaData(metaData); 131 } 132 133 134 AudioTrackSupplier* 135 MediaFileTrackSupplier::CreateAudioTrackForIndex(int32 index) 136 { 137 BMediaTrack* track = (BMediaTrack*)fAudioTracks.ItemAt(index); 138 if (track == NULL) 139 return NULL; 140 141 return new(std::nothrow) MediaTrackAudioSupplier(track, index); 142 } 143 144 145 VideoTrackSupplier* 146 MediaFileTrackSupplier::CreateVideoTrackForIndex(int32 index) 147 { 148 VideoTrackSupplier* supplier; 149 status_t initStatus; 150 151 if (fVideoTracks.CountItems() <= index 152 && index < fVideoTracks.CountItems() + static_cast<int32>(fBitmaps.size())) { 153 supplier = new(std::nothrow) ImageTrackVideoSupplier( 154 fBitmaps[index - fVideoTracks.CountItems()], index, initStatus); 155 } else { 156 BMediaTrack* track = (BMediaTrack*)fVideoTracks.ItemAt(index); 157 if (track == NULL) 158 return NULL; 159 160 supplier = new(std::nothrow) MediaTrackVideoSupplier(track, index, 161 initStatus); 162 } 163 164 if (initStatus != B_OK) { 165 delete supplier; 166 return NULL; 167 } 168 return supplier; 169 } 170 171 172 const SubTitles* 173 MediaFileTrackSupplier::SubTitleTrackForIndex(int32 index) 174 { 175 return reinterpret_cast<SubTitles*>(fSubTitleTracks.ItemAt(index)); 176 } 177 178 179 bool 180 MediaFileTrackSupplier::AddSubTitles(SubTitles* subTitles) 181 { 182 return fSubTitleTracks.AddItem(subTitles); 183 } 184 185 186 status_t 187 MediaFileTrackSupplier::AddMediaFile(BMediaFile* mediaFile) 188 { 189 if (mediaFile->InitCheck() != B_OK) 190 return B_ERROR; 191 int trackCount = mediaFile->CountTracks(); 192 if (trackCount <= 0) 193 return B_ERROR; 194 195 status_t funcStatus = B_ERROR; 196 for (int i = 0; i < trackCount; i++) { 197 BMediaTrack* track = mediaFile->TrackAt(i); 198 media_format format; 199 status_t status = track->EncodedFormat(&format); 200 if (status != B_OK) { 201 fprintf(stderr, "MediaFileTrackSupplier: EncodedFormat failed for " 202 "track index %d, error: %s\n", i, strerror(status)); 203 mediaFile->ReleaseTrack(track); 204 continue; 205 } 206 207 if (track->Duration() <= 0) { 208 fprintf(stderr, "MediaFileTrackSupplier: warning! track index %d " 209 "has no duration\n", i); 210 } 211 212 if (format.IsAudio()) { 213 if (fAudioTracks.AddItem(track)) { 214 funcStatus = B_OK; 215 } else { 216 mediaFile->ReleaseTrack(track); 217 } 218 } else if (format.IsVideo()) { 219 if (fVideoTracks.AddItem(track)) { 220 funcStatus = B_OK; 221 } else { 222 mediaFile->ReleaseTrack(track); 223 } 224 } else { 225 printf("MediaFileTrackSupplier: track index %d has unknown " 226 "type\n", i); 227 mediaFile->ReleaseTrack(track); 228 } 229 } 230 if (funcStatus == B_OK) 231 fMediaFiles.push_back(mediaFile); 232 return funcStatus; 233 } 234 235 236 status_t 237 MediaFileTrackSupplier::AddBitmap(BBitmap* bitmap) 238 { 239 fBitmaps.push_back(bitmap); 240 return B_OK; 241 } 242 243 244