headers/bsd: Add sys/queue.h.
[haiku.git] / src / kits / media / MediaDecoder.cpp
blob8a64a2cbcdc901f4e7f30dbe5d5c844c9e860559
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 "debug.h"
12 /*************************************************************
13 * public BMediaDecoder
14 *************************************************************/
16 BMediaDecoder::BMediaDecoder()
17 : fDecoder(NULL),
18 fInitStatus(B_NO_INIT)
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)
29 SetTo(in_format, info, info_size);
33 BMediaDecoder::BMediaDecoder(const media_codec_info *mci)
34 : fDecoder(NULL),
35 fInitStatus(B_NO_INIT)
37 SetTo(mci);
41 /* virtual */
42 BMediaDecoder::~BMediaDecoder()
44 gPluginManager.DestroyDecoder(fDecoder);
48 status_t
49 BMediaDecoder::InitCheck() const
51 return fInitStatus;
55 status_t
56 BMediaDecoder::SetTo(const media_format *in_format,
57 const void *info,
58 size_t info_size)
60 gPluginManager.DestroyDecoder(fDecoder);
61 fDecoder = NULL;
63 status_t err = gPluginManager.CreateDecoder(&fDecoder, *in_format);
64 if (err < B_OK)
65 goto fail;
67 err = AttachToDecoder();
68 if (err < B_OK)
69 goto fail;
71 err = SetInputFormat(in_format, info, info_size);
72 if (err < B_OK)
73 goto fail;
75 fInitStatus = B_OK;
76 return B_OK;
78 fail:
79 gPluginManager.DestroyDecoder(fDecoder);
80 fDecoder = NULL;
81 fInitStatus = B_NO_INIT;
82 return err;
86 status_t
87 BMediaDecoder::SetTo(const media_codec_info *mci)
89 gPluginManager.DestroyDecoder(fDecoder);
90 fDecoder = NULL;
92 status_t err = gPluginManager.CreateDecoder(&fDecoder, *mci);
93 if (err < B_OK)
94 goto fail;
96 err = AttachToDecoder();
97 if (err < B_OK)
98 goto fail;
100 fInitStatus = B_OK;
101 return B_OK;
103 fail:
104 gPluginManager.DestroyDecoder(fDecoder);
105 fDecoder = NULL;
106 fInitStatus = B_NO_INIT;
107 return err;
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.
119 status_t
120 BMediaDecoder::SetInputFormat(const media_format *in_format,
121 const void *in_info,
122 size_t in_size)
124 if (!fDecoder)
125 return B_NO_INIT;
127 media_format format = *in_format;
128 return fDecoder->Setup(&format, in_info, in_size);
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.
138 status_t
139 BMediaDecoder::SetOutputFormat(media_format *output_format)
141 if (!fDecoder)
142 return B_NO_INIT;
144 return fDecoder->NegotiateOutputFormat(output_format);
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.
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.
161 status_t
162 BMediaDecoder::Decode(void *out_buffer,
163 int64 *out_frameCount,
164 media_header *out_mh,
165 media_decode_info *info)
167 if (!fDecoder)
168 return B_NO_INIT;
170 return fDecoder->Decode(out_buffer, out_frameCount, out_mh, info);
174 status_t
175 BMediaDecoder::GetDecoderInfo(media_codec_info *out_info) const
177 if (!fDecoder)
178 return B_NO_INIT;
180 return gPluginManager.GetDecoderInfo(fDecoder, out_info);
184 /*************************************************************
185 * protected BMediaDecoder
186 *************************************************************/
189 /*************************************************************
190 * private BMediaDecoder
191 *************************************************************/
194 // unimplemented
195 BMediaDecoder::BMediaDecoder(const BMediaDecoder &);
196 BMediaDecoder::BMediaDecoder & operator=(const BMediaDecoder &);
199 status_t
200 BMediaDecoder::AttachToDecoder()
202 class MediaDecoderChunkProvider : public ChunkProvider {
203 private:
204 BMediaDecoder * fDecoder;
205 public:
206 MediaDecoderChunkProvider(BMediaDecoder * decoder) {
207 fDecoder = decoder;
209 virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
210 media_header *mediaHeader) {
211 return fDecoder->GetNextChunk(chunkBuffer, chunkSize, mediaHeader);
213 } * provider = new(std::nothrow) MediaDecoderChunkProvider(this);
215 if (!provider)
216 return B_NO_MEMORY;
218 fDecoder->SetChunkProvider(provider);
219 return B_OK;
223 status_t BMediaDecoder::_Reserved_BMediaDecoder_0(int32 arg, ...) { return B_ERROR; }
224 status_t BMediaDecoder::_Reserved_BMediaDecoder_1(int32 arg, ...) { return B_ERROR; }
225 status_t BMediaDecoder::_Reserved_BMediaDecoder_2(int32 arg, ...) { return B_ERROR; }
226 status_t BMediaDecoder::_Reserved_BMediaDecoder_3(int32 arg, ...) { return B_ERROR; }
227 status_t BMediaDecoder::_Reserved_BMediaDecoder_4(int32 arg, ...) { return B_ERROR; }
228 status_t BMediaDecoder::_Reserved_BMediaDecoder_5(int32 arg, ...) { return B_ERROR; }
229 status_t BMediaDecoder::_Reserved_BMediaDecoder_6(int32 arg, ...) { return B_ERROR; }
230 status_t BMediaDecoder::_Reserved_BMediaDecoder_7(int32 arg, ...) { return B_ERROR; }
231 status_t BMediaDecoder::_Reserved_BMediaDecoder_8(int32 arg, ...) { return B_ERROR; }
232 status_t BMediaDecoder::_Reserved_BMediaDecoder_9(int32 arg, ...) { return B_ERROR; }
233 status_t BMediaDecoder::_Reserved_BMediaDecoder_10(int32 arg, ...) { return B_ERROR; }
234 status_t BMediaDecoder::_Reserved_BMediaDecoder_11(int32 arg, ...) { return B_ERROR; }
235 status_t BMediaDecoder::_Reserved_BMediaDecoder_12(int32 arg, ...) { return B_ERROR; }
236 status_t BMediaDecoder::_Reserved_BMediaDecoder_13(int32 arg, ...) { return B_ERROR; }
237 status_t BMediaDecoder::_Reserved_BMediaDecoder_14(int32 arg, ...) { return B_ERROR; }
238 status_t BMediaDecoder::_Reserved_BMediaDecoder_15(int32 arg, ...) { return B_ERROR; }
240 /*************************************************************
241 * public BMediaBufferDecoder
242 *************************************************************/
244 BMediaBufferDecoder::BMediaBufferDecoder()
245 : BMediaDecoder()
246 , fBufferSize(0)
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)
260 BMediaBufferDecoder::BMediaBufferDecoder(const media_codec_info *mci)
261 : BMediaDecoder(mci)
262 , fBufferSize(0)
267 status_t
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)
275 fBuffer = input_buffer;
276 fBufferSize = input_size;
277 return Decode(out_buffer, out_frameCount, out_mh,info);
281 /*************************************************************
282 * protected BMediaBufferDecoder
283 *************************************************************/
285 /* virtual */
286 status_t
287 BMediaBufferDecoder::GetNextChunk(const void **chunkData,
288 size_t *chunkLen,
289 media_header *mh)
291 if (!fBufferSize)
292 return B_LAST_BUFFER_ERROR;
294 *chunkData = fBuffer;
295 *chunkLen = fBufferSize;
296 fBufferSize = 0;
297 return B_OK;