2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 *************************************************************************
18 * @file VideoEditorVideoEncoder.cpp
19 * @brief StageFright shell video encoder
20 *************************************************************************
23 #define LOG_TAG "VIDEOEDITOR_VIDEOENCODER"
28 #include "M4OSA_Debug.h"
29 #include "M4SYS_AccessUnit.h"
30 #include "VideoEditorVideoEncoder.h"
31 #include "VideoEditorUtils.h"
32 #include "MediaBufferPuller.h"
33 #include <I420ColorConverter.h>
36 #include "utils/Log.h"
37 #include "utils/Vector.h"
38 #include <media/stagefright/foundation/ADebug.h>
39 #include <media/stagefright/MediaSource.h>
40 #include <media/stagefright/MediaDefs.h>
41 #include <media/stagefright/MetaData.h>
42 #include <media/stagefright/OMXClient.h>
43 #include <media/stagefright/OMXCodec.h>
44 #include <media/MediaProfiles.h>
45 #include "OMX_Video.h"
51 // Force using hardware encoder
52 #define VIDEOEDITOR_FORCECODEC kHardwareCodecsOnly
54 #if !defined(VIDEOEDITOR_FORCECODEC)
55 #error "Cannot force DSI retrieval if codec type is not fixed"
64 struct VideoEditorVideoEncoderSource : public MediaSource {
66 static sp<VideoEditorVideoEncoderSource> Create(
67 const sp<MetaData> &format);
68 virtual status_t start(MetaData *params = NULL);
69 virtual status_t stop();
70 virtual sp<MetaData> getFormat();
71 virtual status_t read(MediaBuffer **buffer,
72 const ReadOptions *options = NULL);
73 virtual int32_t storeBuffer(MediaBuffer *buffer);
74 virtual int32_t getNumberOfBuffersInQueue();
77 virtual ~VideoEditorVideoEncoderSource();
80 struct MediaBufferChain {
82 MediaBufferChain* nextLink;
89 VideoEditorVideoEncoderSource(const sp<MetaData> &format);
92 VideoEditorVideoEncoderSource(const VideoEditorVideoEncoderSource &);
93 VideoEditorVideoEncoderSource &operator=(
94 const VideoEditorVideoEncoderSource &);
96 MediaBufferChain* mFirstBufferLink;
97 MediaBufferChain* mLastBufferLink;
101 sp<MetaData> mEncFormat;
103 Condition mBufferCond;
106 sp<VideoEditorVideoEncoderSource> VideoEditorVideoEncoderSource::Create(
107 const sp<MetaData> &format) {
109 sp<VideoEditorVideoEncoderSource> aSource =
110 new VideoEditorVideoEncoderSource(format);
114 VideoEditorVideoEncoderSource::VideoEditorVideoEncoderSource(
115 const sp<MetaData> &format):
116 mFirstBufferLink(NULL),
117 mLastBufferLink(NULL),
122 ALOGV("VideoEditorVideoEncoderSource::VideoEditorVideoEncoderSource");
125 VideoEditorVideoEncoderSource::~VideoEditorVideoEncoderSource() {
128 if( STARTED == mState ) {
133 status_t VideoEditorVideoEncoderSource::start(MetaData *meta) {
136 ALOGV("VideoEditorVideoEncoderSource::start() begin");
138 if( CREATED != mState ) {
139 ALOGV("VideoEditorVideoEncoderSource::start: invalid state %d", mState);
140 return UNKNOWN_ERROR;
144 ALOGV("VideoEditorVideoEncoderSource::start() END (0x%x)", err);
148 status_t VideoEditorVideoEncoderSource::stop() {
151 ALOGV("VideoEditorVideoEncoderSource::stop() begin");
153 if( STARTED != mState ) {
154 ALOGV("VideoEditorVideoEncoderSource::stop: invalid state %d", mState);
155 return UNKNOWN_ERROR;
158 // Release the buffer chain
160 MediaBufferChain* tmpLink = NULL;
161 while( mFirstBufferLink ) {
163 tmpLink = mFirstBufferLink;
164 mFirstBufferLink = mFirstBufferLink->nextLink;
167 ALOGV("VideoEditorVideoEncoderSource::stop : %d buffer remained", i);
168 mFirstBufferLink = NULL;
169 mLastBufferLink = NULL;
173 ALOGV("VideoEditorVideoEncoderSource::stop() END (0x%x)", err);
177 sp<MetaData> VideoEditorVideoEncoderSource::getFormat() {
179 ALOGV("VideoEditorVideoEncoderSource::getFormat");
183 status_t VideoEditorVideoEncoderSource::read(MediaBuffer **buffer,
184 const ReadOptions *options) {
185 Mutex::Autolock autolock(mLock);
186 MediaSource::ReadOptions readOptions;
188 MediaBufferChain* tmpLink = NULL;
190 ALOGV("VideoEditorVideoEncoderSource::read() begin");
192 if ( STARTED != mState ) {
193 ALOGV("VideoEditorVideoEncoderSource::read: invalid state %d", mState);
194 return UNKNOWN_ERROR;
197 while (mFirstBufferLink == NULL && !mIsEOS) {
198 mBufferCond.wait(mLock);
202 if (mFirstBufferLink == NULL) {
204 ALOGV("VideoEditorVideoEncoderSource::read : EOS");
205 return ERROR_END_OF_STREAM;
208 // Get a buffer from the chain
209 *buffer = mFirstBufferLink->buffer;
210 tmpLink = mFirstBufferLink;
211 mFirstBufferLink = mFirstBufferLink->nextLink;
213 if ( NULL == mFirstBufferLink ) {
214 mLastBufferLink = NULL;
219 ALOGV("VideoEditorVideoEncoderSource::read() END (0x%x)", err);
223 int32_t VideoEditorVideoEncoderSource::storeBuffer(MediaBuffer *buffer) {
224 Mutex::Autolock autolock(mLock);
227 ALOGV("VideoEditorVideoEncoderSource::storeBuffer() begin");
229 if( NULL == buffer ) {
230 ALOGV("VideoEditorVideoEncoderSource::storeBuffer : reached EOS");
233 MediaBufferChain* newLink = new MediaBufferChain;
234 newLink->buffer = buffer;
235 newLink->nextLink = NULL;
236 if( NULL != mLastBufferLink ) {
237 mLastBufferLink->nextLink = newLink;
239 mFirstBufferLink = newLink;
241 mLastBufferLink = newLink;
244 mBufferCond.signal();
245 ALOGV("VideoEditorVideoEncoderSource::storeBuffer() end");
249 int32_t VideoEditorVideoEncoderSource::getNumberOfBuffersInQueue() {
250 Mutex::Autolock autolock(mLock);
255 ******************************************************************************
256 * structure VideoEditorVideoEncoder_Context
257 * @brief This structure defines the context of the StageFright video encoder
259 ******************************************************************************
267 } VideoEditorVideoEncoder_State;
270 VideoEditorVideoEncoder_State mState;
271 M4ENCODER_Format mFormat;
272 M4WRITER_DataInterface* mWriterDataInterface;
273 M4VPP_apply_fct* mPreProcFunction;
274 M4VPP_Context mPreProcContext;
275 M4SYS_AccessUnit* mAccessUnit;
276 M4ENCODER_Params* mCodecParams;
277 M4ENCODER_Header mHeader;
278 H264MCS_ProcessEncodedNALU_fct* mH264NALUPostProcessFct;
279 M4OSA_Context mH264NALUPostProcessCtx;
280 M4OSA_UInt32 mLastCTS;
281 sp<VideoEditorVideoEncoderSource> mEncoderSource;
283 sp<MediaSource> mEncoder;
284 OMX_COLOR_FORMATTYPE mEncoderColorFormat;
285 MediaBufferPuller* mPuller;
286 I420ColorConverter* mI420ColorConverter;
288 uint32_t mNbInputFrames;
289 double mFirstInputCts;
290 double mLastInputCts;
291 uint32_t mNbOutputFrames;
292 int64_t mFirstOutputCts;
293 int64_t mLastOutputCts;
295 MediaProfiles *mVideoEditorProfile;
296 int32_t mMaxPrefetchFrames;
297 } VideoEditorVideoEncoder_Context;
299 /********************
301 ********************/
303 M4OSA_ERR VideoEditorVideoEncoder_getDSI(M4ENCODER_Context pContext,
304 sp<MetaData> metaData) {
305 M4OSA_ERR err = M4NO_ERROR;
306 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
307 status_t result = OK;
308 int32_t nbBuffer = 0;
311 int32_t framerate = 0;
312 int32_t isCodecConfig = 0;
314 uint32_t codecFlags = 0;
315 MediaBuffer* inputBuffer = NULL;
316 MediaBuffer* outputBuffer = NULL;
317 sp<VideoEditorVideoEncoderSource> encoderSource = NULL;
318 sp<MediaSource> encoder = NULL;;
321 ALOGV("VideoEditorVideoEncoder_getDSI begin");
322 // Input parameters check
323 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
324 VIDEOEDITOR_CHECK(M4OSA_NULL != metaData.get(), M4ERR_PARAMETER);
326 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
327 VIDEOEDITOR_CHECK(CREATED == pEncoderContext->mState, M4ERR_STATE);
329 // Create the encoder source
330 encoderSource = VideoEditorVideoEncoderSource::Create(metaData);
331 VIDEOEDITOR_CHECK(NULL != encoderSource.get(), M4ERR_STATE);
333 // Connect to the OMX client
334 result = client.connect();
335 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);
337 // Create the OMX codec
338 // VIDEOEDITOR_FORCECODEC MUST be defined here
339 codecFlags |= OMXCodec::VIDEOEDITOR_FORCECODEC;
340 encoder = OMXCodec::Create(client.interface(), metaData, true,
341 encoderSource, NULL, codecFlags);
342 VIDEOEDITOR_CHECK(NULL != encoder.get(), M4ERR_STATE);
345 * Send fake frames and retrieve the DSI
347 // Send a fake frame to the source
348 metaData->findInt32(kKeyStride, &stride);
349 metaData->findInt32(kKeyHeight, &height);
350 metaData->findInt32(kKeySampleRate, &framerate);
351 size = (size_t)(stride*height*3)/2;
352 inputBuffer = new MediaBuffer(size);
353 inputBuffer->meta_data()->setInt64(kKeyTime, 0);
354 nbBuffer = encoderSource->storeBuffer(inputBuffer);
355 encoderSource->storeBuffer(NULL); // Signal EOS
357 // Call read once to get the DSI
358 result = encoder->start();;
359 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);
360 result = encoder->read(&outputBuffer, NULL);
361 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);
362 VIDEOEDITOR_CHECK(outputBuffer->meta_data()->findInt32(
363 kKeyIsCodecConfig, &isCodecConfig) && isCodecConfig, M4ERR_STATE);
365 VIDEOEDITOR_CHECK(M4OSA_NULL == pEncoderContext->mHeader.pBuf, M4ERR_STATE);
366 if ( M4ENCODER_kH264 == pEncoderContext->mFormat ) {
367 // For H264, format the DSI
368 result = buildAVCCodecSpecificData(
369 (uint8_t**)(&(pEncoderContext->mHeader.pBuf)),
370 (size_t*)(&(pEncoderContext->mHeader.Size)),
371 (const uint8_t*)outputBuffer->data() + outputBuffer->range_offset(),
372 outputBuffer->range_length(), encoder->getFormat().get());
373 outputBuffer->release();
374 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);
376 // For MPEG4, just copy the DSI
377 pEncoderContext->mHeader.Size =
378 (M4OSA_UInt32)outputBuffer->range_length();
379 SAFE_MALLOC(pEncoderContext->mHeader.pBuf, M4OSA_Int8,
380 pEncoderContext->mHeader.Size, "Encoder header");
381 memcpy((void *)pEncoderContext->mHeader.pBuf,
382 (void *)((M4OSA_MemAddr8)(outputBuffer->data())+outputBuffer->range_offset()),
383 pEncoderContext->mHeader.Size);
384 outputBuffer->release();
387 result = encoder->stop();
388 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);
392 if ( encoder != NULL ) { encoder.clear(); }
394 if ( encoderSource != NULL ) { encoderSource.clear(); }
395 if ( M4NO_ERROR == err ) {
396 ALOGV("VideoEditorVideoEncoder_getDSI no error");
398 ALOGV("VideoEditorVideoEncoder_getDSI ERROR 0x%X", err);
400 ALOGV("VideoEditorVideoEncoder_getDSI end");
403 /********************
405 ********************/
407 M4OSA_ERR VideoEditorVideoEncoder_cleanup(M4ENCODER_Context pContext) {
408 M4OSA_ERR err = M4NO_ERROR;
409 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
411 ALOGV("VideoEditorVideoEncoder_cleanup begin");
412 // Input parameters check
413 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
415 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
416 VIDEOEDITOR_CHECK(CREATED == pEncoderContext->mState, M4ERR_STATE);
419 SAFE_FREE(pEncoderContext->mHeader.pBuf);
420 SAFE_FREE(pEncoderContext);
421 pContext = M4OSA_NULL;
424 if ( M4NO_ERROR == err ) {
425 ALOGV("VideoEditorVideoEncoder_cleanup no error");
427 ALOGV("VideoEditorVideoEncoder_cleanup ERROR 0x%X", err);
429 ALOGV("VideoEditorVideoEncoder_cleanup end");
433 M4OSA_ERR VideoEditorVideoEncoder_init(M4ENCODER_Format format,
434 M4ENCODER_Context* pContext,
435 M4WRITER_DataInterface* pWriterDataInterface,
436 M4VPP_apply_fct* pVPPfct, M4VPP_Context pVPPctxt,
437 M4OSA_Void* pExternalAPI, M4OSA_Void* pUserData) {
439 M4OSA_ERR err = M4NO_ERROR;
440 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
441 int encoderInput = OMX_COLOR_FormatYUV420Planar;
443 ALOGV("VideoEditorVideoEncoder_init begin: format %d", format);
444 // Input parameters check
445 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
446 VIDEOEDITOR_CHECK(M4OSA_NULL != pWriterDataInterface, M4ERR_PARAMETER);
447 VIDEOEDITOR_CHECK(M4OSA_NULL != pVPPfct, M4ERR_PARAMETER);
448 VIDEOEDITOR_CHECK(M4OSA_NULL != pVPPctxt, M4ERR_PARAMETER);
450 // Context allocation & initialization
451 SAFE_MALLOC(pEncoderContext, VideoEditorVideoEncoder_Context, 1,
452 "VideoEditorVideoEncoder");
453 pEncoderContext->mState = CREATED;
454 pEncoderContext->mFormat = format;
455 pEncoderContext->mWriterDataInterface = pWriterDataInterface;
456 pEncoderContext->mPreProcFunction = pVPPfct;
457 pEncoderContext->mPreProcContext = pVPPctxt;
458 pEncoderContext->mPuller = NULL;
460 // Get color converter and determine encoder input format
461 pEncoderContext->mI420ColorConverter = new I420ColorConverter;
462 if (pEncoderContext->mI420ColorConverter->isLoaded()) {
463 encoderInput = pEncoderContext->mI420ColorConverter->getEncoderInputFormat();
465 if (encoderInput == OMX_COLOR_FormatYUV420Planar) {
466 delete pEncoderContext->mI420ColorConverter;
467 pEncoderContext->mI420ColorConverter = NULL;
469 pEncoderContext->mEncoderColorFormat = (OMX_COLOR_FORMATTYPE)encoderInput;
470 ALOGI("encoder input format = 0x%X\n", encoderInput);
472 *pContext = pEncoderContext;
475 if ( M4NO_ERROR == err ) {
476 ALOGV("VideoEditorVideoEncoder_init no error");
478 VideoEditorVideoEncoder_cleanup(pEncoderContext);
479 *pContext = M4OSA_NULL;
480 ALOGV("VideoEditorVideoEncoder_init ERROR 0x%X", err);
482 ALOGV("VideoEditorVideoEncoder_init end");
486 M4OSA_ERR VideoEditorVideoEncoder_init_H263(M4ENCODER_Context* pContext,
487 M4WRITER_DataInterface* pWriterDataInterface, M4VPP_apply_fct* pVPPfct,
488 M4VPP_Context pVPPctxt, M4OSA_Void* pExternalAPI, M4OSA_Void* pUserData)
491 return VideoEditorVideoEncoder_init(M4ENCODER_kH263, pContext,
492 pWriterDataInterface, pVPPfct, pVPPctxt, pExternalAPI, pUserData);
496 M4OSA_ERR VideoEditorVideoEncoder_init_MPEG4(M4ENCODER_Context* pContext,
497 M4WRITER_DataInterface* pWriterDataInterface, M4VPP_apply_fct* pVPPfct,
498 M4VPP_Context pVPPctxt, M4OSA_Void* pExternalAPI, M4OSA_Void* pUserData)
501 return VideoEditorVideoEncoder_init(M4ENCODER_kMPEG4, pContext,
502 pWriterDataInterface, pVPPfct, pVPPctxt, pExternalAPI, pUserData);
506 M4OSA_ERR VideoEditorVideoEncoder_init_H264(M4ENCODER_Context* pContext,
507 M4WRITER_DataInterface* pWriterDataInterface, M4VPP_apply_fct* pVPPfct,
508 M4VPP_Context pVPPctxt, M4OSA_Void* pExternalAPI, M4OSA_Void* pUserData)
511 return VideoEditorVideoEncoder_init(M4ENCODER_kH264, pContext,
512 pWriterDataInterface, pVPPfct, pVPPctxt, pExternalAPI, pUserData);
515 M4OSA_ERR VideoEditorVideoEncoder_close(M4ENCODER_Context pContext) {
516 M4OSA_ERR err = M4NO_ERROR;
517 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
519 ALOGV("VideoEditorVideoEncoder_close begin");
520 // Input parameters check
521 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
523 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
524 VIDEOEDITOR_CHECK(OPENED == pEncoderContext->mState, M4ERR_STATE);
527 SAFE_FREE(pEncoderContext->mCodecParams);
530 pEncoderContext->mEncoder.clear();
531 pEncoderContext->mClient.disconnect();
532 pEncoderContext->mEncoderSource.clear();
534 delete pEncoderContext->mPuller;
535 pEncoderContext->mPuller = NULL;
537 delete pEncoderContext->mI420ColorConverter;
538 pEncoderContext->mI420ColorConverter = NULL;
541 pEncoderContext->mState = CREATED;
544 if( M4NO_ERROR == err ) {
545 ALOGV("VideoEditorVideoEncoder_close no error");
547 ALOGV("VideoEditorVideoEncoder_close ERROR 0x%X", err);
549 ALOGV("VideoEditorVideoEncoder_close end");
554 M4OSA_ERR VideoEditorVideoEncoder_open(M4ENCODER_Context pContext,
555 M4SYS_AccessUnit* pAU, M4OSA_Void* pParams) {
556 M4OSA_ERR err = M4NO_ERROR;
557 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
558 M4ENCODER_Params* pCodecParams = M4OSA_NULL;
559 status_t result = OK;
560 sp<MetaData> encoderMetadata = NULL;
561 const char* mime = NULL;
562 int32_t iProfile = 0;
565 int32_t iFrameRate = 0;
566 uint32_t codecFlags = 0;
568 ALOGV(">>> VideoEditorVideoEncoder_open begin");
569 // Input parameters check
570 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
571 VIDEOEDITOR_CHECK(M4OSA_NULL != pAU, M4ERR_PARAMETER);
572 VIDEOEDITOR_CHECK(M4OSA_NULL != pParams, M4ERR_PARAMETER);
574 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
575 pCodecParams = (M4ENCODER_Params*)pParams;
576 VIDEOEDITOR_CHECK(CREATED == pEncoderContext->mState, M4ERR_STATE);
578 // Context initialization
579 pEncoderContext->mAccessUnit = pAU;
580 pEncoderContext->mVideoEditorProfile = MediaProfiles::getInstance();
581 pEncoderContext->mMaxPrefetchFrames =
582 pEncoderContext->mVideoEditorProfile->getVideoEditorCapParamByName(
583 "maxPrefetchYUVFrames");
585 // Allocate & initialize the encoding parameters
586 SAFE_MALLOC(pEncoderContext->mCodecParams, M4ENCODER_Params, 1,
587 "VideoEditorVideoEncoder");
590 pEncoderContext->mCodecParams->InputFormat = pCodecParams->InputFormat;
591 pEncoderContext->mCodecParams->InputFrameWidth =
592 pCodecParams->InputFrameWidth;
593 pEncoderContext->mCodecParams->InputFrameHeight =
594 pCodecParams->InputFrameHeight;
595 pEncoderContext->mCodecParams->FrameWidth = pCodecParams->FrameWidth;
596 pEncoderContext->mCodecParams->FrameHeight = pCodecParams->FrameHeight;
597 pEncoderContext->mCodecParams->Bitrate = pCodecParams->Bitrate;
598 pEncoderContext->mCodecParams->FrameRate = pCodecParams->FrameRate;
599 pEncoderContext->mCodecParams->Format = pCodecParams->Format;
600 pEncoderContext->mCodecParams->videoProfile = pCodecParams->videoProfile;
601 pEncoderContext->mCodecParams->videoLevel= pCodecParams->videoLevel;
603 // Check output format consistency and resolution
605 pEncoderContext->mCodecParams->Format == pEncoderContext->mFormat,
607 VIDEOEDITOR_CHECK(0 == pEncoderContext->mCodecParams->FrameWidth % 16,
609 VIDEOEDITOR_CHECK(0 == pEncoderContext->mCodecParams->FrameHeight % 16,
613 * StageFright graph building
616 // Create the meta data for the encoder
617 encoderMetadata = new MetaData;
618 switch( pEncoderContext->mCodecParams->Format ) {
619 case M4ENCODER_kH263:
620 mime = MEDIA_MIMETYPE_VIDEO_H263;
622 case M4ENCODER_kMPEG4:
623 mime = MEDIA_MIMETYPE_VIDEO_MPEG4;
625 case M4ENCODER_kH264:
626 mime = MEDIA_MIMETYPE_VIDEO_AVC;
629 VIDEOEDITOR_CHECK(!"VideoEncoder_open : incorrect input format",
633 iProfile = pEncoderContext->mCodecParams->videoProfile;
634 iLevel = pEncoderContext->mCodecParams->videoLevel;
635 ALOGV("Encoder mime %s profile %d, level %d",
636 mime,iProfile, iLevel);
637 ALOGV("Encoder w %d, h %d, bitrate %d, fps %d",
638 pEncoderContext->mCodecParams->FrameWidth,
639 pEncoderContext->mCodecParams->FrameHeight,
640 pEncoderContext->mCodecParams->Bitrate,
641 pEncoderContext->mCodecParams->FrameRate);
642 CHECK(iProfile != 0x7fffffff);
643 CHECK(iLevel != 0x7fffffff);
645 encoderMetadata->setCString(kKeyMIMEType, mime);
646 encoderMetadata->setInt32(kKeyVideoProfile, iProfile);
648 // Temp: Do not set the level for Mpeg4 / H.263 Enc
649 // as OMX.Nvidia.mp4.encoder and OMX.Nvidia.h263.encoder
651 if (pEncoderContext->mCodecParams->Format == M4ENCODER_kH264) {
652 encoderMetadata->setInt32(kKeyVideoLevel, iLevel);
654 encoderMetadata->setInt32(kKeyWidth,
655 (int32_t)pEncoderContext->mCodecParams->FrameWidth);
656 encoderMetadata->setInt32(kKeyStride,
657 (int32_t)pEncoderContext->mCodecParams->FrameWidth);
658 encoderMetadata->setInt32(kKeyHeight,
659 (int32_t)pEncoderContext->mCodecParams->FrameHeight);
660 encoderMetadata->setInt32(kKeySliceHeight,
661 (int32_t)pEncoderContext->mCodecParams->FrameHeight);
663 switch( pEncoderContext->mCodecParams->FrameRate ) {
664 case M4ENCODER_k5_FPS: iFrameRate = 5; break;
665 case M4ENCODER_k7_5_FPS: iFrameRate = 8; break;
666 case M4ENCODER_k10_FPS: iFrameRate = 10; break;
667 case M4ENCODER_k12_5_FPS: iFrameRate = 13; break;
668 case M4ENCODER_k15_FPS: iFrameRate = 15; break;
669 case M4ENCODER_k20_FPS: iFrameRate = 20; break;
670 case M4ENCODER_k25_FPS: iFrameRate = 25; break;
671 case M4ENCODER_k30_FPS: iFrameRate = 30; break;
672 case M4ENCODER_kVARIABLE_FPS:
674 ALOGI("Frame rate set to M4ENCODER_kVARIABLE_FPS: set to 30");
676 case M4ENCODER_kUSE_TIMESCALE:
678 ALOGI("Frame rate set to M4ENCODER_kUSE_TIMESCALE: set to 30");
682 VIDEOEDITOR_CHECK(!"VideoEncoder_open:incorrect framerate",
686 encoderMetadata->setInt32(kKeyFrameRate, iFrameRate);
687 encoderMetadata->setInt32(kKeyBitRate,
688 (int32_t)pEncoderContext->mCodecParams->Bitrate);
689 encoderMetadata->setInt32(kKeyIFramesInterval, 1);
691 encoderMetadata->setInt32(kKeyColorFormat,
692 pEncoderContext->mEncoderColorFormat);
694 if (pEncoderContext->mCodecParams->Format != M4ENCODER_kH263) {
695 // Get the encoder DSI
696 err = VideoEditorVideoEncoder_getDSI(pEncoderContext, encoderMetadata);
697 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
700 // Create the encoder source
701 pEncoderContext->mEncoderSource = VideoEditorVideoEncoderSource::Create(
704 NULL != pEncoderContext->mEncoderSource.get(), M4ERR_STATE);
706 // Connect to the OMX client
707 result = pEncoderContext->mClient.connect();
708 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);
710 // Create the OMX codec
711 #ifdef VIDEOEDITOR_FORCECODEC
712 codecFlags |= OMXCodec::VIDEOEDITOR_FORCECODEC;
713 #endif /* VIDEOEDITOR_FORCECODEC */
714 pEncoderContext->mEncoder = OMXCodec::Create(
715 pEncoderContext->mClient.interface(), encoderMetadata, true,
716 pEncoderContext->mEncoderSource, NULL, codecFlags);
717 VIDEOEDITOR_CHECK(NULL != pEncoderContext->mEncoder.get(), M4ERR_STATE);
718 ALOGV("VideoEditorVideoEncoder_open : DONE");
719 pEncoderContext->mPuller = new MediaBufferPuller(
720 pEncoderContext->mEncoder);
723 pEncoderContext->mState = OPENED;
726 if( M4NO_ERROR == err ) {
727 ALOGV("VideoEditorVideoEncoder_open no error");
729 VideoEditorVideoEncoder_close(pEncoderContext);
730 ALOGV("VideoEditorVideoEncoder_open ERROR 0x%X", err);
732 ALOGV("VideoEditorVideoEncoder_open end");
736 M4OSA_ERR VideoEditorVideoEncoder_processInputBuffer(
737 M4ENCODER_Context pContext, M4OSA_Double Cts,
738 M4OSA_Bool bReachedEOS) {
739 M4OSA_ERR err = M4NO_ERROR;
740 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
741 M4VIFI_ImagePlane pOutPlane[3];
742 MediaBuffer* buffer = NULL;
743 int32_t nbBuffer = 0;
745 ALOGV("VideoEditorVideoEncoder_processInputBuffer begin: cts %f", Cts);
746 // Input parameters check
747 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
749 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
750 pOutPlane[0].pac_data = M4OSA_NULL;
751 pOutPlane[1].pac_data = M4OSA_NULL;
752 pOutPlane[2].pac_data = M4OSA_NULL;
754 if ( M4OSA_FALSE == bReachedEOS ) {
755 M4OSA_UInt32 sizeY = pEncoderContext->mCodecParams->FrameWidth *
756 pEncoderContext->mCodecParams->FrameHeight;
757 M4OSA_UInt32 sizeU = sizeY >> 2;
758 M4OSA_UInt32 size = sizeY + 2*sizeU;
759 M4OSA_UInt8* pData = M4OSA_NULL;
760 buffer = new MediaBuffer((size_t)size);
761 pData = (M4OSA_UInt8*)buffer->data() + buffer->range_offset();
763 // Prepare the output image for pre-processing
764 pOutPlane[0].u_width = pEncoderContext->mCodecParams->FrameWidth;
765 pOutPlane[0].u_height = pEncoderContext->mCodecParams->FrameHeight;
766 pOutPlane[0].u_topleft = 0;
767 pOutPlane[0].u_stride = pOutPlane[0].u_width;
768 pOutPlane[1].u_width = pOutPlane[0].u_width/2;
769 pOutPlane[1].u_height = pOutPlane[0].u_height/2;
770 pOutPlane[1].u_topleft = 0;
771 pOutPlane[1].u_stride = pOutPlane[0].u_stride/2;
772 pOutPlane[2].u_width = pOutPlane[1].u_width;
773 pOutPlane[2].u_height = pOutPlane[1].u_height;
774 pOutPlane[2].u_topleft = 0;
775 pOutPlane[2].u_stride = pOutPlane[1].u_stride;
777 pOutPlane[0].pac_data = pData;
778 pOutPlane[1].pac_data = pData + sizeY;
779 pOutPlane[2].pac_data = pData + sizeY + sizeU;
781 // Apply pre-processing
782 err = pEncoderContext->mPreProcFunction(
783 pEncoderContext->mPreProcContext, M4OSA_NULL, pOutPlane);
784 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
786 // Convert MediaBuffer to the encoder input format if necessary
787 if (pEncoderContext->mI420ColorConverter) {
788 I420ColorConverter* converter = pEncoderContext->mI420ColorConverter;
789 int actualWidth = pEncoderContext->mCodecParams->FrameWidth;
790 int actualHeight = pEncoderContext->mCodecParams->FrameHeight;
792 int encoderWidth, encoderHeight;
794 int encoderBufferSize;
796 if (converter->getEncoderInputBufferInfo(
797 actualWidth, actualHeight,
798 &encoderWidth, &encoderHeight,
799 &encoderRect, &encoderBufferSize) == 0) {
801 MediaBuffer* newBuffer = new MediaBuffer(encoderBufferSize);
803 if (converter->convertI420ToEncoderInput(
805 actualWidth, actualHeight,
806 encoderWidth, encoderHeight,
808 (uint8_t*)newBuffer->data() + newBuffer->range_offset()) < 0) {
809 ALOGE("convertI420ToEncoderInput failed");
812 // switch to new buffer
819 buffer->meta_data()->setInt64(kKeyTime, (int64_t)(Cts*1000));
822 // Push the buffer to the source, a NULL buffer, notifies the source of EOS
823 nbBuffer = pEncoderContext->mEncoderSource->storeBuffer(buffer);
826 if ( M4NO_ERROR == err ) {
827 ALOGV("VideoEditorVideoEncoder_processInputBuffer error 0x%X", err);
829 if( NULL != buffer ) {
832 ALOGV("VideoEditorVideoEncoder_processInputBuffer ERROR 0x%X", err);
834 ALOGV("VideoEditorVideoEncoder_processInputBuffer end");
838 M4OSA_ERR VideoEditorVideoEncoder_processOutputBuffer(
839 M4ENCODER_Context pContext, MediaBuffer* buffer) {
840 M4OSA_ERR err = M4NO_ERROR;
841 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
842 M4OSA_UInt32 Cts = 0;
845 status_t result = OK;
847 ALOGV("VideoEditorVideoEncoder_processOutputBuffer begin");
848 // Input parameters check
849 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
850 VIDEOEDITOR_CHECK(M4OSA_NULL != buffer, M4ERR_PARAMETER);
852 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
854 // Process the returned AU
855 if ( 0 == buffer->range_length() ) {
856 // Encoder has no data yet, nothing unusual
857 ALOGV("VideoEditorVideoEncoder_processOutputBuffer : buffer is empty");
860 VIDEOEDITOR_CHECK(0 == ((M4OSA_UInt32)buffer->data())%4, M4ERR_PARAMETER);
861 VIDEOEDITOR_CHECK(buffer->meta_data().get(), M4ERR_PARAMETER);
862 if ( buffer->meta_data()->findInt32(kKeyIsCodecConfig, &i32Tmp) && i32Tmp ){
864 ALOGV("VideoEditorVideoEncoder_processOutputBuffer DSI %d",
865 buffer->range_length());
866 uint8_t* tmp = (uint8_t*)(buffer->data());
867 for( uint32_t i=0; i<buffer->range_length(); i++ ) {
868 ALOGV("DSI [%d] %.2X", i, tmp[i]);
873 VIDEOEDITOR_CHECK(buffer->meta_data()->findInt64(kKeyTime, &i64Tmp),
876 pEncoderContext->mNbOutputFrames++;
877 if ( 0 > pEncoderContext->mFirstOutputCts ) {
878 pEncoderContext->mFirstOutputCts = i64Tmp;
880 pEncoderContext->mLastOutputCts = i64Tmp;
882 Cts = (M4OSA_Int32)(i64Tmp/1000);
883 ALOGV("[TS_CHECK] VI/ENC WRITE frame %d @ %lld -> %d (last %d)",
884 pEncoderContext->mNbOutputFrames, i64Tmp, Cts,
885 pEncoderContext->mLastCTS);
886 if ( Cts < pEncoderContext->mLastCTS ) {
887 ALOGV("VideoEncoder_processOutputBuffer WARNING : Cts is going "
888 "backwards %d < %d", Cts, pEncoderContext->mLastCTS);
891 ALOGV("VideoEditorVideoEncoder_processOutputBuffer : %d %d",
892 Cts, pEncoderContext->mLastCTS);
894 // Retrieve the AU container
895 err = pEncoderContext->mWriterDataInterface->pStartAU(
896 pEncoderContext->mWriterDataInterface->pWriterContext,
897 pEncoderContext->mAccessUnit->stream->streamID,
898 pEncoderContext->mAccessUnit);
899 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
903 buffer->range_length() <= pEncoderContext->mAccessUnit->size,
905 // Remove H264 AU start code
906 if ( M4ENCODER_kH264 == pEncoderContext->mFormat ) {
907 if (!memcmp((const uint8_t *)buffer->data() + \
908 buffer->range_offset(), "\x00\x00\x00\x01", 4) ) {
909 buffer->set_range(buffer->range_offset() + 4,
910 buffer->range_length() - 4);
914 if ( (M4ENCODER_kH264 == pEncoderContext->mFormat) &&
915 (M4OSA_NULL != pEncoderContext->mH264NALUPostProcessFct) ) {
916 // H264 trimming case, NALU post processing is needed
917 M4OSA_Int32 outputSize = pEncoderContext->mAccessUnit->size;
918 err = pEncoderContext->mH264NALUPostProcessFct(
919 pEncoderContext->mH264NALUPostProcessCtx,
920 (M4OSA_UInt8*)buffer->data()+buffer->range_offset(),
921 buffer->range_length(),
922 (M4OSA_UInt8*)pEncoderContext->mAccessUnit->dataAddress,
924 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
925 pEncoderContext->mAccessUnit->size = (M4OSA_UInt32)outputSize;
927 // The AU can just be copied
928 memcpy((void *)pEncoderContext->mAccessUnit->\
929 dataAddress, (void *)((M4OSA_MemAddr8)(buffer->data())+buffer->\
930 range_offset()), buffer->range_length());
931 pEncoderContext->mAccessUnit->size =
932 (M4OSA_UInt32)buffer->range_length();
935 if ( buffer->meta_data()->findInt32(kKeyIsSyncFrame,&i32Tmp) && i32Tmp){
936 pEncoderContext->mAccessUnit->attribute = AU_RAP;
938 pEncoderContext->mAccessUnit->attribute = AU_P_Frame;
940 pEncoderContext->mLastCTS = Cts;
941 pEncoderContext->mAccessUnit->CTS = Cts;
942 pEncoderContext->mAccessUnit->DTS = Cts;
944 ALOGV("VideoEditorVideoEncoder_processOutputBuffer: AU @ 0x%X 0x%X %d %d",
945 pEncoderContext->mAccessUnit->dataAddress,
946 *pEncoderContext->mAccessUnit->dataAddress,
947 pEncoderContext->mAccessUnit->size,
948 pEncoderContext->mAccessUnit->CTS);
951 err = pEncoderContext->mWriterDataInterface->pProcessAU(
952 pEncoderContext->mWriterDataInterface->pWriterContext,
953 pEncoderContext->mAccessUnit->stream->streamID,
954 pEncoderContext->mAccessUnit);
955 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
959 if( M4NO_ERROR == err ) {
960 ALOGV("VideoEditorVideoEncoder_processOutputBuffer no error");
962 SAFE_FREE(pEncoderContext->mHeader.pBuf);
963 pEncoderContext->mHeader.Size = 0;
964 ALOGV("VideoEditorVideoEncoder_processOutputBuffer ERROR 0x%X", err);
966 ALOGV("VideoEditorVideoEncoder_processOutputBuffer end");
970 M4OSA_ERR VideoEditorVideoEncoder_encode(M4ENCODER_Context pContext,
971 M4VIFI_ImagePlane* pInPlane, M4OSA_Double Cts,
972 M4ENCODER_FrameMode FrameMode) {
973 M4OSA_ERR err = M4NO_ERROR;
974 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
975 status_t result = OK;
976 MediaBuffer* outputBuffer = NULL;
978 ALOGV("VideoEditorVideoEncoder_encode 0x%X %f %d", pInPlane, Cts, FrameMode);
979 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
981 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
982 if ( STARTED == pEncoderContext->mState ) {
983 pEncoderContext->mState = BUFFERING;
986 (BUFFERING | READING) & pEncoderContext->mState, M4ERR_STATE);
988 pEncoderContext->mNbInputFrames++;
989 if ( 0 > pEncoderContext->mFirstInputCts ) {
990 pEncoderContext->mFirstInputCts = Cts;
992 pEncoderContext->mLastInputCts = Cts;
994 ALOGV("VideoEditorVideoEncoder_encode 0x%X %d %f (%d)", pInPlane, FrameMode,
995 Cts, pEncoderContext->mLastCTS);
997 // Push the input buffer to the encoder source
998 err = VideoEditorVideoEncoder_processInputBuffer(pEncoderContext, Cts,
1000 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
1002 // Notify the source in case of EOS
1003 if ( M4ENCODER_kLastFrame == FrameMode ) {
1004 err = VideoEditorVideoEncoder_processInputBuffer(
1005 pEncoderContext, 0, M4OSA_TRUE);
1006 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
1009 if ( BUFFERING == pEncoderContext->mState ) {
1010 // Prefetch is complete, start reading
1011 pEncoderContext->mState = READING;
1015 MediaBuffer *outputBuffer =
1016 pEncoderContext->mPuller->getBufferNonBlocking();
1018 if (outputBuffer == NULL) {
1019 int32_t YUVBufferNumber =
1020 pEncoderContext->mEncoderSource->getNumberOfBuffersInQueue();
1021 /* Make sure that the configured maximum number of prefetch YUV frames is
1022 * not exceeded. This is to limit the amount of memory usage of video editor engine.
1023 * The value of maximum prefetch Yuv frames is defined in media_profiles.xml */
1024 if ((YUVBufferNumber < pEncoderContext->mMaxPrefetchFrames) ||
1025 (pEncoderContext->mPuller->hasMediaSourceReturnedError()
1030 // Provide the encoded AU to the writer
1031 err = VideoEditorVideoEncoder_processOutputBuffer(pEncoderContext,
1033 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
1035 pEncoderContext->mPuller->putBuffer(outputBuffer);
1040 if( M4NO_ERROR == err ) {
1041 ALOGV("VideoEditorVideoEncoder_encode no error");
1043 ALOGV("VideoEditorVideoEncoder_encode ERROR 0x%X", err);
1045 ALOGV("VideoEditorVideoEncoder_encode end");
1049 M4OSA_ERR VideoEditorVideoEncoder_start(M4ENCODER_Context pContext) {
1050 M4OSA_ERR err = M4NO_ERROR;
1051 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
1052 status_t result = OK;
1054 ALOGV("VideoEditorVideoEncoder_start begin");
1055 // Input parameters check
1056 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
1058 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
1059 VIDEOEDITOR_CHECK(OPENED == pEncoderContext->mState, M4ERR_STATE);
1061 pEncoderContext->mNbInputFrames = 0;
1062 pEncoderContext->mFirstInputCts = -1.0;
1063 pEncoderContext->mLastInputCts = -1.0;
1064 pEncoderContext->mNbOutputFrames = 0;
1065 pEncoderContext->mFirstOutputCts = -1;
1066 pEncoderContext->mLastOutputCts = -1;
1068 result = pEncoderContext->mEncoder->start();
1069 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE);
1071 pEncoderContext->mPuller->start();
1073 // Set the new state
1074 pEncoderContext->mState = STARTED;
1077 if ( M4NO_ERROR == err ) {
1078 ALOGV("VideoEditorVideoEncoder_start no error");
1080 ALOGV("VideoEditorVideoEncoder_start ERROR 0x%X", err);
1082 ALOGV("VideoEditorVideoEncoder_start end");
1086 M4OSA_ERR VideoEditorVideoEncoder_stop(M4ENCODER_Context pContext) {
1087 M4OSA_ERR err = M4NO_ERROR;
1088 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
1089 MediaBuffer* outputBuffer = NULL;
1090 status_t result = OK;
1092 ALOGV("VideoEditorVideoEncoder_stop begin");
1093 // Input parameters check
1094 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
1095 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
1097 // Send EOS again to make sure the source doesn't block.
1098 err = VideoEditorVideoEncoder_processInputBuffer(pEncoderContext, 0,
1100 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
1102 // Process the remaining buffers if necessary
1103 if ( (BUFFERING | READING) & pEncoderContext->mState ) {
1105 MediaBuffer *outputBuffer =
1106 pEncoderContext->mPuller->getBufferBlocking();
1108 if (outputBuffer == NULL) break;
1110 err = VideoEditorVideoEncoder_processOutputBuffer(
1111 pEncoderContext, outputBuffer);
1112 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
1114 pEncoderContext->mPuller->putBuffer(outputBuffer);
1117 pEncoderContext->mState = STARTED;
1120 // Stop the graph module if necessary
1121 if ( STARTED == pEncoderContext->mState ) {
1122 pEncoderContext->mPuller->stop();
1123 pEncoderContext->mEncoder->stop();
1124 pEncoderContext->mState = OPENED;
1127 if (pEncoderContext->mNbInputFrames != pEncoderContext->mNbOutputFrames) {
1128 ALOGW("Some frames were not encoded: input(%d) != output(%d)",
1129 pEncoderContext->mNbInputFrames, pEncoderContext->mNbOutputFrames);
1133 if ( M4NO_ERROR == err ) {
1134 ALOGV("VideoEditorVideoEncoder_stop no error");
1136 ALOGV("VideoEditorVideoEncoder_stop ERROR 0x%X", err);
1138 ALOGV("VideoEditorVideoEncoder_stop end");
1142 M4OSA_ERR VideoEditorVideoEncoder_regulBitRate(M4ENCODER_Context pContext) {
1143 ALOGW("regulBitRate is not implemented");
1147 M4OSA_ERR VideoEditorVideoEncoder_setOption(M4ENCODER_Context pContext,
1148 M4OSA_UInt32 optionID, M4OSA_DataOption optionValue) {
1149 M4OSA_ERR err = M4NO_ERROR;
1150 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
1152 ALOGV("VideoEditorVideoEncoder_setOption start optionID 0x%X", optionID);
1153 // Input parameters check
1154 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
1156 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
1158 switch( optionID ) {
1159 case M4ENCODER_kOptionID_SetH264ProcessNALUfctsPtr:
1160 pEncoderContext->mH264NALUPostProcessFct =
1161 (H264MCS_ProcessEncodedNALU_fct*)optionValue;
1163 case M4ENCODER_kOptionID_H264ProcessNALUContext:
1164 pEncoderContext->mH264NALUPostProcessCtx =
1165 (M4OSA_Context)optionValue;
1168 ALOGV("VideoEditorVideoEncoder_setOption: unsupported optionId 0x%X",
1170 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_BAD_OPTION_ID);
1175 if ( M4NO_ERROR == err ) {
1176 ALOGV("VideoEditorVideoEncoder_setOption no error");
1178 ALOGV("VideoEditorVideoEncoder_setOption ERROR 0x%X", err);
1180 ALOGV("VideoEditorVideoEncoder_setOption end");
1184 M4OSA_ERR VideoEditorVideoEncoder_getOption(M4ENCODER_Context pContext,
1185 M4OSA_UInt32 optionID, M4OSA_DataOption optionValue) {
1186 M4OSA_ERR err = M4NO_ERROR;
1187 VideoEditorVideoEncoder_Context* pEncoderContext = M4OSA_NULL;
1189 ALOGV("VideoEditorVideoEncoder_getOption begin optinId 0x%X", optionID);
1190 // Input parameters check
1191 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
1192 pEncoderContext = (VideoEditorVideoEncoder_Context*)pContext;
1194 switch( optionID ) {
1195 case M4ENCODER_kOptionID_EncoderHeader:
1197 M4OSA_NULL != pEncoderContext->mHeader.pBuf, M4ERR_STATE);
1198 *(M4ENCODER_Header**)optionValue = &(pEncoderContext->mHeader);
1201 ALOGV("VideoEditorVideoEncoder_getOption: unsupported optionId 0x%X",
1203 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_BAD_OPTION_ID);
1208 if ( M4NO_ERROR == err ) {
1209 ALOGV("VideoEditorVideoEncoder_getOption no error");
1211 ALOGV("VideoEditorVideoEncoder_getOption ERROR 0x%X", err);
1216 M4OSA_ERR VideoEditorVideoEncoder_getInterface(M4ENCODER_Format format,
1217 M4ENCODER_Format* pFormat,
1218 M4ENCODER_GlobalInterface** pEncoderInterface, M4ENCODER_OpenMode mode){
1219 M4OSA_ERR err = M4NO_ERROR;
1221 // Input parameters check
1222 VIDEOEDITOR_CHECK(M4OSA_NULL != pFormat, M4ERR_PARAMETER);
1223 VIDEOEDITOR_CHECK(M4OSA_NULL != pEncoderInterface, M4ERR_PARAMETER);
1225 ALOGV("VideoEditorVideoEncoder_getInterface begin 0x%x 0x%x %d", pFormat,
1226 pEncoderInterface, mode);
1228 SAFE_MALLOC(*pEncoderInterface, M4ENCODER_GlobalInterface, 1,
1229 "VideoEditorVideoEncoder");
1234 case M4ENCODER_kH263:
1236 (*pEncoderInterface)->pFctInit =
1237 VideoEditorVideoEncoder_init_H263;
1240 case M4ENCODER_kMPEG4:
1242 (*pEncoderInterface)->pFctInit =
1243 VideoEditorVideoEncoder_init_MPEG4;
1246 case M4ENCODER_kH264:
1248 (*pEncoderInterface)->pFctInit =
1249 VideoEditorVideoEncoder_init_H264;
1253 ALOGV("VideoEditorVideoEncoder_getInterface : unsupported format %d",
1255 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_PARAMETER);
1258 (*pEncoderInterface)->pFctOpen = VideoEditorVideoEncoder_open;
1259 (*pEncoderInterface)->pFctStart = VideoEditorVideoEncoder_start;
1260 (*pEncoderInterface)->pFctStop = VideoEditorVideoEncoder_stop;
1261 (*pEncoderInterface)->pFctPause = M4OSA_NULL;
1262 (*pEncoderInterface)->pFctResume = M4OSA_NULL;
1263 (*pEncoderInterface)->pFctClose = VideoEditorVideoEncoder_close;
1264 (*pEncoderInterface)->pFctCleanup = VideoEditorVideoEncoder_cleanup;
1265 (*pEncoderInterface)->pFctRegulBitRate =
1266 VideoEditorVideoEncoder_regulBitRate;
1267 (*pEncoderInterface)->pFctEncode = VideoEditorVideoEncoder_encode;
1268 (*pEncoderInterface)->pFctSetOption = VideoEditorVideoEncoder_setOption;
1269 (*pEncoderInterface)->pFctGetOption = VideoEditorVideoEncoder_getOption;
1272 if( M4NO_ERROR == err ) {
1273 ALOGV("VideoEditorVideoEncoder_getInterface no error");
1275 *pEncoderInterface = M4OSA_NULL;
1276 ALOGV("VideoEditorVideoEncoder_getInterface ERROR 0x%X", err);
1283 M4OSA_ERR VideoEditorVideoEncoder_getInterface_H263(M4ENCODER_Format* pFormat,
1284 M4ENCODER_GlobalInterface** pEncoderInterface, M4ENCODER_OpenMode mode){
1285 return VideoEditorVideoEncoder_getInterface(M4ENCODER_kH263, pFormat,
1286 pEncoderInterface, mode);
1289 M4OSA_ERR VideoEditorVideoEncoder_getInterface_MPEG4(M4ENCODER_Format* pFormat,
1290 M4ENCODER_GlobalInterface** pEncoderInterface, M4ENCODER_OpenMode mode){
1291 return VideoEditorVideoEncoder_getInterface(M4ENCODER_kMPEG4, pFormat,
1292 pEncoderInterface, mode);
1295 M4OSA_ERR VideoEditorVideoEncoder_getInterface_H264(M4ENCODER_Format* pFormat,
1296 M4ENCODER_GlobalInterface** pEncoderInterface, M4ENCODER_OpenMode mode){
1297 return VideoEditorVideoEncoder_getInterface(M4ENCODER_kH264, pFormat,
1298 pEncoderInterface, mode);
1304 } // namespace android