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
34namespace android {
35
36inline 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
66static int32_t MallocWrapper(
67        void *userData, int32_t size, int32_t attrs) {
68    return reinterpret_cast<int32_t>(malloc(size));
69}
70
71static void FreeWrapper(void *userData, int32_t ptr) {
72    free(reinterpret_cast<void *>(ptr));
73}
74
75static 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
82static 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
89static 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
95AVCEncoder::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
122AVCEncoder::~AVCEncoder() {
123    LOGV("Destruct software AVCEncoder");
124    if (mStarted) {
125        stop();
126    }
127
128    delete mEncParams;
129    delete mHandle;
130}
131
132status_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
252status_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
288status_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
318void 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
328sp<MetaData> AVCEncoder::getFormat() {
329    LOGV("getFormat");
330    return mFormat;
331}
332
333status_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
505int32_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
518void AVCEncoder::unbindOutputBuffer(int32_t index) {
519    CHECK(index >= 0);
520}
521
522int32_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
534void AVCEncoder::signalBufferReturned(MediaBuffer *buffer) {
535}
536
537}  // namespace android
538