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
MediaFileTrackSupplier()25 MediaFileTrackSupplier::MediaFileTrackSupplier()
26 :
27 TrackSupplier()
28 {
29 }
30
31
~MediaFileTrackSupplier()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
InitCheck()51 MediaFileTrackSupplier::InitCheck()
52 {
53 if (fMediaFiles.empty())
54 return B_ERROR;
55
56 return fMediaFiles[0]->InitCheck();
57 }
58
59
60 status_t
GetFileFormatInfo(media_file_format * fileFormat)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
GetCopyright(BString * copyright)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
GetMetaData(BMessage * metaData)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
CountAudioTracks()92 MediaFileTrackSupplier::CountAudioTracks()
93 {
94 return fAudioTracks.CountItems();
95 }
96
97
98 int32
CountVideoTracks()99 MediaFileTrackSupplier::CountVideoTracks()
100 {
101 return fVideoTracks.CountItems() + fBitmaps.size();
102 }
103
104
105 int32
CountSubTitleTracks()106 MediaFileTrackSupplier::CountSubTitleTracks()
107 {
108 return fSubTitleTracks.CountItems();
109 }
110
111
112 status_t
GetAudioMetaData(int32 index,BMessage * metaData)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
GetVideoMetaData(int32 index,BMessage * metaData)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*
CreateAudioTrackForIndex(int32 index)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*
CreateVideoTrackForIndex(int32 index)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*
SubTitleTrackForIndex(int32 index)173 MediaFileTrackSupplier::SubTitleTrackForIndex(int32 index)
174 {
175 return reinterpret_cast<SubTitles*>(fSubTitleTracks.ItemAt(index));
176 }
177
178
179 bool
AddSubTitles(SubTitles * subTitles)180 MediaFileTrackSupplier::AddSubTitles(SubTitles* subTitles)
181 {
182 return fSubTitleTracks.AddItem(subTitles);
183 }
184
185
186 status_t
AddMediaFile(BMediaFile * mediaFile)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
AddBitmap(BBitmap * bitmap)237 MediaFileTrackSupplier::AddBitmap(BBitmap* bitmap)
238 {
239 fBitmaps.push_back(bitmap);
240 return B_OK;
241 }
242
243
244