12b514992SDario Casalinuovo /* 22b514992SDario Casalinuovo * Copyright 2015, Dario Casalinuovo 32b514992SDario Casalinuovo * Copyright 2010, Oleg Krysenkov, beos344@mail.ru. 42b514992SDario Casalinuovo * Copyright 2012, Fredrik Modéen, [firstname]@[lastname].se. 52b514992SDario Casalinuovo * Copyright 2004-2007, Marcus Overhagen. All rights reserved. 62b514992SDario Casalinuovo * Distributed under the terms of the MIT License. 72b514992SDario Casalinuovo */ 82b514992SDario Casalinuovo 92b514992SDario Casalinuovo 1052a38012Sejakowatz #include <MediaEncoder.h> 112b514992SDario Casalinuovo 122b514992SDario Casalinuovo #include <EncoderPlugin.h> 132b514992SDario Casalinuovo #include <PluginManager.h> 142b514992SDario Casalinuovo 152b514992SDario Casalinuovo #include <new> 162b514992SDario Casalinuovo 1752a38012Sejakowatz #include "debug.h" 1852a38012Sejakowatz 1952a38012Sejakowatz /************************************************************* 2052a38012Sejakowatz * public BMediaEncoder 2152a38012Sejakowatz *************************************************************/ 2252a38012Sejakowatz 2352a38012Sejakowatz BMediaEncoder::BMediaEncoder() 242b514992SDario Casalinuovo : 252b514992SDario Casalinuovo fEncoder(NULL), 262b514992SDario Casalinuovo fInitStatus(B_NO_INIT) 2752a38012Sejakowatz { 282b514992SDario Casalinuovo CALLED(); 2952a38012Sejakowatz } 3052a38012Sejakowatz 3152a38012Sejakowatz 32537ea80aSDario Casalinuovo BMediaEncoder::BMediaEncoder(const media_format* outputFormat) 332b514992SDario Casalinuovo : 342b514992SDario Casalinuovo fEncoder(NULL), 352b514992SDario Casalinuovo fInitStatus(B_NO_INIT) 3652a38012Sejakowatz { 372b514992SDario Casalinuovo CALLED(); 38537ea80aSDario Casalinuovo SetTo(outputFormat); 3952a38012Sejakowatz } 4052a38012Sejakowatz 4152a38012Sejakowatz 4252a38012Sejakowatz BMediaEncoder::BMediaEncoder(const media_codec_info* mci) 432b514992SDario Casalinuovo : 442b514992SDario Casalinuovo fEncoder(NULL), 452b514992SDario Casalinuovo fInitStatus(B_NO_INIT) 4652a38012Sejakowatz { 472b514992SDario Casalinuovo CALLED(); 482b514992SDario Casalinuovo SetTo(mci); 4952a38012Sejakowatz } 5052a38012Sejakowatz 5152a38012Sejakowatz 5252a38012Sejakowatz /* virtual */ 5352a38012Sejakowatz BMediaEncoder::~BMediaEncoder() 5452a38012Sejakowatz { 552b514992SDario Casalinuovo CALLED(); 569bc60a8bSDario Casalinuovo ReleaseEncoder(); 5752a38012Sejakowatz } 5852a38012Sejakowatz 5952a38012Sejakowatz 6052a38012Sejakowatz status_t 6152a38012Sejakowatz BMediaEncoder::InitCheck() const 6252a38012Sejakowatz { 632b514992SDario Casalinuovo return fInitStatus; 6452a38012Sejakowatz } 6552a38012Sejakowatz 662b514992SDario Casalinuovo 6752a38012Sejakowatz status_t 68537ea80aSDario Casalinuovo BMediaEncoder::SetTo(const media_format* outputFormat) 6952a38012Sejakowatz { 702b514992SDario Casalinuovo CALLED(); 712b514992SDario Casalinuovo 722b514992SDario Casalinuovo status_t err = B_ERROR; 739bc60a8bSDario Casalinuovo ReleaseEncoder(); 749bc60a8bSDario Casalinuovo 75537ea80aSDario Casalinuovo if (outputFormat == NULL) 769bc60a8bSDario Casalinuovo return fInitStatus; 779bc60a8bSDario Casalinuovo 78537ea80aSDario Casalinuovo media_format format = *outputFormat; 799bc60a8bSDario Casalinuovo err = gPluginManager.CreateEncoder(&fEncoder, format); 809bc60a8bSDario Casalinuovo if (fEncoder != NULL && err == B_OK) { 812b514992SDario Casalinuovo err = _AttachToEncoder(); 822d508790SDario Casalinuovo if (err == B_OK) 832d508790SDario Casalinuovo return err; 849bc60a8bSDario Casalinuovo } 859bc60a8bSDario Casalinuovo ReleaseEncoder(); 862b514992SDario Casalinuovo fInitStatus = err; 872b514992SDario Casalinuovo return err; 882b514992SDario Casalinuovo } 892b514992SDario Casalinuovo 902b514992SDario Casalinuovo 9152a38012Sejakowatz status_t 9252a38012Sejakowatz BMediaEncoder::SetTo(const media_codec_info* mci) 9352a38012Sejakowatz { 942b514992SDario Casalinuovo CALLED(); 952b514992SDario Casalinuovo 969bc60a8bSDario Casalinuovo ReleaseEncoder(); 972b514992SDario Casalinuovo status_t err = gPluginManager.CreateEncoder(&fEncoder, mci, 0); 989bc60a8bSDario Casalinuovo if (fEncoder != NULL && err == B_OK) { 992b514992SDario Casalinuovo err = _AttachToEncoder(); 1009bc60a8bSDario Casalinuovo if (err == B_OK) { 1012b514992SDario Casalinuovo fInitStatus = B_OK; 10252a38012Sejakowatz return B_OK; 1039bc60a8bSDario Casalinuovo } 1049bc60a8bSDario Casalinuovo } 1052b514992SDario Casalinuovo 1069bc60a8bSDario Casalinuovo ReleaseEncoder(); 1079bc60a8bSDario Casalinuovo fInitStatus = err; 1082b514992SDario Casalinuovo return err; 10952a38012Sejakowatz } 11052a38012Sejakowatz 11152a38012Sejakowatz 11252a38012Sejakowatz status_t 113537ea80aSDario Casalinuovo BMediaEncoder::SetFormat(media_format* inputFormat, 114537ea80aSDario Casalinuovo media_format* outputFormat, media_file_format* mfi) 11552a38012Sejakowatz { 1162b514992SDario Casalinuovo CALLED(); 1172b514992SDario Casalinuovo TRACE("BMediaEncoder::SetFormat. Input = %d, Output = %d\n", 118537ea80aSDario Casalinuovo inputFormat->type, outputFormat->type); 1192b514992SDario Casalinuovo 1202b514992SDario Casalinuovo if (!fEncoder) 1212b514992SDario Casalinuovo return B_NO_INIT; 1222b514992SDario Casalinuovo 1232d508790SDario Casalinuovo if (outputFormat != NULL) 1242d508790SDario Casalinuovo SetTo(outputFormat); 1252d508790SDario Casalinuovo 1262d508790SDario Casalinuovo //TODO: How we support mfi? 127537ea80aSDario Casalinuovo return fEncoder->SetUp(inputFormat); 12852a38012Sejakowatz } 12952a38012Sejakowatz 1302b514992SDario Casalinuovo 13152a38012Sejakowatz status_t 13252a38012Sejakowatz BMediaEncoder::Encode(const void* buffer, 133537ea80aSDario Casalinuovo int64 frameCount, media_encode_info* info) 13452a38012Sejakowatz { 1352b514992SDario Casalinuovo CALLED(); 1362b514992SDario Casalinuovo 1372b514992SDario Casalinuovo if (!fEncoder) 1382b514992SDario Casalinuovo return B_NO_INIT; 1392b514992SDario Casalinuovo 140537ea80aSDario Casalinuovo return fEncoder->Encode(buffer, frameCount, info); 14152a38012Sejakowatz } 14252a38012Sejakowatz 14352a38012Sejakowatz 14452a38012Sejakowatz status_t 14552a38012Sejakowatz BMediaEncoder::GetEncodeParameters(encode_parameters* parameters) const 14652a38012Sejakowatz { 1472b514992SDario Casalinuovo CALLED(); 1482b514992SDario Casalinuovo 1492b514992SDario Casalinuovo if (fEncoder == NULL) 1502b514992SDario Casalinuovo return B_NO_INIT; 151*8cd14ac0SDario Casalinuovo 1522b514992SDario Casalinuovo return fEncoder->GetEncodeParameters(parameters); 15352a38012Sejakowatz } 15452a38012Sejakowatz 15552a38012Sejakowatz 15652a38012Sejakowatz status_t 15752a38012Sejakowatz BMediaEncoder::SetEncodeParameters(encode_parameters* parameters) 15852a38012Sejakowatz { 1592b514992SDario Casalinuovo CALLED(); 1602b514992SDario Casalinuovo 1612b514992SDario Casalinuovo if (fEncoder == NULL) 1622b514992SDario Casalinuovo return B_NO_INIT; 163*8cd14ac0SDario Casalinuovo 1642b514992SDario Casalinuovo return fEncoder->SetEncodeParameters(parameters); 16552a38012Sejakowatz } 16652a38012Sejakowatz 16752a38012Sejakowatz 16852a38012Sejakowatz /************************************************************* 16952a38012Sejakowatz * protected BMediaEncoder 17052a38012Sejakowatz *************************************************************/ 17152a38012Sejakowatz 17252a38012Sejakowatz /* virtual */ status_t 17352a38012Sejakowatz BMediaEncoder::AddTrackInfo(uint32 code, const char* data, size_t size) 17452a38012Sejakowatz { 1752b514992SDario Casalinuovo CALLED(); 1762b514992SDario Casalinuovo 1772b514992SDario Casalinuovo if (fEncoder == NULL) 1782b514992SDario Casalinuovo return B_NO_INIT; 179*8cd14ac0SDario Casalinuovo 1802b514992SDario Casalinuovo return fEncoder->AddTrackInfo(code, data, size); 18152a38012Sejakowatz } 18252a38012Sejakowatz 18352a38012Sejakowatz 18452a38012Sejakowatz /************************************************************* 18552a38012Sejakowatz * private BMediaEncoder 18652a38012Sejakowatz *************************************************************/ 18752a38012Sejakowatz 18852a38012Sejakowatz /* 18952a38012Sejakowatz // unimplemented 19052a38012Sejakowatz BMediaEncoder::BMediaEncoder(const BMediaEncoder &); 19152a38012Sejakowatz BMediaEncoder::BMediaEncoder & operator=(const BMediaEncoder &); 19252a38012Sejakowatz */ 19352a38012Sejakowatz 19452a38012Sejakowatz /* static */ status_t 1952b514992SDario Casalinuovo BMediaEncoder::write_chunk(void* classptr, const void* chunk_data, 1962b514992SDario Casalinuovo size_t chunk_len, media_encode_info* info) 19752a38012Sejakowatz { 198106539c2SDario Casalinuovo CALLED(); 199106539c2SDario Casalinuovo 200106539c2SDario Casalinuovo BMediaEncoder* encoder = static_cast<BMediaEncoder*>(classptr); 201106539c2SDario Casalinuovo if (encoder == NULL) 202106539c2SDario Casalinuovo return B_BAD_VALUE; 203106539c2SDario Casalinuovo return encoder->WriteChunk(chunk_data, chunk_len, info); 20452a38012Sejakowatz } 20552a38012Sejakowatz 20652a38012Sejakowatz 20752a38012Sejakowatz void 20852a38012Sejakowatz BMediaEncoder::Init() 20952a38012Sejakowatz { 21052a38012Sejakowatz UNIMPLEMENTED(); 21152a38012Sejakowatz } 21252a38012Sejakowatz 21352a38012Sejakowatz 21452a38012Sejakowatz void 21552a38012Sejakowatz BMediaEncoder::ReleaseEncoder() 21652a38012Sejakowatz { 2179bc60a8bSDario Casalinuovo CALLED(); 2189bc60a8bSDario Casalinuovo if (fEncoder != NULL) { 2199bc60a8bSDario Casalinuovo gPluginManager.DestroyEncoder(fEncoder); 2209bc60a8bSDario Casalinuovo fEncoder = NULL; 2219bc60a8bSDario Casalinuovo } 2229bc60a8bSDario Casalinuovo fInitStatus = B_NO_INIT; 22352a38012Sejakowatz } 22452a38012Sejakowatz 2252b514992SDario Casalinuovo 2262b514992SDario Casalinuovo status_t 2272b514992SDario Casalinuovo BMediaEncoder::_AttachToEncoder() 2282b514992SDario Casalinuovo { 2292b514992SDario Casalinuovo class MediaEncoderChunkWriter : public ChunkWriter { 2302b514992SDario Casalinuovo public: 2312b514992SDario Casalinuovo MediaEncoderChunkWriter(BMediaEncoder* encoder) 2322b514992SDario Casalinuovo { 2332b514992SDario Casalinuovo fEncoder = encoder; 2342b514992SDario Casalinuovo } 2352b514992SDario Casalinuovo virtual status_t WriteChunk(const void* chunkBuffer, 2362b514992SDario Casalinuovo size_t chunkSize, media_encode_info* encodeInfo) 2372b514992SDario Casalinuovo { 2382b514992SDario Casalinuovo return fEncoder->WriteChunk(chunkBuffer, chunkSize, encodeInfo); 2392b514992SDario Casalinuovo } 2402b514992SDario Casalinuovo private: 2412b514992SDario Casalinuovo BMediaEncoder* fEncoder; 2422b514992SDario Casalinuovo } *writer = new(std::nothrow) MediaEncoderChunkWriter(this); 2432b514992SDario Casalinuovo 2442b514992SDario Casalinuovo if (!writer) 2452b514992SDario Casalinuovo return B_NO_MEMORY; 2462b514992SDario Casalinuovo 2472b514992SDario Casalinuovo fEncoder->SetChunkWriter(writer); 2482b514992SDario Casalinuovo return B_OK; 2492b514992SDario Casalinuovo } 2502b514992SDario Casalinuovo 2512b514992SDario Casalinuovo 25252a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_0(int32 arg, ...) { return B_ERROR; } 25352a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_1(int32 arg, ...) { return B_ERROR; } 25452a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_2(int32 arg, ...) { return B_ERROR; } 25552a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_3(int32 arg, ...) { return B_ERROR; } 25652a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_4(int32 arg, ...) { return B_ERROR; } 25752a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_5(int32 arg, ...) { return B_ERROR; } 25852a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_6(int32 arg, ...) { return B_ERROR; } 25952a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_7(int32 arg, ...) { return B_ERROR; } 26052a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_8(int32 arg, ...) { return B_ERROR; } 26152a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_9(int32 arg, ...) { return B_ERROR; } 26252a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_10(int32 arg, ...) { return B_ERROR; } 26352a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_11(int32 arg, ...) { return B_ERROR; } 26452a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_12(int32 arg, ...) { return B_ERROR; } 26552a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_13(int32 arg, ...) { return B_ERROR; } 26652a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_14(int32 arg, ...) { return B_ERROR; } 26752a38012Sejakowatz status_t BMediaEncoder::_Reserved_BMediaEncoder_15(int32 arg, ...) { return B_ERROR; } 26852a38012Sejakowatz 26952a38012Sejakowatz /************************************************************* 27052a38012Sejakowatz * public BMediaBufferEncoder 27152a38012Sejakowatz *************************************************************/ 27252a38012Sejakowatz 27352a38012Sejakowatz BMediaBufferEncoder::BMediaBufferEncoder() 2742b514992SDario Casalinuovo : 2752b514992SDario Casalinuovo BMediaEncoder(), 2762b514992SDario Casalinuovo fBuffer(NULL) 27752a38012Sejakowatz { 2782b514992SDario Casalinuovo CALLED(); 27952a38012Sejakowatz } 28052a38012Sejakowatz 28152a38012Sejakowatz 282537ea80aSDario Casalinuovo BMediaBufferEncoder::BMediaBufferEncoder(const media_format* outputFormat) 2832b514992SDario Casalinuovo : 284537ea80aSDario Casalinuovo BMediaEncoder(outputFormat), 2852b514992SDario Casalinuovo fBuffer(NULL) 28652a38012Sejakowatz { 2872b514992SDario Casalinuovo CALLED(); 28852a38012Sejakowatz } 28952a38012Sejakowatz 29052a38012Sejakowatz 29152a38012Sejakowatz BMediaBufferEncoder::BMediaBufferEncoder(const media_codec_info* mci) 2922b514992SDario Casalinuovo : 2932b514992SDario Casalinuovo BMediaEncoder(mci), 2942b514992SDario Casalinuovo fBuffer(NULL) 29552a38012Sejakowatz { 2962b514992SDario Casalinuovo CALLED(); 29752a38012Sejakowatz } 29852a38012Sejakowatz 29952a38012Sejakowatz 30052a38012Sejakowatz status_t 301537ea80aSDario Casalinuovo BMediaBufferEncoder::EncodeToBuffer(void* outputBuffer, 302537ea80aSDario Casalinuovo size_t* outputSize, const void* inputBuffer, 303537ea80aSDario Casalinuovo int64 frameCount, media_encode_info* info) 30452a38012Sejakowatz { 3052b514992SDario Casalinuovo CALLED(); 30652a38012Sejakowatz 3072b514992SDario Casalinuovo status_t error; 308537ea80aSDario Casalinuovo fBuffer = outputBuffer; 309537ea80aSDario Casalinuovo fBufferSize = *outputSize; 310537ea80aSDario Casalinuovo error = Encode(inputBuffer, frameCount, info); 3112b514992SDario Casalinuovo if (fBuffer) { 3122b514992SDario Casalinuovo fBuffer = NULL; 313537ea80aSDario Casalinuovo *outputSize = 0; 3142b514992SDario Casalinuovo } else { 315537ea80aSDario Casalinuovo *outputSize = fBufferSize; 3162b514992SDario Casalinuovo } 3172b514992SDario Casalinuovo return error; 31852a38012Sejakowatz } 31952a38012Sejakowatz 32052a38012Sejakowatz 32152a38012Sejakowatz /************************************************************* 32252a38012Sejakowatz * public BMediaBufferEncoder 32352a38012Sejakowatz *************************************************************/ 32452a38012Sejakowatz 32552a38012Sejakowatz status_t 326537ea80aSDario Casalinuovo BMediaBufferEncoder::WriteChunk(const void* chunkData, 327537ea80aSDario Casalinuovo size_t chunkLen, media_encode_info* info) 32852a38012Sejakowatz { 3292b514992SDario Casalinuovo CALLED(); 33052a38012Sejakowatz 3312b514992SDario Casalinuovo if (fBuffer == NULL) 3322b514992SDario Casalinuovo return B_ENTRY_NOT_FOUND; 3332b514992SDario Casalinuovo 334537ea80aSDario Casalinuovo if (chunkLen < 0) 33548ff964fSbeveloper return B_ERROR; 3362b514992SDario Casalinuovo 337537ea80aSDario Casalinuovo if (chunkLen > (size_t)fBufferSize) { 338537ea80aSDario Casalinuovo memcpy(fBuffer, chunkData, fBufferSize); 3392b514992SDario Casalinuovo fBuffer = NULL; 3402b514992SDario Casalinuovo return B_DEVICE_FULL; 34152a38012Sejakowatz } 34252a38012Sejakowatz 343537ea80aSDario Casalinuovo memcpy(fBuffer, chunkData, chunkLen); 344537ea80aSDario Casalinuovo fBufferSize = chunkLen; 3452b514992SDario Casalinuovo fBuffer = NULL; 3462b514992SDario Casalinuovo return B_NO_ERROR; 3472b514992SDario Casalinuovo } 348