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