Home | History | Annotate | Download | only in enc
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      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
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     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.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "AVCEncoder"
     19 #include <utils/Log.h>
     20 
     21 #include "AVCEncoder.h"
     22 
     23 #include "avcenc_api.h"
     24 #include "avcenc_int.h"
     25 #include "OMX_Video.h"
     26 
     27 #include <media/stagefright/MediaBufferGroup.h>
     28 #include <media/stagefright/MediaDebug.h>
     29 #include <media/stagefright/MediaDefs.h>
     30 #include <media/stagefright/MediaErrors.h>
     31 #include <media/stagefright/MetaData.h>
     32 #include <media/stagefright/Utils.h>
     33 
     34 namespace android {
     35 
     36 inline static void ConvertYUV420SemiPlanarToYUV420Planar(
     37         uint8_t *inyuv, uint8_t* outyuv,
     38         int32_t width, int32_t height) {
     39 
     40     int32_t outYsize = width * height;
     41     uint32_t *outy =  (uint32_t *) outyuv;
     42     uint16_t *outcb = (uint16_t *) (outyuv + outYsize);
     43     uint16_t *outcr = (uint16_t *) (outyuv + outYsize + (outYsize >> 2));
     44 
     45     /* Y copying */
     46     memcpy(outy, inyuv, outYsize);
     47 
     48     /* U & V copying */
     49     uint32_t *inyuv_4 = (uint32_t *) (inyuv + outYsize);
     50     for (int32_t i = height >> 1; i > 0; --i) {
     51         for (int32_t j = width >> 2; j > 0; --j) {
     52             uint32_t temp = *inyuv_4++;
     53             uint32_t tempU = temp & 0xFF;
     54             tempU = tempU | ((temp >> 8) & 0xFF00);
     55 
     56             uint32_t tempV = (temp >> 8) & 0xFF;
     57             tempV = tempV | ((temp >> 16) & 0xFF00);
     58 
     59             // Flip U and V
     60             *outcb++ = tempV;
     61             *outcr++ = tempU;
     62         }
     63     }
     64 }
     65 
     66 static int32_t MallocWrapper(
     67         void *userData, int32_t size, int32_t attrs) {
     68     return reinterpret_cast<int32_t>(malloc(size));
     69 }
     70 
     71 static void FreeWrapper(void *userData, int32_t ptr) {
     72     free(reinterpret_cast<void *>(ptr));
     73 }
     74 
     75 static int32_t DpbAllocWrapper(void *userData,
     76         unsigned int sizeInMbs, unsigned int numBuffers) {
     77     AVCEncoder *encoder = static_cast<AVCEncoder *>(userData);
     78     CHECK(encoder != NULL);
     79     return encoder->allocOutputBuffers(sizeInMbs, numBuffers);
     80 }
     81 
     82 static int32_t BindFrameWrapper(
     83         void *userData, int32_t index, uint8_t **yuv) {
     84     AVCEncoder *encoder = static_cast<AVCEncoder *>(userData);
     85     CHECK(encoder != NULL);
     86     return encoder->bindOutputBuffer(index, yuv);
     87 }
     88 
     89 static void UnbindFrameWrapper(void *userData, int32_t index) {
     90     AVCEncoder *encoder = static_cast<AVCEncoder *>(userData);
     91     CHECK(encoder != NULL);
     92     return encoder->unbindOutputBuffer(index);
     93 }
     94 
     95 AVCEncoder::AVCEncoder(
     96         const sp<MediaSource>& source,
     97         const sp<MetaData>& meta)
     98     : mSource(source),
     99       mMeta(meta),
    100       mNumInputFrames(-1),
    101       mPrevTimestampUs(-1),
    102       mStarted(false),
    103       mInputBuffer(NULL),
    104       mInputFrameData(NULL),
    105       mGroup(NULL) {
    106 
    107     LOGV("Construct software AVCEncoder");
    108 
    109     mHandle = new tagAVCHandle;
    110     memset(mHandle, 0, sizeof(tagAVCHandle));
    111     mHandle->AVCObject = NULL;
    112     mHandle->userData = this;
    113     mHandle->CBAVC_DPBAlloc = DpbAllocWrapper;
    114     mHandle->CBAVC_FrameBind = BindFrameWrapper;
    115     mHandle->CBAVC_FrameUnbind = UnbindFrameWrapper;
    116     mHandle->CBAVC_Malloc = MallocWrapper;
    117     mHandle->CBAVC_Free = FreeWrapper;
    118 
    119     mInitCheck = initCheck(meta);
    120 }
    121 
    122 AVCEncoder::~AVCEncoder() {
    123     LOGV("Destruct software AVCEncoder");
    124     if (mStarted) {
    125         stop();
    126     }
    127 
    128     delete mEncParams;
    129     delete mHandle;
    130 }
    131 
    132 status_t AVCEncoder::initCheck(const sp<MetaData>& meta) {
    133     LOGV("initCheck");
    134     CHECK(meta->findInt32(kKeyWidth, &mVideoWidth));
    135     CHECK(meta->findInt32(kKeyHeight, &mVideoHeight));
    136     CHECK(meta->findInt32(kKeySampleRate, &mVideoFrameRate));
    137     CHECK(meta->findInt32(kKeyBitRate, &mVideoBitRate));
    138 
    139     // XXX: Add more color format support
    140     CHECK(meta->findInt32(kKeyColorFormat, &mVideoColorFormat));
    141     if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) {
    142         if (mVideoColorFormat != OMX_COLOR_FormatYUV420SemiPlanar) {
    143             LOGE("Color format %d is not supported", mVideoColorFormat);
    144             return BAD_VALUE;
    145         }
    146         // Allocate spare buffer only when color conversion is needed.
    147         // Assume the color format is OMX_COLOR_FormatYUV420SemiPlanar.
    148         mInputFrameData =
    149             (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1);
    150         CHECK(mInputFrameData);
    151     }
    152 
    153     // XXX: Remove this restriction
    154     if (mVideoWidth % 16 != 0 || mVideoHeight % 16 != 0) {
    155         LOGE("Video frame size %dx%d must be a multiple of 16",
    156             mVideoWidth, mVideoHeight);
    157         return BAD_VALUE;
    158     }
    159 
    160     mEncParams = new tagAVCEncParam;
    161     memset(mEncParams, 0, sizeof(mEncParams));
    162     mEncParams->width = mVideoWidth;
    163     mEncParams->height = mVideoHeight;
    164     mEncParams->frame_rate = 1000 * mVideoFrameRate;  // In frames/ms!
    165     mEncParams->rate_control = AVC_ON;
    166     mEncParams->bitrate = mVideoBitRate;
    167     mEncParams->initQP = 0;
    168     mEncParams->init_CBP_removal_delay = 1600;
    169     mEncParams->CPB_size = (uint32_t) (mVideoBitRate >> 1);
    170 
    171     mEncParams->intramb_refresh = 0;
    172     mEncParams->auto_scd = AVC_ON;
    173     mEncParams->out_of_band_param_set = AVC_ON;
    174     mEncParams->poc_type = 2;
    175     mEncParams->log2_max_poc_lsb_minus_4 = 12;
    176     mEncParams->delta_poc_zero_flag = 0;
    177     mEncParams->offset_poc_non_ref = 0;
    178     mEncParams->offset_top_bottom = 0;
    179     mEncParams->num_ref_in_cycle = 0;
    180     mEncParams->offset_poc_ref = NULL;
    181 
    182     mEncParams->num_ref_frame = 1;
    183     mEncParams->num_slice_group = 1;
    184     mEncParams->fmo_type = 0;
    185 
    186     mEncParams->db_filter = AVC_ON;
    187     mEncParams->disable_db_idc = 0;
    188 
    189     mEncParams->alpha_offset = 0;
    190     mEncParams->beta_offset = 0;
    191     mEncParams->constrained_intra_pred = AVC_OFF;
    192 
    193     mEncParams->data_par = AVC_OFF;
    194     mEncParams->fullsearch = AVC_OFF;
    195     mEncParams->search_range = 16;
    196     mEncParams->sub_pel = AVC_OFF;
    197     mEncParams->submb_pred = AVC_OFF;
    198     mEncParams->rdopt_mode = AVC_OFF;
    199     mEncParams->bidir_pred = AVC_OFF;
    200     int32_t nMacroBlocks = ((((mVideoWidth + 15) >> 4) << 4) *
    201             (((mVideoHeight + 15) >> 4) << 4)) >> 8;
    202     uint32_t *sliceGroup = (uint32_t *) malloc(sizeof(uint32_t) * nMacroBlocks);
    203     for (int ii = 0, idx = 0; ii < nMacroBlocks; ++ii) {
    204         sliceGroup[ii] = idx++;
    205         if (idx >= mEncParams->num_slice_group) {
    206             idx = 0;
    207         }
    208     }
    209     mEncParams->slice_group = sliceGroup;
    210 
    211     mEncParams->use_overrun_buffer = AVC_OFF;
    212 
    213     // Set IDR frame refresh interval
    214     int32_t iFramesIntervalSec;
    215     CHECK(meta->findInt32(kKeyIFramesInterval, &iFramesIntervalSec));
    216     if (iFramesIntervalSec < 0) {
    217         mEncParams->idr_period = -1;
    218     } else if (iFramesIntervalSec == 0) {
    219         mEncParams->idr_period = 1;  // All I frames
    220     } else {
    221         mEncParams->idr_period =
    222             (iFramesIntervalSec * mVideoFrameRate);
    223     }
    224     LOGV("idr_period: %d, I-frames interval: %d seconds, and frame rate: %d",
    225         mEncParams->idr_period, iFramesIntervalSec, mVideoFrameRate);
    226 
    227     // Set profile and level
    228     // If profile and level setting is not correct, failure
    229     // is reported when the encoder is initialized.
    230     mEncParams->profile = AVC_BASELINE;
    231     mEncParams->level = AVC_LEVEL3_2;
    232     int32_t profile, level;
    233     if (meta->findInt32(kKeyVideoProfile, &profile)) {
    234         mEncParams->profile = (AVCProfile) profile;
    235     }
    236     if (meta->findInt32(kKeyVideoLevel, &level)) {
    237         mEncParams->level = (AVCLevel) level;
    238     }
    239 
    240 
    241     mFormat = new MetaData;
    242     mFormat->setInt32(kKeyWidth, mVideoWidth);
    243     mFormat->setInt32(kKeyHeight, mVideoHeight);
    244     mFormat->setInt32(kKeyBitRate, mVideoBitRate);
    245     mFormat->setInt32(kKeySampleRate, mVideoFrameRate);
    246     mFormat->setInt32(kKeyColorFormat, mVideoColorFormat);
    247     mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
    248     mFormat->setCString(kKeyDecoderComponent, "AVCEncoder");
    249     return OK;
    250 }
    251 
    252 status_t AVCEncoder::start(MetaData *params) {
    253     LOGV("start");
    254     if (mInitCheck != OK) {
    255         return mInitCheck;
    256     }
    257 
    258     if (mStarted) {
    259         LOGW("Call start() when encoder already started");
    260         return OK;
    261     }
    262 
    263     AVCEnc_Status err;
    264     err = PVAVCEncInitialize(mHandle, mEncParams, NULL, NULL);
    265     if (err != AVCENC_SUCCESS) {
    266         LOGE("Failed to initialize the encoder: %d", err);
    267         return UNKNOWN_ERROR;
    268     }
    269 
    270     mGroup = new MediaBufferGroup();
    271     int32_t maxSize;
    272     if (AVCENC_SUCCESS !=
    273         PVAVCEncGetMaxOutputBufferSize(mHandle, &maxSize)) {
    274         maxSize = 31584;  // Magic #
    275     }
    276     mGroup->add_buffer(new MediaBuffer(maxSize));
    277 
    278     mSource->start(params);
    279     mNumInputFrames = -2;  // 1st two buffers contain SPS and PPS
    280     mStarted = true;
    281     mSpsPpsHeaderReceived = false;
    282     mReadyForNextFrame = true;
    283     mIsIDRFrame = 0;
    284 
    285     return OK;
    286 }
    287 
    288 status_t AVCEncoder::stop() {
    289     LOGV("stop");
    290     if (!mStarted) {
    291         LOGW("Call stop() when encoder has not started");
    292         return OK;
    293     }
    294 
    295     if (mInputBuffer) {
    296         mInputBuffer->release();
    297         mInputBuffer = NULL;
    298     }
    299 
    300     if (mGroup) {
    301         delete mGroup;
    302         mGroup = NULL;
    303     }
    304 
    305     if (mInputFrameData) {
    306         delete mInputFrameData;
    307         mInputFrameData = NULL;
    308     }
    309 
    310     PVAVCCleanUpEncoder(mHandle);
    311     mSource->stop();
    312     releaseOutputBuffers();
    313     mStarted = false;
    314 
    315     return OK;
    316 }
    317 
    318 void AVCEncoder::releaseOutputBuffers() {
    319     LOGV("releaseOutputBuffers");
    320     for (size_t i = 0; i < mOutputBuffers.size(); ++i) {
    321         MediaBuffer *buffer = mOutputBuffers.editItemAt(i);
    322         buffer->setObserver(NULL);
    323         buffer->release();
    324     }
    325     mOutputBuffers.clear();
    326 }
    327 
    328 sp<MetaData> AVCEncoder::getFormat() {
    329     LOGV("getFormat");
    330     return mFormat;
    331 }
    332 
    333 status_t AVCEncoder::read(
    334         MediaBuffer **out, const ReadOptions *options) {
    335 
    336     CHECK(!options);
    337     *out = NULL;
    338 
    339     MediaBuffer *outputBuffer;
    340     CHECK_EQ(OK, mGroup->acquire_buffer(&outputBuffer));
    341     uint8_t *outPtr = (uint8_t *) outputBuffer->data();
    342     uint32_t dataLength = outputBuffer->size();
    343 
    344     if (!mSpsPpsHeaderReceived && mNumInputFrames < 0) {
    345         // 4 bytes are reserved for holding the start code 0x00000001
    346         // of the sequence parameter set at the beginning.
    347         outPtr += 4;
    348         dataLength -= 4;
    349     }
    350 
    351     int32_t type;
    352     AVCEnc_Status encoderStatus = AVCENC_SUCCESS;
    353 
    354     // Combine SPS and PPS and place them in the very first output buffer
    355     // SPS and PPS are separated by start code 0x00000001
    356     // Assume that we have exactly one SPS and exactly one PPS.
    357     while (!mSpsPpsHeaderReceived && mNumInputFrames <= 0) {
    358         encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type);
    359         if (encoderStatus == AVCENC_WRONG_STATE) {
    360             mSpsPpsHeaderReceived = true;
    361             CHECK_EQ(0, mNumInputFrames);  // 1st video frame is 0
    362         } else {
    363             switch (type) {
    364                 case AVC_NALTYPE_SPS:
    365                     ++mNumInputFrames;
    366                     memcpy((uint8_t *)outputBuffer->data(), "\x00\x00\x00\x01", 4);
    367                     outputBuffer->set_range(0, dataLength + 4);
    368                     outPtr += (dataLength + 4);  // 4 bytes for next start code
    369                     dataLength = outputBuffer->size() -
    370                             (outputBuffer->range_length() + 4);
    371                     break;
    372                 case AVC_NALTYPE_PPS:
    373                     ++mNumInputFrames;
    374                     memcpy(((uint8_t *) outputBuffer->data()) +
    375                             outputBuffer->range_length(),
    376                             "\x00\x00\x00\x01", 4);
    377                     outputBuffer->set_range(0,
    378                             dataLength + outputBuffer->range_length() + 4);
    379                     outputBuffer->meta_data()->setInt32(kKeyIsCodecConfig, 1);
    380                     outputBuffer->meta_data()->setInt64(kKeyTime, 0);
    381                     *out = outputBuffer;
    382                     return OK;
    383                 default:
    384                     LOGE("Nal type (%d) other than SPS/PPS is unexpected", type);
    385                     return UNKNOWN_ERROR;
    386             }
    387         }
    388     }
    389 
    390     // Get next input video frame
    391     if (mReadyForNextFrame) {
    392         if (mInputBuffer) {
    393             mInputBuffer->release();
    394             mInputBuffer = NULL;
    395         }
    396         status_t err = mSource->read(&mInputBuffer, options);
    397         if (err != OK) {
    398             LOGE("Failed to read input video frame: %d", err);
    399             outputBuffer->release();
    400             return err;
    401         }
    402 
    403         if (mInputBuffer->size() - ((mVideoWidth * mVideoHeight * 3) >> 1) != 0) {
    404             outputBuffer->release();
    405             mInputBuffer->release();
    406             mInputBuffer = NULL;
    407             return UNKNOWN_ERROR;
    408         }
    409 
    410         int64_t timeUs;
    411         CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
    412         outputBuffer->meta_data()->setInt64(kKeyTime, timeUs);
    413 
    414         // When the timestamp of the current sample is the same as
    415         // that of the previous sample, the encoding of the sample
    416         // is bypassed, and the output length is set to 0.
    417         if (mNumInputFrames >= 1 && mPrevTimestampUs == timeUs) {
    418             // Frame arrives too late
    419             mInputBuffer->release();
    420             mInputBuffer = NULL;
    421             outputBuffer->set_range(0, 0);
    422             *out = outputBuffer;
    423             return OK;
    424         }
    425 
    426         // Don't accept out-of-order samples
    427         CHECK(mPrevTimestampUs < timeUs);
    428         mPrevTimestampUs = timeUs;
    429 
    430         AVCFrameIO videoInput;
    431         memset(&videoInput, 0, sizeof(videoInput));
    432         videoInput.height = ((mVideoHeight  + 15) >> 4) << 4;
    433         videoInput.pitch = ((mVideoWidth + 15) >> 4) << 4;
    434         videoInput.coding_timestamp = (timeUs + 500) / 1000;  // in ms
    435         uint8_t *inputData = (uint8_t *) mInputBuffer->data();
    436 
    437         if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) {
    438             CHECK(mInputFrameData);
    439             CHECK(mVideoColorFormat == OMX_COLOR_FormatYUV420SemiPlanar);
    440             ConvertYUV420SemiPlanarToYUV420Planar(
    441                 inputData, mInputFrameData, mVideoWidth, mVideoHeight);
    442             inputData = mInputFrameData;
    443         }
    444         CHECK(inputData != NULL);
    445         videoInput.YCbCr[0] = inputData;
    446         videoInput.YCbCr[1] = videoInput.YCbCr[0] + videoInput.height * videoInput.pitch;
    447         videoInput.YCbCr[2] = videoInput.YCbCr[1] +
    448             ((videoInput.height * videoInput.pitch) >> 2);
    449         videoInput.disp_order = mNumInputFrames;
    450 
    451         encoderStatus = PVAVCEncSetInput(mHandle, &videoInput);
    452         if (encoderStatus == AVCENC_SUCCESS ||
    453             encoderStatus == AVCENC_NEW_IDR) {
    454             mReadyForNextFrame = false;
    455             ++mNumInputFrames;
    456             if (encoderStatus == AVCENC_NEW_IDR) {
    457                 mIsIDRFrame = 1;
    458             }
    459         } else {
    460             if (encoderStatus < AVCENC_SUCCESS) {
    461                 outputBuffer->release();
    462                 return UNKNOWN_ERROR;
    463             } else {
    464                 outputBuffer->set_range(0, 0);
    465                 *out = outputBuffer;
    466                 return OK;
    467             }
    468         }
    469     }
    470 
    471     // Encode an input video frame
    472     CHECK(encoderStatus == AVCENC_SUCCESS ||
    473           encoderStatus == AVCENC_NEW_IDR);
    474     dataLength = outputBuffer->size();  // Reset the output buffer length
    475     encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type);
    476     if (encoderStatus == AVCENC_SUCCESS) {
    477         outputBuffer->meta_data()->setInt32(kKeyIsSyncFrame, mIsIDRFrame);
    478         CHECK_EQ(NULL, PVAVCEncGetOverrunBuffer(mHandle));
    479     } else if (encoderStatus == AVCENC_PICTURE_READY) {
    480         CHECK_EQ(NULL, PVAVCEncGetOverrunBuffer(mHandle));
    481         if (mIsIDRFrame) {
    482             outputBuffer->meta_data()->setInt32(kKeyIsSyncFrame, mIsIDRFrame);
    483             mIsIDRFrame = 0;
    484             LOGV("Output an IDR frame");
    485         }
    486         mReadyForNextFrame = true;
    487         AVCFrameIO recon;
    488         if (PVAVCEncGetRecon(mHandle, &recon) == AVCENC_SUCCESS) {
    489             PVAVCEncReleaseRecon(mHandle, &recon);
    490         }
    491     } else {
    492         dataLength = 0;
    493         mReadyForNextFrame = true;
    494     }
    495     if (encoderStatus < AVCENC_SUCCESS) {
    496         outputBuffer->release();
    497         return UNKNOWN_ERROR;
    498     }
    499 
    500     outputBuffer->set_range(0, dataLength);
    501     *out = outputBuffer;
    502     return OK;
    503 }
    504 
    505 int32_t AVCEncoder::allocOutputBuffers(
    506         unsigned int sizeInMbs, unsigned int numBuffers) {
    507     CHECK(mOutputBuffers.isEmpty());
    508     size_t frameSize = (sizeInMbs << 7) * 3;
    509     for (unsigned int i = 0; i <  numBuffers; ++i) {
    510         MediaBuffer *buffer = new MediaBuffer(frameSize);
    511         buffer->setObserver(this);
    512         mOutputBuffers.push(buffer);
    513     }
    514 
    515     return 1;
    516 }
    517 
    518 void AVCEncoder::unbindOutputBuffer(int32_t index) {
    519     CHECK(index >= 0);
    520 }
    521 
    522 int32_t AVCEncoder::bindOutputBuffer(int32_t index, uint8_t **yuv) {
    523     CHECK(index >= 0);
    524     CHECK(index < (int32_t) mOutputBuffers.size());
    525     int64_t timeUs;
    526     CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
    527     mOutputBuffers[index]->meta_data()->setInt64(kKeyTime, timeUs);
    528 
    529     *yuv = (uint8_t *) mOutputBuffers[index]->data();
    530 
    531     return 1;
    532 }
    533 
    534 void AVCEncoder::signalBufferReturned(MediaBuffer *buffer) {
    535 }
    536 
    537 }  // namespace android
    538