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
BMediaEncoder()23 BMediaEncoder::BMediaEncoder()
24 :
25 fEncoder(NULL),
26 fInitStatus(B_NO_INIT)
27 {
28 CALLED();
29 }
30
31
BMediaEncoder(const media_format * outputFormat)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
BMediaEncoder(const media_codec_info * mci)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 */
~BMediaEncoder()53 BMediaEncoder::~BMediaEncoder()
54 {
55 CALLED();
56 ReleaseEncoder();
57 }
58
59
60 status_t
InitCheck() const61 BMediaEncoder::InitCheck() const
62 {
63 return fInitStatus;
64 }
65
66
67 status_t
SetTo(const media_format * outputFormat)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
SetTo(const media_codec_info * mci)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
SetFormat(media_format * inputFormat,media_format * outputFormat,media_file_format * mfi)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
Encode(const void * buffer,int64 frameCount,media_encode_info * info)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
GetEncodeParameters(encode_parameters * parameters) const145 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
SetEncodeParameters(encode_parameters * parameters)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
AddTrackInfo(uint32 code,const char * data,size_t size)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
write_chunk(void * classptr,const void * chunk_data,size_t chunk_len,media_encode_info * info)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
Init()208 BMediaEncoder::Init()
209 {
210 UNIMPLEMENTED();
211 }
212
213
214 void
ReleaseEncoder()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
_AttachToEncoder()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
_Reserved_BMediaEncoder_0(int32 arg,...)252 status_t BMediaEncoder::_Reserved_BMediaEncoder_0(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_1(int32 arg,...)253 status_t BMediaEncoder::_Reserved_BMediaEncoder_1(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_2(int32 arg,...)254 status_t BMediaEncoder::_Reserved_BMediaEncoder_2(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_3(int32 arg,...)255 status_t BMediaEncoder::_Reserved_BMediaEncoder_3(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_4(int32 arg,...)256 status_t BMediaEncoder::_Reserved_BMediaEncoder_4(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_5(int32 arg,...)257 status_t BMediaEncoder::_Reserved_BMediaEncoder_5(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_6(int32 arg,...)258 status_t BMediaEncoder::_Reserved_BMediaEncoder_6(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_7(int32 arg,...)259 status_t BMediaEncoder::_Reserved_BMediaEncoder_7(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_8(int32 arg,...)260 status_t BMediaEncoder::_Reserved_BMediaEncoder_8(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_9(int32 arg,...)261 status_t BMediaEncoder::_Reserved_BMediaEncoder_9(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_10(int32 arg,...)262 status_t BMediaEncoder::_Reserved_BMediaEncoder_10(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_11(int32 arg,...)263 status_t BMediaEncoder::_Reserved_BMediaEncoder_11(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_12(int32 arg,...)264 status_t BMediaEncoder::_Reserved_BMediaEncoder_12(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_13(int32 arg,...)265 status_t BMediaEncoder::_Reserved_BMediaEncoder_13(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_14(int32 arg,...)266 status_t BMediaEncoder::_Reserved_BMediaEncoder_14(int32 arg, ...) { return B_ERROR; }
_Reserved_BMediaEncoder_15(int32 arg,...)267 status_t BMediaEncoder::_Reserved_BMediaEncoder_15(int32 arg, ...) { return B_ERROR; }
268
269 /*************************************************************
270 * public BMediaBufferEncoder
271 *************************************************************/
272
BMediaBufferEncoder()273 BMediaBufferEncoder::BMediaBufferEncoder()
274 :
275 BMediaEncoder(),
276 fBuffer(NULL)
277 {
278 CALLED();
279 }
280
281
BMediaBufferEncoder(const media_format * outputFormat)282 BMediaBufferEncoder::BMediaBufferEncoder(const media_format* outputFormat)
283 :
284 BMediaEncoder(outputFormat),
285 fBuffer(NULL)
286 {
287 CALLED();
288 }
289
290
BMediaBufferEncoder(const media_codec_info * mci)291 BMediaBufferEncoder::BMediaBufferEncoder(const media_codec_info* mci)
292 :
293 BMediaEncoder(mci),
294 fBuffer(NULL)
295 {
296 CALLED();
297 }
298
299
300 status_t
EncodeToBuffer(void * outputBuffer,size_t * outputSize,const void * inputBuffer,int64 frameCount,media_encode_info * info)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
WriteChunk(const void * chunkData,size_t chunkLen,media_encode_info * info)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