SoftAVCEnc.cpp revision 22b3b44ae459974794403ed0f76d95ae43d92985
1/*
2 * Copyright 2015 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 "SoftAVCEnc"
19#include <utils/Log.h>
20#include <utils/misc.h>
21
22#include "OMX_Video.h"
23
24#include <HardwareAPI.h>
25#include <MetadataBufferType.h>
26#include <media/stagefright/foundation/ADebug.h>
27#include <media/stagefright/MediaDefs.h>
28#include <media/stagefright/MediaErrors.h>
29#include <media/stagefright/MetaData.h>
30#include <media/stagefright/Utils.h>
31#include <ui/Rect.h>
32
33#include "ih264_typedefs.h"
34#include "iv2.h"
35#include "ive2.h"
36#include "ih264e.h"
37#include "SoftAVCEnc.h"
38
39namespace android {
40
41    #define ive_api_function ih264e_api_function
42
43template<class T>
44static void InitOMXParams(T *params) {
45    params->nSize = sizeof(T);
46    params->nVersion.s.nVersionMajor = 1;
47    params->nVersion.s.nVersionMinor = 0;
48    params->nVersion.s.nRevision = 0;
49    params->nVersion.s.nStep = 0;
50}
51
52typedef struct LevelConversion {
53    OMX_VIDEO_AVCLEVELTYPE omxLevel;
54    WORD32 avcLevel;
55} LevelConcersion;
56
57static LevelConversion ConversionTable[] = {
58    { OMX_VIDEO_AVCLevel1,  10 },
59    { OMX_VIDEO_AVCLevel1b, 9  },
60    { OMX_VIDEO_AVCLevel11, 11 },
61    { OMX_VIDEO_AVCLevel12, 12 },
62    { OMX_VIDEO_AVCLevel13, 13 },
63    { OMX_VIDEO_AVCLevel2,  20 },
64    { OMX_VIDEO_AVCLevel21, 21 },
65    { OMX_VIDEO_AVCLevel22, 22 },
66    { OMX_VIDEO_AVCLevel3,  30 },
67    { OMX_VIDEO_AVCLevel31, 31 },
68    { OMX_VIDEO_AVCLevel32, 32 },
69    { OMX_VIDEO_AVCLevel4,  40 },
70    { OMX_VIDEO_AVCLevel41, 41 },
71    { OMX_VIDEO_AVCLevel42, 42 },
72    { OMX_VIDEO_AVCLevel5,  50 },
73    { OMX_VIDEO_AVCLevel51, 51 },
74};
75
76static const CodecProfileLevel kProfileLevels[] = {
77    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1  },
78    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b },
79    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11 },
80    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12 },
81    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13 },
82    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2  },
83    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21 },
84    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22 },
85    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3  },
86    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31 },
87    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 },
88    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4  },
89    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 },
90};
91
92
93static size_t GetCPUCoreCount() {
94    long cpuCoreCount = 1;
95#if defined(_SC_NPROCESSORS_ONLN)
96    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
97#else
98    // _SC_NPROC_ONLN must be defined...
99    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
100#endif
101    CHECK(cpuCoreCount >= 1);
102    ALOGD("Number of CPU cores: %ld", cpuCoreCount);
103    return (size_t)cpuCoreCount;
104}
105
106static status_t ConvertOmxAvcLevelToAvcSpecLevel(
107        OMX_VIDEO_AVCLEVELTYPE omxLevel, WORD32 *avcLevel) {
108    for (size_t i = 0; i < NELEM(ConversionTable); ++i) {
109        if (omxLevel == ConversionTable[i].omxLevel) {
110            *avcLevel = ConversionTable[i].avcLevel;
111            return OK;
112        }
113    }
114
115    ALOGE("ConvertOmxAvcLevelToAvcSpecLevel: %d level not supported",
116            (int32_t)omxLevel);
117
118    return BAD_VALUE;
119}
120
121static status_t ConvertAvcSpecLevelToOmxAvcLevel(
122        WORD32 avcLevel, OMX_VIDEO_AVCLEVELTYPE *omxLevel) {
123    for (size_t i = 0; i < NELEM(ConversionTable); ++i) {
124        if (avcLevel == ConversionTable[i].avcLevel) {
125            *omxLevel = ConversionTable[i].omxLevel;
126            return OK;
127        }
128    }
129
130    ALOGE("ConvertAvcSpecLevelToOmxAvcLevel: %d level not supported",
131            (int32_t)avcLevel);
132
133    return BAD_VALUE;
134}
135
136
137SoftAVC::SoftAVC(
138        const char *name,
139        const OMX_CALLBACKTYPE *callbacks,
140        OMX_PTR appData,
141        OMX_COMPONENTTYPE **component)
142    : SoftVideoEncoderOMXComponent(
143            name, "video_encoder.avc", OMX_VIDEO_CodingAVC,
144            kProfileLevels, NELEM(kProfileLevels),
145            176 /* width */, 144 /* height */,
146            callbacks, appData, component),
147      mIvVideoColorFormat(IV_YUV_420P),
148      mIDRFrameRefreshIntervalInSec(1),
149      mAVCEncProfile(IV_PROFILE_BASE),
150      mAVCEncLevel(31),
151      mPrevTimestampUs(-1),
152      mStarted(false),
153      mSawInputEOS(false),
154      mSignalledError(false),
155      mConversionBuffer(NULL),
156      mCodecCtx(NULL) {
157
158    initPorts(kNumBuffers, kNumBuffers, ((mWidth * mHeight * 3) >> 1),
159            MEDIA_MIMETYPE_VIDEO_AVC, 2);
160
161    // If dump is enabled, then open create an empty file
162    GENERATE_FILE_NAMES();
163    CREATE_DUMP_FILE(mInFile);
164    CREATE_DUMP_FILE(mOutFile);
165
166}
167
168SoftAVC::~SoftAVC() {
169    releaseEncoder();
170    List<BufferInfo *> &outQueue = getPortQueue(1);
171    List<BufferInfo *> &inQueue = getPortQueue(0);
172    CHECK(outQueue.empty());
173    CHECK(inQueue.empty());
174}
175
176OMX_ERRORTYPE SoftAVC::initEncParams() {
177    mCodecCtx = NULL;
178    mMemRecords = NULL;
179    mNumMemRecords = DEFAULT_MEM_REC_CNT;
180    mHeaderGenerated = 0;
181    mNumCores = GetCPUCoreCount();
182    mArch = DEFAULT_ARCH;
183    mSliceMode = DEFAULT_SLICE_MODE;
184    mSliceParam = DEFAULT_SLICE_PARAM;
185    mHalfPelEnable = DEFAULT_HPEL;
186    mIInterval = DEFAULT_I_INTERVAL;
187    mIDRInterval = DEFAULT_IDR_INTERVAL;
188    mDisableDeblkLevel = DEFAULT_DISABLE_DEBLK_LEVEL;
189    mFrameRate = DEFAULT_SRC_FRAME_RATE;
190    mEnableFastSad = DEFAULT_ENABLE_FAST_SAD;
191    mEnableAltRef = DEFAULT_ENABLE_ALT_REF;
192    mEncSpeed = DEFAULT_ENC_SPEED;
193    mIntra4x4 = DEFAULT_INTRA4x4;
194    mAIRMode = DEFAULT_AIR;
195    mAIRRefreshPeriod = DEFAULT_AIR_REFRESH_PERIOD;
196    mPSNREnable = DEFAULT_PSNR_ENABLE;
197    mReconEnable = DEFAULT_RECON_ENABLE;
198
199    gettimeofday(&mTimeStart, NULL);
200    gettimeofday(&mTimeEnd, NULL);
201
202    return OMX_ErrorNone;
203}
204
205
206OMX_ERRORTYPE SoftAVC::setDimensions() {
207    ive_ctl_set_dimensions_ip_t s_dimensions_ip;
208    ive_ctl_set_dimensions_op_t s_dimensions_op;
209    IV_STATUS_T status;
210
211    s_dimensions_ip.e_cmd = IVE_CMD_VIDEO_CTL;
212    s_dimensions_ip.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS;
213    s_dimensions_ip.u4_ht = mHeight;
214    s_dimensions_ip.u4_wd = mWidth;
215    s_dimensions_ip.u4_strd = mStride;
216
217    s_dimensions_ip.u4_timestamp_high = -1;
218    s_dimensions_ip.u4_timestamp_low = -1;
219
220    s_dimensions_ip.u4_size = sizeof(ive_ctl_set_dimensions_ip_t);
221    s_dimensions_op.u4_size = sizeof(ive_ctl_set_dimensions_op_t);
222
223    status = ive_api_function(mCodecCtx, &s_dimensions_ip, &s_dimensions_op);
224    if (status != IV_SUCCESS) {
225        ALOGE("Unable to set frame dimensions = 0x%x\n",
226                s_dimensions_op.u4_error_code);
227        return OMX_ErrorUndefined;
228    }
229    return OMX_ErrorNone;
230}
231
232OMX_ERRORTYPE SoftAVC::setNumCores() {
233    IV_STATUS_T status;
234    ive_ctl_set_num_cores_ip_t s_num_cores_ip;
235    ive_ctl_set_num_cores_op_t s_num_cores_op;
236    s_num_cores_ip.e_cmd = IVE_CMD_VIDEO_CTL;
237    s_num_cores_ip.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES;
238    s_num_cores_ip.u4_num_cores = MIN(mNumCores, CODEC_MAX_CORES);
239    s_num_cores_ip.u4_timestamp_high = -1;
240    s_num_cores_ip.u4_timestamp_low = -1;
241    s_num_cores_ip.u4_size = sizeof(ive_ctl_set_num_cores_ip_t);
242
243    s_num_cores_op.u4_size = sizeof(ive_ctl_set_num_cores_op_t);
244
245    status = ive_api_function(
246            mCodecCtx, (void *) &s_num_cores_ip, (void *) &s_num_cores_op);
247    if (status != IV_SUCCESS) {
248        ALOGE("Unable to set processor params = 0x%x\n",
249                s_num_cores_op.u4_error_code);
250        return OMX_ErrorUndefined;
251    }
252    return OMX_ErrorNone;
253}
254
255OMX_ERRORTYPE SoftAVC::setFrameRate() {
256    ive_ctl_set_frame_rate_ip_t s_frame_rate_ip;
257    ive_ctl_set_frame_rate_op_t s_frame_rate_op;
258    IV_STATUS_T status;
259
260    s_frame_rate_ip.e_cmd = IVE_CMD_VIDEO_CTL;
261    s_frame_rate_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE;
262
263    s_frame_rate_ip.u4_src_frame_rate = mFrameRate;
264    s_frame_rate_ip.u4_tgt_frame_rate = mFrameRate;
265
266    s_frame_rate_ip.u4_timestamp_high = -1;
267    s_frame_rate_ip.u4_timestamp_low = -1;
268
269    s_frame_rate_ip.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t);
270    s_frame_rate_op.u4_size = sizeof(ive_ctl_set_frame_rate_op_t);
271
272    status = ive_api_function(mCodecCtx, &s_frame_rate_ip, &s_frame_rate_op);
273    if (status != IV_SUCCESS) {
274        ALOGE("Unable to set frame rate = 0x%x\n",
275                s_frame_rate_op.u4_error_code);
276        return OMX_ErrorUndefined;
277    }
278    return OMX_ErrorNone;
279}
280
281OMX_ERRORTYPE SoftAVC::setIpeParams() {
282    ive_ctl_set_ipe_params_ip_t s_ipe_params_ip;
283    ive_ctl_set_ipe_params_op_t s_ipe_params_op;
284    IV_STATUS_T status;
285
286    s_ipe_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
287    s_ipe_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS;
288
289    s_ipe_params_ip.u4_enable_intra_4x4 = mIntra4x4;
290    s_ipe_params_ip.u4_enc_speed_preset = mEncSpeed;
291
292    s_ipe_params_ip.u4_timestamp_high = -1;
293    s_ipe_params_ip.u4_timestamp_low = -1;
294
295    s_ipe_params_ip.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t);
296    s_ipe_params_op.u4_size = sizeof(ive_ctl_set_ipe_params_op_t);
297
298    status = ive_api_function(mCodecCtx, &s_ipe_params_ip, &s_ipe_params_op);
299    if (status != IV_SUCCESS) {
300        ALOGE("Unable to set ipe params = 0x%x\n",
301                s_ipe_params_op.u4_error_code);
302        return OMX_ErrorUndefined;
303    }
304    return OMX_ErrorNone;
305}
306
307OMX_ERRORTYPE SoftAVC::setBitRate() {
308    ive_ctl_set_bitrate_ip_t s_bitrate_ip;
309    ive_ctl_set_bitrate_op_t s_bitrate_op;
310    IV_STATUS_T status;
311
312    s_bitrate_ip.e_cmd = IVE_CMD_VIDEO_CTL;
313    s_bitrate_ip.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE;
314
315    s_bitrate_ip.u4_target_bitrate = mBitrate;
316
317    s_bitrate_ip.u4_timestamp_high = -1;
318    s_bitrate_ip.u4_timestamp_low = -1;
319
320    s_bitrate_ip.u4_size = sizeof(ive_ctl_set_bitrate_ip_t);
321    s_bitrate_op.u4_size = sizeof(ive_ctl_set_bitrate_op_t);
322
323    status = ive_api_function(mCodecCtx, &s_bitrate_ip, &s_bitrate_op);
324    if (status != IV_SUCCESS) {
325        ALOGE("Unable to set bit rate = 0x%x\n", s_bitrate_op.u4_error_code);
326        return OMX_ErrorUndefined;
327    }
328    return OMX_ErrorNone;
329}
330
331OMX_ERRORTYPE SoftAVC::setFrameType(IV_PICTURE_CODING_TYPE_T e_frame_type) {
332    ive_ctl_set_frame_type_ip_t s_frame_type_ip;
333    ive_ctl_set_frame_type_op_t s_frame_type_op;
334    IV_STATUS_T status;
335
336    s_frame_type_ip.e_cmd = IVE_CMD_VIDEO_CTL;
337    s_frame_type_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE;
338
339    s_frame_type_ip.e_frame_type = e_frame_type;
340
341    s_frame_type_ip.u4_timestamp_high = -1;
342    s_frame_type_ip.u4_timestamp_low = -1;
343
344    s_frame_type_ip.u4_size = sizeof(ive_ctl_set_frame_type_ip_t);
345    s_frame_type_op.u4_size = sizeof(ive_ctl_set_frame_type_op_t);
346
347    status = ive_api_function(mCodecCtx, &s_frame_type_ip, &s_frame_type_op);
348    if (status != IV_SUCCESS) {
349        ALOGE("Unable to set frame type = 0x%x\n",
350                s_frame_type_op.u4_error_code);
351        return OMX_ErrorUndefined;
352    }
353    return OMX_ErrorNone;
354}
355
356OMX_ERRORTYPE SoftAVC::setQp() {
357    ive_ctl_set_qp_ip_t s_qp_ip;
358    ive_ctl_set_qp_op_t s_qp_op;
359    IV_STATUS_T status;
360
361    s_qp_ip.e_cmd = IVE_CMD_VIDEO_CTL;
362    s_qp_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP;
363
364    s_qp_ip.u4_i_qp = DEFAULT_I_QP;
365    s_qp_ip.u4_i_qp_max = DEFAULT_QP_MAX;
366    s_qp_ip.u4_i_qp_min = DEFAULT_QP_MIN;
367
368    s_qp_ip.u4_p_qp = DEFAULT_P_QP;
369    s_qp_ip.u4_p_qp_max = DEFAULT_QP_MAX;
370    s_qp_ip.u4_p_qp_min = DEFAULT_QP_MIN;
371
372    s_qp_ip.u4_b_qp = DEFAULT_P_QP;
373    s_qp_ip.u4_b_qp_max = DEFAULT_QP_MAX;
374    s_qp_ip.u4_b_qp_min = DEFAULT_QP_MIN;
375
376    s_qp_ip.u4_timestamp_high = -1;
377    s_qp_ip.u4_timestamp_low = -1;
378
379    s_qp_ip.u4_size = sizeof(ive_ctl_set_qp_ip_t);
380    s_qp_op.u4_size = sizeof(ive_ctl_set_qp_op_t);
381
382    status = ive_api_function(mCodecCtx, &s_qp_ip, &s_qp_op);
383    if (status != IV_SUCCESS) {
384        ALOGE("Unable to set qp 0x%x\n", s_qp_op.u4_error_code);
385        return OMX_ErrorUndefined;
386    }
387    return OMX_ErrorNone;
388}
389
390OMX_ERRORTYPE SoftAVC::setEncMode(IVE_ENC_MODE_T e_enc_mode) {
391    IV_STATUS_T status;
392    ive_ctl_set_enc_mode_ip_t s_enc_mode_ip;
393    ive_ctl_set_enc_mode_op_t s_enc_mode_op;
394
395    s_enc_mode_ip.e_cmd = IVE_CMD_VIDEO_CTL;
396    s_enc_mode_ip.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE;
397
398    s_enc_mode_ip.e_enc_mode = e_enc_mode;
399
400    s_enc_mode_ip.u4_timestamp_high = -1;
401    s_enc_mode_ip.u4_timestamp_low = -1;
402
403    s_enc_mode_ip.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t);
404    s_enc_mode_op.u4_size = sizeof(ive_ctl_set_enc_mode_op_t);
405
406    status = ive_api_function(mCodecCtx, &s_enc_mode_ip, &s_enc_mode_op);
407    if (status != IV_SUCCESS) {
408        ALOGE("Unable to set in header encode mode = 0x%x\n",
409                s_enc_mode_op.u4_error_code);
410        return OMX_ErrorUndefined;
411    }
412    return OMX_ErrorNone;
413}
414
415OMX_ERRORTYPE SoftAVC::setVbvParams() {
416    ive_ctl_set_vbv_params_ip_t s_vbv_ip;
417    ive_ctl_set_vbv_params_op_t s_vbv_op;
418    IV_STATUS_T status;
419
420    s_vbv_ip.e_cmd = IVE_CMD_VIDEO_CTL;
421    s_vbv_ip.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS;
422
423    s_vbv_ip.u4_vbv_buf_size = 0;
424    s_vbv_ip.u4_vbv_buffer_delay = 1000;
425
426    s_vbv_ip.u4_timestamp_high = -1;
427    s_vbv_ip.u4_timestamp_low = -1;
428
429    s_vbv_ip.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t);
430    s_vbv_op.u4_size = sizeof(ive_ctl_set_vbv_params_op_t);
431
432    status = ive_api_function(mCodecCtx, &s_vbv_ip, &s_vbv_op);
433    if (status != IV_SUCCESS) {
434        ALOGE("Unable to set VBC params = 0x%x\n", s_vbv_op.u4_error_code);
435        return OMX_ErrorUndefined;
436    }
437    return OMX_ErrorNone;
438}
439
440OMX_ERRORTYPE SoftAVC::setAirParams() {
441    ive_ctl_set_air_params_ip_t s_air_ip;
442    ive_ctl_set_air_params_op_t s_air_op;
443    IV_STATUS_T status;
444
445    s_air_ip.e_cmd = IVE_CMD_VIDEO_CTL;
446    s_air_ip.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS;
447
448    s_air_ip.e_air_mode = mAIRMode;
449    s_air_ip.u4_air_refresh_period = mAIRRefreshPeriod;
450
451    s_air_ip.u4_timestamp_high = -1;
452    s_air_ip.u4_timestamp_low = -1;
453
454    s_air_ip.u4_size = sizeof(ive_ctl_set_air_params_ip_t);
455    s_air_op.u4_size = sizeof(ive_ctl_set_air_params_op_t);
456
457    status = ive_api_function(mCodecCtx, &s_air_ip, &s_air_op);
458    if (status != IV_SUCCESS) {
459        ALOGE("Unable to set air params = 0x%x\n", s_air_op.u4_error_code);
460        return OMX_ErrorUndefined;
461    }
462    return OMX_ErrorNone;
463}
464
465OMX_ERRORTYPE SoftAVC::setMeParams() {
466    IV_STATUS_T status;
467    ive_ctl_set_me_params_ip_t s_me_params_ip;
468    ive_ctl_set_me_params_op_t s_me_params_op;
469
470    s_me_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
471    s_me_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS;
472
473    s_me_params_ip.u4_enable_fast_sad = mEnableFastSad;
474    s_me_params_ip.u4_enable_alt_ref = mEnableAltRef;
475
476    s_me_params_ip.u4_enable_hpel = mHalfPelEnable;
477    s_me_params_ip.u4_enable_qpel = DEFAULT_QPEL;
478    s_me_params_ip.u4_me_speed_preset = DEFAULT_ME_SPEED;
479    s_me_params_ip.u4_srch_rng_x = DEFAULT_SRCH_RNG_X;
480    s_me_params_ip.u4_srch_rng_y = DEFAULT_SRCH_RNG_Y;
481
482    s_me_params_ip.u4_timestamp_high = -1;
483    s_me_params_ip.u4_timestamp_low = -1;
484
485    s_me_params_ip.u4_size = sizeof(ive_ctl_set_me_params_ip_t);
486    s_me_params_op.u4_size = sizeof(ive_ctl_set_me_params_op_t);
487
488    status = ive_api_function(mCodecCtx, &s_me_params_ip, &s_me_params_op);
489    if (status != IV_SUCCESS) {
490        ALOGE("Unable to set me params = 0x%x\n", s_me_params_op.u4_error_code);
491        return OMX_ErrorUndefined;
492    }
493    return OMX_ErrorNone;
494}
495
496OMX_ERRORTYPE SoftAVC::setGopParams() {
497    IV_STATUS_T status;
498    ive_ctl_set_gop_params_ip_t s_gop_params_ip;
499    ive_ctl_set_gop_params_op_t s_gop_params_op;
500
501    s_gop_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
502    s_gop_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS;
503
504    s_gop_params_ip.u4_i_frm_interval = mIInterval;
505    s_gop_params_ip.u4_idr_frm_interval = mIDRInterval;
506    s_gop_params_ip.u4_num_b_frames = DEFAULT_B_FRAMES;
507
508    s_gop_params_ip.u4_timestamp_high = -1;
509    s_gop_params_ip.u4_timestamp_low = -1;
510
511    s_gop_params_ip.u4_size = sizeof(ive_ctl_set_gop_params_ip_t);
512    s_gop_params_op.u4_size = sizeof(ive_ctl_set_gop_params_op_t);
513
514    status = ive_api_function(mCodecCtx, &s_gop_params_ip, &s_gop_params_op);
515    if (status != IV_SUCCESS) {
516        ALOGE("Unable to set ME params = 0x%x\n",
517                s_gop_params_op.u4_error_code);
518        return OMX_ErrorUndefined;
519    }
520    return OMX_ErrorNone;
521}
522
523OMX_ERRORTYPE SoftAVC::setProfileParams() {
524    IV_STATUS_T status;
525    ive_ctl_set_profile_params_ip_t s_profile_params_ip;
526    ive_ctl_set_profile_params_op_t s_profile_params_op;
527
528    s_profile_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
529    s_profile_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS;
530
531    s_profile_params_ip.e_profile = DEFAULT_EPROFILE;
532
533    s_profile_params_ip.u4_timestamp_high = -1;
534    s_profile_params_ip.u4_timestamp_low = -1;
535
536    s_profile_params_ip.u4_size = sizeof(ive_ctl_set_profile_params_ip_t);
537    s_profile_params_op.u4_size = sizeof(ive_ctl_set_profile_params_op_t);
538
539    status = ive_api_function(mCodecCtx, &s_profile_params_ip, &s_profile_params_op);
540    if (status != IV_SUCCESS) {
541        ALOGE("Unable to set profile params = 0x%x\n",
542                s_profile_params_op.u4_error_code);
543        return OMX_ErrorUndefined;
544    }
545    return OMX_ErrorNone;
546}
547
548OMX_ERRORTYPE SoftAVC::setDeblockParams() {
549    IV_STATUS_T status;
550    ive_ctl_set_deblock_params_ip_t s_deblock_params_ip;
551    ive_ctl_set_deblock_params_op_t s_deblock_params_op;
552
553    s_deblock_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
554    s_deblock_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS;
555
556    s_deblock_params_ip.u4_disable_deblock_level = mDisableDeblkLevel;
557
558    s_deblock_params_ip.u4_timestamp_high = -1;
559    s_deblock_params_ip.u4_timestamp_low = -1;
560
561    s_deblock_params_ip.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t);
562    s_deblock_params_op.u4_size = sizeof(ive_ctl_set_deblock_params_op_t);
563
564    status = ive_api_function(mCodecCtx, &s_deblock_params_ip, &s_deblock_params_op);
565    if (status != IV_SUCCESS) {
566        ALOGE("Unable to enable/disable deblock params = 0x%x\n",
567                s_deblock_params_op.u4_error_code);
568        return OMX_ErrorUndefined;
569    }
570    return OMX_ErrorNone;
571}
572
573void SoftAVC::logVersion() {
574    ive_ctl_getversioninfo_ip_t s_ctl_ip;
575    ive_ctl_getversioninfo_op_t s_ctl_op;
576    UWORD8 au1_buf[512];
577    IV_STATUS_T status;
578
579    s_ctl_ip.e_cmd = IVE_CMD_VIDEO_CTL;
580    s_ctl_ip.e_sub_cmd = IVE_CMD_CTL_GETVERSION;
581    s_ctl_ip.u4_size = sizeof(ive_ctl_getversioninfo_ip_t);
582    s_ctl_op.u4_size = sizeof(ive_ctl_getversioninfo_op_t);
583    s_ctl_ip.pu1_version = au1_buf;
584    s_ctl_ip.u4_version_bufsize = sizeof(au1_buf);
585
586    status = ive_api_function(mCodecCtx, (void *) &s_ctl_ip, (void *) &s_ctl_op);
587
588    if (status != IV_SUCCESS) {
589        ALOGE("Error in getting version: 0x%x", s_ctl_op.u4_error_code);
590    } else {
591        ALOGV("Ittiam encoder version: %s", (char *)s_ctl_ip.pu1_version);
592    }
593    return;
594}
595
596OMX_ERRORTYPE SoftAVC::initEncoder() {
597    IV_STATUS_T status;
598    size_t i;
599    WORD32 level;
600    uint32_t displaySizeY;
601    CHECK(!mStarted);
602
603    OMX_ERRORTYPE errType = OMX_ErrorNone;
604
605    displaySizeY = mWidth * mHeight;
606    if (displaySizeY > (1920 * 1088)) {
607        level = 50;
608    } else if (displaySizeY > (1280 * 720)) {
609        level = 40;
610    } else if (displaySizeY > (720 * 576)) {
611        level = 31;
612    } else if (displaySizeY > (624 * 320)) {
613        level = 30;
614    } else if (displaySizeY > (352 * 288)) {
615        level = 21;
616    } else {
617        level = 20;
618    }
619    mAVCEncLevel = MAX(level, mAVCEncLevel);
620
621    if (OMX_ErrorNone != (errType = initEncParams())) {
622        ALOGE("Failed to initialize encoder params");
623        mSignalledError = true;
624        notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
625        return errType;
626    }
627
628    mStride = ALIGN16(mWidth);
629
630    if (mInputDataIsMeta) {
631        if (mConversionBuffer) {
632            free(mConversionBuffer);
633            mConversionBuffer = NULL;
634        }
635
636        if (mConversionBuffer == NULL) {
637            mConversionBuffer = (uint8_t *)malloc(mStride * mHeight * 3 / 2);
638            if (mConversionBuffer == NULL) {
639                ALOGE("Allocating conversion buffer failed.");
640                return OMX_ErrorUndefined;
641            }
642        }
643    }
644
645    switch (mColorFormat) {
646        case OMX_COLOR_FormatYUV420SemiPlanar:
647            mIvVideoColorFormat = IV_YUV_420SP_UV;
648            ALOGV("colorFormat YUV_420SP");
649            break;
650        default:
651        case OMX_COLOR_FormatYUV420Planar:
652            mIvVideoColorFormat = IV_YUV_420P;
653            ALOGV("colorFormat YUV_420P");
654            break;
655    }
656
657    ALOGV("Params width %d height %d level %d colorFormat %d", mWidth,
658            mHeight, mAVCEncLevel, mIvVideoColorFormat);
659
660    /* Getting Number of MemRecords */
661    {
662        iv_num_mem_rec_ip_t s_num_mem_rec_ip;
663        iv_num_mem_rec_op_t s_num_mem_rec_op;
664
665        s_num_mem_rec_ip.u4_size = sizeof(iv_num_mem_rec_ip_t);
666        s_num_mem_rec_op.u4_size = sizeof(iv_num_mem_rec_op_t);
667
668        s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
669
670        status = ive_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op);
671
672        if (status != IV_SUCCESS) {
673            ALOGE("Get number of memory records failed = 0x%x\n",
674                    s_num_mem_rec_op.u4_error_code);
675            return OMX_ErrorUndefined;
676        }
677
678        mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec;
679    }
680
681    /* Allocate array to hold memory records */
682    mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t));
683    if (NULL == mMemRecords) {
684        ALOGE("Unable to allocate memory for hold memory records: Size %d",
685                mNumMemRecords * sizeof(iv_mem_rec_t));
686        mSignalledError = true;
687        notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
688        return OMX_ErrorUndefined;
689    }
690
691    {
692        iv_mem_rec_t *ps_mem_rec;
693        ps_mem_rec = mMemRecords;
694        for (i = 0; i < mNumMemRecords; i++) {
695            ps_mem_rec->u4_size = sizeof(iv_mem_rec_t);
696            ps_mem_rec->pv_base = NULL;
697            ps_mem_rec->u4_mem_size = 0;
698            ps_mem_rec->u4_mem_alignment = 0;
699            ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE;
700
701            ps_mem_rec++;
702        }
703    }
704
705    /* Getting MemRecords Attributes */
706    {
707        iv_fill_mem_rec_ip_t s_fill_mem_rec_ip;
708        iv_fill_mem_rec_op_t s_fill_mem_rec_op;
709
710        s_fill_mem_rec_ip.u4_size = sizeof(iv_fill_mem_rec_ip_t);
711        s_fill_mem_rec_op.u4_size = sizeof(iv_fill_mem_rec_op_t);
712
713        s_fill_mem_rec_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
714        s_fill_mem_rec_ip.ps_mem_rec = mMemRecords;
715        s_fill_mem_rec_ip.u4_num_mem_rec = mNumMemRecords;
716        s_fill_mem_rec_ip.u4_max_wd = mWidth;
717        s_fill_mem_rec_ip.u4_max_ht = mHeight;
718        s_fill_mem_rec_ip.u4_max_level = mAVCEncLevel;
719        s_fill_mem_rec_ip.e_color_format = DEFAULT_INP_COLOR_FORMAT;
720        s_fill_mem_rec_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
721        s_fill_mem_rec_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
722        s_fill_mem_rec_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
723        s_fill_mem_rec_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
724
725        status = ive_api_function(0, &s_fill_mem_rec_ip, &s_fill_mem_rec_op);
726
727        if (status != IV_SUCCESS) {
728            ALOGE("Fill memory records failed = 0x%x\n",
729                    s_fill_mem_rec_op.u4_error_code);
730            mSignalledError = true;
731            notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
732            return OMX_ErrorUndefined;
733        }
734    }
735
736    /* Allocating Memory for Mem Records */
737    {
738        WORD32 total_size;
739        iv_mem_rec_t *ps_mem_rec;
740        total_size = 0;
741
742        ps_mem_rec = mMemRecords;
743        for (i = 0; i < mNumMemRecords; i++) {
744            ps_mem_rec->pv_base = ive_aligned_malloc(
745                    ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
746            if (ps_mem_rec->pv_base == NULL) {
747                ALOGE("Allocation failure for mem record id %d size %d\n", i,
748                        ps_mem_rec->u4_mem_size);
749                mSignalledError = true;
750                notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
751                return OMX_ErrorUndefined;
752
753            }
754            total_size += ps_mem_rec->u4_mem_size;
755
756            ps_mem_rec++;
757        }
758        printf("\nTotal memory for codec %d\n", total_size);
759    }
760
761    /* Codec Instance Creation */
762    {
763        ive_init_ip_t s_init_ip;
764        ive_init_op_t s_init_op;
765
766        mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base;
767        mCodecCtx->u4_size = sizeof(iv_obj_t);
768        mCodecCtx->pv_fxns = (void *)ive_api_function;
769
770        s_init_ip.u4_size = sizeof(ive_init_ip_t);
771        s_init_op.u4_size = sizeof(ive_init_op_t);
772
773        s_init_ip.e_cmd = IV_CMD_INIT;
774        s_init_ip.u4_num_mem_rec = mNumMemRecords;
775        s_init_ip.ps_mem_rec = mMemRecords;
776        s_init_ip.u4_max_wd = mWidth;
777        s_init_ip.u4_max_ht = mHeight;
778        s_init_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
779        s_init_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
780        s_init_ip.u4_max_level = mAVCEncLevel;
781        s_init_ip.e_inp_color_fmt = mIvVideoColorFormat;
782
783        if (mReconEnable || mPSNREnable) {
784            s_init_ip.u4_enable_recon = 1;
785        } else {
786            s_init_ip.u4_enable_recon = 0;
787        }
788        s_init_ip.e_recon_color_fmt = DEFAULT_RECON_COLOR_FORMAT;
789        s_init_ip.e_rc_mode = DEFAULT_RC_MODE;
790        s_init_ip.u4_max_framerate = DEFAULT_MAX_FRAMERATE;
791        s_init_ip.u4_max_bitrate = DEFAULT_MAX_BITRATE;
792        s_init_ip.u4_max_num_bframes = DEFAULT_B_FRAMES;
793        s_init_ip.e_content_type = IV_PROGRESSIVE;
794        s_init_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
795        s_init_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
796        s_init_ip.e_slice_mode = mSliceMode;
797        s_init_ip.u4_slice_param = mSliceParam;
798        s_init_ip.e_arch = mArch;
799        s_init_ip.e_soc = DEFAULT_SOC;
800
801        status = ive_api_function(mCodecCtx, &s_init_ip, &s_init_op);
802
803        if (status != IV_SUCCESS) {
804            ALOGE("Init memory records failed = 0x%x\n",
805                    s_init_op.u4_error_code);
806            mSignalledError = true;
807            notify(OMX_EventError, OMX_ErrorUndefined, 0 /* arg2 */, NULL /* data */);
808            return OMX_ErrorUndefined;
809        }
810    }
811
812    /* Get Codec Version */
813    logVersion();
814
815    /* set processor details */
816    setNumCores();
817
818    /* Video control Set Frame dimensions */
819    setDimensions();
820
821    /* Video control Set Frame rates */
822    setFrameRate();
823
824    /* Video control Set IPE Params */
825    setIpeParams();
826
827    /* Video control Set Bitrate */
828    setBitRate();
829
830    /* Video control Set QP */
831    setQp();
832
833    /* Video control Set AIR params */
834    setAirParams();
835
836    /* Video control Set VBV params */
837    setVbvParams();
838
839    /* Video control Set Motion estimation params */
840    setMeParams();
841
842    /* Video control Set GOP params */
843    setGopParams();
844
845    /* Video control Set Deblock params */
846    setDeblockParams();
847
848    /* Video control Set Profile params */
849    setProfileParams();
850
851    /* Video control Set in Encode header mode */
852    setEncMode(IVE_ENC_MODE_HEADER);
853
854    ALOGV("init_codec successfull");
855
856    mSpsPpsHeaderReceived = false;
857    mStarted = true;
858
859    return OMX_ErrorNone;
860}
861
862OMX_ERRORTYPE SoftAVC::releaseEncoder() {
863    IV_STATUS_T status = IV_SUCCESS;
864    iv_retrieve_mem_rec_ip_t s_retrieve_mem_ip;
865    iv_retrieve_mem_rec_op_t s_retrieve_mem_op;
866    iv_mem_rec_t *ps_mem_rec;
867    UWORD32 i;
868
869    if (!mStarted) {
870        return OMX_ErrorNone;
871    }
872
873    s_retrieve_mem_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t);
874    s_retrieve_mem_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t);
875    s_retrieve_mem_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC;
876    s_retrieve_mem_ip.ps_mem_rec = mMemRecords;
877
878    status = ive_api_function(mCodecCtx, &s_retrieve_mem_ip, &s_retrieve_mem_op);
879
880    if (status != IV_SUCCESS) {
881        ALOGE("Unable to retrieve memory records = 0x%x\n",
882                s_retrieve_mem_op.u4_error_code);
883        return OMX_ErrorUndefined;
884    }
885
886    /* Free memory records */
887    ps_mem_rec = mMemRecords;
888    for (i = 0; i < s_retrieve_mem_op.u4_num_mem_rec_filled; i++) {
889        ive_aligned_free(ps_mem_rec->pv_base);
890        ps_mem_rec++;
891    }
892
893    free(mMemRecords);
894
895    if (mConversionBuffer != NULL) {
896        free(mConversionBuffer);
897        mConversionBuffer = NULL;
898    }
899
900    mStarted = false;
901
902    return OMX_ErrorNone;
903}
904
905OMX_ERRORTYPE SoftAVC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params) {
906    switch (index) {
907        case OMX_IndexParamVideoBitrate:
908        {
909            OMX_VIDEO_PARAM_BITRATETYPE *bitRate =
910                (OMX_VIDEO_PARAM_BITRATETYPE *)params;
911
912            if (bitRate->nPortIndex != 1) {
913                return OMX_ErrorUndefined;
914            }
915
916            bitRate->eControlRate = OMX_Video_ControlRateVariable;
917            bitRate->nTargetBitrate = mBitrate;
918            return OMX_ErrorNone;
919        }
920
921        case OMX_IndexParamVideoAvc:
922        {
923            OMX_VIDEO_PARAM_AVCTYPE *avcParams = (OMX_VIDEO_PARAM_AVCTYPE *)params;
924
925            if (avcParams->nPortIndex != 1) {
926                return OMX_ErrorUndefined;
927            }
928
929            avcParams->eProfile = OMX_VIDEO_AVCProfileBaseline;
930            OMX_VIDEO_AVCLEVELTYPE omxLevel = OMX_VIDEO_AVCLevel31;
931            if (OMX_ErrorNone
932                    != ConvertAvcSpecLevelToOmxAvcLevel(mAVCEncLevel, &omxLevel)) {
933                return OMX_ErrorUndefined;
934            }
935
936            avcParams->eLevel = omxLevel;
937            avcParams->nRefFrames = 1;
938            avcParams->nBFrames = 0;
939            avcParams->bUseHadamard = OMX_TRUE;
940            avcParams->nAllowedPictureTypes = (OMX_VIDEO_PictureTypeI
941                    | OMX_VIDEO_PictureTypeP);
942            avcParams->nRefIdx10ActiveMinus1 = 0;
943            avcParams->nRefIdx11ActiveMinus1 = 0;
944            avcParams->bWeightedPPrediction = OMX_FALSE;
945            avcParams->bEntropyCodingCABAC = OMX_FALSE;
946            avcParams->bconstIpred = OMX_FALSE;
947            avcParams->bDirect8x8Inference = OMX_FALSE;
948            avcParams->bDirectSpatialTemporal = OMX_FALSE;
949            avcParams->nCabacInitIdc = 0;
950            return OMX_ErrorNone;
951        }
952
953        default:
954            return SoftVideoEncoderOMXComponent::internalGetParameter(index, params);
955    }
956}
957
958OMX_ERRORTYPE SoftAVC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR params) {
959    int32_t indexFull = index;
960
961    switch (indexFull) {
962        case OMX_IndexParamVideoBitrate:
963        {
964            return internalSetBitrateParams(
965                    (const OMX_VIDEO_PARAM_BITRATETYPE *)params);
966        }
967
968        case OMX_IndexParamVideoAvc:
969        {
970            OMX_VIDEO_PARAM_AVCTYPE *avcType = (OMX_VIDEO_PARAM_AVCTYPE *)params;
971
972            if (avcType->nPortIndex != 1) {
973                return OMX_ErrorUndefined;
974            }
975
976            if (avcType->eProfile != OMX_VIDEO_AVCProfileBaseline
977                    || avcType->nRefFrames != 1 || avcType->nBFrames != 0
978                    || avcType->bUseHadamard != OMX_TRUE
979                    || (avcType->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) != 0
980                    || avcType->nRefIdx10ActiveMinus1 != 0
981                    || avcType->nRefIdx11ActiveMinus1 != 0
982                    || avcType->bWeightedPPrediction != OMX_FALSE
983                    || avcType->bEntropyCodingCABAC != OMX_FALSE
984                    || avcType->bconstIpred != OMX_FALSE
985                    || avcType->bDirect8x8Inference != OMX_FALSE
986                    || avcType->bDirectSpatialTemporal != OMX_FALSE
987                    || avcType->nCabacInitIdc != 0) {
988                return OMX_ErrorUndefined;
989            }
990
991            if (OK != ConvertOmxAvcLevelToAvcSpecLevel(avcType->eLevel, &mAVCEncLevel)) {
992                return OMX_ErrorUndefined;
993            }
994
995            return OMX_ErrorNone;
996        }
997
998        default:
999            return SoftVideoEncoderOMXComponent::internalSetParameter(index, params);
1000    }
1001}
1002
1003OMX_ERRORTYPE SoftAVC::setConfig(
1004        OMX_INDEXTYPE index, const OMX_PTR _params) {
1005    switch (index) {
1006        case OMX_IndexConfigVideoIntraVOPRefresh:
1007        {
1008            OMX_CONFIG_INTRAREFRESHVOPTYPE *params =
1009                (OMX_CONFIG_INTRAREFRESHVOPTYPE *)_params;
1010
1011            if (params->nPortIndex != kOutputPortIndex) {
1012                return OMX_ErrorBadPortIndex;
1013            }
1014
1015            mKeyFrameRequested = params->IntraRefreshVOP;
1016            return OMX_ErrorNone;
1017        }
1018
1019        case OMX_IndexConfigVideoBitrate:
1020        {
1021            OMX_VIDEO_CONFIG_BITRATETYPE *params =
1022                (OMX_VIDEO_CONFIG_BITRATETYPE *)_params;
1023
1024            if (params->nPortIndex != kOutputPortIndex) {
1025                return OMX_ErrorBadPortIndex;
1026            }
1027
1028            if (mBitrate != params->nEncodeBitrate) {
1029                mBitrate = params->nEncodeBitrate;
1030                mBitrateUpdated = true;
1031            }
1032            return OMX_ErrorNone;
1033        }
1034
1035        default:
1036            return SimpleSoftOMXComponent::setConfig(index, _params);
1037    }
1038}
1039
1040OMX_ERRORTYPE SoftAVC::internalSetBitrateParams(
1041        const OMX_VIDEO_PARAM_BITRATETYPE *bitrate) {
1042    if (bitrate->nPortIndex != kOutputPortIndex) {
1043        return OMX_ErrorUnsupportedIndex;
1044    }
1045
1046    mBitrate = bitrate->nTargetBitrate;
1047    mBitrateUpdated = true;
1048
1049    return OMX_ErrorNone;
1050}
1051
1052OMX_ERRORTYPE SoftAVC::setEncodeArgs(
1053        ive_video_encode_ip_t *ps_encode_ip,
1054        ive_video_encode_op_t *ps_encode_op,
1055        OMX_BUFFERHEADERTYPE *inputBufferHeader,
1056        OMX_BUFFERHEADERTYPE *outputBufferHeader) {
1057    iv_raw_buf_t *ps_inp_raw_buf;
1058    const uint8_t *source;
1059    UWORD8 *pu1_buf;
1060
1061    ps_inp_raw_buf = &ps_encode_ip->s_inp_buf;
1062    ps_encode_ip->s_out_buf.pv_buf = outputBufferHeader->pBuffer;
1063    ps_encode_ip->s_out_buf.u4_bytes = 0;
1064    ps_encode_ip->s_out_buf.u4_bufsize = outputBufferHeader->nAllocLen;
1065    ps_encode_ip->u4_size = sizeof(ive_video_encode_ip_t);
1066    ps_encode_op->u4_size = sizeof(ive_video_encode_op_t);
1067
1068    ps_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE;
1069    ps_encode_ip->pv_bufs = NULL;
1070    ps_encode_ip->pv_mb_info = NULL;
1071    ps_encode_ip->pv_pic_info = NULL;
1072    ps_encode_ip->u4_mb_info_type = 0;
1073    ps_encode_ip->u4_pic_info_type = 0;
1074    ps_encode_op->s_out_buf.pv_buf = NULL;
1075
1076    /* Initialize color formats */
1077    ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat;
1078
1079    source = NULL;
1080    if (inputBufferHeader) {
1081        source = inputBufferHeader->pBuffer + inputBufferHeader->nOffset;
1082
1083        if (mInputDataIsMeta) {
1084            source = extractGraphicBuffer(
1085                    mConversionBuffer, (mWidth * mHeight * 3 / 2), source,
1086                    inputBufferHeader->nFilledLen, mWidth, mHeight);
1087
1088            if (source == NULL) {
1089                ALOGE("Error in extractGraphicBuffer");
1090                notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
1091                return OMX_ErrorUndefined;
1092            }
1093        }
1094    }
1095
1096    pu1_buf = (UWORD8 *)source;
1097    switch (mIvVideoColorFormat) {
1098        case IV_YUV_420P:
1099        {
1100            ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
1101            pu1_buf += (mStride) * mHeight;
1102            ps_inp_raw_buf->apv_bufs[1] = pu1_buf;
1103            pu1_buf += (mStride / 2) * mHeight / 2;
1104            ps_inp_raw_buf->apv_bufs[2] = pu1_buf;
1105
1106            ps_inp_raw_buf->au4_wd[0] = mWidth;
1107            ps_inp_raw_buf->au4_wd[1] = mWidth / 2;
1108            ps_inp_raw_buf->au4_wd[2] = mWidth / 2;
1109
1110            ps_inp_raw_buf->au4_ht[0] = mHeight;
1111            ps_inp_raw_buf->au4_ht[1] = mHeight / 2;
1112            ps_inp_raw_buf->au4_ht[2] = mHeight / 2;
1113
1114            ps_inp_raw_buf->au4_strd[0] = mStride;
1115            ps_inp_raw_buf->au4_strd[1] = (mStride / 2);
1116            ps_inp_raw_buf->au4_strd[2] = (mStride / 2);
1117            break;
1118        }
1119
1120        case IV_YUV_422ILE:
1121        {
1122            ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
1123            ps_inp_raw_buf->au4_wd[0] = mWidth * 2;
1124            ps_inp_raw_buf->au4_ht[0] = mHeight;
1125            ps_inp_raw_buf->au4_strd[0] = mStride * 2;
1126            break;
1127        }
1128
1129        case IV_YUV_420SP_UV:
1130        case IV_YUV_420SP_VU:
1131        default:
1132        {
1133            ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
1134            pu1_buf += (mStride) * mHeight;
1135            ps_inp_raw_buf->apv_bufs[1] = pu1_buf;
1136
1137            ps_inp_raw_buf->au4_wd[0] = mWidth;
1138            ps_inp_raw_buf->au4_wd[1] = mWidth;
1139
1140            ps_inp_raw_buf->au4_ht[0] = mHeight;
1141            ps_inp_raw_buf->au4_ht[1] = mHeight / 2;
1142
1143            ps_inp_raw_buf->au4_strd[0] = mStride;
1144            ps_inp_raw_buf->au4_strd[1] = mStride;
1145            break;
1146        }
1147    }
1148
1149    ps_encode_ip->u4_is_last = 0;
1150
1151    if (inputBufferHeader) {
1152        ps_encode_ip->u4_timestamp_high = (inputBufferHeader->nTimeStamp) >> 32;
1153        ps_encode_ip->u4_timestamp_low = (inputBufferHeader->nTimeStamp) & 0xFFFFFFFF;
1154    }
1155
1156    return OMX_ErrorNone;
1157}
1158
1159void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
1160    IV_STATUS_T status;
1161    WORD32 timeDelay, timeTaken;
1162
1163    UNUSED(portIndex);
1164
1165    // Initialize encoder if not already initialized
1166    if (mCodecCtx == NULL) {
1167        if (OMX_ErrorNone != initEncoder()) {
1168            ALOGE("Failed to initialize encoder");
1169            notify(OMX_EventError, OMX_ErrorUndefined, 0 /* arg2 */, NULL /* data */);
1170            return;
1171        }
1172    }
1173    if (mSignalledError || mSawInputEOS) {
1174        return;
1175    }
1176
1177    List<BufferInfo *> &inQueue = getPortQueue(0);
1178    List<BufferInfo *> &outQueue = getPortQueue(1);
1179
1180    while (!mSawInputEOS && !inQueue.empty() && !outQueue.empty()) {
1181        OMX_ERRORTYPE error;
1182        ive_video_encode_ip_t s_encode_ip;
1183        ive_video_encode_op_t s_encode_op;
1184
1185        BufferInfo *inputBufferInfo = *inQueue.begin();
1186        OMX_BUFFERHEADERTYPE *inputBufferHeader = inputBufferInfo->mHeader;
1187
1188        BufferInfo *outputBufferInfo = *outQueue.begin();
1189        OMX_BUFFERHEADERTYPE *outputBufferHeader = outputBufferInfo->mHeader;
1190
1191        if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS) {
1192            inQueue.erase(inQueue.begin());
1193            inputBufferInfo->mOwnedByUs = false;
1194            notifyEmptyBufferDone(inputBufferHeader);
1195
1196            outputBufferHeader->nFilledLen = 0;
1197            outputBufferHeader->nFlags = OMX_BUFFERFLAG_EOS;
1198
1199            outQueue.erase(outQueue.begin());
1200            outputBufferInfo->mOwnedByUs = false;
1201            notifyFillBufferDone(outputBufferHeader);
1202            return;
1203        }
1204
1205        outputBufferHeader->nTimeStamp = 0;
1206        outputBufferHeader->nFlags = 0;
1207        outputBufferHeader->nOffset = 0;
1208        outputBufferHeader->nFilledLen = 0;
1209        outputBufferHeader->nOffset = 0;
1210
1211        uint8_t *outPtr = (uint8_t *)outputBufferHeader->pBuffer;
1212
1213        if (!mSpsPpsHeaderReceived) {
1214            error = setEncodeArgs(&s_encode_ip, &s_encode_op, NULL, outputBufferHeader);
1215            if (error != OMX_ErrorNone) {
1216                mSignalledError = true;
1217                notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
1218                return;
1219            }
1220            status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
1221
1222            if (IV_SUCCESS != status) {
1223                ALOGE("Encode Frame failed = 0x%x\n",
1224                        s_encode_op.u4_error_code);
1225            } else {
1226                ALOGV("Bytes Generated in header %d\n",
1227                        s_encode_op.s_out_buf.u4_bytes);
1228            }
1229
1230            mSpsPpsHeaderReceived = true;
1231
1232            outputBufferHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
1233            outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes;
1234            outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp;
1235
1236            outQueue.erase(outQueue.begin());
1237            outputBufferInfo->mOwnedByUs = false;
1238            DUMP_TO_FILE(
1239                    mOutFile, outputBufferHeader->pBuffer,
1240                    outputBufferHeader->nFilledLen);
1241            notifyFillBufferDone(outputBufferHeader);
1242
1243            setEncMode(IVE_ENC_MODE_PICTURE);
1244            return;
1245        }
1246
1247        if (mBitrateUpdated) {
1248            setBitRate();
1249        }
1250
1251        if (mKeyFrameRequested) {
1252            setFrameType(IV_IDR_FRAME);
1253        }
1254
1255        mPrevTimestampUs = inputBufferHeader->nTimeStamp;
1256
1257        if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS) {
1258            mSawInputEOS = true;
1259        }
1260
1261        error = setEncodeArgs(
1262                &s_encode_ip, &s_encode_op, inputBufferHeader, outputBufferHeader);
1263        if (error != OMX_ErrorNone) {
1264            mSignalledError = true;
1265            notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
1266            return;
1267        }
1268
1269        DUMP_TO_FILE(
1270                mInFile, s_encode_ip.s_inp_buf.apv_bufs[0],
1271                (mHeight * mStride * 3 / 2));
1272        //DUMP_TO_FILE(mInFile, inputBufferHeader->pBuffer + inputBufferHeader->nOffset,
1273        //    inputBufferHeader->nFilledLen);
1274
1275        GETTIME(&mTimeStart, NULL);
1276        /* Compute time elapsed between end of previous decode()
1277         * to start of current decode() */
1278        TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
1279
1280        status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
1281
1282        if (IV_SUCCESS != status) {
1283            ALOGE("Encode Frame failed = 0x%x\n",
1284                    s_encode_op.u4_error_code);
1285            mSignalledError = true;
1286            notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
1287            return;
1288        }
1289
1290        GETTIME(&mTimeEnd, NULL);
1291        /* Compute time taken for decode() */
1292        TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
1293
1294        ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
1295                s_encode_op.s_out_buf.u4_bytes);
1296
1297
1298        outputBufferHeader->nFlags = inputBufferHeader->nFlags;
1299        outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes;
1300        outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp;
1301
1302        if (IV_IDR_FRAME
1303                == s_encode_op.u4_encoded_frame_type) {
1304            outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
1305        }
1306
1307        inQueue.erase(inQueue.begin());
1308        inputBufferInfo->mOwnedByUs = false;
1309
1310        notifyEmptyBufferDone(inputBufferHeader);
1311
1312        if (mSawInputEOS) {
1313            outputBufferHeader->nFlags |= OMX_BUFFERFLAG_EOS;
1314        }
1315
1316        outputBufferInfo->mOwnedByUs = false;
1317        outQueue.erase(outQueue.begin());
1318
1319        DUMP_TO_FILE(
1320                mOutFile, outputBufferHeader->pBuffer,
1321                outputBufferHeader->nFilledLen);
1322        notifyFillBufferDone(outputBufferHeader);
1323
1324    }
1325    return;
1326}
1327
1328
1329}  // namespace android
1330
1331android::SoftOMXComponent *createSoftOMXComponent(
1332        const char *name, const OMX_CALLBACKTYPE *callbacks,
1333        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
1334    return new android::SoftAVC(name, callbacks, appData, component);
1335}
1336