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 23 BMediaEncoder::BMediaEncoder() 24 : 25 fEncoder(NULL), 26 fInitStatus(B_NO_INIT) 27 { 28 CALLED(); 29 } 30 31 32 BMediaEncoder::BMediaEncoder(const media_format* outputFormat) 33 : 34 fEncoder(NULL), 35 fInitStatus(B_NO_INIT) 36 { 37 CALLED(); 38 SetTo(outputFormat); 39 } 40 41 42 BMediaEncoder::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 */ 53 BMediaEncoder::~BMediaEncoder() 54 { 55 CALLED(); 56 ReleaseEncoder(); 57 } 58 59 60 status_t 61 BMediaEncoder::InitCheck() const 62 { 63 return fInitStatus; 64 } 65 66 67 status_t 68 BMediaEncoder::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 91 status_t 92 BMediaEncoder::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 112 status_t 113 BMediaEncoder::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 131 status_t 132 BMediaEncoder::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 144 status_t 145 BMediaEncoder::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 156 status_t 157 BMediaEncoder::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 173 BMediaEncoder::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 190 BMediaEncoder::BMediaEncoder(const BMediaEncoder &); 191 BMediaEncoder::BMediaEncoder & operator=(const BMediaEncoder &); 192 */ 193 194 /* static */ status_t 195 BMediaEncoder::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 207 void 208 BMediaEncoder::Init() 209 { 210 UNIMPLEMENTED(); 211 } 212 213 214 void 215 BMediaEncoder::ReleaseEncoder() 216 { 217 CALLED(); 218 if (fEncoder != NULL) { 219 gPluginManager.DestroyEncoder(fEncoder); 220 fEncoder = NULL; 221 } 222 fInitStatus = B_NO_INIT; 223 } 224 225 226 status_t 227 BMediaEncoder::_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 252 status_t BMediaEncoder::_Reserved_BMediaEncoder_0(int32 arg, ...) { return B_ERROR; } 253 status_t BMediaEncoder::_Reserved_BMediaEncoder_1(int32 arg, ...) { return B_ERROR; } 254 status_t BMediaEncoder::_Reserved_BMediaEncoder_2(int32 arg, ...) { return B_ERROR; } 255 status_t BMediaEncoder::_Reserved_BMediaEncoder_3(int32 arg, ...) { return B_ERROR; } 256 status_t BMediaEncoder::_Reserved_BMediaEncoder_4(int32 arg, ...) { return B_ERROR; } 257 status_t BMediaEncoder::_Reserved_BMediaEncoder_5(int32 arg, ...) { return B_ERROR; } 258 status_t BMediaEncoder::_Reserved_BMediaEncoder_6(int32 arg, ...) { return B_ERROR; } 259 status_t BMediaEncoder::_Reserved_BMediaEncoder_7(int32 arg, ...) { return B_ERROR; } 260 status_t BMediaEncoder::_Reserved_BMediaEncoder_8(int32 arg, ...) { return B_ERROR; } 261 status_t BMediaEncoder::_Reserved_BMediaEncoder_9(int32 arg, ...) { return B_ERROR; } 262 status_t BMediaEncoder::_Reserved_BMediaEncoder_10(int32 arg, ...) { return B_ERROR; } 263 status_t BMediaEncoder::_Reserved_BMediaEncoder_11(int32 arg, ...) { return B_ERROR; } 264 status_t BMediaEncoder::_Reserved_BMediaEncoder_12(int32 arg, ...) { return B_ERROR; } 265 status_t BMediaEncoder::_Reserved_BMediaEncoder_13(int32 arg, ...) { return B_ERROR; } 266 status_t BMediaEncoder::_Reserved_BMediaEncoder_14(int32 arg, ...) { return B_ERROR; } 267 status_t BMediaEncoder::_Reserved_BMediaEncoder_15(int32 arg, ...) { return B_ERROR; } 268 269 /************************************************************* 270 * public BMediaBufferEncoder 271 *************************************************************/ 272 273 BMediaBufferEncoder::BMediaBufferEncoder() 274 : 275 BMediaEncoder(), 276 fBuffer(NULL) 277 { 278 CALLED(); 279 } 280 281 282 BMediaBufferEncoder::BMediaBufferEncoder(const media_format* outputFormat) 283 : 284 BMediaEncoder(outputFormat), 285 fBuffer(NULL) 286 { 287 CALLED(); 288 } 289 290 291 BMediaBufferEncoder::BMediaBufferEncoder(const media_codec_info* mci) 292 : 293 BMediaEncoder(mci), 294 fBuffer(NULL) 295 { 296 CALLED(); 297 } 298 299 300 status_t 301 BMediaBufferEncoder::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 325 status_t 326 BMediaBufferEncoder::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