blob: 090d9c3877431976cc45774696358cfda4d56b4e [file] [log] [blame]
/*--------------------------------------------------------------------------
Copyright (c) 2009, Code Aurora Forum. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Code Aurora nor
the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/
/*
An Open max test application ....
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <time.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdint.h>
#ifdef _ANDROID_
#include <binder/MemoryHeapBase.h>
#endif
#include "OMX_Core.h"
#include "OMX_Component.h"
#include "OMX_QCOMExtns.h"
#include "qtv_msg.h"
extern "C" {
#include "queue.h"
#include "pmem.h"
}
#include <linux/msm_mdp.h>
#include <linux/fb.h>
#include "qutility.h"
/************************************************************************/
/* #DEFINES */
/************************************************************************/
#define DELAY 66
#define false 0
#define true 1
#define VOP_START_CODE 0x000001B6
#define SHORT_HEADER_START_CODE 0x00008000
#define SPARK1_START_CODE 0x00008400
#define VC1_START_CODE 0x00000100
#define NUMBER_OF_ARBITRARYBYTES_READ (4 * 1024)
#define VC1_SEQ_LAYER_SIZE_WITHOUT_STRUCTC 32
#define VC1_SEQ_LAYER_SIZE_V1_WITHOUT_STRUCTC 16
#define CONFIG_VERSION_SIZE(param) \
param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\
param.nSize = sizeof(param);
#define FAILED(result) (result != OMX_ErrorNone)
#define SUCCEEDED(result) (result == OMX_ErrorNone)
#define SWAPBYTES(ptrA, ptrB) { char t = *ptrA; *ptrA = *ptrB; *ptrB = t;}
#define SIZE_NAL_FIELD_MAX 4
#define MDP_DEINTERLACE 0x80000000
/************************************************************************/
/* GLOBAL DECLARATIONS */
/************************************************************************/
#ifdef _ANDROID_
using namespace android;
#endif
typedef enum {
CODEC_FORMAT_H264 = 1,
CODEC_FORMAT_MP4,
CODEC_FORMAT_H263,
CODEC_FORMAT_VC1,
CODEC_FORMAT_DIVX,
CODEC_FORMAT_VP,
CODEC_FORMAT_SPARK0,
CODEC_FORMAT_SPARK1,
CODEC_FORMAT_MAX = CODEC_FORMAT_SPARK1
} codec_format;
typedef enum {
FILE_TYPE_DAT_PER_AU = 1,
FILE_TYPE_ARBITRARY_BYTES,
FILE_TYPE_COMMON_CODEC_MAX,
FILE_TYPE_START_OF_H264_SPECIFIC = 10,
FILE_TYPE_264_NAL_SIZE_LENGTH = FILE_TYPE_START_OF_H264_SPECIFIC,
FILE_TYPE_START_OF_MP4_SPECIFIC = 20,
FILE_TYPE_PICTURE_START_CODE = FILE_TYPE_START_OF_MP4_SPECIFIC,
FILE_TYPE_START_OF_VC1_SPECIFIC = 30,
FILE_TYPE_RCV = FILE_TYPE_START_OF_VC1_SPECIFIC,
FILE_TYPE_VC1,
FILE_TYPE_START_OF_DIVX_SPECIFIC = 40,
FILE_TYPE_DIVX_4_5_6 = FILE_TYPE_START_OF_DIVX_SPECIFIC,
FILE_TYPE_DIVX_311,
FILE_TYPE_START_OF_VP_SPECIFIC = 50,
FILE_TYPE_VP_6 = FILE_TYPE_START_OF_VP_SPECIFIC,
} file_type;
typedef enum {
GOOD_STATE = 0,
PORT_SETTING_CHANGE_STATE,
ERROR_STATE,
INVALID_STATE
} test_status;
typedef enum {
FREE_HANDLE_AT_LOADED = 1,
FREE_HANDLE_AT_IDLE,
FREE_HANDLE_AT_EXECUTING,
FREE_HANDLE_AT_PAUSE
} freeHandle_test;
struct use_egl_id {
int pmem_fd;
int offset;
};
static int (*Read_Buffer)(OMX_BUFFERHEADERTYPE *pBufHdr );
struct use_egl_id *egl_id = NULL;
int is_use_egl_image = 0;
FILE * inputBufferFile;
FILE * outputBufferFile;
int takeYuvLog = 0;
int displayYuv = 0;
int displayWindow = 0;
int is_yamato = 0;
Queue *etb_queue = NULL;
Queue *fbd_queue = NULL;
pthread_t ebd_thread_id;
pthread_t fbd_thread_id;
void* ebd_thread(void*);
void* fbd_thread(void*);
pthread_mutex_t etb_lock;
pthread_mutex_t fbd_lock;
pthread_mutex_t lock;
pthread_cond_t cond;
pthread_mutex_t elock;
pthread_cond_t econd;
pthread_cond_t fcond;
pthread_mutex_t eos_lock;
pthread_cond_t eos_cond;
sem_t etb_sem;
sem_t fbd_sem;
OMX_PARAM_PORTDEFINITIONTYPE portFmt;
OMX_PORT_PARAM_TYPE portParam;
OMX_ERRORTYPE error;
static int fb_fd = -1;
static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr);
/************************************************************************/
/* GLOBAL INIT */
/************************************************************************/
int input_buf_cnt = 0;
int height =0, width =0;
int used_ip_buf_cnt = 0;
volatile int event_is_done = 0;
int ebd_cnt, fbd_cnt;
int bInputEosReached = 0;
int bOutputEosReached = 0;
char in_filename[512];
int timeStampLfile = 0;
int timestampInterval = 100;
codec_format codec_format_option;
file_type file_type_option;
freeHandle_test freeHandle_option;
int nalSize;
int sent_disabled = 0;
int waitForPortSettingsChanged = 1;
test_status currentStatus = GOOD_STATE;
//* OMX Spec Version supported by the wrappers. Version = 1.1 */
const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101;
OMX_COMPONENTTYPE* dec_handle = 0;
OMX_BUFFERHEADERTYPE **pInputBufHdrs = NULL;
OMX_BUFFERHEADERTYPE **pOutYUVBufHdrs= NULL;
int rcv_v1=0;
/* Performance related variable*/
QPERF_INIT(render_fb);
QPERF_INIT(client_decode);
/************************************************************************/
/* GLOBAL FUNC DECL */
/************************************************************************/
int Init_Decoder();
int Play_Decoder();
int run_tests();
/**************************************************************************/
/* STATIC DECLARATIONS */
/**************************************************************************/
static int video_playback_count = 1;
static int open_video_file ();
static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE *pBufHdr );
static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE *pBufHdr);
static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr);
static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE *pBufHdr);
static int Read_Buffer_From_FrameSize_File(OMX_BUFFERHEADERTYPE *pBufHdr);
static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE *pBufHdr);
static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE *pBufHdr);
static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE *pBufHdr);
static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle,
OMX_BUFFERHEADERTYPE ***pBufHdrs,
OMX_U32 nPortIndex,
long bufCntMin, long bufSize);
static OMX_ERRORTYPE Use_EGL_Buffer ( OMX_COMPONENTTYPE *dec_handle,
OMX_BUFFERHEADERTYPE ***pBufHdrs,
OMX_U32 nPortIndex,
long bufCntMin, long bufSize,
struct use_egl_id **egl);
static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData);
static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
static OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent,
OMX_OUT OMX_PTR pAppData,
OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);
static void do_freeHandle_and_clean_up(bool isDueToError);
/*static usecs_t get_time(void)
{
struct timeval tv;
gettimeofday(&tv, 0);
return ((usecs_t)tv.tv_usec) +
(((usecs_t)tv.tv_sec) * ((usecs_t)1000000));
}*/
void wait_for_event(void)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Waiting for event\n");
pthread_mutex_lock(&lock);
while (event_is_done == 0) {
pthread_cond_wait(&cond, &lock);
}
event_is_done = 0;
pthread_mutex_unlock(&lock);
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Running .... get the event\n");
}
void event_complete(void )
{
pthread_mutex_lock(&lock);
if (event_is_done == 0) {
event_is_done = 1;
pthread_cond_broadcast(&cond);
}
pthread_mutex_unlock(&lock);
}
void* ebd_thread(void* pArg)
{
while(currentStatus != INVALID_STATE)
{
int readBytes =0;
OMX_BUFFERHEADERTYPE* pBuffer = NULL;
sem_wait(&etb_sem);
pthread_mutex_lock(&etb_lock);
pBuffer = (OMX_BUFFERHEADERTYPE *) pop(etb_queue);
pthread_mutex_unlock(&etb_lock);
if(pBuffer == NULL)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - No etb pBuffer to dequeue\n");
continue;
}
pBuffer->nOffset = 0;
if((readBytes = Read_Buffer(pBuffer)) > 0) {
pBuffer->nFilledLen = readBytes;
OMX_EmptyThisBuffer(dec_handle,pBuffer);
}
else
{
pBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
bInputEosReached = true;
pBuffer->nFilledLen = readBytes;
OMX_EmptyThisBuffer(dec_handle,pBuffer);
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,
"EBD::Either EOS or Some Error while reading file\n");
break;
}
}
return NULL;
}
void* fbd_thread(void* pArg)
{
while(currentStatus != INVALID_STATE)
{
int bytes_written = 0;
OMX_BUFFERHEADERTYPE *pBuffer;
sem_wait(&fbd_sem);
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s fbd_cnt[%d] \n", __FUNCTION__, fbd_cnt);
fbd_cnt++;
pthread_mutex_lock(&fbd_lock);
pBuffer = (OMX_BUFFERHEADERTYPE *) pop(fbd_queue);
pthread_mutex_unlock(&fbd_lock);
if (pBuffer == NULL)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Error - No pBuffer to dequeue\n");
continue;
}
/*********************************************
Write the output of the decoder to the file.
*********************************************/
if (sent_disabled)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Ignoring FillBufferDone\n");
continue;
}
if (displayYuv && pBuffer->nFilledLen > 0)
{
QPERF_TIME(render_fb, render_fb(pBuffer));
}
if (takeYuvLog) {
bytes_written = fwrite((const char *)pBuffer->pBuffer,
pBuffer->nFilledLen,1,outputBufferFile);
if (bytes_written < 0) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"\nFillBufferDone: Failed to write to the file\n");
}
else {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"\nFillBufferDone: Wrote %d YUV bytes to the file\n",
bytes_written);
}
}
/********************************************************************/
/* De-Initializing the open max and relasing the buffers and */
/* closing the files.*/
/********************************************************************/
if (pBuffer->nFlags & OMX_BUFFERFLAG_EOS ) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"***************************************************\n");
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"FillBufferDone: End Of Stream Reached\n");
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"***************************************************\n");
pthread_mutex_lock(&eos_lock);
bOutputEosReached = true;
pthread_cond_broadcast(&eos_cond);
pthread_mutex_unlock(&eos_lock);
QPERF_END(client_decode);
QPERF_SET_ITERATION(client_decode, fbd_cnt);
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"***************************************************\n");
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"FBD_THREAD bOutputEosReached %d\n",bOutputEosReached);
break;
}
OMX_FillThisBuffer(dec_handle, pBuffer);
}
return NULL;
}
OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData)
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Function %s \n", __FUNCTION__);
switch(eEvent) {
case OMX_EventCmdComplete:
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\n OMX_EventCmdComplete \n");
// check nData1 for DISABLE event
if(OMX_CommandPortDisable == (OMX_COMMANDTYPE)nData1)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"*********************************************\n");
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Recieved DISABLE Event Command Complete[%d]\n",nData2);
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"*********************************************\n");
sent_disabled = 0;
}
else if(OMX_CommandPortEnable == (OMX_COMMANDTYPE)nData1)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"*********************************************\n");
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Recieved ENABLE Event Command Complete[%d]\n",nData2);
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"*********************************************\n");
}
currentStatus = GOOD_STATE;
event_complete();
break;
case OMX_EventError:
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"OMX_EventError \n");
currentStatus = INVALID_STATE;
if (OMX_ErrorInvalidState == (OMX_ERRORTYPE)nData1)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Invalid State \n");
if(event_is_done == 0)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Event error in the middle of Decode \n");
pthread_mutex_lock(&eos_lock);
bOutputEosReached = true;
pthread_cond_broadcast(&eos_cond);
pthread_mutex_unlock(&eos_lock);
}
}
event_complete();
break;
case OMX_EventPortSettingsChanged:
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"OMX_EventPortSettingsChanged port[%d]\n",nData1);
waitForPortSettingsChanged = 0;
currentStatus = PORT_SETTING_CHANGE_STATE;
// reset the event
event_complete();
break;
default:
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"ERROR - Unknown Event \n");
break;
}
return OMX_ErrorNone;
}
OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
{
int readBytes =0; int bufCnt=0;
OMX_ERRORTYPE result;
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Function %s cnt[%d]\n", __FUNCTION__, ebd_cnt);
ebd_cnt++;
if(bInputEosReached) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"*****EBD:Input EoS Reached************\n");
return OMX_ErrorNone;
}
pthread_mutex_lock(&etb_lock);
if(push(etb_queue, (void *) pBuffer) < 0)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Error in enqueue ebd data\n");
return OMX_ErrorUndefined;
}
pthread_mutex_unlock(&etb_lock);
sem_post(&etb_sem);
return OMX_ErrorNone;
}
OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent,
OMX_OUT OMX_PTR pAppData,
OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
{
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Inside %s callback_count[%d] \n", __FUNCTION__, fbd_cnt);
/* Test app will assume there is a dynamic port setting
* In case that there is no dynamic port setting, OMX will not call event cb,
* instead OMX will send empty this buffer directly and we need to clear an event here
*/
if(waitForPortSettingsChanged && currentStatus != INVALID_STATE)
{
currentStatus = GOOD_STATE;
waitForPortSettingsChanged = 0;
event_complete();
}
if(!sent_disabled)
{
pthread_mutex_lock(&fbd_lock);
if(push(fbd_queue, (void *)pBuffer) < 0)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"Error in enqueueing fbd_data\n");
return OMX_ErrorUndefined;
}
pthread_mutex_unlock(&fbd_lock);
sem_post(&fbd_sem);
}
return OMX_ErrorNone;
}
int main(int argc, char **argv)
{
int i=0;
int bufCnt=0;
int num=0;
int outputOption = 0;
int test_option = 0;
OMX_ERRORTYPE result;
strncpy(in_filename, argv[1], strlen(argv[1])+1);
if(argc > 5)
{
codec_format_option = (codec_format)atoi(argv[2]);
file_type_option = (file_type)atoi(argv[3]);
}
else
{
printf("Command line argument is available\n");
printf("To use it: ./mm-vdec-omx-test <clip location> <codec_type> \n");
printf(" <input_type: 1. per AU(.dat), 2. arbitrary, 3.per NAL/frame>\n");
printf(" <output_type> <test_case> <size_nal if H264>\n\n\n");
printf(" *********************************************\n");
printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n");
printf(" *********************************************\n");
printf(" 1--> H264\n");
printf(" 2--> MP4\n");
printf(" 3--> H263\n");
printf(" 4--> VC1\n");
printf(" 5--> DIVX\n");
printf(" 6--> VP6\n");
printf(" 7--> Spark0\n");
printf(" 8--> Spark1\n");
fflush(stdin);
scanf("%d", &codec_format_option);
fflush(stdin);
if (codec_format_option > CODEC_FORMAT_MAX)
{
printf(" Wrong test case...[%d] \n", codec_format_option);
return -1;
}
printf(" *********************************************\n");
printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n");
printf(" *********************************************\n");
if (codec_format_option != CODEC_FORMAT_DIVX && codec_format_option != CODEC_FORMAT_VP) {
printf(" 1--> PER ACCESS UNIT CLIP (.dat). Clip only available for H264 and Mpeg4\n");
printf(" 2--> ARBITRARY BYTES (need .264/.264c/.mv4/.263/.rcv/.vc1)\n");
}
if (codec_format_option == CODEC_FORMAT_H264)
{
printf(" 3--> NAL LENGTH SIZE CLIP (.264c)\n");
}
else if ( (codec_format_option == CODEC_FORMAT_MP4) || (codec_format_option == CODEC_FORMAT_H263) )
{
printf(" 3--> MP4 VOP or H263 P0 SHORT HEADER START CODE CLIP or DIVX (.m4v or .263)\n");
}
else if (codec_format_option == CODEC_FORMAT_VC1)
{
printf(" 3--> VC1 clip Simple/Main Profile (.rcv)\n");
printf(" 4--> VC1 clip Advance Profile (.vc1)\n");
}
else if (codec_format_option == CODEC_FORMAT_DIVX) {
printf(" 3--> Divx clip 4, 5, 6 format\n");
printf(" 4--> Divx clip 311 format\n");
}
else if (codec_format_option == CODEC_FORMAT_VP)
{
printf(" 3--> VP6 raw bit stream (.vp)\n");
}
else if (codec_format_option == CODEC_FORMAT_SPARK0 || codec_format_option == CODEC_FORMAT_SPARK1)
{
printf(" 3--> SPARK start code based clip\n");
}
fflush(stdin);
scanf("%d", &file_type_option);
fflush(stdin);
}
if (file_type_option >= FILE_TYPE_COMMON_CODEC_MAX)
{
switch (codec_format_option)
{
case CODEC_FORMAT_H264:
file_type_option = (file_type)(FILE_TYPE_START_OF_H264_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
break;
case CODEC_FORMAT_MP4:
case CODEC_FORMAT_H263:
case CODEC_FORMAT_SPARK0:
case CODEC_FORMAT_SPARK1:
file_type_option = (file_type)(FILE_TYPE_START_OF_MP4_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
break;
case CODEC_FORMAT_VC1:
file_type_option = (file_type)(FILE_TYPE_START_OF_VC1_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
break;
case CODEC_FORMAT_DIVX:
file_type_option = (file_type)(FILE_TYPE_START_OF_DIVX_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
break;
case CODEC_FORMAT_VP:
file_type_option = (file_type)(FILE_TYPE_START_OF_VP_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
break;
default:
printf("Error: Unknown code %d\n", codec_format_option);
}
}
if(argc > 5)
{
outputOption = atoi(argv[4]);
test_option = atoi(argv[5]);
if (argc > 6)
{
nalSize = atoi(argv[6]);
}
else
{
nalSize = 0;
}
if(argc > 7)
{
displayWindow = atoi(argv[7]);
if(displayWindow > 4)
{
printf(" display window 0-4 only supported forcing it to 0 \n");
displayWindow = 0;
}
}
else
{
displayWindow = 0;
}
}
else
{
switch(file_type_option)
{
case FILE_TYPE_DAT_PER_AU:
case FILE_TYPE_ARBITRARY_BYTES:
case FILE_TYPE_264_NAL_SIZE_LENGTH:
case FILE_TYPE_PICTURE_START_CODE:
case FILE_TYPE_RCV:
case FILE_TYPE_VC1:
case FILE_TYPE_DIVX_4_5_6:
case FILE_TYPE_DIVX_311:
case FILE_TYPE_VP_6:
{
nalSize = 0;
if ((file_type_option == FILE_TYPE_264_NAL_SIZE_LENGTH) ||
((codec_format_option == CODEC_FORMAT_H264) && (file_type_option == FILE_TYPE_ARBITRARY_BYTES)))
{
printf(" Enter Nal length size [2 or 4] \n");
if (file_type_option == FILE_TYPE_ARBITRARY_BYTES)
{
printf(" Enter 0 if it is a start code based clip\n");
}
scanf("%d", &nalSize);
if ((file_type_option == FILE_TYPE_264_NAL_SIZE_LENGTH) &&
(nalSize == 0))
{
printf("Error - Can't pass NAL length size = 0\n");
return -1;
}
}
height=144;width=176; // Assume Default as QCIF
printf("Executing DynPortReconfig QCIF 144 x 176 \n");
break;
}
default:
{
printf(" Wrong test case...[%d] \n",file_type_option);
return -1;
}
}
printf(" *********************************************\n");
printf(" Output buffer option:\n");
printf(" *********************************************\n");
printf(" 0 --> No display and no YUV log\n");
printf(" 1 --> Diplay YUV\n");
printf(" 2 --> Take YUV log\n");
printf(" 3 --> Display YUV and take YUV log\n");
fflush(stdin);
scanf("%d", &outputOption);
fflush(stdin);
printf(" *********************************************\n");
printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n");
printf(" *********************************************\n");
printf(" 1 --> Play the clip till the end\n");
printf(" 2 --> Run compliance test. Do NOT expect any display for most option. \n");
printf(" Please only see \"TEST SUCCESSFULL\" to indidcate test pass\n");
fflush(stdin);
scanf("%d", &test_option);
fflush(stdin);
printf(" *********************************************\n");
printf(" ENTER THE PORTION OF DISPLAY TO USE\n");
printf(" *********************************************\n");
printf(" 0 --> Entire Screen\n");
printf(" 1 --> 1/4 th of the screen starting from top left corner to middle \n");
printf(" 2 --> 1/4 th of the screen starting from middle to top right corner \n");
printf(" 3 --> 1/4 th of the screen starting from middle to bottom left \n");
printf(" 4 --> 1/4 th of the screen starting from middle to bottom right \n");
printf(" Please only see \"TEST SUCCESSFULL\" to indidcate test pass\n");
fflush(stdin);
scanf("%d", &displayWindow);
fflush(stdin);
}
if (outputOption == 0)
{
displayYuv = 0;
takeYuvLog = 0;
}
else if (outputOption == 1)
{
displayYuv = 1;
}
else if (outputOption == 2)
{
takeYuvLog = 1;
}
else if (outputOption == 3)
{
displayYuv = 1;
takeYuvLog = 1;
}
else
{
printf("Wrong option. Assume you want to see the YUV display\n");
displayYuv = 1;
}
if (test_option == 2)
{
printf(" *********************************************\n");
printf(" ENTER THE COMPLIANCE TEST YOU WOULD LIKE TO EXECUTE\n");
printf(" *********************************************\n");
printf(" 1 --> Call Free Handle at the OMX_StateLoaded\n");
printf(" 2 --> Call Free Handle at the OMX_StateIdle\n");
printf(" 3 --> Call Free Handle at the OMX_StateExecuting\n");
printf(" 4 --> Call Free Handle at the OMX_StatePause\n");
fflush(stdin);
scanf("%d", &freeHandle_option);
fflush(stdin);
}
else
{
freeHandle_option = (freeHandle_test)0;
}
printf("Input values: inputfilename[%s]\n", in_filename);
printf("*******************************************************\n");
pthread_cond_init(&cond, 0);
pthread_cond_init(&eos_cond, 0);
pthread_mutex_init(&eos_lock, 0);
pthread_mutex_init(&lock, 0);
pthread_mutex_init(&etb_lock, 0);
pthread_mutex_init(&fbd_lock, 0);
if (-1 == sem_init(&etb_sem, 0, 0))
{
printf("Error - sem_init failed %d\n", errno);
}
if (-1 == sem_init(&fbd_sem, 0, 0))
{
printf("Error - sem_init failed %d\n", errno);
}
etb_queue = alloc_queue();
if (etb_queue == NULL)
{
printf("\n Error in Creating etb_queue\n");
return -1;
}
fbd_queue = alloc_queue();
if (fbd_queue == NULL)
{
printf("\n Error in Creating fbd_queue\n");
free_queue(etb_queue);
return -1;
}
if(0 != pthread_create(&fbd_thread_id, NULL, fbd_thread, NULL))
{
printf("\n Error in Creating fbd_thread \n");
free_queue(etb_queue);
free_queue(fbd_queue);
return -1;
}
if (displayYuv)
{
QPERF_RESET(render_fb);
#ifdef _ANDROID_
fb_fd = open("/dev/graphics/fb0", O_RDWR);
#else
fb_fd = open("/dev/fb0", O_RDWR);
#endif
if (fb_fd < 0) {
printf("[omx_vdec_test] - ERROR - can't open framebuffer!\n");
return -1;
}
if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
printf("[omx_vdec_test] - ERROR - can't retrieve vscreenInfo!\n");
close(fb_fd);
return -1;
}
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
printf("[omx_vdec_test] - ERROR - can't retrieve fscreenInfo!\n");
close(fb_fd);
return -1;
}
}
run_tests();
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&lock);
pthread_mutex_destroy(&etb_lock);
pthread_mutex_destroy(&fbd_lock);
pthread_cond_destroy(&eos_cond);
pthread_mutex_destroy(&eos_lock);
if (-1 == sem_destroy(&etb_sem))
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - sem_destroy failed %d\n", errno);
}
if (-1 == sem_destroy(&fbd_sem))
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - sem_destroy failed %d\n", errno);
}
if (displayYuv)
{
close(fb_fd);
fb_fd = -1;
QPERF_TERMINATE(render_fb);
}
QPERF_TERMINATE(client_decode);
return 0;
}
int run_tests()
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s\n", __FUNCTION__);
waitForPortSettingsChanged = 1;
currentStatus = GOOD_STATE;
if(file_type_option == FILE_TYPE_DAT_PER_AU) {
Read_Buffer = Read_Buffer_From_DAT_File;
}
else if(file_type_option == FILE_TYPE_ARBITRARY_BYTES) {
Read_Buffer = Read_Buffer_ArbitraryBytes;
}
else if(codec_format_option == CODEC_FORMAT_H264) {
Read_Buffer = Read_Buffer_From_Size_Nal;
}
else if((codec_format_option == CODEC_FORMAT_H263) ||
(codec_format_option == CODEC_FORMAT_MP4) ||
(codec_format_option == CODEC_FORMAT_SPARK0) ||
(codec_format_option == CODEC_FORMAT_SPARK1) ||
(file_type_option == FILE_TYPE_DIVX_4_5_6)) {
Read_Buffer = Read_Buffer_From_Vop_Start_Code_File;
}
else if(file_type_option == FILE_TYPE_RCV) {
Read_Buffer = Read_Buffer_From_RCV_File;
}
else if(file_type_option == FILE_TYPE_VC1) {
Read_Buffer = Read_Buffer_From_VC1_File;
}
else if (file_type_option == FILE_TYPE_DIVX_311) {
Read_Buffer = Read_Buffer_From_FrameSize_File;
}
else if (file_type_option == FILE_TYPE_VP_6) {
Read_Buffer = Read_Buffer_From_FrameSize_File;
}
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"file_type_option %d!\n", file_type_option);
switch(file_type_option)
{
case FILE_TYPE_DAT_PER_AU:
case FILE_TYPE_ARBITRARY_BYTES:
case FILE_TYPE_264_NAL_SIZE_LENGTH:
case FILE_TYPE_PICTURE_START_CODE:
case FILE_TYPE_RCV:
case FILE_TYPE_VC1:
case FILE_TYPE_DIVX_4_5_6:
case FILE_TYPE_DIVX_311:
case FILE_TYPE_VP_6:
if(Init_Decoder()!= 0x00)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"Error - Decoder Init failed\n");
return -1;
}
if(Play_Decoder() != 0x00)
{
return -1;
}
break;
default:
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - Invalid Entry...%d\n",file_type_option);
break;
}
pthread_mutex_lock(&eos_lock);
while (bOutputEosReached == false)
{
pthread_cond_wait(&eos_cond, &eos_lock);
}
pthread_mutex_unlock(&eos_lock);
// Wait till EOS is reached...
if(bOutputEosReached)
{
int bufCnt = 0;
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Moving the decoder to idle state \n");
OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateIdle,0);
wait_for_event();
if (currentStatus == INVALID_STATE)
{
do_freeHandle_and_clean_up(true);
return 0;
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Moving the decoder to loaded state \n");
OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateLoaded,0);
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"[OMX Vdec Test] - Deallocating i/p and o/p buffers \n");
for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt)
{
OMX_FreeBuffer(dec_handle, 0, pInputBufHdrs[bufCnt]);
}
for(bufCnt=0; bufCnt < portFmt.nBufferCountMin; ++bufCnt)
{
OMX_FreeBuffer(dec_handle, 1, pOutYUVBufHdrs[bufCnt]);
}
fbd_cnt = 0; ebd_cnt=0;
bInputEosReached = false;
bOutputEosReached = false;
wait_for_event();
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"[OMX Vdec Test] - Free handle decoder\n");
OMX_ERRORTYPE result = OMX_FreeHandle(dec_handle);
if (result != OMX_ErrorNone)
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"[OMX Vdec Test] - Terminate: OMX_FreeHandle error. Error code: %d\n", result);
}
dec_handle = NULL;
/* Deinit OpenMAX */
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"[OMX Vdec Test] - Terminate: De-initializing OMX \n");
OMX_Deinit();
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"[OMX Vdec Test] - Terminate: closing all files\n");
if(inputBufferFile)
{
fclose(inputBufferFile);
inputBufferFile = NULL;
}
if (takeYuvLog && outputBufferFile) {
fclose(outputBufferFile);
outputBufferFile = NULL;
}
if(etb_queue)
{
free_queue(etb_queue);
etb_queue = NULL;
}
if(fbd_queue)
{
free_queue(fbd_queue);
fbd_queue = NULL;
}
printf("*****************************************\n");
printf("******...TEST SUCCESSFULL...*******\n");
printf("*****************************************\n");
}
return 0;
}
int Init_Decoder()
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s \n", __FUNCTION__);
OMX_ERRORTYPE omxresult;
OMX_U32 total = 0;
char vdecCompNames[50];
typedef OMX_U8* OMX_U8_PTR;
char *role ="video_decoder";
static OMX_CALLBACKTYPE call_back = {&EventHandler, &EmptyBufferDone, &FillBufferDone};
int i = 0;
long bufCnt = 0;
/* Init. the OpenMAX Core */
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nInitializing OpenMAX Core....\n");
omxresult = OMX_Init();
if(OMX_ErrorNone != omxresult) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"\n Failed to Init OpenMAX core");
return -1;
}
else {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"\nOpenMAX Core Init Done\n");
}
/* Query for video decoders*/
OMX_GetComponentsOfRole(role, &total, 0);
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nTotal components of role=%s :%d", role, total);
if(total)
{
/* Allocate memory for pointers to component name */
OMX_U8** vidCompNames = (OMX_U8**)malloc((sizeof(OMX_U8*))*total);
for (i = 0; i < total; ++i) {
vidCompNames[i] = (OMX_U8*)malloc(sizeof(OMX_U8)*OMX_MAX_STRINGNAME_SIZE);
}
OMX_GetComponentsOfRole(role, &total, vidCompNames);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nComponents of Role:%s\n", role);
for (i = 0; i < total; ++i) {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nComponent Name [%s]\n",vidCompNames[i]);
free(vidCompNames[i]);
}
free(vidCompNames);
}
else {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"No components found with Role:%s", role);
}
if (codec_format_option == CODEC_FORMAT_H264)
{
strncpy(vdecCompNames, "OMX.qcom.video.decoder.avc", 27);
}
else if (codec_format_option == CODEC_FORMAT_MP4)
{
strncpy(vdecCompNames, "OMX.qcom.video.decoder.mpeg4", 29);
}
else if (codec_format_option == CODEC_FORMAT_H263)
{
strncpy(vdecCompNames, "OMX.qcom.video.decoder.h263", 28);
}
else if (codec_format_option == CODEC_FORMAT_SPARK0 || codec_format_option == CODEC_FORMAT_SPARK1)
{
strncpy(vdecCompNames, "OMX.qcom.video.decoder.spark", 29);
}
else if (codec_format_option == CODEC_FORMAT_VC1)
{
strncpy(vdecCompNames, "OMX.qcom.video.decoder.vc1", 27);
}
else if (codec_format_option == CODEC_FORMAT_DIVX)
{
strncpy(vdecCompNames, "OMX.qcom.video.decoder.divx", 28);
}
else if (codec_format_option == CODEC_FORMAT_VP)
{
strncpy(vdecCompNames, "OMX.qcom.video.decoder.vp", 26);
}
else
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error: Unsupported codec %d\n", codec_format_option);
return -1;
}
omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&dec_handle),
(OMX_STRING)vdecCompNames, NULL, &call_back);
if (FAILED(omxresult)) {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"\nFailed to Load the component:%s\n", vdecCompNames);
return -1;
}
else
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nComponent %s is in LOADED state\n", vdecCompNames);
}
/* Get the port information */
CONFIG_VERSION_SIZE(portParam);
omxresult = OMX_GetParameter(dec_handle, OMX_IndexParamVideoInit,
(OMX_PTR)&portParam);
if(FAILED(omxresult)) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"ERROR - Failed to get Port Param\n");
return -1;
}
else
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"portParam.nPorts:%d\n", portParam.nPorts);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"portParam.nStartPortNumber:%d\n", portParam.nStartPortNumber);
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Set parameter immediately followed by getparameter");
if(is_use_egl_image) {
portFmt.format.video.pNativeWindow = (void *)0xDEADBEAF;
}
omxresult = OMX_SetParameter(dec_handle,
OMX_IndexParamPortDefinition,
&portFmt);
if(OMX_ErrorNone != omxresult)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"ERROR - Set parameter failed");
}
/* Set the compression format on i/p port */
if (codec_format_option == CODEC_FORMAT_H264)
{
portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
}
else if (codec_format_option == CODEC_FORMAT_MP4)
{
portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
}
else if (codec_format_option == CODEC_FORMAT_H263)
{
portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
}
else if (codec_format_option == CODEC_FORMAT_SPARK0 || codec_format_option == CODEC_FORMAT_SPARK1)
{
//portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingSpark;
portFmt.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingSpark;
}
else if (codec_format_option == CODEC_FORMAT_VC1)
{
portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV;
}
else if (codec_format_option == CODEC_FORMAT_DIVX)
{
portFmt.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
}
else if (codec_format_option == CODEC_FORMAT_VP)
{
portFmt.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingVp;
}
else
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error: Unsupported codec %d\n", codec_format_option);
}
return 0;
}
int Play_Decoder()
{
int i, bufCnt;
int frameSize=0;
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s \n", __FUNCTION__);
OMX_ERRORTYPE ret;
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"sizeof[%d]\n", sizeof(OMX_BUFFERHEADERTYPE));
/* open the i/p and o/p files based on the video file format passed */
if(open_video_file()) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error in opening video file\n");
return -1;
}
OMX_QCOM_PARAM_PORTDEFINITIONTYPE inputPortFmt;
memset(&inputPortFmt, 0, sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE));
CONFIG_VERSION_SIZE(inputPortFmt);
inputPortFmt.nPortIndex = 0; // input port
switch (file_type_option)
{
case FILE_TYPE_DAT_PER_AU:
case FILE_TYPE_PICTURE_START_CODE:
case FILE_TYPE_RCV:
case FILE_TYPE_DIVX_4_5_6:
case FILE_TYPE_DIVX_311:
case FILE_TYPE_VP_6:
{
inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_OnlyOneCompleteFrame;
break;
}
case FILE_TYPE_ARBITRARY_BYTES:
{
inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Arbitrary;
break;
}
case FILE_TYPE_264_NAL_SIZE_LENGTH:
case FILE_TYPE_VC1:
{
inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_OnlyOneCompleteSubFrame;
break;
}
default:
inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Unspecified;
}
OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPortDefn,
(OMX_PTR)&inputPortFmt);
OMX_VIDEO_PARAM_PORTFORMATTYPE colorFormat;
memset(&colorFormat,0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
CONFIG_VERSION_SIZE(colorFormat);
colorFormat.nPortIndex = 1;
if (!is_yamato) {
colorFormat.eColorFormat = (OMX_COLOR_FORMATTYPE) OMX_QCOM_COLOR_FormatYVU420SemiPlanar;
printf("color format nv21 %d\n", colorFormat.eColorFormat);
}
else {
colorFormat.eColorFormat = (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatYVU420PackedSemiPlanar32m4ka;
printf("color format nv21 yamato %d\n", colorFormat.eColorFormat);
}
OMX_SetParameter(dec_handle, (OMX_INDEXTYPE)OMX_IndexParamVideoPortFormat,
(OMX_PTR)&colorFormat);
/* Query the decoder outport's min buf requirements */
CONFIG_VERSION_SIZE(portFmt);
/* Port for which the Client needs to obtain info */
portFmt.nPortIndex = portParam.nStartPortNumber;
OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nDec: Min Buffer Count %d\n", portFmt.nBufferCountMin);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nDec: Buffer Size %d\n", portFmt.nBufferSize);
if(OMX_DirInput != portFmt.eDir) {
printf ("\nDec: Expect Input Port\n");
return -1;
}
if(codec_format_option == CODEC_FORMAT_DIVX) {
QOMX_VIDEO_PARAM_DIVXTYPE paramDivx;
CONFIG_VERSION_SIZE(paramDivx);
paramDivx.nPortIndex = 0;
if(file_type_option == FILE_TYPE_DIVX_311) {
int off;
paramDivx.eFormat = QOMX_VIDEO_DIVXFormat311;
off = fread(&width, 1, 4, inputBufferFile);
if (off == 0)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_MED, "Failed to read width for divx\n");
return -1;
}
off = fread(&height, 1, 4, inputBufferFile);
if (off == 0)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_MED, "Failed to read wodth for divx\n");
return -1;
}
}
else if (file_type_option == FILE_TYPE_DIVX_4_5_6) {
paramDivx.eFormat = QOMX_VIDEO_DIVXFormat4;
}
paramDivx.eProfile = QOMX_VIDEO_DivXProfileqMobile;
OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamVideoDivx,
(OMX_PTR)&paramDivx);
}
else if(codec_format_option == CODEC_FORMAT_VP) {
QOMX_VIDEO_PARAM_VPTYPE paramVp;
CONFIG_VERSION_SIZE(paramVp);
paramVp.nPortIndex = 0;
if(file_type_option == FILE_TYPE_VP_6) {
paramVp.eFormat = QOMX_VIDEO_VPFormat6;
}
paramVp.eProfile = QOMX_VIDEO_VPProfileAdvanced;
OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamVideoVp,
(OMX_PTR)&paramVp);
} else
if(codec_format_option == CODEC_FORMAT_SPARK0 || codec_format_option == CODEC_FORMAT_SPARK1) {
QOMX_VIDEO_PARAM_SPARKTYPE paramSpark;
CONFIG_VERSION_SIZE(paramSpark);
paramSpark.nPortIndex = 0;
if( codec_format_option == CODEC_FORMAT_SPARK1 ) {
paramSpark.eFormat = QOMX_VIDEO_SparkFormat1;
}
else if (codec_format_option == CODEC_FORMAT_SPARK0 ) {
paramSpark.eFormat = QOMX_VIDEO_SparkFormat0;
}
OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamVideoSpark,
(OMX_PTR)&paramSpark);
}
bufCnt = 0;
portFmt.format.video.nFrameHeight = height;
portFmt.format.video.nFrameWidth = width;
if(is_use_egl_image) {
portFmt.format.video.pNativeWindow = (void *)0xDEADBEAF;
}
OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition,
(OMX_PTR)&portFmt);
OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,
&portFmt);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nDec: New Min Buffer Count %d", portFmt.nBufferCountMin);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nVideo format, height = %d", portFmt.format.video.nFrameHeight);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nVideo format, height = %d\n", portFmt.format.video.nFrameWidth);
if(codec_format_option == CODEC_FORMAT_H264)
{
OMX_VIDEO_CONFIG_NALSIZE naluSize;
naluSize.nNaluBytes = nalSize;
OMX_SetConfig(dec_handle,OMX_IndexConfigVideoNalSize,(OMX_PTR)&naluSize);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"SETTING THE NAL SIZE to %d\n",naluSize.nNaluBytes);
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nOMX_SendCommand Decoder -> IDLE\n");
OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateIdle,0);
input_buf_cnt = portFmt.nBufferCountMin;
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Transition to Idle State succesful...\n");
/* Allocate buffer on decoder's i/p port */
error = Allocate_Buffer(dec_handle, &pInputBufHdrs, portFmt.nPortIndex,
portFmt.nBufferCountMin, portFmt.nBufferSize);
if (error != OMX_ErrorNone) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - OMX_AllocateBuffer Input buffer error\n");
return -1;
}
else {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\nOMX_AllocateBuffer Input buffer success\n");
}
portFmt.nPortIndex = portParam.nStartPortNumber+1;
/* Port for which the Client needs to obtain info */
OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"nMin Buffer Count=%d", portFmt.nBufferCountMin);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"nBuffer Size=%d", portFmt.nBufferSize);
if(OMX_DirOutput != portFmt.eDir) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - Expect Output Port\n");
return -1;
}
if(!is_use_egl_image) {
/* Allocate buffer on decoder's o/p port */
error = Allocate_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex,
portFmt.nBufferCountMin, portFmt.nBufferSize);
}
else {
error = Use_EGL_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex,
portFmt.nBufferCountMin, portFmt.nBufferSize, &egl_id);
}
if (error != OMX_ErrorNone) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - OMX_AllocateBuffer Output buffer error\n");
return -1;
}
else
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"OMX_AllocateBuffer Output buffer success\n");
}
wait_for_event();
if (currentStatus == INVALID_STATE)
{
do_freeHandle_and_clean_up(true);
return -1;
}
if (freeHandle_option == FREE_HANDLE_AT_IDLE)
{
OMX_STATETYPE state = OMX_StateInvalid;
OMX_GetState(dec_handle, &state);
if (state == OMX_StateIdle)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Decoder is in OMX_StateIdle and trying to call OMX_FreeHandle \n");
do_freeHandle_and_clean_up(false);
}
else
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state);
do_freeHandle_and_clean_up(true);
}
return -1;
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"OMX_SendCommand Decoder -> Executing\n");
OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
wait_for_event();
if (currentStatus == INVALID_STATE)
{
do_freeHandle_and_clean_up(true);
return -1;
}
for(bufCnt=0; bufCnt < portFmt.nBufferCountMin; ++bufCnt) {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"OMX_FillThisBuffer on output buf no.%d\n",bufCnt);
pOutYUVBufHdrs[bufCnt]->nOutputPortIndex = 1;
pOutYUVBufHdrs[bufCnt]->nFlags &= ~OMX_BUFFERFLAG_EOS;
ret = OMX_FillThisBuffer(dec_handle, pOutYUVBufHdrs[bufCnt]);
if (OMX_ErrorNone != ret) {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - OMX_FillThisBuffer failed with result %d\n", ret);
}
else {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"OMX_FillThisBuffer success!\n");
}
}
used_ip_buf_cnt = input_buf_cnt;
rcv_v1 = 0;
QPERF_START(client_decode);
if ((codec_format_option == CODEC_FORMAT_VC1) && (file_type_option == FILE_TYPE_RCV))
{
pInputBufHdrs[0]->nOffset = 0;
frameSize = Read_Buffer_From_RCV_File_Seq_Layer(pInputBufHdrs[0]);
pInputBufHdrs[0]->nFilledLen = frameSize;
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"After Read_Buffer_From_RCV_File_Seq_Layer frameSize %d\n", frameSize);
pInputBufHdrs[0]->nInputPortIndex = 0;
pInputBufHdrs[0]->nOffset = 0;
pInputBufHdrs[0]->nFlags = 0;
//pBufHdr[bufCnt]->pAppPrivate = this;
ret = OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[0]);
if (OMX_ErrorNone != ret) {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"ERROR - OMX_EmptyThisBuffer failed with result %d\n", ret);
do_freeHandle_and_clean_up(true);
return -1;
}
else {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"OMX_EmptyThisBuffer success!\n");
}
i = 1;
}
else
{
i = 0;
}
for (i; i < used_ip_buf_cnt;i++) {
pInputBufHdrs[i]->nInputPortIndex = 0;
pInputBufHdrs[i]->nOffset = 0;
if((frameSize = Read_Buffer(pInputBufHdrs[i])) <= 0 ){
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,"NO FRAME READ\n");
pInputBufHdrs[i]->nFilledLen = frameSize;
pInputBufHdrs[i]->nInputPortIndex = 0;
pInputBufHdrs[i]->nFlags |= OMX_BUFFERFLAG_EOS;;
bInputEosReached = true;
OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[i]);
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,
"File is small::Either EOS or Some Error while reading file\n");
break;
}
pInputBufHdrs[i]->nFilledLen = frameSize;
pInputBufHdrs[i]->nInputPortIndex = 0;
pInputBufHdrs[i]->nFlags = 0;
//pBufHdr[bufCnt]->pAppPrivate = this;
ret = OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[i]);
if (OMX_ErrorNone != ret) {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"ERROR - OMX_EmptyThisBuffer failed with result %d\n", ret);
do_freeHandle_and_clean_up(true);
return -1;
}
else {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"OMX_EmptyThisBuffer success!\n");
}
}
if(0 != pthread_create(&ebd_thread_id, NULL, ebd_thread, NULL))
{
printf("\n Error in Creating fbd_thread \n");
free_queue(etb_queue);
free_queue(fbd_queue);
return -1;
}
// wait for event port settings changed event
wait_for_event();
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"RECIEVED EVENT PORT TO DETERMINE IF DYN PORT RECONFIGURATION NEEDED, currentStatus %d\n",
currentStatus);
if (currentStatus == INVALID_STATE)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - INVALID_STATE\n");
do_freeHandle_and_clean_up(true);
return -1;
}
else if (currentStatus == PORT_SETTING_CHANGE_STATE)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"PORT_SETTING_CHANGE_STATE\n");
// Send DISABLE command
sent_disabled = 1;
OMX_SendCommand(dec_handle, OMX_CommandPortDisable, 1, 0);
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"FREEING BUFFERS\n");
// Free output Buffer
for(bufCnt=0; bufCnt < portFmt.nBufferCountMin; ++bufCnt) {
OMX_FreeBuffer(dec_handle, 1, pOutYUVBufHdrs[bufCnt]);
if(is_use_egl_image && egl_id) {
struct pmem arena;
arena.fd = egl_id[bufCnt].pmem_fd;
arena.size = pOutYUVBufHdrs[bufCnt]->nAllocLen;
pmem_free(&arena);
}
}
if(egl_id) {
free(egl_id);
egl_id = NULL;
}
// wait for Disable event to come back
wait_for_event();
if (currentStatus == INVALID_STATE)
{
do_freeHandle_and_clean_up(true);
return -1;
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"DISABLE EVENT RECD\n");
// GetParam and SetParam
// Send Enable command
OMX_SendCommand(dec_handle, OMX_CommandPortEnable, 1, 0);
// AllocateBuffers
/* Allocate buffer on decoder's o/p port */
portFmt.nPortIndex = 1;
/* Port for which the Client needs to obtain info */
OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Min Buffer Count=%d", portFmt.nBufferCountMin);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Buffer Size=%d", portFmt.nBufferSize);
if(OMX_DirOutput != portFmt.eDir) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - Expect Output Port\n");
return -1;
}
if(!is_use_egl_image) {
/* Allocate buffer on decoder's o/p port */
error = Allocate_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex,
portFmt.nBufferCountMin, portFmt.nBufferSize);
}
else {
error = Use_EGL_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex,
portFmt.nBufferCountMin, portFmt.nBufferSize, &egl_id);
}
if (error != OMX_ErrorNone) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - OMX_AllocateBuffer Output buffer error\n");
return -1;
}
else
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"OMX_AllocateBuffer Output buffer success\n");
}
// wait for enable event to come back
wait_for_event();
if (currentStatus == INVALID_STATE)
{
do_freeHandle_and_clean_up(true);
return -1;
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"ENABLE EVENT HANDLER RECD\n");
for(bufCnt=0; bufCnt < portFmt.nBufferCountMin; ++bufCnt) {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"OMX_FillThisBuffer on output buf no.%d\n",bufCnt);
pOutYUVBufHdrs[bufCnt]->nOutputPortIndex = 1;
pOutYUVBufHdrs[bufCnt]->nFlags &= ~OMX_BUFFERFLAG_EOS;
ret = OMX_FillThisBuffer(dec_handle, pOutYUVBufHdrs[bufCnt]);
if (OMX_ErrorNone != ret) {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"ERROR - OMX_FillThisBuffer failed with result %d\n", ret);
}
else {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"OMX_FillThisBuffer success!\n");
}
}
}
if (freeHandle_option == FREE_HANDLE_AT_EXECUTING)
{
OMX_STATETYPE state = OMX_StateInvalid;
OMX_GetState(dec_handle, &state);
if (state == OMX_StateExecuting)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Decoder is in OMX_StateExecuting and trying to call OMX_FreeHandle \n");
do_freeHandle_and_clean_up(false);
}
else
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state);
do_freeHandle_and_clean_up(true);
}
return -1;
}
else if (freeHandle_option == FREE_HANDLE_AT_PAUSE)
{
OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StatePause,0);
wait_for_event();
OMX_STATETYPE state = OMX_StateInvalid;
OMX_GetState(dec_handle, &state);
if (state == OMX_StatePause)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Decoder is in OMX_StatePause and trying to call OMX_FreeHandle \n");
do_freeHandle_and_clean_up(false);
}
else
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state);
do_freeHandle_and_clean_up(true);
}
return -1;
}
return 0;
}
static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle,
OMX_BUFFERHEADERTYPE ***pBufHdrs,
OMX_U32 nPortIndex,
long bufCntMin, long bufSize)
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s \n", __FUNCTION__);
OMX_ERRORTYPE error=OMX_ErrorNone;
long bufCnt=0;
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"pBufHdrs = %x,bufCntMin = %d\n", pBufHdrs, bufCntMin);
*pBufHdrs= (OMX_BUFFERHEADERTYPE **)
malloc(sizeof(OMX_BUFFERHEADERTYPE)*bufCntMin);
for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"OMX_AllocateBuffer No %d \n", bufCnt);
error = OMX_AllocateBuffer(dec_handle, &((*pBufHdrs)[bufCnt]),
nPortIndex, NULL, bufSize);
}
return error;
}
static OMX_ERRORTYPE Use_EGL_Buffer ( OMX_COMPONENTTYPE *dec_handle,
OMX_BUFFERHEADERTYPE ***pBufHdrs,
OMX_U32 nPortIndex,
long bufCntMin, long bufSize,
struct use_egl_id **egl)
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s \n", __FUNCTION__);
OMX_ERRORTYPE error=OMX_ErrorNone;
long bufCnt=0;
struct use_egl_id *egl_info;
struct pmem arena;
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"pBufHdrs = %x,bufCntMin = %d\n", pBufHdrs, bufCntMin);
*pBufHdrs= (OMX_BUFFERHEADERTYPE **)
malloc(sizeof(OMX_BUFFERHEADERTYPE)*bufCntMin);
*egl = (struct use_egl_id *)
malloc(sizeof(struct use_egl_id) * bufCntMin);
for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
egl_info = *egl+bufCnt;
if (pmem_alloc (&arena, bufSize))
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"OMX_Use_EGL_Buffer No pmem %d \n", bufSize);
return OMX_ErrorInsufficientResources;
}
egl_info->pmem_fd = arena.fd;
egl_info->offset = 0;
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"OMX_AllocateBuffer No %d \n", bufCnt);
error = OMX_UseEGLImage(dec_handle, &((*pBufHdrs)[bufCnt]),
nPortIndex, NULL, (void *) egl_info);
}
return error;
}
static void do_freeHandle_and_clean_up(bool isDueToError)
{
int bufCnt = 0;
for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt)
{
OMX_FreeBuffer(dec_handle, 0, pInputBufHdrs[bufCnt]);
}
for(bufCnt=0; bufCnt < portFmt.nBufferCountMin; ++bufCnt)
{
OMX_FreeBuffer(dec_handle, 1, pOutYUVBufHdrs[bufCnt]);
if(is_use_egl_image && egl_id) {
struct pmem arena;
arena.fd = egl_id[bufCnt].pmem_fd;
arena.size = pOutYUVBufHdrs[bufCnt]->nAllocLen;
pmem_free(&arena);
}
}
if(egl_id) {
free(egl_id);
egl_id = NULL;
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"[OMX Vdec Test] - Free handle decoder\n");
OMX_ERRORTYPE result = OMX_FreeHandle(dec_handle);
if (result != OMX_ErrorNone)
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"[OMX Vdec Test] - OMX_FreeHandle error. Error code: %d\n", result);
}
dec_handle = NULL;
/* Deinit OpenMAX */
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"[OMX Vdec Test] - De-initializing OMX \n");
OMX_Deinit();
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"[OMX Vdec Test] - closing all files\n");
if(inputBufferFile)
{
fclose(inputBufferFile);
inputBufferFile = NULL;
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"[OMX Vdec Test] - after free inputfile\n");
if (takeYuvLog && outputBufferFile) {
fclose(outputBufferFile);
outputBufferFile = NULL;
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"[OMX Vdec Test] - after free outputfile\n");
if(etb_queue)
{
free_queue(etb_queue);
etb_queue = NULL;
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"[OMX Vdec Test] - after free etb_queue \n");
if(fbd_queue)
{
free_queue(fbd_queue);
fbd_queue = NULL;
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"[OMX Vdec Test] - after free iftb_queue\n");
printf("*****************************************\n");
if (isDueToError)
{
printf("************...TEST FAILED...************\n");
}
else
{
printf("**********...TEST SUCCESSFULL...*********\n");
}
printf("*****************************************\n");
}
static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE *pBufHdr)
{
long frameSize=0;
char temp_buffer[10];
char temp_byte;
int bytes_read=0;
int i=0;
unsigned char *read_buffer=NULL;
char c = '1'; //initialize to anything except '\0'(0)
char inputFrameSize[10];
int count =0; char cnt =0;
memset(temp_buffer, 0, sizeof(temp_buffer));
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Inside %s \n", __FUNCTION__);
while (cnt < 10)
/* Check the input file format, may result in infinite loop */
{
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"loop[%d] count[%d]\n",cnt,count);
count = fread(&inputFrameSize[cnt], 1, 1, inputBufferFile);
if(inputFrameSize[cnt] == '\0' )
break;
cnt++;
}
inputFrameSize[cnt]='\0';
frameSize = atoi(inputFrameSize);
pBufHdr->nFilledLen = 0;
/* get the frame length */
fseek(inputBufferFile, -1, SEEK_CUR);
bytes_read = fread(pBufHdr->pBuffer, 1, frameSize, inputBufferFile);
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Actual frame Size [%d] bytes_read using fread[%d]\n",
frameSize, bytes_read);
if(bytes_read == 0 || bytes_read < frameSize ) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Bytes read Zero After Read frame Size \n");
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Checking VideoPlayback Count:video_playback_count is:%d\n",
video_playback_count);
return 0;
}
pBufHdr->nTimeStamp = timeStampLfile;
timeStampLfile += timestampInterval;
return bytes_read;
}
static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE *pBufHdr)
{
char temp_buffer[10];
char temp_byte;
int bytes_read=0;
int i=0;
unsigned char *read_buffer=NULL;
char c = '1'; //initialize to anything except '\0'(0)
char inputFrameSize[10];
int count =0; char cnt =0;
memset(temp_buffer, 0, sizeof(temp_buffer));
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s \n", __FUNCTION__);
bytes_read = fread(pBufHdr->pBuffer, 1, NUMBER_OF_ARBITRARYBYTES_READ, inputBufferFile);
if(bytes_read == 0) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Bytes read Zero After Read frame Size \n");
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Checking VideoPlayback Count:video_playback_count is:%d\n",
video_playback_count);
return 0;
}
pBufHdr->nTimeStamp = timeStampLfile;
timeStampLfile += timestampInterval;
return bytes_read;
}
static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr)
{
unsigned int readOffset = 0;
unsigned int ret = 0;
int bytes_read = 0;
unsigned int code = 0;
pBufHdr->nFilledLen = 0;
static unsigned int header_code = 0;
unsigned char data;
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s \n", __FUNCTION__);
do
{
//Start codes are always byte aligned.
if(readOffset <= pBufHdr->nAllocLen) {
bytes_read = fread(&pBufHdr->pBuffer[readOffset],1, 1,inputBufferFile);
data = pBufHdr->pBuffer[readOffset];
}
else {
bytes_read = fread(&data,1, 1,inputBufferFile);
}
if(!bytes_read)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Bytes read Zero \n");
break;
}
code <<= 8;
code |= (0x000000FF & data);
//VOP start code comparision
if (readOffset>3)
{
if(!header_code ){
if( VOP_START_CODE == code)
{
header_code = VOP_START_CODE;
}
else if ( (0xFFFFFC00 & code) == SHORT_HEADER_START_CODE )
{
header_code = SHORT_HEADER_START_CODE;
}
else if ( (0xFFFFFC00 & code) == SPARK1_START_CODE )
{
header_code = SPARK1_START_CODE;
}
}
if ((header_code == VOP_START_CODE) && (code == VOP_START_CODE))
{
//Seek backwards by 4
fseek(inputBufferFile, -4, SEEK_CUR);
readOffset-=3;
break;
}
else if ( (( header_code == SHORT_HEADER_START_CODE ) && ( SHORT_HEADER_START_CODE == (code & 0xFFFFFC00))) ||
(( header_code == SPARK1_START_CODE ) && ( SPARK1_START_CODE == (code & 0xFFFFFC00))) )
{
//Seek backwards by 4
fseek(inputBufferFile, -4, SEEK_CUR);
readOffset-=3;
break;
}
}
readOffset++;
}while (1);
pBufHdr->nTimeStamp = timeStampLfile;
timeStampLfile += timestampInterval;
ret = ((readOffset > pBufHdr->nAllocLen)?pBufHdr->nAllocLen:readOffset);
return ret;
}
static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE *pBufHdr)
{
// NAL unit stream processing
char temp_size[SIZE_NAL_FIELD_MAX];
int i = 0;
int j = 0;
unsigned int size = 0, readSize = 0; // Need to make sure that uint32 has SIZE_NAL_FIELD_MAX (4) bytes
int bytes_read = 0;
// read the "size_nal_field"-byte size field
bytes_read = fread(pBufHdr->pBuffer + pBufHdr->nOffset, 1, nalSize, inputBufferFile);
if (bytes_read == 0)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_MED, "Failed to read frame or it might be EOF\n");
return 0;
}
for (i=0; i<SIZE_NAL_FIELD_MAX-nalSize; i++)
{
temp_size[SIZE_NAL_FIELD_MAX - 1 - i] = 0;
}
/* Due to little endiannes, Reorder the size based on size_nal_field */
for (j=0; i<SIZE_NAL_FIELD_MAX; i++, j++)
{
temp_size[SIZE_NAL_FIELD_MAX - 1 - i] = pBufHdr->pBuffer[pBufHdr->nOffset + j];
}
size = (unsigned int)(*((unsigned int *)(temp_size)));
readSize =( (size > pBufHdr->nAllocLen)?pBufHdr->nAllocLen:size);
// now read the data
bytes_read = fread(pBufHdr->pBuffer + pBufHdr->nOffset + nalSize, 1, readSize, inputBufferFile);
if (bytes_read != readSize)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR, "Failed to read frame\n");
}
if(readSize < size)
{
/* reseek to beginning of sequence header */
fseek(inputBufferFile, size-bytes_read, SEEK_CUR);
}
return bytes_read + nalSize;
}
static int Read_Buffer_From_FrameSize_File(OMX_BUFFERHEADERTYPE *pBufHdr)
{
unsigned int size = 0, readSize =0;
unsigned int readOffset = 0;
unsigned char* pBuf = pBufHdr->pBuffer + pBufHdr->nOffset;
// read the vop size bytes
readOffset = fread(&size, 1, 4, inputBufferFile);
if (readOffset != 4)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,"ReadBufferUsingVopSize failed to read vop size bytes\n");
return 0;
}
QTV_MSG_PRIO2(QTVDIAG_GENERAL, QTVDIAG_PRIO_HIGH,"vop Size=%d bytes_read=%d \n",size,readOffset);
readSize =( (size > pBufHdr->nAllocLen)?pBufHdr->nAllocLen:size);
// read the vop
readOffset = fread(pBuf, 1, readSize, inputBufferFile);
if (readOffset != readSize)
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL, QTVDIAG_PRIO_ERROR,"ReadBufferUsingVopSize failed to read vop %d bytes\n", size);
return 0;
}
if(readSize < size)
{
/* reseek to beginning of next frame */
fseek(inputBufferFile, size-readOffset, SEEK_CUR);
}
pBufHdr->nTimeStamp = timeStampLfile;
timeStampLfile += timestampInterval;;
return readOffset;
}
static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE *pBufHdr)
{
unsigned int readOffset = 0, size_struct_C = 0;
unsigned int startcode = 0;
pBufHdr->nFilledLen = 0;
pBufHdr->nFlags = 0;
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s \n", __FUNCTION__);
fread(&startcode, 4, 1, inputBufferFile);
/* read size of struct C as it need not be 4 always*/
fread(&size_struct_C, 1, 4, inputBufferFile);
/* reseek to beginning of sequence header */
fseek(inputBufferFile, -8, SEEK_CUR);
if ((startcode & 0xFF000000) == 0xC5000000)
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Read_Buffer_From_RCV_File_Seq_Layer size_struct_C: %d\n", size_struct_C);
readOffset = fread(pBufHdr->pBuffer, 1, VC1_SEQ_LAYER_SIZE_WITHOUT_STRUCTC + size_struct_C, inputBufferFile);
}
else if((startcode & 0xFF000000) == 0x85000000)
{
// .RCV V1 file
rcv_v1 = 1;
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Read_Buffer_From_RCV_File_Seq_Layer size_struct_C: %d\n", size_struct_C);
readOffset = fread(pBufHdr->pBuffer, 1, VC1_SEQ_LAYER_SIZE_V1_WITHOUT_STRUCTC + size_struct_C, inputBufferFile);
}
else
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error: Unknown VC1 clip format %x\n", startcode);
}
#if 0
{
int i=0;
printf("Read_Buffer_From_RCV_File, length %d readOffset %d\n", readOffset, readOffset);
for (i=0; i<36; i++)
{
printf("0x%.2x ", pBufHdr->pBuffer[i]);
if (i%16 == 15) {
printf("\n");
}
}
printf("\n");
}
#endif
return readOffset;
}
static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE *pBufHdr)
{
unsigned int readOffset = 0;
unsigned int len = 0;
unsigned int key = 0;
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s \n", __FUNCTION__);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Read_Buffer_From_RCV_File - nOffset %d\n", pBufHdr->nOffset);
if(rcv_v1)
{
/* for the case of RCV V1 format, the frame header is only of 4 bytes and has
only the frame size information */
readOffset = fread(&len, 1, 4, inputBufferFile);
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Read_Buffer_From_RCV_File - framesize %d %x\n", len, len);
}
else
{
/* for a regular RCV file, 3 bytes comprise the frame size and 1 byte for key*/
readOffset = fread(&len, 1, 3, inputBufferFile);
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Read_Buffer_From_RCV_File - framesize %d %x\n", len, len);
readOffset = fread(&key, 1, 1, inputBufferFile);
if ( (key & 0x80) == false)
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Read_Buffer_From_RCV_File - Non IDR frame key %x\n", key);
}
}
if(!rcv_v1)
{
/* There is timestamp field only for regular RCV format and not for RCV V1 format*/
readOffset = fread(&pBufHdr->nTimeStamp, 1, 4, inputBufferFile);
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Read_Buffer_From_RCV_File - timeStamp %d\n", pBufHdr->nTimeStamp);
}
if(len > pBufHdr->nAllocLen)
{
QTV_MSG_PRIO3(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"Error in sufficient buffer framesize %d, allocalen %d noffset %d\n",len,pBufHdr->nAllocLen, pBufHdr->nOffset);
readOffset = fread(pBufHdr->pBuffer+pBufHdr->nOffset, 1, pBufHdr->nAllocLen - pBufHdr->nOffset , inputBufferFile);
fseek(inputBufferFile, len - readOffset,SEEK_CUR);
return readOffset;
}
else
readOffset = fread(pBufHdr->pBuffer+pBufHdr->nOffset, 1, len, inputBufferFile);
if (readOffset != len)
{
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"EOS reach or Reading error %d, %s \n", readOffset, strerror( errno ));
return 0;
}
#if 0
{
int i=0;
printf("Read_Buffer_From_RCV_File, length %d readOffset %d\n", len, readOffset);
for (i=0; i<64; i++)
{
printf("0x%.2x ", pBufHdr->pBuffer[i]);
if (i%16 == 15) {
printf("\n");
}
}
printf("\n");
}
#endif
return readOffset;
}
static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE *pBufHdr)
{
static int timeStampLfile = 0;
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"Inside %s \n", __FUNCTION__);
unsigned int readOffset = 0;
int bytes_read = 0;
unsigned int code = 0;
pBufHdr->nFilledLen = 0;
do
{
//Start codes are always byte aligned.
bytes_read = fread(&pBufHdr->pBuffer[readOffset],1, 1,inputBufferFile);
if(!bytes_read)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"\n Bytes read Zero \n");
break;
}
code <<= 8;
code |= (0x000000FF & pBufHdr->pBuffer[readOffset]);
//VOP start code comparision
if (readOffset>3)
{
if (VC1_START_CODE == (code & 0xFFFFFF00))
{
//Seek backwards by 4
fseek(inputBufferFile, -4, SEEK_CUR);
readOffset-=3;
while(pBufHdr->pBuffer[readOffset-1] == 0)
readOffset--;
break;
}
}
readOffset++;
}while (1);
pBufHdr->nTimeStamp = timeStampLfile;
timeStampLfile += 100;
#if 0
{
int i=0;
printf("Read_Buffer_From_VC1_File, readOffset %d\n", readOffset);
for (i=0; i<64; i++)
{
printf("0x%.2x ", pBufHdr->pBuffer[i]);
if (i%16 == 15) {
printf("\n");
}
}
printf("\n");
}
#endif
return readOffset;
}
static int open_video_file ()
{
int error_code = 0;
char outputfilename[512];
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"Inside %s filename=%s\n", __FUNCTION__, in_filename);
inputBufferFile = fopen (in_filename, "rb");
if (inputBufferFile == NULL) {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Error - i/p file %s could NOT be opened\n",
in_filename);
error_code = -1;
}
else {
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"I/p file %s is opened \n", in_filename);
}
if (takeYuvLog) {
strncpy(outputfilename, "yuvframes.yuv", 14);
outputBufferFile = fopen (outputfilename, "ab");
if (outputBufferFile == NULL)
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"ERROR - o/p file %s could NOT be opened\n", outputfilename);
error_code = -1;
}
else
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,
"O/p file %s is opened \n", outputfilename);
}
}
return error_code;
}
void swap_byte(char *pByte, int nbyte)
{
int i=0;
for (i=0; i<nbyte/2; i++)
{
pByte[i] ^= pByte[nbyte-i-1];
pByte[nbyte-i-1] ^= pByte[i];
pByte[i] ^= pByte[nbyte-i-1];
}
}
void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr)
{
unsigned int addr = 0;
OMX_OTHER_EXTRADATATYPE *pExtraData = 0;
OMX_QCOM_EXTRADATA_FRAMEINFO *pExtraFrameInfo = 0;
OMX_QCOM_EXTRADATA_FRAMEDIMENSION *pExtraFrameDimension = 0;
OMX_QCOM_EXTRADATA_CODEC_DATA *pExtraCodecData = 0;
OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
unsigned int destx, desty,destW, destH;
struct use_egl_id *egl_info = NULL;
#ifdef _ANDROID_
MemoryHeapBase *vheap = NULL;
#endif
unsigned int end = (unsigned int)(pBufHdr->pBuffer + pBufHdr->nAllocLen);
struct mdp_blit_req *e;
union {
char dummy[sizeof(struct mdp_blit_req_list) +
sizeof(struct mdp_blit_req) * 1];
struct mdp_blit_req_list list;
} img;
if (fb_fd < 0)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Warning: /dev/fb0 is not opened!\n");
return;
}
if(is_use_egl_image) {
egl_info = (struct use_egl_id *)pBufHdr->pBuffer;
}
img.list.count = 1;
e = &img.list.req[0];
if(!is_use_egl_image) {
addr = (unsigned int)(pBufHdr->pBuffer + pBufHdr->nFilledLen);
// align to a 4 byte boundary
addr = (addr + 3) & (~3);
// read to the end of existing extra data sections
pExtraData = (OMX_OTHER_EXTRADATATYPE*)addr;
while (addr < end && pExtraData->eType != OMX_ExtraDataNone)
{
if (pExtraData->eType == OMX_ExtraDataFrameInfo)
{
pExtraFrameInfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)pExtraData->data;
}
if (pExtraData->eType == OMX_ExtraDataFrameDimension)
{
pExtraFrameDimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)pExtraData->data;
}
if (pExtraData->eType == OMX_ExtraDataH264)
{
pExtraCodecData = (OMX_QCOM_EXTRADATA_CODEC_DATA *)pExtraData->data;
}
addr += pExtraData->nSize;
pExtraData = (OMX_OTHER_EXTRADATATYPE*)addr;
}
if (pExtraData->eType == OMX_ExtraDataNone)
{
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"pExtraData->eType %d pExtraData->nSize %d\n",pExtraData->eType,pExtraData->nSize);
}
if (pExtraCodecData)
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"Extra Data Codec Data TimeStamp %d\n",pExtraCodecData->h264ExtraData.seiTimeStamp);
if (pExtraFrameDimension)
{
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Extra Data FrameDimension DecWidth %d DecHeight %d\n",pExtraFrameDimension->nDecWidth,pExtraFrameDimension->nDecHeight);
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"Extra Data FrameDimension CropWidth %d CropHeight %d\n",pExtraFrameDimension->nActualWidth,pExtraFrameDimension->nActualHeight);
}
}
if (pBufHdr->nOffset)
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"pBufHdr->nOffset = %d \n",pBufHdr->nOffset);
pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
pBufHdr->pPlatformPrivate)->entryList->entry;
#ifdef _ANDROID_
vheap = (MemoryHeapBase *)pPMEMInfo->pmem_fd;
#endif
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"DecWidth %d DecHeight %d\n",portFmt.format.video.nStride,portFmt.format.video.nSliceHeight);
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"DispWidth %d DispHeight %d\n",portFmt.format.video.nFrameWidth,portFmt.format.video.nFrameHeight);
if(pExtraFrameDimension)
{
e->src.width = pExtraFrameDimension->nDecWidth;
e->src.height = pExtraFrameDimension->nDecHeight;
}else{
e->src.width = portFmt.format.video.nStride;
e->src.height = portFmt.format.video.nSliceHeight;
}
e->src.format = MDP_Y_CBCR_H2V2;
if(is_use_egl_image) {
e->src.offset = egl_info->offset;
e->src.memory_id = egl_info->pmem_fd;
}
else {
e->src.offset = pPMEMInfo->offset;
#ifdef _ANDROID_
e->src.memory_id = vheap->getHeapID();
#else
e->src.memory_id = pPMEMInfo->pmem_fd;
#endif
}
QTV_MSG_PRIO2(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"pmemOffset %d pmemID %d\n",e->src.offset,e->src.memory_id);
e->dst.width = finfo.line_length/2;
e->dst.height = vinfo.yres;
e->dst.format = MDP_RGB_565;
e->dst.offset = 0;
e->dst.memory_id = fb_fd;
e->transp_mask = 0xffffffff;
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,
"Frame interlace type %d!\n", pExtraFrameInfo->interlaceType);
if(pExtraFrameInfo && pExtraFrameInfo->interlaceType != OMX_QCOM_InterlaceFrameProgressive)
{
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_HIGH,
"Intrelaced Frame!\n");
e->flags = MDP_DEINTERLACE;
}
else
e->flags = 0;
e->alpha = 0xff;
switch(displayWindow)
{
case 1: destx = 0;
desty = 0;
destW = vinfo.xres/2;
destH = vinfo.yres/2;
break;
case 2: destx = vinfo.xres/2;
desty = 0;
destW = vinfo.xres/2;
destH = vinfo.yres/2;
break;
case 3: destx = 0;
desty = vinfo.yres/2;
destW = vinfo.xres/2;
destH = vinfo.yres/2;
break;
case 4: destx = vinfo.xres/2;
desty = vinfo.yres/2;
destW = vinfo.xres/2;
destH = vinfo.yres/2;
break;
case 0:
default:
destx = 0;
desty = 0;
destW = finfo.line_length;
destH = vinfo.yres;
}
if(portFmt.format.video.nFrameWidth < destW)
{
if(pExtraFrameDimension)
destW=pExtraFrameDimension->nActualWidth;
else
destW = portFmt.format.video.nFrameWidth ;
}
if(portFmt.format.video.nFrameHeight < destH)
{
if(pExtraFrameDimension)
destH=pExtraFrameDimension->nActualHeight;
else
destH = portFmt.format.video.nFrameHeight;
}
e->dst_rect.x = destx;
e->dst_rect.y = desty;
e->dst_rect.w = destW;
e->dst_rect.h = destH;
//e->dst_rect.w = 800;
//e->dst_rect.h = 480;
e->src_rect.x = 0;
e->src_rect.y = 0;
if(pExtraFrameDimension)
{
e->src_rect.w = pExtraFrameDimension->nActualWidth;
e->src_rect.h = pExtraFrameDimension->nActualHeight;
}else{
e->src_rect.w = portFmt.format.video.nFrameWidth;
e->src_rect.h = portFmt.format.video.nFrameHeight;
}
//e->src_rect.w = portFmt.format.video.nStride;
//e->src_rect.h = portFmt.format.video.nSliceHeight;
if (ioctl(fb_fd, MSMFB_BLIT, &img)) {
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,"MSMFB_BLIT ioctl failed!\n");
return;
}
if (ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0)
{
QTV_MSG_PRIO1(QTVDIAG_GENERAL,QTVDIAG_PRIO_ERROR,
"FBIOPAN_DISPLAY failed! line=%d\n", __LINE__);
return;
}
QTV_MSG_PRIO(QTVDIAG_GENERAL,QTVDIAG_PRIO_MED,"render_fb complete!\n");
}