xref: /haiku/src/apps/mediaplayer/supplier/MediaFileTrackSupplier.cpp (revision ec2878c3cf93d351213f9c2f4407fc921a4860fb)
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