1 /***********************************************************************
2 * AUTHOR: Andrew Bachmann, Marcus Overhagen
3 * FILE: MediaDecoder.cpp
4 * DESCR:
5 ***********************************************************************/
6 #include <MediaDecoder.h>
7 #include <DecoderPlugin.h>
8 #include <new>
9 #include "PluginManager.h"
10 #include "MediaDebug.h"
11
12 /*************************************************************
13 * public BMediaDecoder
14 *************************************************************/
15
BMediaDecoder()16 BMediaDecoder::BMediaDecoder()
17 : fDecoder(NULL),
18 fInitStatus(B_NO_INIT)
19 {
20 }
21
22
BMediaDecoder(const media_format * in_format,const void * info,size_t info_size)23 BMediaDecoder::BMediaDecoder(const media_format *in_format,
24 const void *info,
25 size_t info_size)
26 : fDecoder(NULL),
27 fInitStatus(B_NO_INIT)
28 {
29 SetTo(in_format, info, info_size);
30 }
31
32
BMediaDecoder(const media_codec_info * mci)33 BMediaDecoder::BMediaDecoder(const media_codec_info *mci)
34 : fDecoder(NULL),
35 fInitStatus(B_NO_INIT)
36 {
37 SetTo(mci);
38 }
39
40
41 /* virtual */
~BMediaDecoder()42 BMediaDecoder::~BMediaDecoder()
43 {
44 gPluginManager.DestroyDecoder(fDecoder);
45 }
46
47
48 status_t
InitCheck() const49 BMediaDecoder::InitCheck() const
50 {
51 return fInitStatus;
52 }
53
54
55 status_t
SetTo(const media_format * in_format,const void * info,size_t info_size)56 BMediaDecoder::SetTo(const media_format *in_format,
57 const void *info,
58 size_t info_size)
59 {
60 gPluginManager.DestroyDecoder(fDecoder);
61 fDecoder = NULL;
62
63 status_t err = gPluginManager.CreateDecoder(&fDecoder, *in_format);
64 if (err < B_OK)
65 goto fail;
66
67 err = AttachToDecoder();
68 if (err < B_OK)
69 goto fail;
70
71 err = SetInputFormat(in_format, info, info_size);
72 if (err < B_OK)
73 goto fail;
74
75 fInitStatus = B_OK;
76 return B_OK;
77
78 fail:
79 gPluginManager.DestroyDecoder(fDecoder);
80 fDecoder = NULL;
81 fInitStatus = B_NO_INIT;
82 return err;
83 }
84
85
86 status_t
SetTo(const media_codec_info * mci)87 BMediaDecoder::SetTo(const media_codec_info *mci)
88 {
89 gPluginManager.DestroyDecoder(fDecoder);
90 fDecoder = NULL;
91
92 status_t err = gPluginManager.CreateDecoder(&fDecoder, *mci);
93 if (err < B_OK)
94 goto fail;
95
96 err = AttachToDecoder();
97 if (err < B_OK)
98 goto fail;
99
100 fInitStatus = B_OK;
101 return B_OK;
102
103 fail:
104 gPluginManager.DestroyDecoder(fDecoder);
105 fDecoder = NULL;
106 fInitStatus = B_NO_INIT;
107 return err;
108 }
109
110
111 /** SetInputFormat() sets the input data format to in_format.
112 * Unlike SetTo(), the SetInputFormat() function does not
113 * select a codec, so the currently-selected codec will
114 * continue to be used. You should only use SetInputFormat()
115 * to refine the format settings if it will not require the
116 * use of a different decoder.
117 */
118
119 status_t
SetInputFormat(const media_format * in_format,const void * in_info,size_t in_size)120 BMediaDecoder::SetInputFormat(const media_format *in_format,
121 const void *in_info,
122 size_t in_size)
123 {
124 if (!fDecoder)
125 return B_NO_INIT;
126
127 media_format format = *in_format;
128 return fDecoder->Setup(&format, in_info, in_size);
129 }
130
131
132 /** SetOutputFormat() sets the format the decoder should output.
133 * On return, the output_format is changed to match the actual
134 * format that will be output; this can be different if you
135 * specified any wildcards.
136 */
137
138 status_t
SetOutputFormat(media_format * output_format)139 BMediaDecoder::SetOutputFormat(media_format *output_format)
140 {
141 if (!fDecoder)
142 return B_NO_INIT;
143
144 return fDecoder->NegotiateOutputFormat(output_format);
145 }
146
147
148 /** Decodes a chunk of media data into the output buffer specified
149 * by out_buffer. On return, out_frameCount is set to indicate how
150 * many frames of data were decoded, and out_mh is the header for
151 * the decoded buffer. The media_decode_info structure info is used
152 * on input to specify decoding parameters.
153 *
154 * The amount of data decoded is part of the format determined by
155 * SetTo() or SetInputFormat(). For audio, it's the buffer_size.
156 * For video, it's one frame, which is height*row_bytes. The data
157 * to be decoded will be fetched from the source by the decoder
158 * add-on calling the derived class' GetNextChunk() function.
159 */
160
161 status_t
Decode(void * out_buffer,int64 * out_frameCount,media_header * out_mh,media_decode_info * info)162 BMediaDecoder::Decode(void *out_buffer,
163 int64 *out_frameCount,
164 media_header *out_mh,
165 media_decode_info *info)
166 {
167 if (!fDecoder)
168 return B_NO_INIT;
169
170 return fDecoder->Decode(out_buffer, out_frameCount, out_mh, info);
171 }
172
173
174 status_t
GetDecoderInfo(media_codec_info * out_info) const175 BMediaDecoder::GetDecoderInfo(media_codec_info *out_info) const
176 {
177 if (!fDecoder)
178 return B_NO_INIT;
179
180 return gPluginManager.GetDecoderInfo(fDecoder, out_info);
181 }
182
183
184 /*************************************************************
185 * protected BMediaDecoder
186 *************************************************************/
187
188
189 /*************************************************************
190 * private BMediaDecoder
191 *************************************************************/
192
193 /*
194 // unimplemented
195 BMediaDecoder::BMediaDecoder(const BMediaDecoder &);
196 BMediaDecoder::BMediaDecoder & operator=(const BMediaDecoder &);
197 */
198
199 status_t
AttachToDecoder()200 BMediaDecoder::AttachToDecoder()
201 {
202 class MediaDecoderChunkProvider : public ChunkProvider {
203 private:
204 BMediaDecoder * fDecoder;
205 public:
206 MediaDecoderChunkProvider(BMediaDecoder * decoder) {
207 fDecoder = decoder;
208 }
209 virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
210 media_header *mediaHeader) {
211 return fDecoder->GetNextChunk(chunkBuffer, chunkSize, mediaHeader);
212 }
213 } * provider = new(std::nothrow) MediaDecoderChunkProvider(this);
214
215 if (!provider)
216 return B_NO_MEMORY;
217
218 fDecoder->SetChunkProvider(provider);
219 return B_OK;
220 }
221
222
_Reserved_BMediaDecoder_0(int32 arg,...)223 status_t BMediaDecoder::_Reserved_BMediaDecoder_0(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_1(int32 arg,...)224 status_t BMediaDecoder::_Reserved_BMediaDecoder_1(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_2(int32 arg,...)225 status_t BMediaDecoder::_Reserved_BMediaDecoder_2(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_3(int32 arg,...)226 status_t BMediaDecoder::_Reserved_BMediaDecoder_3(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_4(int32 arg,...)227 status_t BMediaDecoder::_Reserved_BMediaDecoder_4(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_5(int32 arg,...)228 status_t BMediaDecoder::_Reserved_BMediaDecoder_5(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_6(int32 arg,...)229 status_t BMediaDecoder::_Reserved_BMediaDecoder_6(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_7(int32 arg,...)230 status_t BMediaDecoder::_Reserved_BMediaDecoder_7(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_8(int32 arg,...)231 status_t BMediaDecoder::_Reserved_BMediaDecoder_8(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_9(int32 arg,...)232 status_t BMediaDecoder::_Reserved_BMediaDecoder_9(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_10(int32 arg,...)233 status_t BMediaDecoder::_Reserved_BMediaDecoder_10(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_11(int32 arg,...)234 status_t BMediaDecoder::_Reserved_BMediaDecoder_11(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_12(int32 arg,...)235 status_t BMediaDecoder::_Reserved_BMediaDecoder_12(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_13(int32 arg,...)236 status_t BMediaDecoder::_Reserved_BMediaDecoder_13(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_14(int32 arg,...)237 status_t BMediaDecoder::_Reserved_BMediaDecoder_14(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaDecoder_15(int32 arg,...)238 status_t BMediaDecoder::_Reserved_BMediaDecoder_15(int32 arg, ...) { return B_ERROR; }
239
240 /*************************************************************
241 * public BMediaBufferDecoder
242 *************************************************************/
243
BMediaBufferDecoder()244 BMediaBufferDecoder::BMediaBufferDecoder()
245 : BMediaDecoder()
246 , fBufferSize(0)
247 {
248 }
249
250
BMediaBufferDecoder(const media_format * in_format,const void * info,size_t info_size)251 BMediaBufferDecoder::BMediaBufferDecoder(const media_format *in_format,
252 const void *info,
253 size_t info_size)
254 : BMediaDecoder(in_format, info, info_size)
255 , fBufferSize(0)
256 {
257 }
258
259
BMediaBufferDecoder(const media_codec_info * mci)260 BMediaBufferDecoder::BMediaBufferDecoder(const media_codec_info *mci)
261 : BMediaDecoder(mci)
262 , fBufferSize(0)
263 {
264 }
265
266
267 status_t
DecodeBuffer(const void * input_buffer,size_t input_size,void * out_buffer,int64 * out_frameCount,media_header * out_mh,media_decode_info * info)268 BMediaBufferDecoder::DecodeBuffer(const void *input_buffer,
269 size_t input_size,
270 void *out_buffer,
271 int64 *out_frameCount,
272 media_header *out_mh,
273 media_decode_info *info)
274 {
275 fBuffer = input_buffer;
276 fBufferSize = input_size;
277 return Decode(out_buffer, out_frameCount, out_mh,info);
278 }
279
280
281 /*************************************************************
282 * protected BMediaBufferDecoder
283 *************************************************************/
284
285 /* virtual */
286 status_t
GetNextChunk(const void ** chunkData,size_t * chunkLen,media_header * mh)287 BMediaBufferDecoder::GetNextChunk(const void **chunkData,
288 size_t *chunkLen,
289 media_header *mh)
290 {
291 if (!fBufferSize)
292 return B_LAST_BUFFER_ERROR;
293
294 *chunkData = fBuffer;
295 *chunkLen = fBufferSize;
296 fBufferSize = 0;
297 return B_OK;
298 }
299