Shalaj Jain | 273b3e0 | 2012-06-22 19:08:03 -0700 | [diff] [blame^] | 1 | /*--------------------------------------------------------------------------
|
| 2 | Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
|
| 3 |
|
| 4 | Redistribution and use in source and binary forms, with or without
|
| 5 | modification, are permitted provided that the following conditions are met:
|
| 6 | * Redistributions of source code must retain the above copyright
|
| 7 | notice, this list of conditions and the following disclaimer.
|
| 8 | * Redistributions in binary form must reproduce the above copyright
|
| 9 | notice, this list of conditions and the following disclaimer in the
|
| 10 | documentation and/or other materials provided with the distribution.
|
| 11 | * Neither the name of Code Aurora nor
|
| 12 | the names of its contributors may be used to endorse or promote
|
| 13 | products derived from this software without specific prior written
|
| 14 | permission.
|
| 15 |
|
| 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
| 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| 18 | IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 19 | NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
| 20 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
| 21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
| 22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
| 23 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
| 24 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
| 25 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
| 26 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 27 | --------------------------------------------------------------------------*/
|
| 28 | /*============================================================================
|
| 29 | V E N C _ T E S T. C P P
|
| 30 |
|
| 31 | DESCRIPTION
|
| 32 |
|
| 33 | This is the OMX test app .
|
| 34 |
|
| 35 | REFERENCES
|
| 36 |
|
| 37 | ============================================================================*/
|
| 38 |
|
| 39 | //usage
|
| 40 | // FILE QVGA MP4 24 384000 100 enc_qvga.yuv QVGA_24.m4v
|
| 41 | // FILE QCIF MP4 15 96000 0 foreman.qcif.yuv output_qcif.m4v
|
| 42 | // FILE VGA MP4 24 1200000 218 enc_vga.yuv vga_output.m4v
|
| 43 | #include <sys/types.h>
|
| 44 | #include <sys/stat.h>
|
| 45 | #include <string.h>
|
| 46 | #include <unistd.h>
|
| 47 | #include <stdlib.h>
|
| 48 | #include <stdio.h>
|
| 49 | #include <pthread.h>
|
| 50 | #include <fcntl.h>
|
| 51 | #include <sys/mman.h>
|
| 52 | //#include <sys/time.h>
|
| 53 | #include <time.h>
|
| 54 | #include <sys/ioctl.h>
|
| 55 | #include <limits.h>
|
| 56 | #include <string.h>
|
| 57 | //#include <sys/stat.h>
|
| 58 | #include "OMX_QCOMExtns.h"
|
| 59 | #include "OMX_Core.h"
|
| 60 |
|
| 61 | #define QCOM_EXT 1
|
| 62 |
|
| 63 | #include "OMX_Core.h"
|
| 64 | #include "OMX_Video.h"
|
| 65 | #include "OMX_Component.h"
|
| 66 | #include "camera_test.h"
|
| 67 | #include "fb_test.h"
|
| 68 | #include "venc_util.h"
|
| 69 | #include "extra_data_handler.h"
|
| 70 | #ifdef USE_ION
|
| 71 | #include <ion_msm.h>
|
| 72 | #endif
|
| 73 |
|
| 74 | //////////////////////////
|
| 75 | // MACROS
|
| 76 | //////////////////////////
|
| 77 |
|
| 78 | #define CHK(result) if (result != OMX_ErrorNone) { E("*************** error *************"); exit(0); }
|
| 79 | #define TEST_LOG
|
| 80 | #ifdef VENC_SYSLOG
|
| 81 | #include "cutils/log.h"
|
| 82 | /// Debug message macro
|
| 83 | #define D(fmt, ...) LOGE("venc_test Debug %s::%d "fmt"\n", \
|
| 84 | __FUNCTION__, __LINE__, \
|
| 85 | ## __VA_ARGS__)
|
| 86 |
|
| 87 | /// Error message macro
|
| 88 | #define E(fmt, ...) LOGE("venc_test Error %s::%d "fmt"\n", \
|
| 89 | __FUNCTION__, __LINE__, \
|
| 90 | ## __VA_ARGS__)
|
| 91 |
|
| 92 | #else
|
| 93 | #ifdef TEST_LOG
|
| 94 | #define D(fmt, ...) fprintf(stderr, "venc_test Debug %s::%d "fmt"\n", \
|
| 95 | __FUNCTION__, __LINE__, \
|
| 96 | ## __VA_ARGS__)
|
| 97 |
|
| 98 | /// Error message macro
|
| 99 | #define E(fmt, ...) fprintf(stderr, "venc_test Error %s::%d "fmt"\n", \
|
| 100 | __FUNCTION__, __LINE__, \
|
| 101 | ## __VA_ARGS__)
|
| 102 | #else
|
| 103 | #define D(fmt, ...)
|
| 104 | #define E(fmt, ...)
|
| 105 | #endif
|
| 106 |
|
| 107 | #endif
|
| 108 |
|
| 109 | //////////////////////////
|
| 110 | // CONSTANTS
|
| 111 | //////////////////////////
|
| 112 | static const int MAX_MSG = 100;
|
| 113 | //#warning do not hardcode these use port definition
|
| 114 | static const int PORT_INDEX_IN = 0;
|
| 115 | static const int PORT_INDEX_OUT = 1;
|
| 116 |
|
| 117 | static const int NUM_IN_BUFFERS = 10;
|
| 118 | static const int NUM_OUT_BUFFERS = 10;
|
| 119 |
|
| 120 | unsigned int num_in_buffers = 0;
|
| 121 | unsigned int num_out_buffers = 0;
|
| 122 |
|
| 123 | //////////////////////////
|
| 124 | /* MPEG4 profile and level table*/
|
| 125 | static const unsigned int mpeg4_profile_level_table[][5]=
|
| 126 | {
|
| 127 | /*max mb per frame, max mb per sec, max bitrate, level, profile*/
|
| 128 | {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
|
| 129 | {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
|
| 130 | {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
|
| 131 | {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
|
| 132 | {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
|
| 133 | {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
|
| 134 | {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
|
| 135 | {0,0,0,0,0},
|
| 136 |
|
| 137 | {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
|
| 138 | {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
|
| 139 | {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
|
| 140 | {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
|
| 141 | {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
|
| 142 | {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
|
| 143 | {0,0,0,0,0},
|
| 144 | };
|
| 145 |
|
| 146 | /* H264 profile and level table*/
|
| 147 | static const unsigned int h264_profile_level_table[][5]=
|
| 148 | {
|
| 149 | /*max mb per frame, max mb per sec, max bitrate, level, profile*/
|
| 150 | {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
|
| 151 | {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
|
| 152 | {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
|
| 153 | {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
|
| 154 | {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
|
| 155 | {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
|
| 156 | {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
|
| 157 | {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
|
| 158 | {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
|
| 159 | {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
|
| 160 | {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
|
| 161 | {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
|
| 162 | {0,0,0,0,0},
|
| 163 |
|
| 164 | {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
|
| 165 | {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
|
| 166 | {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
|
| 167 | {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
|
| 168 | {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
|
| 169 | {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
|
| 170 | {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
|
| 171 | {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
|
| 172 | {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
|
| 173 | {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
|
| 174 | {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
|
| 175 | {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
|
| 176 | {0,0,0,0,0},
|
| 177 |
|
| 178 | {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
|
| 179 | {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
|
| 180 | {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
|
| 181 | {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
|
| 182 | {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
|
| 183 | {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
|
| 184 | {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
|
| 185 | {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
|
| 186 | {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
|
| 187 | {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
|
| 188 | {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
|
| 189 | {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
|
| 190 | {0,0,0,0,0}
|
| 191 |
|
| 192 | };
|
| 193 |
|
| 194 | /* H263 profile and level table*/
|
| 195 | static const unsigned int h263_profile_level_table[][5]=
|
| 196 | {
|
| 197 | /*max mb per frame, max mb per sec, max bitrate, level, profile*/
|
| 198 | {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
|
| 199 | {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
|
| 200 | {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
|
| 201 | {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
|
| 202 | {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
|
| 203 | {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
|
| 204 | {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
|
| 205 | {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
|
| 206 | {0,0,0,0,0}
|
| 207 | };
|
| 208 |
|
| 209 | #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
|
| 210 | #define FractionToQ16(q,num,den) { OMX_U32 power; Log2(den,power); q = num << (16 - power); }
|
| 211 |
|
| 212 | //////////////////////////
|
| 213 | // TYPES
|
| 214 | //////////////////////////
|
| 215 | struct ProfileType
|
| 216 | {
|
| 217 | OMX_VIDEO_CODINGTYPE eCodec;
|
| 218 | OMX_VIDEO_MPEG4LEVELTYPE eLevel;
|
| 219 | OMX_VIDEO_CONTROLRATETYPE eControlRate;
|
| 220 | OMX_VIDEO_AVCSLICEMODETYPE eSliceMode;
|
| 221 | OMX_U32 nFrameWidth;
|
| 222 | OMX_U32 nFrameHeight;
|
| 223 | OMX_U32 nFrameBytes;
|
| 224 | #ifdef BADGER
|
| 225 | OMX_U32 nFramestride;
|
| 226 | OMX_U32 nFrameScanlines;
|
| 227 | OMX_U32 nFrameRead;
|
| 228 | #endif
|
| 229 | OMX_U32 nBitrate;
|
| 230 | float nFramerate;
|
| 231 | char* cInFileName;
|
| 232 | char* cOutFileName;
|
| 233 | OMX_U32 nUserProfile;
|
| 234 | };
|
| 235 |
|
| 236 | enum MsgId
|
| 237 | {
|
| 238 | MSG_ID_OUTPUT_FRAME_DONE,
|
| 239 | MSG_ID_INPUT_FRAME_DONE,
|
| 240 | MSG_ID_MAX
|
| 241 | };
|
| 242 | union MsgData
|
| 243 | {
|
| 244 | struct
|
| 245 | {
|
| 246 | OMX_BUFFERHEADERTYPE* pBuffer;
|
| 247 | } sBitstreamData;
|
| 248 | };
|
| 249 | struct Msg
|
| 250 | {
|
| 251 | MsgId id;
|
| 252 | MsgData data;
|
| 253 | };
|
| 254 | struct MsgQ
|
| 255 | {
|
| 256 | Msg q[MAX_MSG];
|
| 257 | int head;
|
| 258 | int size;
|
| 259 | };
|
| 260 |
|
| 261 | enum Mode
|
| 262 | {
|
| 263 | MODE_PREVIEW,
|
| 264 | MODE_DISPLAY,
|
| 265 | MODE_PROFILE,
|
| 266 | MODE_FILE_ENCODE,
|
| 267 | MODE_LIVE_ENCODE
|
| 268 | };
|
| 269 |
|
| 270 | enum ResyncMarkerType
|
| 271 | {
|
| 272 | RESYNC_MARKER_NONE, ///< No resync marker
|
| 273 | RESYNC_MARKER_BYTE, ///< BYTE Resync marker for MPEG4, H.264
|
| 274 | RESYNC_MARKER_MB, ///< MB resync marker for MPEG4, H.264
|
| 275 | RESYNC_MARKER_GOB ///< GOB resync marker for H.263
|
| 276 | };
|
| 277 |
|
| 278 | union DynamicConfigData
|
| 279 | {
|
| 280 | OMX_VIDEO_CONFIG_BITRATETYPE bitrate;
|
| 281 | OMX_CONFIG_FRAMERATETYPE framerate;
|
| 282 | QOMX_VIDEO_INTRAPERIODTYPE intraperiod;
|
| 283 | OMX_CONFIG_INTRAREFRESHVOPTYPE intravoprefresh;
|
| 284 | OMX_CONFIG_ROTATIONTYPE rotation;
|
| 285 | float f_framerate;
|
| 286 | };
|
| 287 |
|
| 288 | struct DynamicConfig
|
| 289 | {
|
| 290 | bool pending;
|
| 291 | unsigned frame_num;
|
| 292 | OMX_INDEXTYPE config_param;
|
| 293 | union DynamicConfigData config_data;
|
| 294 | };
|
| 295 |
|
| 296 | #ifdef USE_ION
|
| 297 | struct enc_ion
|
| 298 | {
|
| 299 | int ion_device_fd;
|
| 300 | struct ion_allocation_data alloc_data;
|
| 301 | struct ion_fd_data ion_alloc_fd;
|
| 302 | };
|
| 303 | #endif
|
| 304 |
|
| 305 | //////////////////////////
|
| 306 | // MODULE VARS
|
| 307 | //////////////////////////
|
| 308 | static pthread_mutex_t m_mutex;
|
| 309 | static pthread_cond_t m_signal;
|
| 310 | static MsgQ m_sMsgQ;
|
| 311 |
|
| 312 | //#warning determine how many buffers we really have
|
| 313 | OMX_STATETYPE m_eState = OMX_StateInvalid;
|
| 314 | OMX_COMPONENTTYPE m_sComponent;
|
| 315 | OMX_HANDLETYPE m_hHandle = NULL;
|
| 316 | OMX_BUFFERHEADERTYPE* m_pOutBuffers[NUM_OUT_BUFFERS] = {NULL};
|
| 317 | OMX_BUFFERHEADERTYPE* m_pInBuffers[NUM_IN_BUFFERS] = {NULL};
|
| 318 | OMX_BOOL m_bInFrameFree[NUM_IN_BUFFERS];
|
| 319 |
|
| 320 | ProfileType m_sProfile;
|
| 321 |
|
| 322 | static int m_nFramePlay = 0;
|
| 323 | static int m_eMode = MODE_PREVIEW;
|
| 324 | static int m_nInFd = -1;
|
| 325 | static int m_nOutFd = -1;
|
| 326 | static int m_nTimeStamp = 0;
|
| 327 | static int m_nFrameIn = 0; // frames pushed to encoder
|
| 328 | static int m_nFrameOut = 0; // frames returned by encoder
|
| 329 | static int m_nAVCSliceMode = 0;
|
| 330 | static bool m_bWatchDogKicked = false;
|
| 331 | FILE *m_pDynConfFile = NULL;
|
| 332 | static struct DynamicConfig dynamic_config;
|
| 333 |
|
| 334 | /* Statistics Logging */
|
| 335 | static long long tot_bufsize = 0;
|
| 336 | int ebd_cnt=0, fbd_cnt=0;
|
| 337 |
|
| 338 | #ifdef USE_ION
|
| 339 | static const char* PMEM_DEVICE = "/dev/ion";
|
| 340 | #elif MAX_RES_720P
|
| 341 | static const char* PMEM_DEVICE = "/dev/pmem_adsp";
|
| 342 | #elif MAX_RES_1080P_EBI
|
| 343 | static const char* PMEM_DEVICE = "/dev/pmem_adsp";
|
| 344 | #elif MAX_RES_1080P
|
| 345 | static const char* PMEM_DEVICE = "/dev/pmem_smipool";
|
| 346 | #else
|
| 347 | #error PMEM_DEVICE cannot be determined.
|
| 348 | #endif
|
| 349 |
|
| 350 | #ifdef USE_ION
|
| 351 | struct enc_ion ion_data;
|
| 352 | #endif
|
| 353 | //////////////////////////
|
| 354 | // MODULE FUNCTIONS
|
| 355 | //////////////////////////
|
| 356 |
|
| 357 | void* PmemMalloc(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, int nSize)
|
| 358 | {
|
| 359 | void *pvirt = NULL;
|
| 360 | int rc = 0;
|
| 361 |
|
| 362 | if (!pMem)
|
| 363 | return NULL;
|
| 364 |
|
| 365 | #ifdef USE_ION
|
| 366 | ion_data.ion_device_fd = open (PMEM_DEVICE,O_RDONLY/*|O_DSYNC*/);
|
| 367 | if(ion_data.ion_device_fd < 0)
|
| 368 | {
|
| 369 | E("\nERROR: ION Device open() Failed");
|
| 370 | return NULL;
|
| 371 | }
|
| 372 | nSize = (nSize + 4095) & (~4095);
|
| 373 | ion_data.alloc_data.len = nSize;
|
| 374 | ion_data.alloc_data.flags = 0x1 << ION_CP_MM_HEAP_ID;
|
| 375 | ion_data.alloc_data.align = 4096;
|
| 376 |
|
| 377 | rc = ioctl(ion_data.ion_device_fd,ION_IOC_ALLOC,&ion_data.alloc_data);
|
| 378 | if(rc || !ion_data.alloc_data.handle) {
|
| 379 | E("\n ION ALLOC memory failed ");
|
| 380 | ion_data.alloc_data.handle=NULL;
|
| 381 | return NULL;
|
| 382 | }
|
| 383 |
|
| 384 | ion_data.ion_alloc_fd.handle = ion_data.alloc_data.handle;
|
| 385 | rc = ioctl(ion_data.ion_device_fd,ION_IOC_MAP,&ion_data.ion_alloc_fd);
|
| 386 | if(rc) {
|
| 387 | E("\n ION MAP failed ");
|
| 388 | ion_data.ion_alloc_fd.fd =-1;
|
| 389 | ion_data.ion_alloc_fd.fd =-1;
|
| 390 | return NULL;
|
| 391 | }
|
| 392 | pMem->pmem_fd = ion_data.ion_alloc_fd.fd;
|
| 393 | #else
|
| 394 | pMem->pmem_fd = open(PMEM_DEVICE, O_RDWR);
|
| 395 | if ((int)(pMem->pmem_fd) < 0)
|
| 396 | return NULL;
|
| 397 | nSize = (nSize + 4095) & (~4095);
|
| 398 | #endif
|
| 399 | pMem->offset = 0;
|
| 400 | pvirt = mmap(NULL, nSize,
|
| 401 | PROT_READ | PROT_WRITE,
|
| 402 | MAP_SHARED, pMem->pmem_fd, pMem->offset);
|
| 403 | if (pvirt == (void*) MAP_FAILED)
|
| 404 | {
|
| 405 | close(pMem->pmem_fd);
|
| 406 | pMem->pmem_fd = -1;
|
| 407 | #ifdef USE_ION
|
| 408 | if(ioctl(ion_data.ion_device_fd,ION_IOC_FREE,
|
| 409 | &ion_data.alloc_data.handle)) {
|
| 410 | E("ion recon buffer free failed");
|
| 411 | }
|
| 412 | ion_data.alloc_data.handle = NULL;
|
| 413 | ion_data.ion_alloc_fd.fd =-1;
|
| 414 | close(ion_data.ion_device_fd);
|
| 415 | ion_data.ion_device_fd =-1;
|
| 416 | #endif
|
| 417 | return NULL;
|
| 418 | }
|
| 419 | D("allocated pMem->fd = %d pvirt=0x%x, pMem->phys=0x%x, size = %d", pMem->pmem_fd,
|
| 420 | pvirt, pMem->offset, nSize);
|
| 421 | return pvirt;
|
| 422 | }
|
| 423 |
|
| 424 | int PmemFree(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, void* pvirt, int nSize)
|
| 425 | {
|
| 426 | if (!pMem || !pvirt)
|
| 427 | return -1;
|
| 428 |
|
| 429 | nSize = (nSize + 4095) & (~4095);
|
| 430 | munmap(pvirt, nSize);
|
| 431 | close(pMem->pmem_fd);
|
| 432 | pMem->pmem_fd = -1;
|
| 433 | #ifdef USE_ION
|
| 434 | if(ioctl(ion_data.ion_device_fd,ION_IOC_FREE,
|
| 435 | &ion_data.alloc_data.handle)) {
|
| 436 | E("ion recon buffer free failed");
|
| 437 | }
|
| 438 | ion_data.alloc_data.handle = NULL;
|
| 439 | ion_data.ion_alloc_fd.fd =-1;
|
| 440 | close(ion_data.ion_device_fd);
|
| 441 | ion_data.ion_device_fd =-1;
|
| 442 | #endif
|
| 443 | return 0;
|
| 444 | }
|
| 445 | void PrintFramePackArrangement(OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement)
|
| 446 | {
|
| 447 | printf("id (%d)\n",
|
| 448 | framePackingArrangement.id);
|
| 449 | printf("cancel_flag (%d)\n",
|
| 450 | framePackingArrangement.cancel_flag);
|
| 451 | printf("type (%d)\n",
|
| 452 | framePackingArrangement.type);
|
| 453 | printf("quincunx_sampling_flag (%d)\n",
|
| 454 | framePackingArrangement.quincunx_sampling_flag);
|
| 455 | printf("content_interpretation_type (%d)\n",
|
| 456 | framePackingArrangement.content_interpretation_type);
|
| 457 | printf("spatial_flipping_flag (%d)\n",
|
| 458 | framePackingArrangement.spatial_flipping_flag);
|
| 459 | printf("frame0_flipped_flag (%d)\n",
|
| 460 | framePackingArrangement.frame0_flipped_flag);
|
| 461 | printf("field_views_flag (%d)\n",
|
| 462 | framePackingArrangement.field_views_flag);
|
| 463 | printf("current_frame_is_frame0_flag (%d)\n",
|
| 464 | framePackingArrangement.current_frame_is_frame0_flag);
|
| 465 | printf("frame0_self_contained_flag (%d)\n",
|
| 466 | framePackingArrangement.frame0_self_contained_flag);
|
| 467 | printf("frame1_self_contained_flag (%d)\n",
|
| 468 | framePackingArrangement.frame1_self_contained_flag);
|
| 469 | printf("frame0_grid_position_x (%d)\n",
|
| 470 | framePackingArrangement.frame0_grid_position_x);
|
| 471 | printf("frame0_grid_position_y (%d)\n",
|
| 472 | framePackingArrangement.frame0_grid_position_y);
|
| 473 | printf("frame1_grid_position_x (%d)\n",
|
| 474 | framePackingArrangement.frame1_grid_position_x);
|
| 475 | printf("frame1_grid_position_y (%d)\n",
|
| 476 | framePackingArrangement.frame1_grid_position_y);
|
| 477 | printf("reserved_byte (%d)\n",
|
| 478 | framePackingArrangement.reserved_byte);
|
| 479 | printf("repetition_period (%d)\n",
|
| 480 | framePackingArrangement.repetition_period);
|
| 481 | printf("extension_flag (%d)\n",
|
| 482 | framePackingArrangement.extension_flag);
|
| 483 | }
|
| 484 | void SetState(OMX_STATETYPE eState)
|
| 485 | {
|
| 486 | #define GOTO_STATE(eState) \
|
| 487 | case eState: \
|
| 488 | { \
|
| 489 | D("Going to state " # eState"..."); \
|
| 490 | OMX_SendCommand(m_hHandle, \
|
| 491 | OMX_CommandStateSet, \
|
| 492 | (OMX_U32) eState, \
|
| 493 | NULL); \
|
| 494 | while (m_eState != eState) \
|
| 495 | { \
|
| 496 | sleep(1); \
|
| 497 | } \
|
| 498 | D("Now in state " # eState); \
|
| 499 | break; \
|
| 500 | }
|
| 501 |
|
| 502 | switch (eState)
|
| 503 | {
|
| 504 | GOTO_STATE(OMX_StateLoaded);
|
| 505 | GOTO_STATE(OMX_StateIdle);
|
| 506 | GOTO_STATE(OMX_StateExecuting);
|
| 507 | GOTO_STATE(OMX_StateInvalid);
|
| 508 | GOTO_STATE(OMX_StateWaitForResources);
|
| 509 | GOTO_STATE(OMX_StatePause);
|
| 510 | }
|
| 511 | }
|
| 512 | ////////////////////////////////////////////////////////////////////////////////
|
| 513 | OMX_ERRORTYPE ConfigureEncoder()
|
| 514 | {
|
| 515 | OMX_ERRORTYPE result = OMX_ErrorNone;
|
| 516 | unsigned const int *profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
|
| 517 | OMX_U32 mb_per_sec, mb_per_frame;
|
| 518 | bool profile_level_found = false;
|
| 519 | OMX_U32 eProfile,eLevel;
|
| 520 |
|
| 521 | OMX_PARAM_PORTDEFINITIONTYPE portdef; // OMX_IndexParamPortDefinition
|
| 522 | #ifdef QCOM_EXT
|
| 523 | OMX_QCOM_PARAM_PORTDEFINITIONTYPE qPortDefnType;
|
| 524 | #endif
|
| 525 | portdef.nPortIndex = (OMX_U32) 0; // input
|
| 526 | result = OMX_GetParameter(m_hHandle,
|
| 527 | OMX_IndexParamPortDefinition,
|
| 528 | &portdef);
|
| 529 | E("\n OMX_IndexParamPortDefinition Get Paramter on input port");
|
| 530 | CHK(result);
|
| 531 | portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth;
|
| 532 | portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight;
|
| 533 |
|
| 534 | E ("\n Height %d width %d bit rate %d",portdef.format.video.nFrameHeight
|
| 535 | ,portdef.format.video.nFrameWidth,portdef.format.video.nBitrate);
|
| 536 | result = OMX_SetParameter(m_hHandle,
|
| 537 | OMX_IndexParamPortDefinition,
|
| 538 | &portdef);
|
| 539 | E("\n OMX_IndexParamPortDefinition Set Paramter on input port");
|
| 540 | CHK(result);
|
| 541 | // once more to get proper buffer size
|
| 542 | result = OMX_GetParameter(m_hHandle,
|
| 543 | OMX_IndexParamPortDefinition,
|
| 544 | &portdef);
|
| 545 | E("\n OMX_IndexParamPortDefinition Get Paramter on input port, 2nd pass");
|
| 546 | CHK(result);
|
| 547 | // update size accordingly
|
| 548 | m_sProfile.nFrameBytes = portdef.nBufferSize;
|
| 549 | portdef.nPortIndex = (OMX_U32) 1; // output
|
| 550 | result = OMX_GetParameter(m_hHandle,
|
| 551 | OMX_IndexParamPortDefinition,
|
| 552 | &portdef);
|
| 553 | E("\n OMX_IndexParamPortDefinition Get Paramter on output port");
|
| 554 | CHK(result);
|
| 555 | portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth;
|
| 556 | portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight;
|
| 557 | portdef.format.video.nBitrate = m_sProfile.nBitrate;
|
| 558 | FractionToQ16(portdef.format.video.xFramerate,(int) (m_sProfile.nFramerate * 2),2);
|
| 559 | result = OMX_SetParameter(m_hHandle,
|
| 560 | OMX_IndexParamPortDefinition,
|
| 561 | &portdef);
|
| 562 | E("\n OMX_IndexParamPortDefinition Set Paramter on output port");
|
| 563 | CHK(result);
|
| 564 |
|
| 565 | #ifdef QCOM_EXT
|
| 566 |
|
| 567 | qPortDefnType.nPortIndex = PORT_INDEX_IN;
|
| 568 | qPortDefnType.nMemRegion = OMX_QCOM_MemRegionEBI1;
|
| 569 | qPortDefnType.nSize = sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
|
| 570 |
|
| 571 | result = OMX_SetParameter(m_hHandle,
|
| 572 | (OMX_INDEXTYPE)OMX_QcomIndexPortDefn,
|
| 573 | &qPortDefnType);
|
| 574 |
|
| 575 | #endif
|
| 576 | if (!m_sProfile.nUserProfile) // profile not set by user, go ahead with table calculation
|
| 577 | {
|
| 578 | //validate the ht,width,fps,bitrate and set the appropriate profile and level
|
| 579 | if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
|
| 580 | {
|
| 581 | profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
|
| 582 | }
|
| 583 | else if(m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
|
| 584 | {
|
| 585 | profile_tbl = (unsigned int const *)h264_profile_level_table;
|
| 586 | }
|
| 587 | else if(m_sProfile.eCodec == OMX_VIDEO_CodingH263)
|
| 588 | {
|
| 589 | profile_tbl = (unsigned int const *)h263_profile_level_table;
|
| 590 | }
|
| 591 |
|
| 592 | mb_per_frame = ((m_sProfile.nFrameHeight+15)>>4)*
|
| 593 | ((m_sProfile.nFrameWidth+15)>>4);
|
| 594 |
|
| 595 | mb_per_sec = mb_per_frame*(m_sProfile.nFramerate);
|
| 596 |
|
| 597 | do{
|
| 598 | if(mb_per_frame <= (int)profile_tbl[0])
|
| 599 | {
|
| 600 | if(mb_per_sec <= (int)profile_tbl[1])
|
| 601 | {
|
| 602 | if(m_sProfile.nBitrate <= (int)profile_tbl[2])
|
| 603 | {
|
| 604 | eLevel = (int)profile_tbl[3];
|
| 605 | eProfile = (int)profile_tbl[4];
|
| 606 | E("\n profile/level found: %d/%d\n",eProfile/eLevel);
|
| 607 | profile_level_found = true;
|
| 608 | break;
|
| 609 | }
|
| 610 | }
|
| 611 | }
|
| 612 | profile_tbl = profile_tbl + 5;
|
| 613 | }while(profile_tbl[0] != 0);
|
| 614 |
|
| 615 | if ( profile_level_found != true )
|
| 616 | {
|
| 617 | E("\n Error: Unsupported profile/level\n");
|
| 618 | return OMX_ErrorNone;
|
| 619 | }
|
| 620 | }
|
| 621 | else // Profile set by user!
|
| 622 | {
|
| 623 | eProfile = m_sProfile.nUserProfile;
|
| 624 | eLevel = 0;
|
| 625 | }
|
| 626 | if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
|
| 627 | {
|
| 628 | D("Configuring H263...");
|
| 629 |
|
| 630 | OMX_VIDEO_PARAM_H263TYPE h263;
|
| 631 | result = OMX_GetParameter(m_hHandle,
|
| 632 | OMX_IndexParamVideoH263,
|
| 633 | &h263);
|
| 634 | CHK(result);
|
| 635 | h263.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
|
| 636 | h263.nPFrames = m_sProfile.nFramerate * 2 - 1; // intra period
|
| 637 | h263.nBFrames = 0;
|
| 638 | h263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile;
|
| 639 | h263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel;
|
| 640 | h263.bPLUSPTYPEAllowed = OMX_FALSE;
|
| 641 | h263.nAllowedPictureTypes = 2;
|
| 642 | h263.bForceRoundingTypeToZero = OMX_TRUE;
|
| 643 | h263.nPictureHeaderRepetition = 0;
|
| 644 | h263.nGOBHeaderInterval = 1;
|
| 645 | result = OMX_SetParameter(m_hHandle,
|
| 646 | OMX_IndexParamVideoH263,
|
| 647 | &h263);
|
| 648 | }
|
| 649 | else
|
| 650 | {
|
| 651 | D("Configuring MP4/H264...");
|
| 652 |
|
| 653 | OMX_VIDEO_PARAM_PROFILELEVELTYPE profileLevel; // OMX_IndexParamVideoProfileLevelCurrent
|
| 654 | profileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
|
| 655 | profileLevel.eProfile = eProfile;
|
| 656 | profileLevel.eLevel = eLevel;
|
| 657 | result = OMX_SetParameter(m_hHandle,
|
| 658 | OMX_IndexParamVideoProfileLevelCurrent,
|
| 659 | &profileLevel);
|
| 660 | E("\n OMX_IndexParamVideoProfileLevelCurrent Set Paramter port");
|
| 661 | CHK(result);
|
| 662 | //profileLevel.eLevel = (OMX_U32) m_sProfile.eLevel;
|
| 663 | result = OMX_GetParameter(m_hHandle,
|
| 664 | OMX_IndexParamVideoProfileLevelCurrent,
|
| 665 | &profileLevel);
|
| 666 | E("\n OMX_IndexParamVideoProfileLevelCurrent Get Paramter port");
|
| 667 | D ("\n Profile = %d level = %d",profileLevel.eProfile,profileLevel.eLevel);
|
| 668 | CHK(result);
|
| 669 |
|
| 670 | if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
|
| 671 | {
|
| 672 | OMX_VIDEO_PARAM_MPEG4TYPE mp4; // OMX_IndexParamVideoMpeg4
|
| 673 | result = OMX_GetParameter(m_hHandle,
|
| 674 | OMX_IndexParamVideoMpeg4,
|
| 675 | &mp4);
|
| 676 | CHK(result);
|
| 677 | mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
|
| 678 | mp4.nTimeIncRes = 1000;
|
| 679 | result = OMX_SetParameter(m_hHandle,
|
| 680 | OMX_IndexParamVideoMpeg4,
|
| 681 | &mp4);
|
| 682 | CHK(result);
|
| 683 | }
|
| 684 | }
|
| 685 | if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
|
| 686 | {
|
| 687 | #if 1
|
| 688 | /////////////C A B A C ///A N D/////D E B L O C K I N G /////////////////
|
| 689 |
|
| 690 | OMX_VIDEO_PARAM_AVCTYPE avcdata;
|
| 691 | avcdata.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
|
| 692 | result = OMX_GetParameter(m_hHandle,
|
| 693 | OMX_IndexParamVideoAvc,
|
| 694 | &avcdata);
|
| 695 | CHK(result);
|
| 696 | // TEST VALUES (CHANGE FOR DIFF CONFIG's)
|
| 697 | avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
|
| 698 | // avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisable;
|
| 699 | // avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisableSliceBoundary;
|
| 700 | avcdata.bEntropyCodingCABAC = OMX_FALSE;
|
| 701 | // avcdata.bEntropyCodingCABAC = OMX_TRUE;
|
| 702 | avcdata.nCabacInitIdc = 1;
|
| 703 | ///////////////////////////////////////////////
|
| 704 |
|
| 705 | result = OMX_SetParameter(m_hHandle,
|
| 706 | OMX_IndexParamVideoAvc,
|
| 707 | &avcdata);
|
| 708 | CHK(result);
|
| 709 |
|
| 710 | /////////////C A B A C ///A N D/////D E B L O C K I N G /////////////////
|
| 711 | #endif
|
| 712 | }
|
| 713 |
|
| 714 | OMX_VIDEO_PARAM_BITRATETYPE bitrate; // OMX_IndexParamVideoBitrate
|
| 715 | bitrate.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
|
| 716 | result = OMX_GetParameter(m_hHandle,
|
| 717 | OMX_IndexParamVideoBitrate,
|
| 718 | &bitrate);
|
| 719 | E("\n OMX_IndexParamVideoBitrate Get Paramter port");
|
| 720 | CHK(result);
|
| 721 | bitrate.eControlRate = m_sProfile.eControlRate;
|
| 722 | bitrate.nTargetBitrate = m_sProfile.nBitrate;
|
| 723 | result = OMX_SetParameter(m_hHandle,
|
| 724 | OMX_IndexParamVideoBitrate,
|
| 725 | &bitrate);
|
| 726 | E("\n OMX_IndexParamVideoBitrate Set Paramter port");
|
| 727 | CHK(result);
|
| 728 |
|
| 729 | OMX_VIDEO_PARAM_PORTFORMATTYPE framerate; // OMX_IndexParamVidePortFormat
|
| 730 | framerate.nPortIndex = 0;
|
| 731 | result = OMX_GetParameter(m_hHandle,
|
| 732 | OMX_IndexParamVideoPortFormat,
|
| 733 | &framerate);
|
| 734 | E("\n OMX_IndexParamVideoPortFormat Get Paramter port");
|
| 735 | CHK(result);
|
| 736 | FractionToQ16(framerate.xFramerate,(int) (m_sProfile.nFramerate * 2),2);
|
| 737 | result = OMX_SetParameter(m_hHandle,
|
| 738 | OMX_IndexParamVideoPortFormat,
|
| 739 | &framerate);
|
| 740 | E("\n OMX_IndexParamVideoPortFormat Set Paramter port");
|
| 741 | CHK(result);
|
| 742 |
|
| 743 | #if 1
|
| 744 | ///////////////////I N T R A P E R I O D ///////////////////
|
| 745 |
|
| 746 | QOMX_VIDEO_INTRAPERIODTYPE intra;
|
| 747 |
|
| 748 | intra.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
|
| 749 | result = OMX_GetConfig(m_hHandle,
|
| 750 | (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod,
|
| 751 | (OMX_PTR) &intra);
|
| 752 |
|
| 753 | if (result == OMX_ErrorNone)
|
| 754 | {
|
| 755 | intra.nPFrames = (OMX_U32) (2 * m_sProfile.nFramerate - 1); //setting I
|
| 756 | //frame interval to
|
| 757 | //2 x framerate
|
| 758 | intra.nIDRPeriod = 1; //every I frame is an IDR
|
| 759 | intra.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
|
| 760 | result = OMX_SetConfig(m_hHandle,
|
| 761 | (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod,
|
| 762 | (OMX_PTR) &intra);
|
| 763 | }
|
| 764 | else
|
| 765 | {
|
| 766 | E("failed to get state", 0, 0, 0);
|
| 767 | }
|
| 768 |
|
| 769 |
|
| 770 | ///////////////////I N T R A P E R I O D ///////////////////
|
| 771 | #endif
|
| 772 |
|
| 773 | #if 1
|
| 774 | ///////////////////E R R O R C O R R E C T I O N ///////////////////
|
| 775 |
|
| 776 | ResyncMarkerType eResyncMarkerType = RESYNC_MARKER_NONE;
|
| 777 | unsigned long int nResyncMarkerSpacing = 0;
|
| 778 | OMX_BOOL enableHEC = OMX_FALSE;
|
| 779 |
|
| 780 | //For Testing ONLY
|
| 781 | if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
|
| 782 | {
|
| 783 | // MPEG4
|
| 784 | // eResyncMarkerType = RESYNC_MARKER_BYTE;
|
| 785 | // nResyncMarkerSpacing = 1920;
|
| 786 | eResyncMarkerType = RESYNC_MARKER_MB;
|
| 787 | nResyncMarkerSpacing = 50;
|
| 788 | enableHEC = OMX_TRUE;
|
| 789 | }
|
| 790 | else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
|
| 791 | {
|
| 792 | //H263
|
| 793 | eResyncMarkerType = RESYNC_MARKER_GOB;
|
| 794 | nResyncMarkerSpacing = 0;
|
| 795 | }
|
| 796 | else if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
|
| 797 | {
|
| 798 | //H264
|
| 799 | // eResyncMarkerType = RESYNC_MARKER_BYTE;
|
| 800 | // nResyncMarkerSpacing = 1920;
|
| 801 |
|
| 802 | //nResyncMarkerSpacing sets the slice size in venc_set_multislice_cfg
|
| 803 | //
|
| 804 | //As of 9/24/10, it is known that the firmware has a bitstream
|
| 805 | //corruption issue when RateControl and multislice are enabled for 720P
|
| 806 | //So, disabling multislice for 720P when ratecontrol is enabled until
|
| 807 | //the firmware issue is resolved.
|
| 808 |
|
| 809 | if ( ( (m_sProfile.nFrameWidth == 1280) && (m_sProfile.nFrameHeight = 720) ) &&
|
| 810 | (m_sProfile.eControlRate != OMX_Video_ControlRateDisable) )
|
| 811 | {
|
| 812 | eResyncMarkerType = RESYNC_MARKER_NONE;
|
| 813 | nResyncMarkerSpacing = 0;
|
| 814 | }
|
| 815 | else
|
| 816 | {
|
| 817 | eResyncMarkerType = RESYNC_MARKER_MB;
|
| 818 | nResyncMarkerSpacing = 50;
|
| 819 | }
|
| 820 | }
|
| 821 |
|
| 822 | OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrection; //OMX_IndexParamVideoErrorCorrection
|
| 823 | errorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
|
| 824 | result = OMX_GetParameter(m_hHandle,
|
| 825 | (OMX_INDEXTYPE) OMX_IndexParamVideoErrorCorrection,
|
| 826 | (OMX_PTR) &errorCorrection);
|
| 827 |
|
| 828 | errorCorrection.bEnableRVLC = OMX_FALSE;
|
| 829 | errorCorrection.bEnableDataPartitioning = OMX_FALSE;
|
| 830 |
|
| 831 | if ((eResyncMarkerType == RESYNC_MARKER_BYTE) &&
|
| 832 | (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)){
|
| 833 | errorCorrection.bEnableResync = OMX_TRUE;
|
| 834 | errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing;
|
| 835 | errorCorrection.bEnableHEC = enableHEC;
|
| 836 | }
|
| 837 | else if ((eResyncMarkerType == RESYNC_MARKER_BYTE) &&
|
| 838 | (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)){
|
| 839 | errorCorrection.bEnableResync = OMX_TRUE;
|
| 840 | errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing;
|
| 841 | }
|
| 842 | else if ((eResyncMarkerType == RESYNC_MARKER_GOB) &&
|
| 843 | (m_sProfile.eCodec == OMX_VIDEO_CodingH263)){
|
| 844 | errorCorrection.bEnableResync = OMX_FALSE;
|
| 845 | errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing;
|
| 846 | errorCorrection.bEnableDataPartitioning = OMX_TRUE;
|
| 847 | }
|
| 848 |
|
| 849 | result = OMX_SetParameter(m_hHandle,
|
| 850 | (OMX_INDEXTYPE) OMX_IndexParamVideoErrorCorrection,
|
| 851 | (OMX_PTR) &errorCorrection);
|
| 852 | CHK(result);
|
| 853 |
|
| 854 | if (eResyncMarkerType == RESYNC_MARKER_MB){
|
| 855 | if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC){
|
| 856 | OMX_VIDEO_PARAM_AVCTYPE avcdata;
|
| 857 | avcdata.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
|
| 858 | result = OMX_GetParameter(m_hHandle,
|
| 859 | OMX_IndexParamVideoAvc,
|
| 860 | (OMX_PTR) &avcdata);
|
| 861 | CHK(result);
|
| 862 | if (result == OMX_ErrorNone)
|
| 863 | {
|
| 864 | avcdata.nSliceHeaderSpacing = nResyncMarkerSpacing;
|
| 865 | result = OMX_SetParameter(m_hHandle,
|
| 866 | OMX_IndexParamVideoAvc,
|
| 867 | (OMX_PTR) &avcdata);
|
| 868 | CHK(result);
|
| 869 |
|
| 870 | }
|
| 871 | }
|
| 872 | else if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4){
|
| 873 | OMX_VIDEO_PARAM_MPEG4TYPE mp4;
|
| 874 | mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
|
| 875 | result = OMX_GetParameter(m_hHandle,
|
| 876 | OMX_IndexParamVideoMpeg4,
|
| 877 | (OMX_PTR) &mp4);
|
| 878 | CHK(result);
|
| 879 |
|
| 880 | if (result == OMX_ErrorNone)
|
| 881 | {
|
| 882 | mp4.nSliceHeaderSpacing = nResyncMarkerSpacing;
|
| 883 | result = OMX_SetParameter(m_hHandle,
|
| 884 | OMX_IndexParamVideoMpeg4,
|
| 885 | (OMX_PTR) &mp4);
|
| 886 | CHK(result);
|
| 887 | }
|
| 888 | }
|
| 889 | }
|
| 890 |
|
| 891 | ///////////////////E R R O R C O R R E C T I O N ///////////////////
|
| 892 | #endif
|
| 893 |
|
| 894 | #if 1
|
| 895 | ///////////////////I N T R A R E F R E S H///////////////////
|
| 896 | bool bEnableIntraRefresh = OMX_TRUE;
|
| 897 |
|
| 898 | if (result == OMX_ErrorNone)
|
| 899 | {
|
| 900 | OMX_VIDEO_PARAM_INTRAREFRESHTYPE ir; // OMX_IndexParamVideoIntraRefresh
|
| 901 | ir.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
|
| 902 | result = OMX_GetParameter(m_hHandle,
|
| 903 | OMX_IndexParamVideoIntraRefresh,
|
| 904 | (OMX_PTR) &ir);
|
| 905 | if (result == OMX_ErrorNone)
|
| 906 | {
|
| 907 | if (bEnableIntraRefresh)
|
| 908 | {
|
| 909 | ir.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
|
| 910 | ir.nCirMBs = 5;
|
| 911 | result = OMX_SetParameter(m_hHandle,
|
| 912 | OMX_IndexParamVideoIntraRefresh,
|
| 913 | (OMX_PTR) &ir);
|
| 914 | CHK(result);
|
| 915 | }
|
| 916 | }
|
| 917 | }
|
| 918 | #endif
|
| 919 | #if 1
|
| 920 | ///////////////////FRAMEPACKING DATA///////////////////
|
| 921 | OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement;
|
| 922 | FILE *m_pConfigFile;
|
| 923 | char m_configFilename [128] = "/data/configFile.cfg";
|
| 924 | memset(&framePackingArrangement, 0, sizeof(framePackingArrangement));
|
| 925 | m_pConfigFile = fopen(m_configFilename, "r");
|
| 926 | if (m_pConfigFile != NULL)
|
| 927 | {
|
| 928 | //read all frame packing data
|
| 929 | framePackingArrangement.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
|
| 930 | int totalSizeToRead = FRAME_PACK_SIZE * sizeof(OMX_U32);
|
| 931 | char *pFramePack = (char *) &(framePackingArrangement.id);
|
| 932 | while ( ( (fscanf(m_pConfigFile, "%d", pFramePack)) != EOF ) &&
|
| 933 | (totalSizeToRead != 0) )
|
| 934 | {
|
| 935 | //printf("Addr = %p, Value read = %d, sizeToRead remaining=%d\n",
|
| 936 | // pFramePack, *pFramePack, totalSizeToRead);
|
| 937 | pFramePack += sizeof(OMX_U32);
|
| 938 | totalSizeToRead -= sizeof(OMX_U32);
|
| 939 | }
|
| 940 | //close the file.
|
| 941 | fclose(m_pConfigFile);
|
| 942 |
|
| 943 | printf("Frame Packing data from config file:\n");
|
| 944 | PrintFramePackArrangement(framePackingArrangement);
|
| 945 | }
|
| 946 | else
|
| 947 | {
|
| 948 | D("\n Config file does not exist or could not be opened.");
|
| 949 | //set the default values
|
| 950 | framePackingArrangement.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
|
| 951 | framePackingArrangement.id = 123;
|
| 952 | framePackingArrangement.cancel_flag = false;
|
| 953 | framePackingArrangement.type = 3;
|
| 954 | framePackingArrangement.quincunx_sampling_flag = false;
|
| 955 | framePackingArrangement.content_interpretation_type = 0;
|
| 956 | framePackingArrangement.spatial_flipping_flag = true;
|
| 957 | framePackingArrangement.frame0_flipped_flag = false;
|
| 958 | framePackingArrangement.field_views_flag = false;
|
| 959 | framePackingArrangement.current_frame_is_frame0_flag = false;
|
| 960 | framePackingArrangement.frame0_self_contained_flag = true;
|
| 961 | framePackingArrangement.frame1_self_contained_flag = false;
|
| 962 | framePackingArrangement.frame0_grid_position_x = 3;
|
| 963 | framePackingArrangement.frame0_grid_position_y = 15;
|
| 964 | framePackingArrangement.frame1_grid_position_x = 11;
|
| 965 | framePackingArrangement.frame1_grid_position_y = 7;
|
| 966 | framePackingArrangement.reserved_byte = 0;
|
| 967 | framePackingArrangement.repetition_period = 16381;
|
| 968 | framePackingArrangement.extension_flag = false;
|
| 969 |
|
| 970 | printf("Frame Packing Defaults :\n");
|
| 971 | PrintFramePackArrangement(framePackingArrangement);
|
| 972 | }
|
| 973 | result = OMX_SetConfig(m_hHandle,
|
| 974 | (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement,
|
| 975 | (OMX_PTR) &framePackingArrangement);
|
| 976 | CHK(result);
|
| 977 |
|
| 978 | //////////////////////OMX_VIDEO_PARAM_INTRAREFRESHTYPE///////////////////
|
| 979 | #endif
|
| 980 |
|
| 981 | OMX_CONFIG_FRAMERATETYPE enc_framerate; // OMX_IndexConfigVideoFramerate
|
| 982 | enc_framerate.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
|
| 983 | result = OMX_GetConfig(m_hHandle,
|
| 984 | OMX_IndexConfigVideoFramerate,
|
| 985 | &enc_framerate);
|
| 986 | CHK(result);
|
| 987 | FractionToQ16(enc_framerate.xEncodeFramerate,(int) (m_sProfile.nFramerate * 2),2);
|
| 988 | result = OMX_SetConfig(m_hHandle,
|
| 989 | OMX_IndexConfigVideoFramerate,
|
| 990 | &enc_framerate);
|
| 991 | CHK(result);
|
| 992 | return OMX_ErrorNone;
|
| 993 | }
|
| 994 | ////////////////////////////////////////////////////////////////////////////////
|
| 995 | void SendMessage(MsgId id, MsgData* data)
|
| 996 | {
|
| 997 | pthread_mutex_lock(&m_mutex);
|
| 998 | if (m_sMsgQ.size >= MAX_MSG)
|
| 999 | {
|
| 1000 | E("main msg m_sMsgQ is full");
|
| 1001 | return;
|
| 1002 | }
|
| 1003 | m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].id = id;
|
| 1004 | if (data)
|
| 1005 | m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].data = *data;
|
| 1006 | ++m_sMsgQ.size;
|
| 1007 | pthread_cond_signal(&m_signal);
|
| 1008 | pthread_mutex_unlock(&m_mutex);
|
| 1009 | }
|
| 1010 | ////////////////////////////////////////////////////////////////////////////////
|
| 1011 | void PopMessage(Msg* msg)
|
| 1012 | {
|
| 1013 | pthread_mutex_lock(&m_mutex);
|
| 1014 | while (m_sMsgQ.size == 0)
|
| 1015 | {
|
| 1016 | pthread_cond_wait(&m_signal, &m_mutex);
|
| 1017 | }
|
| 1018 | *msg = m_sMsgQ.q[m_sMsgQ.head];
|
| 1019 | --m_sMsgQ.size;
|
| 1020 | m_sMsgQ.head = (m_sMsgQ.head + 1) % MAX_MSG;
|
| 1021 | pthread_mutex_unlock(&m_mutex);
|
| 1022 | }
|
| 1023 | ////////////////////////////////////////////////////////////////////////////////
|
| 1024 | OMX_ERRORTYPE EVT_CB(OMX_IN OMX_HANDLETYPE hComponent,
|
| 1025 | OMX_IN OMX_PTR pAppData,
|
| 1026 | OMX_IN OMX_EVENTTYPE eEvent,
|
| 1027 | OMX_IN OMX_U32 nData1,
|
| 1028 | OMX_IN OMX_U32 nData2,
|
| 1029 | OMX_IN OMX_PTR pEventData)
|
| 1030 | {
|
| 1031 | #define SET_STATE(eState) \
|
| 1032 | case eState: \
|
| 1033 | { \
|
| 1034 | D("" # eState " complete"); \
|
| 1035 | m_eState = eState; \
|
| 1036 | break; \
|
| 1037 | }
|
| 1038 |
|
| 1039 | if (eEvent == OMX_EventCmdComplete)
|
| 1040 | {
|
| 1041 | if ((OMX_COMMANDTYPE) nData1 == OMX_CommandStateSet)
|
| 1042 | {
|
| 1043 | switch ((OMX_STATETYPE) nData2)
|
| 1044 | {
|
| 1045 | SET_STATE(OMX_StateLoaded);
|
| 1046 | SET_STATE(OMX_StateIdle);
|
| 1047 | SET_STATE(OMX_StateExecuting);
|
| 1048 | SET_STATE(OMX_StateInvalid);
|
| 1049 | SET_STATE(OMX_StateWaitForResources);
|
| 1050 | SET_STATE(OMX_StatePause);
|
| 1051 | default:
|
| 1052 | E("invalid state %d", (int) nData2);
|
| 1053 | }
|
| 1054 | }
|
| 1055 | }
|
| 1056 |
|
| 1057 | else if (eEvent == OMX_EventError)
|
| 1058 | {
|
| 1059 | E("OMX_EventError");
|
| 1060 | }
|
| 1061 |
|
| 1062 | else
|
| 1063 | {
|
| 1064 | E("unexpected event %d", (int) eEvent);
|
| 1065 | }
|
| 1066 | return OMX_ErrorNone;
|
| 1067 | }
|
| 1068 | ////////////////////////////////////////////////////////////////////////////////
|
| 1069 | OMX_ERRORTYPE EBD_CB(OMX_IN OMX_HANDLETYPE hComponent,
|
| 1070 | OMX_IN OMX_PTR pAppData,
|
| 1071 | OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
|
| 1072 | {
|
| 1073 | D("Got EBD callback ts=%lld", pBuffer->nTimeStamp);
|
| 1074 |
|
| 1075 | for (int i = 0; i < num_in_buffers; i++)
|
| 1076 | {
|
| 1077 | // mark this buffer ready for use again
|
| 1078 | if (m_pInBuffers[i] == pBuffer)
|
| 1079 | {
|
| 1080 |
|
| 1081 | D("Marked input buffer idx %d as free, buf %p", i, pBuffer->pBuffer);
|
| 1082 | m_bInFrameFree[i] = OMX_TRUE;
|
| 1083 | break;
|
| 1084 | }
|
| 1085 | }
|
| 1086 |
|
| 1087 | if (m_eMode == MODE_LIVE_ENCODE)
|
| 1088 | {
|
| 1089 | CameraTest_ReleaseFrame(pBuffer->pBuffer,
|
| 1090 | ((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)pBuffer->pAppPrivate));
|
| 1091 | }
|
| 1092 | else
|
| 1093 | {
|
| 1094 | // wake up main thread and tell it to send next frame
|
| 1095 | MsgData data;
|
| 1096 | data.sBitstreamData.pBuffer = pBuffer;
|
| 1097 | SendMessage(MSG_ID_INPUT_FRAME_DONE,
|
| 1098 | &data);
|
| 1099 |
|
| 1100 | }
|
| 1101 | return OMX_ErrorNone;
|
| 1102 | }
|
| 1103 | ////////////////////////////////////////////////////////////////////////////////
|
| 1104 | OMX_ERRORTYPE FBD_CB(OMX_OUT OMX_HANDLETYPE hComponent,
|
| 1105 | OMX_OUT OMX_PTR pAppData,
|
| 1106 | OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
|
| 1107 | {
|
| 1108 | D("Got FBD callback ts=%lld", pBuffer->nTimeStamp);
|
| 1109 |
|
| 1110 | static long long prevTime = 0;
|
| 1111 | long long currTime = GetTimeStamp();
|
| 1112 |
|
| 1113 | m_bWatchDogKicked = true;
|
| 1114 |
|
| 1115 | /* Empty Buffers should not be counted */
|
| 1116 | if(pBuffer->nFilledLen !=0)
|
| 1117 | {
|
| 1118 | /* Counting Buffers supplied from OpneMax Encoder */
|
| 1119 | fbd_cnt++;
|
| 1120 | tot_bufsize += pBuffer->nFilledLen;
|
| 1121 | }
|
| 1122 | if (prevTime != 0)
|
| 1123 | {
|
| 1124 | long long currTime = GetTimeStamp();
|
| 1125 | D("FBD_DELTA = %lld\n", currTime - prevTime);
|
| 1126 | }
|
| 1127 | prevTime = currTime;
|
| 1128 |
|
| 1129 | if (m_eMode == MODE_PROFILE)
|
| 1130 | {
|
| 1131 | // if we are profiling we are not doing file I/O
|
| 1132 | // so just give back to encoder
|
| 1133 | if (OMX_FillThisBuffer(m_hHandle, pBuffer) != OMX_ErrorNone)
|
| 1134 | {
|
| 1135 | E("empty buffer failed for profiling");
|
| 1136 | }
|
| 1137 | }
|
| 1138 | else
|
| 1139 | {
|
| 1140 | // wake up main thread and tell it to write to file
|
| 1141 | MsgData data;
|
| 1142 | data.sBitstreamData.pBuffer = pBuffer;
|
| 1143 | SendMessage(MSG_ID_OUTPUT_FRAME_DONE,
|
| 1144 | &data);
|
| 1145 | }
|
| 1146 | return OMX_ErrorNone;
|
| 1147 | }
|
| 1148 | ////////////////////////////////////////////////////////////////////////////////
|
| 1149 | OMX_ERRORTYPE VencTest_Initialize()
|
| 1150 | {
|
| 1151 | OMX_ERRORTYPE result = OMX_ErrorNone;
|
| 1152 | static OMX_CALLBACKTYPE sCallbacks = {EVT_CB, EBD_CB, FBD_CB};
|
| 1153 | int i;
|
| 1154 |
|
| 1155 | for (i = 0; i < num_in_buffers; i++)
|
| 1156 | {
|
| 1157 | m_pInBuffers[i] = NULL;
|
| 1158 | }
|
| 1159 |
|
| 1160 | result = OMX_Init();
|
| 1161 | CHK(result);
|
| 1162 |
|
| 1163 | if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
|
| 1164 | {
|
| 1165 | result = OMX_GetHandle(&m_hHandle,
|
| 1166 | "OMX.qcom.video.encoder.mpeg4",
|
| 1167 | NULL,
|
| 1168 | &sCallbacks);
|
| 1169 | // CHK(result);
|
| 1170 | }
|
| 1171 | else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
|
| 1172 | {
|
| 1173 | result = OMX_GetHandle(&m_hHandle,
|
| 1174 | "OMX.qcom.video.encoder.h263",
|
| 1175 | NULL,
|
| 1176 | &sCallbacks);
|
| 1177 | CHK(result);
|
| 1178 | }
|
| 1179 | else
|
| 1180 | {
|
| 1181 | result = OMX_GetHandle(&m_hHandle,
|
| 1182 | "OMX.qcom.video.encoder.avc",
|
| 1183 | NULL,
|
| 1184 | &sCallbacks);
|
| 1185 | CHK(result);
|
| 1186 | }
|
| 1187 |
|
| 1188 |
|
| 1189 | result = ConfigureEncoder();
|
| 1190 | CHK(result);
|
| 1191 |
|
| 1192 | return result;
|
| 1193 | }
|
| 1194 |
|
| 1195 | ////////////////////////////////////////////////////////////////////////////////
|
| 1196 | OMX_ERRORTYPE VencTest_RegisterYUVBuffer(OMX_BUFFERHEADERTYPE** ppBufferHeader,
|
| 1197 | OMX_U8 *pBuffer,
|
| 1198 | OMX_PTR pAppPrivate)
|
| 1199 | {
|
| 1200 | OMX_ERRORTYPE result = OMX_ErrorNone;
|
| 1201 | #if 0
|
| 1202 | D("register buffer");
|
| 1203 | if ((result = OMX_AllocateBuffer(m_hHandle,
|
| 1204 | ppBufferHeader,
|
| 1205 | (OMX_U32) PORT_INDEX_IN,
|
| 1206 | pAppPrivate,
|
| 1207 | m_sProfile.nFrameBytes
|
| 1208 | )) != OMX_ErrorNone)
|
| 1209 | {
|
| 1210 | E("use buffer failed");
|
| 1211 | }
|
| 1212 | else
|
| 1213 | {
|
| 1214 | E("Allocate Buffer Success %x", (*ppBufferHeader)->pBuffer);
|
| 1215 | }
|
| 1216 | #endif
|
| 1217 | D("register buffer");
|
| 1218 | D("Calling UseBuffer for Input port");
|
| 1219 | if ((result = OMX_UseBuffer(m_hHandle,
|
| 1220 | ppBufferHeader,
|
| 1221 | (OMX_U32) PORT_INDEX_IN,
|
| 1222 | pAppPrivate,
|
| 1223 | m_sProfile.nFrameBytes,
|
| 1224 | pBuffer)) != OMX_ErrorNone)
|
| 1225 | {
|
| 1226 | E("use buffer failed");
|
| 1227 | }
|
| 1228 |
|
| 1229 | return result;
|
| 1230 | }
|
| 1231 | ////////////////////////////////////////////////////////////////////////////////
|
| 1232 | OMX_ERRORTYPE VencTest_EncodeFrame(void* pYUVBuff,
|
| 1233 | long long nTimeStamp)
|
| 1234 | {
|
| 1235 | OMX_ERRORTYPE result = OMX_ErrorUndefined;
|
| 1236 | D("calling OMX empty this buffer");
|
| 1237 | for (int i = 0; i < num_in_buffers; i++)
|
| 1238 | {
|
| 1239 | if (pYUVBuff == m_pInBuffers[i]->pBuffer)
|
| 1240 | {
|
| 1241 | m_pInBuffers[i]->nTimeStamp = nTimeStamp;
|
| 1242 | D("Sending Buffer - %x", m_pInBuffers[i]->pBuffer);
|
| 1243 | result = OMX_EmptyThisBuffer(m_hHandle,
|
| 1244 | m_pInBuffers[i]);
|
| 1245 | /* Counting Buffers supplied to OpenMax Encoder */
|
| 1246 | if(OMX_ErrorNone == result)
|
| 1247 | ebd_cnt++;
|
| 1248 | CHK(result);
|
| 1249 | break;
|
| 1250 | }
|
| 1251 | }
|
| 1252 | return result;
|
| 1253 | }
|
| 1254 | ////////////////////////////////////////////////////////////////////////////////
|
| 1255 | OMX_ERRORTYPE VencTest_Exit(void)
|
| 1256 | {
|
| 1257 | int i;
|
| 1258 | OMX_ERRORTYPE result = OMX_ErrorNone;
|
| 1259 | D("trying to exit venc");
|
| 1260 |
|
| 1261 | D("going to idle state");
|
| 1262 | SetState(OMX_StateIdle);
|
| 1263 |
|
| 1264 |
|
| 1265 | D("going to loaded state");
|
| 1266 | //SetState(OMX_StateLoaded);
|
| 1267 | OMX_SendCommand(m_hHandle,
|
| 1268 | OMX_CommandStateSet,
|
| 1269 | (OMX_U32) OMX_StateLoaded,
|
| 1270 | NULL);
|
| 1271 |
|
| 1272 | for (i = 0; i < num_in_buffers; i++)
|
| 1273 | {
|
| 1274 | D("free buffer");
|
| 1275 | if (m_pInBuffers[i]->pBuffer)
|
| 1276 | {
|
| 1277 | // free(m_pInBuffers[i]->pBuffer);
|
| 1278 | result = OMX_FreeBuffer(m_hHandle,
|
| 1279 | PORT_INDEX_IN,
|
| 1280 | m_pInBuffers[i]);
|
| 1281 | CHK(result);
|
| 1282 | }
|
| 1283 | else
|
| 1284 | {
|
| 1285 | E("buffer %d is null", i);
|
| 1286 | result = OMX_ErrorUndefined;
|
| 1287 | CHK(result);
|
| 1288 | }
|
| 1289 | }
|
| 1290 | for (i = 0; i < num_out_buffers; i++)
|
| 1291 | {
|
| 1292 | D("free buffer");
|
| 1293 | if (m_pOutBuffers[i]->pBuffer)
|
| 1294 | {
|
| 1295 | free(m_pOutBuffers[i]->pBuffer);
|
| 1296 | result = OMX_FreeBuffer(m_hHandle,
|
| 1297 | PORT_INDEX_OUT,
|
| 1298 | m_pOutBuffers[i]);
|
| 1299 | CHK(result);
|
| 1300 |
|
| 1301 | }
|
| 1302 | else
|
| 1303 | {
|
| 1304 | E("buffer %d is null", i);
|
| 1305 | result = OMX_ErrorUndefined;
|
| 1306 | CHK(result);
|
| 1307 | }
|
| 1308 | }
|
| 1309 |
|
| 1310 | while (m_eState != OMX_StateLoaded)
|
| 1311 | {
|
| 1312 | sleep(1);
|
| 1313 | }
|
| 1314 | D("component_deinit...");
|
| 1315 | result = OMX_Deinit();
|
| 1316 | CHK(result);
|
| 1317 |
|
| 1318 | D("venc is exiting...");
|
| 1319 | return result;
|
| 1320 | }
|
| 1321 | ////////////////////////////////////////////////////////////////////////////////
|
| 1322 |
|
| 1323 | void VencTest_ReadDynamicConfigMsg()
|
| 1324 | {
|
| 1325 | char frame_n[8], config[16], param[8];
|
| 1326 | char *dest = frame_n;
|
| 1327 | bool end = false;
|
| 1328 | int cntr, nparam = 0;
|
| 1329 | memset(&dynamic_config, 0, sizeof(struct DynamicConfig));
|
| 1330 | do
|
| 1331 | {
|
| 1332 | cntr = -1;
|
| 1333 | do
|
| 1334 | {
|
| 1335 | dest[++cntr] = fgetc(m_pDynConfFile);
|
| 1336 | } while(dest[cntr] != ' ' && dest[cntr] != '\t' && dest[cntr] != '\n' && dest[cntr] != '\r' && !feof(m_pDynConfFile));
|
| 1337 | if (dest[cntr] == '\n' || dest[cntr] == '\r')
|
| 1338 | end = true;
|
| 1339 | dest[cntr] = NULL;
|
| 1340 | if (dest == frame_n)
|
| 1341 | dest = config;
|
| 1342 | else if (dest == config)
|
| 1343 | dest = param;
|
| 1344 | else
|
| 1345 | end = true;
|
| 1346 | nparam++;
|
| 1347 | } while (!end && !feof(m_pDynConfFile));
|
| 1348 |
|
| 1349 | if (nparam > 1)
|
| 1350 | {
|
| 1351 | dynamic_config.pending = true;
|
| 1352 | dynamic_config.frame_num = atoi(frame_n);
|
| 1353 | if (!strcmp(config, "bitrate"))
|
| 1354 | {
|
| 1355 | dynamic_config.config_param = OMX_IndexConfigVideoBitrate;
|
| 1356 | dynamic_config.config_data.bitrate.nPortIndex = PORT_INDEX_OUT;
|
| 1357 | dynamic_config.config_data.bitrate.nEncodeBitrate = strtoul(param, NULL, 10);
|
| 1358 | }
|
| 1359 | else if (!strcmp(config, "framerate"))
|
| 1360 | {
|
| 1361 | dynamic_config.config_param = OMX_IndexConfigVideoFramerate;
|
| 1362 | dynamic_config.config_data.framerate.nPortIndex = PORT_INDEX_OUT;
|
| 1363 | dynamic_config.config_data.f_framerate = atof(param);
|
| 1364 | }
|
| 1365 | else if (!strcmp(config, "iperiod"))
|
| 1366 | {
|
| 1367 | dynamic_config.config_param = (OMX_INDEXTYPE)QOMX_IndexConfigVideoIntraperiod;
|
| 1368 | dynamic_config.config_data.intraperiod.nPortIndex = PORT_INDEX_OUT;
|
| 1369 | dynamic_config.config_data.intraperiod.nPFrames = strtoul(param, NULL, 10) - 1;
|
| 1370 | dynamic_config.config_data.intraperiod.nIDRPeriod = 1; // This value is ignored in OMX component
|
| 1371 | }
|
| 1372 | else if (!strcmp(config, "ivoprefresh"))
|
| 1373 | {
|
| 1374 | dynamic_config.config_param = OMX_IndexConfigVideoIntraVOPRefresh;
|
| 1375 | dynamic_config.config_data.intravoprefresh.nPortIndex = PORT_INDEX_OUT;
|
| 1376 | dynamic_config.config_data.intravoprefresh.IntraRefreshVOP = OMX_TRUE;
|
| 1377 | }
|
| 1378 | else if (!strcmp(config, "rotation"))
|
| 1379 | {
|
| 1380 | dynamic_config.config_param = OMX_IndexConfigCommonRotate;
|
| 1381 | dynamic_config.config_data.rotation.nPortIndex = PORT_INDEX_OUT;
|
| 1382 | dynamic_config.config_data.rotation.nRotation = strtoul(param, NULL, 10);
|
| 1383 | }
|
| 1384 | else
|
| 1385 | {
|
| 1386 | E("UNKNOWN CONFIG PARAMETER: %s!", config);
|
| 1387 | dynamic_config.pending = false;
|
| 1388 | }
|
| 1389 | }
|
| 1390 | else if (feof(m_pDynConfFile))
|
| 1391 | {
|
| 1392 | fclose(m_pDynConfFile);
|
| 1393 | m_pDynConfFile = NULL;
|
| 1394 | }
|
| 1395 | }
|
| 1396 |
|
| 1397 | void VencTest_ProcessDynamicConfigurationFile()
|
| 1398 | {
|
| 1399 | do
|
| 1400 | {
|
| 1401 | if (dynamic_config.pending)
|
| 1402 | {
|
| 1403 | if(m_nFrameIn == dynamic_config.frame_num)
|
| 1404 | {
|
| 1405 | if (dynamic_config.config_param == OMX_IndexConfigVideoFramerate)
|
| 1406 | {
|
| 1407 | m_sProfile.nFramerate = dynamic_config.config_data.f_framerate;
|
| 1408 | FractionToQ16(dynamic_config.config_data.framerate.xEncodeFramerate,
|
| 1409 | (int)(m_sProfile.nFramerate * 2), 2);
|
| 1410 | }
|
| 1411 | if (OMX_SetConfig(m_hHandle, dynamic_config.config_param,
|
| 1412 | &dynamic_config.config_data) != OMX_ErrorNone)
|
| 1413 | E("ERROR: Setting dynamic config to OMX param[0x%x]", dynamic_config.config_param);
|
| 1414 | dynamic_config.pending = false;
|
| 1415 | }
|
| 1416 | else if (m_nFrameIn > dynamic_config.frame_num)
|
| 1417 | {
|
| 1418 | E("WARNING: Config change requested in passed frame(%d)", dynamic_config.frame_num);
|
| 1419 | dynamic_config.pending = false;
|
| 1420 | }
|
| 1421 | }
|
| 1422 | if (!dynamic_config.pending)
|
| 1423 | VencTest_ReadDynamicConfigMsg();
|
| 1424 | } while (!dynamic_config.pending && m_pDynConfFile);
|
| 1425 | }
|
| 1426 |
|
| 1427 | ////////////////////////////////////////////////////////////////////////////////
|
| 1428 | OMX_ERRORTYPE VencTest_ReadAndEmpty(OMX_BUFFERHEADERTYPE* pYUVBuffer)
|
| 1429 | {
|
| 1430 | OMX_ERRORTYPE result = OMX_ErrorNone;
|
| 1431 | #ifdef T_ARM
|
| 1432 | #ifdef MAX_RES_720P
|
| 1433 | if (read(m_nInFd,
|
| 1434 | pYUVBuffer->pBuffer,
|
| 1435 | m_sProfile.nFrameBytes) != m_sProfile.nFrameBytes)
|
| 1436 | {
|
| 1437 | return OMX_ErrorUndefined;
|
| 1438 | }
|
| 1439 | #elif BADGER
|
| 1440 | int bytes;
|
| 1441 | E("will read YUV now: %d bytes to buffer %p\n", m_sProfile.nFrameRead, pYUVBuffer->pBuffer);
|
| 1442 | E("W: %d H: %d Str: %d scal: %d \n", m_sProfile.nFrameWidth, m_sProfile.nFrameHeight,
|
| 1443 | m_sProfile.nFramestride, m_sProfile.nFrameScanlines);
|
| 1444 | bytes = read(m_nInFd, pYUVBuffer->pBuffer, m_sProfile.nFrameRead);
|
| 1445 | if (bytes != m_sProfile.nFrameRead) {
|
| 1446 | E("read failed: %d != %d\n", read, m_sProfile.nFrameRead);
|
| 1447 | return OMX_ErrorUndefined;
|
| 1448 | }
|
| 1449 | E("\n\nRead %d bytes\n\n\n", m_sProfile.nFrameRead);
|
| 1450 | #else
|
| 1451 | OMX_U32 bytestoread = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight;
|
| 1452 | // read Y first
|
| 1453 | if (read(m_nInFd,
|
| 1454 | pYUVBuffer->pBuffer,
|
| 1455 | bytestoread) != bytestoread)
|
| 1456 | return OMX_ErrorUndefined;
|
| 1457 |
|
| 1458 | // check alignment for offset to C
|
| 1459 | OMX_U32 offset_to_c = m_sProfile.nFrameWidth * m_sProfile.nFrameHeight;
|
| 1460 |
|
| 1461 | const OMX_U32 C_2K = (1024*2),
|
| 1462 | MASK_2K = C_2K-1,
|
| 1463 | IMASK_2K = ~MASK_2K;
|
| 1464 |
|
| 1465 | if (offset_to_c & MASK_2K)
|
| 1466 | {
|
| 1467 | // offset to C is not 2k aligned, adjustment is required
|
| 1468 | offset_to_c = (offset_to_c & IMASK_2K) + C_2K;
|
| 1469 | }
|
| 1470 |
|
| 1471 | bytestoread = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight/2;
|
| 1472 | // read C
|
| 1473 | if (read(m_nInFd,
|
| 1474 | pYUVBuffer->pBuffer + offset_to_c,
|
| 1475 | bytestoread)!= bytestoread)
|
| 1476 | return OMX_ErrorUndefined;
|
| 1477 | #endif
|
| 1478 | #else
|
| 1479 | {
|
| 1480 | char * pInputbuf = (char *)(pYUVBuffer->pBuffer) ;
|
| 1481 | read(m_nInFd,pInputbuf,m_sProfile.nFrameBytes) ;
|
| 1482 |
|
| 1483 | }
|
| 1484 | #endif
|
| 1485 | if (m_pDynConfFile)
|
| 1486 | VencTest_ProcessDynamicConfigurationFile();
|
| 1487 | D("about to call VencTest_EncodeFrame...");
|
| 1488 | pthread_mutex_lock(&m_mutex);
|
| 1489 | ++m_nFrameIn;
|
| 1490 | #ifdef BADGER
|
| 1491 | pYUVBuffer->nFilledLen = m_sProfile.nFrameRead;
|
| 1492 | #else
|
| 1493 | pYUVBuffer->nFilledLen = m_sProfile.nFrameBytes;
|
| 1494 | #endif
|
| 1495 | D("Called Buffer with Data filled length %d",pYUVBuffer->nFilledLen);
|
| 1496 |
|
| 1497 | result = VencTest_EncodeFrame(pYUVBuffer->pBuffer,
|
| 1498 | m_nTimeStamp);
|
| 1499 |
|
| 1500 | m_nTimeStamp += (1000000) / m_sProfile.nFramerate;
|
| 1501 | CHK(result);
|
| 1502 | pthread_mutex_unlock(&m_mutex);
|
| 1503 | return result;
|
| 1504 | }
|
| 1505 | ////////////////////////////////////////////////////////////////////////////////
|
| 1506 | void PreviewCallback(int nFD,
|
| 1507 | int nOffset,
|
| 1508 | void* pPhys,
|
| 1509 | void* pVirt,
|
| 1510 | long long nTimeStamp)
|
| 1511 | {
|
| 1512 |
|
| 1513 | D("================= preview frame %d, phys=0x%x, nTimeStamp(millis)=%lld",
|
| 1514 | m_nFrameIn+1, pPhys, (nTimeStamp / 1000));
|
| 1515 |
|
| 1516 | if (m_nFrameIn == m_nFramePlay &&
|
| 1517 | m_nFramePlay != 0)
|
| 1518 | {
|
| 1519 | // we will stop camera after last frame is encoded.
|
| 1520 | // for now just ignore input frames
|
| 1521 |
|
| 1522 | CameraTest_ReleaseFrame(pPhys, pVirt);
|
| 1523 | return;
|
| 1524 | }
|
| 1525 |
|
| 1526 | // see if we should stop
|
| 1527 | pthread_mutex_lock(&m_mutex);
|
| 1528 | ++m_nFrameIn;
|
| 1529 | pthread_mutex_unlock(&m_mutex);
|
| 1530 |
|
| 1531 |
|
| 1532 | if (m_eMode == MODE_LIVE_ENCODE)
|
| 1533 | {
|
| 1534 |
|
| 1535 | OMX_ERRORTYPE result;
|
| 1536 |
|
| 1537 | // register new camera buffers with encoder
|
| 1538 | int i;
|
| 1539 | for (i = 0; i < num_in_buffers; i++)
|
| 1540 | {
|
| 1541 | if (m_pInBuffers[i] != NULL &&
|
| 1542 | m_pInBuffers[i]->pBuffer == pPhys)
|
| 1543 | {
|
| 1544 | break;
|
| 1545 | }
|
| 1546 | else if (m_pInBuffers[i] == NULL)
|
| 1547 | {
|
| 1548 | D("registering buffer...");
|
| 1549 | result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i],
|
| 1550 | (OMX_U8*) pPhys,
|
| 1551 | (OMX_PTR) pVirt); // store virt in app private field
|
| 1552 | D("register done");
|
| 1553 | CHK(result);
|
| 1554 | break;
|
| 1555 | }
|
| 1556 | }
|
| 1557 |
|
| 1558 | if (i == num_in_buffers)
|
| 1559 | {
|
| 1560 | E("There are more camera buffers than we thought");
|
| 1561 | CHK(1);
|
| 1562 | }
|
| 1563 |
|
| 1564 | // encode the yuv frame
|
| 1565 |
|
| 1566 | D("StartEncodeTime=%lld", GetTimeStamp());
|
| 1567 | result = VencTest_EncodeFrame(pPhys,
|
| 1568 | nTimeStamp);
|
| 1569 | CHK(result);
|
| 1570 | // FBTest_DisplayImage(nFD, nOffset);
|
| 1571 | }
|
| 1572 | else
|
| 1573 | {
|
| 1574 | // FBTest_DisplayImage(nFD, nOffset);
|
| 1575 | CameraTest_ReleaseFrame(pPhys, pVirt);
|
| 1576 | }
|
| 1577 | }
|
| 1578 | ////////////////////////////////////////////////////////////////////////////////
|
| 1579 | void usage(char* filename)
|
| 1580 | {
|
| 1581 | char* fname = strrchr(filename, (int) '/');
|
| 1582 | fname = (fname == NULL) ? filename : fname;
|
| 1583 |
|
| 1584 | fprintf(stderr, "usage: %s LIVE <QCIF|QVGA> <MP4|H263> <FPS> <BITRATE> <NFRAMES> <OUTFILE>\n", fname);
|
| 1585 | fprintf(stderr, "usage: %s FILE <QCIF|QVGA> <MP4|H263 <FPS> <BITRATE> <NFRAMES> <INFILE> <OUTFILE> ", fname);
|
| 1586 | fprintf(stderr, "<Dynamic config file - opt> <Rate Control - opt> <AVC Slice Mode - opt>\n", fname);
|
| 1587 | fprintf(stderr, "usage: %s PROFILE <QCIF|QVGA> <MP4|H263 <FPS> <BITRATE> <NFRAMES> <INFILE>\n", fname);
|
| 1588 | fprintf(stderr, "usage: %s PREVIEW <QCIF|QVGA> <FPS> <NFRAMES>\n", fname);
|
| 1589 | fprintf(stderr, "usage: %s DISPLAY <QCIF|QVGA> <FPS> <NFRAMES> <INFILE>\n", fname);
|
| 1590 | fprintf(stderr, "\n BITRATE - bitrate in kbps\n");
|
| 1591 | fprintf(stderr, " FPS - frames per second\n");
|
| 1592 | fprintf(stderr, " NFRAMES - number of frames to play, 0 for infinite\n");
|
| 1593 | fprintf(stderr, " RateControl (Values 0 - 4 for RC_OFF, RC_CBR_CFR, RC_CBR_VFR, RC_VBR_CFR, RC_VBR_VFR\n");
|
| 1594 | exit(1);
|
| 1595 | }
|
| 1596 |
|
| 1597 | bool parseWxH(char *str, OMX_U32 *width, OMX_U32 *height)
|
| 1598 | {
|
| 1599 | bool parseOK = false;
|
| 1600 | const char delimiters[] = " x*,";
|
| 1601 | char *token, *dupstr, *temp;
|
| 1602 | OMX_U32 w, h;
|
| 1603 |
|
| 1604 | dupstr = strdup(str);
|
| 1605 | token = strtok_r(dupstr, delimiters, &temp);
|
| 1606 | if (token)
|
| 1607 | {
|
| 1608 | w = strtoul(token, NULL, 10);
|
| 1609 | token = strtok_r(NULL, delimiters, &temp);
|
| 1610 | if (token)
|
| 1611 | {
|
| 1612 | h = strtoul(token, NULL, 10);
|
| 1613 | if (w != ULONG_MAX && h != ULONG_MAX)
|
| 1614 | {
|
| 1615 | #ifdef MAX_RES_720P
|
| 1616 | if ((w * h >> 8) <= 3600)
|
| 1617 | {
|
| 1618 | parseOK = true;
|
| 1619 | *width = w;
|
| 1620 | *height = h;
|
| 1621 | }
|
| 1622 | #else
|
| 1623 | if ((w * h >> 8) <= 8160)
|
| 1624 | {
|
| 1625 | parseOK = true;
|
| 1626 | *width = w;
|
| 1627 | *height = h;
|
| 1628 | }
|
| 1629 | #endif
|
| 1630 | else
|
| 1631 | E("\nInvalid dimensions %dx%d",w,h);
|
| 1632 | }
|
| 1633 | }
|
| 1634 | }
|
| 1635 | free(dupstr);
|
| 1636 | return parseOK;
|
| 1637 | }
|
| 1638 |
|
| 1639 | ////////////////////////////////////////////////////////////////////////////////
|
| 1640 | void parseArgs(int argc, char** argv)
|
| 1641 | {
|
| 1642 | int dyn_file_arg = argc;
|
| 1643 | if (argc == 1)
|
| 1644 | {
|
| 1645 | usage(argv[0]);
|
| 1646 | }
|
| 1647 | else if (strcmp("PREVIEW", argv[1]) == 0 ||
|
| 1648 | strcmp("preview", argv[1]) == 0)
|
| 1649 | {
|
| 1650 | m_eMode = MODE_PREVIEW;
|
| 1651 | if (argc != 5)
|
| 1652 | {
|
| 1653 | usage(argv[0]);
|
| 1654 | }
|
| 1655 | }
|
| 1656 | else if (strcmp("DISPLAY", argv[1]) == 0 ||
|
| 1657 | strcmp("display", argv[1]) == 0)
|
| 1658 | {
|
| 1659 | m_eMode = MODE_DISPLAY;
|
| 1660 | if (argc != 6)
|
| 1661 | {
|
| 1662 | usage(argv[0]);
|
| 1663 | }
|
| 1664 | m_sProfile.cInFileName = argv[5];
|
| 1665 | m_sProfile.cOutFileName = NULL;
|
| 1666 | }
|
| 1667 | else if (strcmp("LIVE", argv[1]) == 0 ||
|
| 1668 | strcmp("live", argv[1]) == 0)
|
| 1669 | {//263
|
| 1670 | m_eMode = MODE_LIVE_ENCODE;
|
| 1671 | if (argc != 8)
|
| 1672 | {
|
| 1673 | usage(argv[0]);
|
| 1674 | }
|
| 1675 | m_sProfile.cInFileName = NULL;
|
| 1676 | m_sProfile.cOutFileName = argv[7];
|
| 1677 | }
|
| 1678 | else if (strcmp("FILE", argv[1]) == 0 ||
|
| 1679 | strcmp("file", argv[1]) == 0)
|
| 1680 | {//263
|
| 1681 | m_eMode = MODE_FILE_ENCODE;
|
| 1682 |
|
| 1683 | if(argc < 9 || argc > 13)
|
| 1684 | {
|
| 1685 | usage(argv[0]);
|
| 1686 | }
|
| 1687 | else
|
| 1688 | {
|
| 1689 | if (argc > 9)
|
| 1690 | dyn_file_arg = 9;
|
| 1691 |
|
| 1692 | if (argc > 10)
|
| 1693 | {
|
| 1694 | m_sProfile.eControlRate = OMX_Video_ControlRateVariable;
|
| 1695 | int RC = atoi(argv[10]);
|
| 1696 |
|
| 1697 | switch (RC)
|
| 1698 | {
|
| 1699 | case 0:
|
| 1700 | m_sProfile.eControlRate = OMX_Video_ControlRateDisable ;//VENC_RC_NONE
|
| 1701 | break;
|
| 1702 | case 1:
|
| 1703 | m_sProfile.eControlRate = OMX_Video_ControlRateConstant;//VENC_RC_CBR_CFR
|
| 1704 | break;
|
| 1705 |
|
| 1706 | case 2:
|
| 1707 | m_sProfile.eControlRate = OMX_Video_ControlRateConstantSkipFrames;//VENC_RC_CBR_VFR
|
| 1708 | break;
|
| 1709 |
|
| 1710 | case 3:
|
| 1711 | m_sProfile.eControlRate =OMX_Video_ControlRateVariable ;//VENC_RC_VBR_CFR
|
| 1712 | break;
|
| 1713 |
|
| 1714 | case 4:
|
| 1715 | m_sProfile.eControlRate = OMX_Video_ControlRateVariableSkipFrames;//VENC_RC_VBR_VFR
|
| 1716 | break;
|
| 1717 |
|
| 1718 | default:
|
| 1719 | E("invalid rate control selection");
|
| 1720 | m_sProfile.eControlRate = OMX_Video_ControlRateVariable; //VENC_RC_VBR_CFR
|
| 1721 | break;
|
| 1722 | }
|
| 1723 | }
|
| 1724 |
|
| 1725 | if (argc > 11)
|
| 1726 | {
|
| 1727 | int profile_argi = 11;
|
| 1728 | if(!strcmp(argv[3], "H264") || !strcmp(argv[3], "h264"))
|
| 1729 | {
|
| 1730 | profile_argi = 12;
|
| 1731 | D("\nSetting AVCSliceMode ... ");
|
| 1732 | int AVCSliceMode = atoi(argv[11]);
|
| 1733 | switch(AVCSliceMode)
|
| 1734 | {
|
| 1735 | case 0:
|
| 1736 | m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault;
|
| 1737 | break;
|
| 1738 |
|
| 1739 | case 1:
|
| 1740 | m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCMBSlice;
|
| 1741 | break;
|
| 1742 |
|
| 1743 | case 2:
|
| 1744 | m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCByteSlice;
|
| 1745 | break;
|
| 1746 |
|
| 1747 | default:
|
| 1748 | E("invalid Slice Mode");
|
| 1749 | m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault;
|
| 1750 | break;
|
| 1751 | }
|
| 1752 | }
|
| 1753 | if (profile_argi < argc)
|
| 1754 | {
|
| 1755 | if (!strncmp(argv[profile_argi], "0x", 2) || !strncmp(argv[profile_argi], "0x", 2))
|
| 1756 | {
|
| 1757 | m_sProfile.nUserProfile = strtoul(argv[profile_argi], NULL, 16);
|
| 1758 | }
|
| 1759 | else
|
| 1760 | {
|
| 1761 | m_sProfile.nUserProfile = strtoul(argv[profile_argi], NULL, 10);
|
| 1762 | }
|
| 1763 | if (!m_sProfile.nUserProfile || m_sProfile.nUserProfile == ULONG_MAX)
|
| 1764 | {
|
| 1765 | E("invalid specified Profile %s, using default", argv[profile_argi]);
|
| 1766 | m_sProfile.nUserProfile = 0;
|
| 1767 | }
|
| 1768 | }
|
| 1769 | }
|
| 1770 | }
|
| 1771 | m_sProfile.cInFileName = argv[7];
|
| 1772 | m_sProfile.cOutFileName = argv[8];
|
| 1773 | }
|
| 1774 | else if (strcmp("PROFILE", argv[1]) == 0 ||
|
| 1775 | strcmp("profile", argv[1]) == 0)
|
| 1776 | {//263
|
| 1777 | m_eMode = MODE_PROFILE;
|
| 1778 | if (argc != 8)
|
| 1779 | {
|
| 1780 | usage(argv[0]);
|
| 1781 | }
|
| 1782 | m_sProfile.cInFileName = argv[7];
|
| 1783 | m_sProfile.cOutFileName = NULL;
|
| 1784 | }
|
| 1785 | else
|
| 1786 | {
|
| 1787 | usage(argv[0]);
|
| 1788 | }
|
| 1789 |
|
| 1790 |
|
| 1791 | if (strcmp("QCIF", argv[2]) == 0 ||
|
| 1792 | strcmp("qcif", argv[2]) == 0)
|
| 1793 | {
|
| 1794 | m_sProfile.nFrameWidth = 176;
|
| 1795 | m_sProfile.nFrameHeight = 144;
|
| 1796 | m_sProfile.nFrameBytes = 176*144*3/2;
|
| 1797 | m_sProfile.eLevel = OMX_VIDEO_MPEG4Level0;
|
| 1798 | }
|
| 1799 | else if (strcmp("QVGA", argv[2]) == 0 ||
|
| 1800 | strcmp("qvga", argv[2]) == 0)
|
| 1801 | {
|
| 1802 | m_sProfile.nFrameWidth = 320;
|
| 1803 | m_sProfile.nFrameHeight = 240;
|
| 1804 | m_sProfile.nFrameBytes = 320*240*3/2;
|
| 1805 | m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
|
| 1806 | }
|
| 1807 |
|
| 1808 |
|
| 1809 | else if (strcmp("VGA", argv[2]) == 0 ||
|
| 1810 | strcmp("vga", argv[2]) == 0)
|
| 1811 | {
|
| 1812 | m_sProfile.nFrameWidth = 640;
|
| 1813 | m_sProfile.nFrameHeight = 480;
|
| 1814 | m_sProfile.nFrameBytes = 640*480*3/2;
|
| 1815 | m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
|
| 1816 | }
|
| 1817 |
|
| 1818 | else if (strcmp("WVGA", argv[2]) == 0 ||
|
| 1819 | strcmp("wvga", argv[2]) == 0)
|
| 1820 | {
|
| 1821 | m_sProfile.nFrameWidth = 800;
|
| 1822 | m_sProfile.nFrameHeight = 480;
|
| 1823 | m_sProfile.nFrameBytes = 800*480*3/2;
|
| 1824 | m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
|
| 1825 | }
|
| 1826 | else if (strcmp("CIF", argv[2]) == 0 ||
|
| 1827 | strcmp("cif", argv[2]) == 0)
|
| 1828 | {
|
| 1829 | m_sProfile.nFrameWidth = 352;
|
| 1830 | m_sProfile.nFrameHeight = 288;
|
| 1831 | m_sProfile.nFrameBytes = 352*288*3/2;
|
| 1832 | m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
|
| 1833 | }
|
| 1834 | else if (strcmp("720", argv[2]) == 0)
|
| 1835 | {
|
| 1836 | m_sProfile.nFrameWidth = 1280;
|
| 1837 | m_sProfile.nFrameHeight = 720;
|
| 1838 | m_sProfile.nFrameBytes = 720*1280*3/2;
|
| 1839 | m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
|
| 1840 | }
|
| 1841 | else if (strcmp("1080", argv[2]) == 0)
|
| 1842 | {
|
| 1843 | m_sProfile.nFrameWidth = 1920;
|
| 1844 | m_sProfile.nFrameHeight = 1080;
|
| 1845 | m_sProfile.nFrameBytes = 1920*1080*3/2;
|
| 1846 | m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
|
| 1847 | }
|
| 1848 | else if (parseWxH(argv[2], &m_sProfile.nFrameWidth, &m_sProfile.nFrameHeight))
|
| 1849 | {
|
| 1850 | m_sProfile.nFrameBytes = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight*3/2;
|
| 1851 | m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
|
| 1852 | }
|
| 1853 | else
|
| 1854 | {
|
| 1855 | usage(argv[0]);
|
| 1856 | }
|
| 1857 |
|
| 1858 | #ifdef BADGER
|
| 1859 | m_sProfile.nFramestride = (m_sProfile.nFrameWidth + 31) & (~31);
|
| 1860 | m_sProfile.nFrameScanlines = (m_sProfile.nFrameHeight + 31) & (~31);
|
| 1861 | m_sProfile.nFrameBytes = ((m_sProfile.nFramestride * m_sProfile.nFrameScanlines * 3/2) + 4095) & (~4095);
|
| 1862 | E("stride: %d, Scanlines: %d, Size: %d",
|
| 1863 | m_sProfile.nFramestride, m_sProfile.nFrameScanlines, m_sProfile.nFrameBytes);
|
| 1864 | m_sProfile.nFrameRead = m_sProfile.nFramestride * m_sProfile.nFrameScanlines * 3/2;
|
| 1865 | #endif
|
| 1866 | if (m_eMode == MODE_DISPLAY ||
|
| 1867 | m_eMode == MODE_PREVIEW)
|
| 1868 | {
|
| 1869 | m_sProfile.nFramerate = atof(argv[3]);
|
| 1870 | m_nFramePlay = atoi(argv[4]);
|
| 1871 |
|
| 1872 | }
|
| 1873 | else if (m_eMode == MODE_LIVE_ENCODE ||
|
| 1874 | m_eMode == MODE_FILE_ENCODE ||
|
| 1875 | m_eMode == MODE_PROFILE)
|
| 1876 | {
|
| 1877 | if ((!strcmp(argv[3], "MP4")) || (!strcmp(argv[3], "mp4")))
|
| 1878 | {
|
| 1879 | m_sProfile.eCodec = OMX_VIDEO_CodingMPEG4;
|
| 1880 | }
|
| 1881 | else if ((!strcmp(argv[3], "H263")) || (!strcmp(argv[3], "h263")))
|
| 1882 | {
|
| 1883 | m_sProfile.eCodec = OMX_VIDEO_CodingH263;
|
| 1884 | }
|
| 1885 | else if ((!strcmp(argv[3], "H264")) || (!strcmp(argv[3], "h264")))
|
| 1886 | {
|
| 1887 | m_sProfile.eCodec = OMX_VIDEO_CodingAVC;
|
| 1888 | }
|
| 1889 | else
|
| 1890 | {
|
| 1891 | usage(argv[0]);
|
| 1892 | }
|
| 1893 |
|
| 1894 | m_sProfile.nFramerate = atof(argv[4]);
|
| 1895 | m_sProfile.nBitrate = atoi(argv[5]);
|
| 1896 | // m_sProfile.eControlRate = OMX_Video_ControlRateVariable;
|
| 1897 | m_nFramePlay = atoi(argv[6]);
|
| 1898 | if (dyn_file_arg < argc)
|
| 1899 | {
|
| 1900 | m_pDynConfFile = fopen(argv[dyn_file_arg], "r");
|
| 1901 | if (!m_pDynConfFile)
|
| 1902 | E("ERROR: Cannot open dynamic config file: %s", argv[dyn_file_arg]);
|
| 1903 | else
|
| 1904 | {
|
| 1905 | memset(&dynamic_config, 0, sizeof(struct DynamicConfig));
|
| 1906 | }
|
| 1907 | }
|
| 1908 | }
|
| 1909 | }
|
| 1910 |
|
| 1911 | void* Watchdog(void* data)
|
| 1912 | {
|
| 1913 | while (1)
|
| 1914 | {
|
| 1915 | sleep(1000);
|
| 1916 | if (m_bWatchDogKicked == true)
|
| 1917 | m_bWatchDogKicked = false;
|
| 1918 | else
|
| 1919 | E("watchdog has not been kicked. we may have a deadlock");
|
| 1920 | }
|
| 1921 | return NULL;
|
| 1922 | }
|
| 1923 |
|
| 1924 | int main(int argc, char** argv)
|
| 1925 | {
|
| 1926 | OMX_U8* pvirt = NULL;
|
| 1927 | int result;
|
| 1928 | float enc_time_sec=0.0,enc_time_usec=0.0;
|
| 1929 |
|
| 1930 | m_nInFd = -1;
|
| 1931 | m_nOutFd = -1;
|
| 1932 | m_nTimeStamp = 0;
|
| 1933 | m_nFrameIn = 0;
|
| 1934 | m_nFrameOut = 0;
|
| 1935 |
|
| 1936 | memset(&m_sMsgQ, 0, sizeof(MsgQ));
|
| 1937 | parseArgs(argc, argv);
|
| 1938 |
|
| 1939 | D("fps=%d, bitrate=%d, width=%d, height=%d",
|
| 1940 | m_sProfile.nFramerate,
|
| 1941 | m_sProfile.nBitrate,
|
| 1942 | m_sProfile.nFrameWidth,
|
| 1943 | m_sProfile.nFrameHeight);
|
| 1944 |
|
| 1945 |
|
| 1946 | //if (m_eMode != MODE_PREVIEW && m_eMode != MODE_DISPLAY)
|
| 1947 | //{
|
| 1948 | // pthread_t wd;
|
| 1949 | // pthread_create(&wd, NULL, Watchdog, NULL);
|
| 1950 | //}
|
| 1951 |
|
| 1952 | for (int x = 0; x < num_in_buffers; x++)
|
| 1953 | {
|
| 1954 | // mark all buffers as ready to use
|
| 1955 | m_bInFrameFree[x] = OMX_TRUE;
|
| 1956 | }
|
| 1957 |
|
| 1958 |
|
| 1959 | if (m_eMode != MODE_PROFILE)
|
| 1960 | {
|
| 1961 | #if T_ARM
|
| 1962 | m_nOutFd = open(m_sProfile.cOutFileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
|
| 1963 | #else
|
| 1964 | m_nOutFd = open(m_sProfile.cOutFileName,0);
|
| 1965 | #endif
|
| 1966 | if (m_nOutFd < 0)
|
| 1967 | {
|
| 1968 | E("could not open output file %s", m_sProfile.cOutFileName);
|
| 1969 | CHK(1);
|
| 1970 | }
|
| 1971 | }
|
| 1972 |
|
| 1973 | pthread_mutex_init(&m_mutex, NULL);
|
| 1974 | pthread_cond_init(&m_signal, NULL);
|
| 1975 |
|
| 1976 | if (m_eMode != MODE_PREVIEW)
|
| 1977 | {
|
| 1978 | VencTest_Initialize();
|
| 1979 | }
|
| 1980 |
|
| 1981 | ////////////////////////////////////////
|
| 1982 | // Camera + Encode
|
| 1983 | ////////////////////////////////////////
|
| 1984 | if (m_eMode == MODE_LIVE_ENCODE)
|
| 1985 | {
|
| 1986 | CameraTest_Initialize(m_sProfile.nFramerate,
|
| 1987 | m_sProfile.nFrameWidth,
|
| 1988 | m_sProfile.nFrameHeight,
|
| 1989 | PreviewCallback);
|
| 1990 | CameraTest_Run();
|
| 1991 | }
|
| 1992 |
|
| 1993 | if (m_eMode == MODE_FILE_ENCODE ||
|
| 1994 | m_eMode == MODE_PROFILE)
|
| 1995 | {
|
| 1996 | int i;
|
| 1997 | #if T_ARM
|
| 1998 | m_nInFd = open(m_sProfile.cInFileName, O_RDONLY);
|
| 1999 | #else
|
| 2000 | m_nInFd = open(m_sProfile.cInFileName,1);
|
| 2001 | #endif
|
| 2002 | if (m_nInFd < 0)
|
| 2003 | {
|
| 2004 | E("could not open input file");
|
| 2005 | CHK(1);
|
| 2006 |
|
| 2007 | }
|
| 2008 | D("going to idle state");
|
| 2009 | //SetState(OMX_StateIdle);
|
| 2010 | OMX_SendCommand(m_hHandle,
|
| 2011 | OMX_CommandStateSet,
|
| 2012 | (OMX_U32) OMX_StateIdle,
|
| 2013 | NULL);
|
| 2014 |
|
| 2015 | OMX_PARAM_PORTDEFINITIONTYPE portDef;
|
| 2016 |
|
| 2017 | portDef.nPortIndex = 0;
|
| 2018 | result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef);
|
| 2019 | CHK(result);
|
| 2020 |
|
| 2021 | D("allocating Input buffers");
|
| 2022 | num_in_buffers = portDef.nBufferCountActual;
|
| 2023 | for (i = 0; i < portDef.nBufferCountActual; i++)
|
| 2024 | {
|
| 2025 | OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem = new OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO;
|
| 2026 | pvirt = (OMX_U8*)PmemMalloc(pMem, m_sProfile.nFrameBytes);
|
| 2027 |
|
| 2028 | if(pvirt == NULL)
|
| 2029 | {
|
| 2030 | CHK(1);
|
| 2031 | }
|
| 2032 | result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i],
|
| 2033 | (OMX_U8*) pvirt,
|
| 2034 | (OMX_PTR) pMem);
|
| 2035 | CHK(result);
|
| 2036 | }
|
| 2037 | }
|
| 2038 | else if (m_eMode == MODE_LIVE_ENCODE)
|
| 2039 | {
|
| 2040 | D("going to idle state");
|
| 2041 | //SetState(OMX_StateIdle);
|
| 2042 | OMX_SendCommand(m_hHandle,
|
| 2043 | OMX_CommandStateSet,
|
| 2044 | (OMX_U32) OMX_StateIdle,
|
| 2045 | NULL);
|
| 2046 | }
|
| 2047 |
|
| 2048 | int i;
|
| 2049 | OMX_PARAM_PORTDEFINITIONTYPE portDef;
|
| 2050 |
|
| 2051 | portDef.nPortIndex = 1;
|
| 2052 | result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef);
|
| 2053 | CHK(result);
|
| 2054 |
|
| 2055 | D("allocating output buffers");
|
| 2056 | D("Calling UseBuffer for Output port");
|
| 2057 | num_out_buffers = portDef.nBufferCountActual;
|
| 2058 | for (i = 0; i < portDef.nBufferCountActual; i++)
|
| 2059 | {
|
| 2060 | void* pBuff;
|
| 2061 |
|
| 2062 | pBuff = malloc(portDef.nBufferSize);
|
| 2063 | D("portDef.nBufferSize = %d ",portDef.nBufferSize);
|
| 2064 | result = OMX_UseBuffer(m_hHandle,
|
| 2065 | &m_pOutBuffers[i],
|
| 2066 | (OMX_U32) PORT_INDEX_OUT,
|
| 2067 | NULL,
|
| 2068 | portDef.nBufferSize,
|
| 2069 | (OMX_U8*) pBuff);
|
| 2070 | CHK(result);
|
| 2071 | }
|
| 2072 | D("allocate done");
|
| 2073 |
|
| 2074 | // D("Going to state " # eState"...");
|
| 2075 |
|
| 2076 | while (m_eState != OMX_StateIdle)
|
| 2077 | {
|
| 2078 | sleep(1);
|
| 2079 | }
|
| 2080 | //D("Now in state " # eState);
|
| 2081 |
|
| 2082 |
|
| 2083 | D("going to executing state");
|
| 2084 | SetState(OMX_StateExecuting);
|
| 2085 | for (i = 0; i < num_out_buffers; i++)
|
| 2086 | {
|
| 2087 | D("filling buffer %d", i);
|
| 2088 | result = OMX_FillThisBuffer(m_hHandle, m_pOutBuffers[i]);
|
| 2089 | //sleep(1000);
|
| 2090 | CHK(result);
|
| 2091 | }
|
| 2092 |
|
| 2093 | if (m_eMode == MODE_FILE_ENCODE)
|
| 2094 | {
|
| 2095 | // encode the first frame to kick off the whole process
|
| 2096 | VencTest_ReadAndEmpty(m_pInBuffers[0]);
|
| 2097 | // FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[0]->pAppPrivate)->fd,0);
|
| 2098 | }
|
| 2099 |
|
| 2100 | if (m_eMode == MODE_PROFILE)
|
| 2101 | {
|
| 2102 | int i;
|
| 2103 |
|
| 2104 | // read several frames into memory
|
| 2105 | D("reading frames into memory");
|
| 2106 | for (i = 0; i < num_in_buffers; i++)
|
| 2107 | {
|
| 2108 | D("[%d] address 0x%x",i, m_pInBuffers[i]->pBuffer);
|
| 2109 | #ifdef MAX_RES_720P
|
| 2110 | read(m_nInFd,
|
| 2111 | m_pInBuffers[i]->pBuffer,
|
| 2112 | m_sProfile.nFrameBytes);
|
| 2113 | #else
|
| 2114 | // read Y first
|
| 2115 | read(m_nInFd,
|
| 2116 | m_pInBuffers[i]->pBuffer,
|
| 2117 | m_sProfile.nFrameWidth*m_sProfile.nFrameHeight);
|
| 2118 |
|
| 2119 | // check alignment for offset to C
|
| 2120 | OMX_U32 offset_to_c = m_sProfile.nFrameWidth * m_sProfile.nFrameHeight;
|
| 2121 |
|
| 2122 | const OMX_U32 C_2K = (1024*2),
|
| 2123 | MASK_2K = C_2K-1,
|
| 2124 | IMASK_2K = ~MASK_2K;
|
| 2125 |
|
| 2126 | if (offset_to_c & MASK_2K)
|
| 2127 | {
|
| 2128 | // offset to C is not 2k aligned, adjustment is required
|
| 2129 | offset_to_c = (offset_to_c & IMASK_2K) + C_2K;
|
| 2130 | }
|
| 2131 |
|
| 2132 | // read C
|
| 2133 | read(m_nInFd,
|
| 2134 | m_pInBuffers[i]->pBuffer + offset_to_c,
|
| 2135 | m_sProfile.nFrameWidth*m_sProfile.nFrameHeight/2);
|
| 2136 | #endif
|
| 2137 |
|
| 2138 | }
|
| 2139 |
|
| 2140 | // FBTest_Initialize(m_sProfile.nFrameWidth, m_sProfile.nFrameHeight);
|
| 2141 |
|
| 2142 | // loop over the mem-resident frames and encode them
|
| 2143 | D("beging playing mem-resident frames...");
|
| 2144 | for (i = 0; m_nFramePlay == 0 || i < m_nFramePlay; i++)
|
| 2145 | {
|
| 2146 | int idx = i % num_in_buffers;
|
| 2147 | if (m_bInFrameFree[idx] == OMX_FALSE)
|
| 2148 | {
|
| 2149 | int j;
|
| 2150 | E("the expected buffer is not free, but lets find another");
|
| 2151 |
|
| 2152 | idx = -1;
|
| 2153 |
|
| 2154 | // lets see if we can find another free buffer
|
| 2155 | for (j = 0; j < num_in_buffers; j++)
|
| 2156 | {
|
| 2157 | if(m_bInFrameFree[j])
|
| 2158 | {
|
| 2159 | idx = j;
|
| 2160 | break;
|
| 2161 | }
|
| 2162 | }
|
| 2163 | }
|
| 2164 |
|
| 2165 | // if we have a free buffer let's encode it
|
| 2166 | if (idx >= 0)
|
| 2167 | {
|
| 2168 | D("encode frame %d...m_pInBuffers[idx]->pBuffer=0x%x", i,m_pInBuffers[idx]->pBuffer);
|
| 2169 | m_bInFrameFree[idx] = OMX_FALSE;
|
| 2170 | VencTest_EncodeFrame(m_pInBuffers[idx]->pBuffer,
|
| 2171 | m_nTimeStamp);
|
| 2172 | D("display frame %d...", i);
|
| 2173 | // FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[idx]->pAppPrivate)->fd,0);
|
| 2174 | m_nTimeStamp += 1000000 / m_sProfile.nFramerate;
|
| 2175 | }
|
| 2176 | else
|
| 2177 | {
|
| 2178 | E("wow, no buffers are free, performance "
|
| 2179 | "is not so good. lets just sleep some more");
|
| 2180 |
|
| 2181 | }
|
| 2182 | D("sleep for %d microsec", 1000000/m_sProfile.nFramerate);
|
| 2183 | sleep (1000000 / m_sProfile.nFramerate);
|
| 2184 | }
|
| 2185 | // FBTest_Exit();
|
| 2186 | }
|
| 2187 |
|
| 2188 | Msg msg;
|
| 2189 | bool bQuit = false;
|
| 2190 | while ((m_eMode == MODE_FILE_ENCODE || m_eMode == MODE_LIVE_ENCODE) &&
|
| 2191 | !bQuit)
|
| 2192 | {
|
| 2193 | PopMessage(&msg);
|
| 2194 | switch (msg.id)
|
| 2195 | {
|
| 2196 | //////////////////////////////////
|
| 2197 | // FRAME IS ENCODED
|
| 2198 | //////////////////////////////////
|
| 2199 | case MSG_ID_INPUT_FRAME_DONE:
|
| 2200 | /*pthread_mutex_lock(&m_mutex);
|
| 2201 | ++m_nFrameOut;
|
| 2202 | if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0)
|
| 2203 | {
|
| 2204 | bQuit = true;
|
| 2205 | }
|
| 2206 | pthread_mutex_unlock(&m_mutex);*/
|
| 2207 |
|
| 2208 | if (!bQuit && m_eMode == MODE_FILE_ENCODE)
|
| 2209 | {
|
| 2210 | D("pushing another frame down to encoder");
|
| 2211 | if (VencTest_ReadAndEmpty(msg.data.sBitstreamData.pBuffer))
|
| 2212 | {
|
| 2213 | // we have read the last frame
|
| 2214 | D("main is exiting...");
|
| 2215 | bQuit = true;
|
| 2216 | }
|
| 2217 | }
|
| 2218 | break;
|
| 2219 | case MSG_ID_OUTPUT_FRAME_DONE:
|
| 2220 | D("================ writing frame %d = %d bytes to output file",
|
| 2221 | m_nFrameOut+1,
|
| 2222 | msg.data.sBitstreamData.pBuffer->nFilledLen);
|
| 2223 | D("StopEncodeTime=%lld", GetTimeStamp());
|
| 2224 |
|
| 2225 |
|
| 2226 | write(m_nOutFd,
|
| 2227 | msg.data.sBitstreamData.pBuffer->pBuffer,
|
| 2228 | msg.data.sBitstreamData.pBuffer->nFilledLen);
|
| 2229 |
|
| 2230 |
|
| 2231 | result = OMX_FillThisBuffer(m_hHandle,
|
| 2232 | msg.data.sBitstreamData.pBuffer);
|
| 2233 |
|
| 2234 | if (result != OMX_ErrorNone)
|
| 2235 | {
|
| 2236 | CHK(result);
|
| 2237 | }
|
| 2238 |
|
| 2239 | pthread_mutex_lock(&m_mutex);
|
| 2240 | ++m_nFrameOut;
|
| 2241 | if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0)
|
| 2242 | {
|
| 2243 | bQuit = true;
|
| 2244 | }
|
| 2245 | pthread_mutex_unlock(&m_mutex);
|
| 2246 | break;
|
| 2247 |
|
| 2248 | default:
|
| 2249 | E("invalid msg id %d", (int) msg.id);
|
| 2250 | } // end switch (msg.id)
|
| 2251 |
|
| 2252 | /* // TO UNCOMMENT FOR PAUSE TESTINGS
|
| 2253 | if(m_nFrameOut == 10)
|
| 2254 | {
|
| 2255 | E("\nGoing to Pause state\n");
|
| 2256 | SetState(OMX_StatePause);
|
| 2257 | sleep(3);
|
| 2258 | //REQUEST AN I FRAME AFTER PAUSE
|
| 2259 | OMX_CONFIG_INTRAREFRESHVOPTYPE voprefresh;
|
| 2260 | voprefresh.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
|
| 2261 | voprefresh.IntraRefreshVOP = OMX_TRUE;
|
| 2262 | result = OMX_SetConfig(m_hHandle,
|
| 2263 | OMX_IndexConfigVideoIntraVOPRefresh,
|
| 2264 | &voprefresh);
|
| 2265 | E("\n OMX_IndexConfigVideoIntraVOPRefresh Set Paramter port");
|
| 2266 | CHK(result);
|
| 2267 | E("\nGoing to executing state\n");
|
| 2268 | SetState(OMX_StateExecuting);
|
| 2269 | }
|
| 2270 | */
|
| 2271 | } // end while (!bQuit)
|
| 2272 |
|
| 2273 |
|
| 2274 | if (m_eMode == MODE_LIVE_ENCODE)
|
| 2275 | {
|
| 2276 | CameraTest_Exit();
|
| 2277 | close(m_nOutFd);
|
| 2278 | }
|
| 2279 | else if (m_eMode == MODE_FILE_ENCODE ||
|
| 2280 | m_eMode == MODE_PROFILE)
|
| 2281 | {
|
| 2282 | // deallocate pmem buffers
|
| 2283 | for (int i = 0; i < num_in_buffers; i++)
|
| 2284 | {
|
| 2285 | PmemFree((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)m_pInBuffers[i]->pAppPrivate,
|
| 2286 | m_pInBuffers[i]->pBuffer,
|
| 2287 | m_sProfile.nFrameBytes);
|
| 2288 | delete (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*) m_pInBuffers[i]->pAppPrivate;
|
| 2289 | }
|
| 2290 | close(m_nInFd);
|
| 2291 |
|
| 2292 | if (m_eMode == MODE_FILE_ENCODE)
|
| 2293 | {
|
| 2294 | close(m_nOutFd);
|
| 2295 | }
|
| 2296 | if (m_pDynConfFile)
|
| 2297 | {
|
| 2298 | fclose(m_pDynConfFile);
|
| 2299 | m_pDynConfFile = NULL;
|
| 2300 | }
|
| 2301 | }
|
| 2302 |
|
| 2303 | if (m_eMode != MODE_PREVIEW)
|
| 2304 | {
|
| 2305 | D("exit encoder test");
|
| 2306 | VencTest_Exit();
|
| 2307 | }
|
| 2308 |
|
| 2309 | pthread_mutex_destroy(&m_mutex);
|
| 2310 | pthread_cond_destroy(&m_signal);
|
| 2311 |
|
| 2312 | /* Time Statistics Logging */
|
| 2313 | if(0 != m_sProfile.nFramerate)
|
| 2314 | {
|
| 2315 | enc_time_usec = m_nTimeStamp - (1000000 / m_sProfile.nFramerate);
|
| 2316 | enc_time_sec =enc_time_usec/1000000;
|
| 2317 | if(0 != enc_time_sec)
|
| 2318 | {
|
| 2319 | printf("Total Frame Rate: %f",ebd_cnt/enc_time_sec);
|
| 2320 | printf("\nEncoder Bitrate :%lf Kbps",(tot_bufsize*8)/(enc_time_sec*1000));
|
| 2321 | }
|
| 2322 | }
|
| 2323 | else
|
| 2324 | {
|
| 2325 | printf("\n\n Encode Time is zero");
|
| 2326 | }
|
| 2327 | printf("\nTotal Number of Frames :%d",ebd_cnt);
|
| 2328 | printf("\nNumber of dropped frames during encoding:%d\n",ebd_cnt-fbd_cnt);
|
| 2329 | /* End of Time Statistics Logging */
|
| 2330 |
|
| 2331 | D("main has exited");
|
| 2332 | return 0;
|
| 2333 | }
|