1/* 2 * Copyright 2015, Dario Casalinuovo 3 * Copyright 2010, Oleg Krysenkov, beos344@mail.ru. 4 * Copyright 2012, Fredrik Mod��en, [firstname]@[lastname].se. 5 * Copyright 2004-2007, Marcus Overhagen. All rights reserved. 6 * Distributed under the terms of the MIT License. 7 */ 8 9 10#include <MediaEncoder.h> 11 12#include <EncoderPlugin.h> 13#include <PluginManager.h> 14 15#include <new> 16 17#include "MediaDebug.h" 18 19/************************************************************* 20 * public BMediaEncoder 21 *************************************************************/ 22 23BMediaEncoder::BMediaEncoder() 24 : 25 fEncoder(NULL), 26 fInitStatus(B_NO_INIT) 27{ 28 CALLED(); 29} 30 31 32BMediaEncoder::BMediaEncoder(const media_format* outputFormat) 33 : 34 fEncoder(NULL), 35 fInitStatus(B_NO_INIT) 36{ 37 CALLED(); 38 SetTo(outputFormat); 39} 40 41 42BMediaEncoder::BMediaEncoder(const media_codec_info* mci) 43 : 44 fEncoder(NULL), 45 fInitStatus(B_NO_INIT) 46{ 47 CALLED(); 48 SetTo(mci); 49} 50 51 52/* virtual */ 53BMediaEncoder::~BMediaEncoder() 54{ 55 CALLED(); 56 ReleaseEncoder(); 57} 58 59 60status_t 61BMediaEncoder::InitCheck() const 62{ 63 return fInitStatus; 64} 65 66 67status_t 68BMediaEncoder::SetTo(const media_format* outputFormat) 69{ 70 CALLED(); 71 72 status_t err = B_ERROR; 73 ReleaseEncoder(); 74 75 if (outputFormat == NULL) 76 return fInitStatus; 77 78 media_format format = *outputFormat; 79 err = gPluginManager.CreateEncoder(&fEncoder, format); 80 if (fEncoder != NULL && err == B_OK) { 81 err = _AttachToEncoder(); 82 if (err == B_OK) 83 return err; 84 } 85 ReleaseEncoder(); 86 fInitStatus = err; 87 return err; 88} 89 90 91status_t 92BMediaEncoder::SetTo(const media_codec_info* mci) 93{ 94 CALLED(); 95 96 ReleaseEncoder(); 97 status_t err = gPluginManager.CreateEncoder(&fEncoder, mci, 0); 98 if (fEncoder != NULL && err == B_OK) { 99 err = _AttachToEncoder(); 100 if (err == B_OK) { 101 fInitStatus = B_OK; 102 return B_OK; 103 } 104 } 105 106 ReleaseEncoder(); 107 fInitStatus = err; 108 return err; 109} 110 111 112status_t 113BMediaEncoder::SetFormat(media_format* inputFormat, 114 media_format* outputFormat, media_file_format* mfi) 115{ 116 CALLED(); 117 TRACE("BMediaEncoder::SetFormat. Input = %d, Output = %d\n", 118 inputFormat->type, outputFormat->type); 119 120 if (!fEncoder) 121 return B_NO_INIT; 122 123 if (outputFormat != NULL) 124 SetTo(outputFormat); 125 126 //TODO: How we support mfi? 127 return fEncoder->SetUp(inputFormat); 128} 129 130 131status_t 132BMediaEncoder::Encode(const void* buffer, 133 int64 frameCount, media_encode_info* info) 134{ 135 CALLED(); 136 137 if (!fEncoder) 138 return B_NO_INIT; 139 140 return fEncoder->Encode(buffer, frameCount, info); 141} 142 143 144status_t 145BMediaEncoder::GetEncodeParameters(encode_parameters* parameters) const 146{ 147 CALLED(); 148 149 if (fEncoder == NULL) 150 return B_NO_INIT; 151 152 return fEncoder->GetEncodeParameters(parameters); 153} 154 155 156status_t 157BMediaEncoder::SetEncodeParameters(encode_parameters* parameters) 158{ 159 CALLED(); 160 161 if (fEncoder == NULL) 162 return B_NO_INIT; 163 164 return fEncoder->SetEncodeParameters(parameters); 165} 166 167 168/************************************************************* 169 * protected BMediaEncoder 170 *************************************************************/ 171 172/* virtual */ status_t 173BMediaEncoder::AddTrackInfo(uint32 code, const char* data, size_t size) 174{ 175 CALLED(); 176 177 if (fEncoder == NULL) 178 return B_NO_INIT; 179 180 return fEncoder->AddTrackInfo(code, data, size); 181} 182 183 184/************************************************************* 185 * private BMediaEncoder 186 *************************************************************/ 187 188/* 189// unimplemented 190BMediaEncoder::BMediaEncoder(const BMediaEncoder &); 191BMediaEncoder::BMediaEncoder & operator=(const BMediaEncoder &); 192*/ 193 194/* static */ status_t 195BMediaEncoder::write_chunk(void* classptr, const void* chunk_data, 196 size_t chunk_len, media_encode_info* info) 197{ 198 CALLED(); 199 200 BMediaEncoder* encoder = static_cast<BMediaEncoder*>(classptr); 201 if (encoder == NULL) 202 return B_BAD_VALUE; 203 return encoder->WriteChunk(chunk_data, chunk_len, info); 204} 205 206 207void 208BMediaEncoder::Init() 209{ 210 UNIMPLEMENTED(); 211} 212 213 214void 215BMediaEncoder::ReleaseEncoder() 216{ 217 CALLED(); 218 if (fEncoder != NULL) { 219 gPluginManager.DestroyEncoder(fEncoder); 220 fEncoder = NULL; 221 } 222 fInitStatus = B_NO_INIT; 223} 224 225 226status_t 227BMediaEncoder::_AttachToEncoder() 228{ 229 class MediaEncoderChunkWriter : public ChunkWriter { 230 public: 231 MediaEncoderChunkWriter(BMediaEncoder* encoder) 232 { 233 fEncoder = encoder; 234 } 235 virtual status_t WriteChunk(const void* chunkBuffer, 236 size_t chunkSize, media_encode_info* encodeInfo) 237 { 238 return fEncoder->WriteChunk(chunkBuffer, chunkSize, encodeInfo); 239 } 240 private: 241 BMediaEncoder* fEncoder; 242 } *writer = new(std::nothrow) MediaEncoderChunkWriter(this); 243 244 if (!writer) 245 return B_NO_MEMORY; 246 247 fEncoder->SetChunkWriter(writer); 248 return B_OK; 249} 250 251 252status_t BMediaEncoder::_Reserved_BMediaEncoder_0(int32 arg, ...) { return B_ERROR; } 253status_t BMediaEncoder::_Reserved_BMediaEncoder_1(int32 arg, ...) { return B_ERROR; } 254status_t BMediaEncoder::_Reserved_BMediaEncoder_2(int32 arg, ...) { return B_ERROR; } 255status_t BMediaEncoder::_Reserved_BMediaEncoder_3(int32 arg, ...) { return B_ERROR; } 256status_t BMediaEncoder::_Reserved_BMediaEncoder_4(int32 arg, ...) { return B_ERROR; } 257status_t BMediaEncoder::_Reserved_BMediaEncoder_5(int32 arg, ...) { return B_ERROR; } 258status_t BMediaEncoder::_Reserved_BMediaEncoder_6(int32 arg, ...) { return B_ERROR; } 259status_t BMediaEncoder::_Reserved_BMediaEncoder_7(int32 arg, ...) { return B_ERROR; } 260status_t BMediaEncoder::_Reserved_BMediaEncoder_8(int32 arg, ...) { return B_ERROR; } 261status_t BMediaEncoder::_Reserved_BMediaEncoder_9(int32 arg, ...) { return B_ERROR; } 262status_t BMediaEncoder::_Reserved_BMediaEncoder_10(int32 arg, ...) { return B_ERROR; } 263status_t BMediaEncoder::_Reserved_BMediaEncoder_11(int32 arg, ...) { return B_ERROR; } 264status_t BMediaEncoder::_Reserved_BMediaEncoder_12(int32 arg, ...) { return B_ERROR; } 265status_t BMediaEncoder::_Reserved_BMediaEncoder_13(int32 arg, ...) { return B_ERROR; } 266status_t BMediaEncoder::_Reserved_BMediaEncoder_14(int32 arg, ...) { return B_ERROR; } 267status_t BMediaEncoder::_Reserved_BMediaEncoder_15(int32 arg, ...) { return B_ERROR; } 268 269/************************************************************* 270 * public BMediaBufferEncoder 271 *************************************************************/ 272 273BMediaBufferEncoder::BMediaBufferEncoder() 274 : 275 BMediaEncoder(), 276 fBuffer(NULL) 277{ 278 CALLED(); 279} 280 281 282BMediaBufferEncoder::BMediaBufferEncoder(const media_format* outputFormat) 283 : 284 BMediaEncoder(outputFormat), 285 fBuffer(NULL) 286{ 287 CALLED(); 288} 289 290 291BMediaBufferEncoder::BMediaBufferEncoder(const media_codec_info* mci) 292 : 293 BMediaEncoder(mci), 294 fBuffer(NULL) 295{ 296 CALLED(); 297} 298 299 300status_t 301BMediaBufferEncoder::EncodeToBuffer(void* outputBuffer, 302 size_t* outputSize, const void* inputBuffer, 303 int64 frameCount, media_encode_info* info) 304{ 305 CALLED(); 306 307 status_t error; 308 fBuffer = outputBuffer; 309 fBufferSize = *outputSize; 310 error = Encode(inputBuffer, frameCount, info); 311 if (fBuffer) { 312 fBuffer = NULL; 313 *outputSize = 0; 314 } else { 315 *outputSize = fBufferSize; 316 } 317 return error; 318} 319 320 321/************************************************************* 322 * public BMediaBufferEncoder 323 *************************************************************/ 324 325status_t 326BMediaBufferEncoder::WriteChunk(const void* chunkData, 327 size_t chunkLen, media_encode_info* info) 328{ 329 CALLED(); 330 331 if (fBuffer == NULL) 332 return B_ENTRY_NOT_FOUND; 333 334 if (chunkLen > (size_t)fBufferSize) { 335 memcpy(fBuffer, chunkData, fBufferSize); 336 fBuffer = NULL; 337 return B_DEVICE_FULL; 338 } 339 340 memcpy(fBuffer, chunkData, chunkLen); 341 fBufferSize = chunkLen; 342 fBuffer = NULL; 343 return B_NO_ERROR; 344} 345