vfs: check userland buffers before reading them.
[haiku.git] / src / apps / mediaplayer / supplier / MediaFileTrackSupplier.cpp
blobfba82e90dcbdfd91681e20f412caadbec1baacc7
1 /*
2 * Copyright 2010-2011, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 * SHINTA
8 */
9 #include "MediaFileTrackSupplier.h"
11 #include <new>
13 #include <stdio.h>
14 #include <string.h>
16 #include <MediaFile.h>
17 #include <MediaTrack.h>
18 #include <String.h>
20 #include "MediaTrackAudioSupplier.h"
21 #include "MediaTrackVideoSupplier.h"
22 #include "ImageTrackVideoSupplier.h"
25 MediaFileTrackSupplier::MediaFileTrackSupplier()
27 TrackSupplier()
32 MediaFileTrackSupplier::~MediaFileTrackSupplier()
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()
40 for (vector<BBitmap*>::size_type i = fBitmaps.size() - 1;
41 static_cast<int32>(i) >= 0; i--) {
42 delete fBitmaps[i];
45 for (int32 i = fSubTitleTracks.CountItems() - 1; i >= 0; i--)
46 delete reinterpret_cast<SubTitles*>(fSubTitleTracks.ItemAtFast(i));
50 status_t
51 MediaFileTrackSupplier::InitCheck()
53 if (fMediaFiles.empty())
54 return B_ERROR;
56 return fMediaFiles[0]->InitCheck();
60 status_t
61 MediaFileTrackSupplier::GetFileFormatInfo(media_file_format* fileFormat)
63 if (fMediaFiles.empty())
64 return B_ERROR;
66 return fMediaFiles[0]->GetFileFormatInfo(fileFormat);
70 status_t
71 MediaFileTrackSupplier::GetCopyright(BString* copyright)
73 if (fMediaFiles.empty())
74 return B_ERROR;
76 *copyright = fMediaFiles[0]->Copyright();
77 return B_OK;
81 status_t
82 MediaFileTrackSupplier::GetMetaData(BMessage* metaData)
84 if (fMediaFiles.empty())
85 return B_ERROR;
87 return fMediaFiles[0]->GetMetaData(metaData);
91 int32
92 MediaFileTrackSupplier::CountAudioTracks()
94 return fAudioTracks.CountItems();
98 int32
99 MediaFileTrackSupplier::CountVideoTracks()
101 return fVideoTracks.CountItems() + fBitmaps.size();
105 int32
106 MediaFileTrackSupplier::CountSubTitleTracks()
108 return fSubTitleTracks.CountItems();
112 status_t
113 MediaFileTrackSupplier::GetAudioMetaData(int32 index, BMessage* metaData)
115 BMediaTrack* track = (BMediaTrack*)fAudioTracks.ItemAt(index);
116 if (track == NULL)
117 return B_BAD_INDEX;
119 return track->GetMetaData(metaData);
123 status_t
124 MediaFileTrackSupplier::GetVideoMetaData(int32 index, BMessage* metaData)
126 BMediaTrack* track = (BMediaTrack*)fVideoTracks.ItemAt(index);
127 if (track == NULL)
128 return B_BAD_INDEX;
130 return track->GetMetaData(metaData);
134 AudioTrackSupplier*
135 MediaFileTrackSupplier::CreateAudioTrackForIndex(int32 index)
137 BMediaTrack* track = (BMediaTrack*)fAudioTracks.ItemAt(index);
138 if (track == NULL)
139 return NULL;
141 return new(std::nothrow) MediaTrackAudioSupplier(track, index);
145 VideoTrackSupplier*
146 MediaFileTrackSupplier::CreateVideoTrackForIndex(int32 index)
148 VideoTrackSupplier* supplier;
149 status_t initStatus;
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;
160 supplier = new(std::nothrow) MediaTrackVideoSupplier(track, index,
161 initStatus);
164 if (initStatus != B_OK) {
165 delete supplier;
166 return NULL;
168 return supplier;
172 const SubTitles*
173 MediaFileTrackSupplier::SubTitleTrackForIndex(int32 index)
175 return reinterpret_cast<SubTitles*>(fSubTitleTracks.ItemAt(index));
179 bool
180 MediaFileTrackSupplier::AddSubTitles(SubTitles* subTitles)
182 return fSubTitleTracks.AddItem(subTitles);
186 status_t
187 MediaFileTrackSupplier::AddMediaFile(BMediaFile* mediaFile)
189 if (mediaFile->InitCheck() != B_OK)
190 return B_ERROR;
191 int trackCount = mediaFile->CountTracks();
192 if (trackCount <= 0)
193 return B_ERROR;
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;
207 if (track->Duration() <= 0) {
208 fprintf(stderr, "MediaFileTrackSupplier: warning! track index %d "
209 "has no duration\n", i);
212 if (format.IsAudio()) {
213 if (fAudioTracks.AddItem(track)) {
214 funcStatus = B_OK;
215 } else {
216 mediaFile->ReleaseTrack(track);
218 } else if (format.IsVideo()) {
219 if (fVideoTracks.AddItem(track)) {
220 funcStatus = B_OK;
221 } else {
222 mediaFile->ReleaseTrack(track);
224 } else {
225 printf("MediaFileTrackSupplier: track index %d has unknown "
226 "type\n", i);
227 mediaFile->ReleaseTrack(track);
230 if (funcStatus == B_OK)
231 fMediaFiles.push_back(mediaFile);
232 return funcStatus;
236 status_t
237 MediaFileTrackSupplier::AddBitmap(BBitmap* bitmap)
239 fBitmaps.push_back(bitmap);
240 return B_OK;