/*
* Copyright 2004-2011 Freescale Semiconductor, Inc.
*
* Copyright (c) 2006, Chips & Media. All rights reserved.
*/
/*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vpu_test.h"
extern int quitflag;
extern int g_enc_is_on; //qiang_debug added
int vpu_v4l_performance_test;
static FILE *fpFrmStatusLogfile = NULL;
static FILE *fpErrMapLogfile = NULL;
static FILE *fpQpLogfile = NULL;
static FILE *fpSliceBndLogfile = NULL;
static FILE *fpMvLogfile = NULL;
static FILE *fpUserDataLogfile = NULL;
static int isInterlacedMPEG4 = 0;
#define FN_FRAME_BUFFER_STATUS "dec_frame_buf_status.log"
#define FN_ERR_MAP_DATA "dec_error_map.log"
#define FN_QP_DATA "dec_qp.log"
#define FN_SB_DATA "dec_slice_bnd.log"
#define FN_MV_DATA "dec_mv.log"
#define FN_USER_DATA "dec_user_data.log"
#ifdef COMBINED_VIDEO_SUPPORT
#define MAX_FRAME_WIDTH 720
#define MAX_FRAME_HEIGHT 576
#endif
void SaveFrameBufStat(u8 *frmStatusBuf, int size, int DecNum)
{
int i;
if (fpFrmStatusLogfile == NULL) {
fpFrmStatusLogfile = fopen(FN_FRAME_BUFFER_STATUS, "w+");
}
fprintf(fpFrmStatusLogfile, "FRAME [%1d]\n", DecNum);
for (i = 0; i < size; i++) {
fprintf(fpFrmStatusLogfile, "[%d] %d ", i*2, ((frmStatusBuf[i]>>4)&0x0F));
fprintf(fpFrmStatusLogfile, "[%d] %d ", (i*2)+1, (frmStatusBuf[i]&0x0F));
}
fprintf(fpFrmStatusLogfile, "\n");
fflush(fpFrmStatusLogfile);
}
void SaveMB_Para(u8 *mbParaBuf, int size, int DecNum)
{
int i;
if (DecNum == 1)
DecNum = DecNum;
if (fpErrMapLogfile == NULL)
fpErrMapLogfile = fopen(FN_ERR_MAP_DATA, "w+");
if (fpQpLogfile == NULL)
fpQpLogfile = fopen(FN_QP_DATA, "w+");
if (fpSliceBndLogfile == NULL)
fpSliceBndLogfile = fopen(FN_SB_DATA, "w+");
fprintf(fpQpLogfile, "FRAME [%1d]\n", DecNum);
fprintf(fpSliceBndLogfile, "FRAME [%1d]\n", DecNum);
fprintf(fpErrMapLogfile, "FRAME [%1d]\n", DecNum);
for (i = 0; i < size; i++) {
fprintf(fpQpLogfile, "MbAddr[%4d]: MbQs[%2d]\n", i, mbParaBuf[i]&0x3F);
fprintf(fpSliceBndLogfile, "MbAddr[%4d]: Slice Boundary Flag[%1d]\n", i, (mbParaBuf[i]>>6)&1);
fprintf(fpErrMapLogfile, "MbAddr[%4d]: ErrMap[%1d]\n", i, (mbParaBuf[i]>>7)&1);
}
fflush(fpQpLogfile);
fflush(fpSliceBndLogfile);
fflush(fpErrMapLogfile);
}
void SaveMvPara(u8 *mvParaBuf, int size, int mvNumPerMb, int mbNumX, int DecNum)
{
int i, j;
short mvX, mvY;
u8 *mvDatabuf;
if (fpMvLogfile == 0) {
fpMvLogfile = fopen(FN_MV_DATA, "w+");
}
fprintf(fpMvLogfile, "FRAME [%1d]\n", DecNum);
for (i = 0; i < size; i++) {
for (j = 0; j < mvNumPerMb; j++) {
mvDatabuf = (mvParaBuf + (i*mvNumPerMb + j)*4);
mvX = (short)((mvDatabuf[0]<<8) | (mvDatabuf[1]<<0));
mvY = (short)((mvDatabuf[2]<<8) | (mvDatabuf[3]<<0));
if (!(mvX & 0x8000)){
/* Intra MB */
mvX = 0;
mvY = 0;
if (j == 0 )
fprintf(fpMvLogfile, "MbAddr[%4d:For ]: Avail[0] Mv[%5d:%5d]\n", i, mvX, mvY);
if (j == 1)
fprintf(fpMvLogfile, "MbAddr[%4d:Back]: Avail[0] Mv[%5d:%5d]\n", i, mvX, mvY);
} else {
if(mvX & 0x2000) {/* Signed extension */
mvX = mvX | 0xC000;
} else {
mvX = mvX & 0x1FFF;
}
if(mvY & 0x2000) {
mvY = mvY | 0xC000;
} else {
mvY = mvY & 0x1FFF;
}
if (j == 0 )
fprintf(fpMvLogfile, "MbAddr[%4d:For ]: Avail[1] Mv[%5d:%5d]\n", i, mvX, mvY);
if (j == 1)
fprintf(fpMvLogfile, "MbAddr[%4d:Back]: Avail[1] Mv[%5d:%5d]\n", i, mvX, mvY);
}
}
}
fflush(fpMvLogfile);
}
void SaveUserData(u8 *userDataBuf) {
int i, UserDataType, UserDataSize, userDataNum, TotalSize;
u8 *tmpBuf;
if(fpUserDataLogfile == 0) {
fpUserDataLogfile = fopen(FN_USER_DATA, "w+");
}
tmpBuf = userDataBuf;
userDataNum = (short)((tmpBuf[0]<<8) | (tmpBuf[1]<<0));
TotalSize = (short)((tmpBuf[2]<<8) | (tmpBuf[3]<<0));
tmpBuf = userDataBuf + 8;
for(i=0; i<userDataNum; i++) {
UserDataType = (short)((tmpBuf[0]<<8) | (tmpBuf[1]<<0));
UserDataSize = (short)((tmpBuf[2]<<8) | (tmpBuf[3]<<0));
fprintf(fpUserDataLogfile, "\n[Idx Type Size] : [%4d %4d %4d]",i, UserDataType, UserDataSize);
tmpBuf += 8;
}
fprintf(fpUserDataLogfile, "\n");
tmpBuf = userDataBuf + USER_DATA_INFO_OFFSET;
for(i=0; i<TotalSize; i++) {
fprintf(fpUserDataLogfile, "%02x", tmpBuf[i]);
if ((i&7) == 7)
fprintf(fpUserDataLogfile, "\n");
}
fprintf(fpUserDataLogfile, "\n");
fflush(fpUserDataLogfile);
}
/*
* Fill the bitstream ring buffer
*/
int dec_fill_bsbuffer(DecHandle handle, struct cmd_line *cmd,
u32 bs_va_startaddr, u32 bs_va_endaddr,
u32 bs_pa_startaddr, int defaultsize,
int *eos, int *fill_end_bs)
{
RetCode ret;
PhysicalAddress pa_read_ptr, pa_write_ptr;
u32 target_addr, space;
int size;
int nread, room;
*eos = 0;
ret = vpu_DecGetBitstreamBuffer(handle, &pa_read_ptr, &pa_write_ptr,
&space);
if (ret != RETCODE_SUCCESS) {
err_msg("vpu_DecGetBitstreamBuffer failed\n");
return -1;
}
/* Decoder bitstream buffer is empty */
if (space <= 0)
return 0;
if (defaultsize > 0) {
if (space < defaultsize)
return 0;
size = defaultsize;
} else {
size = ((space >> 9) << 9);
}
if (size == 0)
return 0;
/* Fill the bitstream buffer */
target_addr = bs_va_startaddr + (pa_write_ptr - bs_pa_startaddr);
if ( (target_addr + size) > bs_va_endaddr) {
room = bs_va_endaddr - target_addr;
nread = vpu_read(cmd, (void *)target_addr, room);
if (nread <= 0) {
/* EOF or error */
if (nread < 0) {
if (nread == -EAGAIN)
return 0;
return -1;
}
*eos = 1;
} else {
/* unable to fill the requested size, so back off! */
if (nread != room)
goto update;
/* read the remaining */
space = nread;
nread = vpu_read(cmd, (void *)bs_va_startaddr,
(size - room));
if (nread <= 0) {
/* EOF or error */
if (nread < 0) {
if (nread == -EAGAIN)
return 0;
return -1;
}
*eos = 1;
}
nread += space;
}
} else {
nread = vpu_read(cmd, (void *)target_addr, size);
if (nread <= 0) {
/* EOF or error */
if (nread < 0) {
if (nread == -EAGAIN)
return 0;
return -1;
}
*eos = 1;
}
}
update:
if (*eos == 0) {
ret = vpu_DecUpdateBitstreamBuffer(handle, nread);
if (ret != RETCODE_SUCCESS) {
err_msg("vpu_DecUpdateBitstreamBuffer failed\n");
return -1;
}
*fill_end_bs = 0;
} else {
if (!*fill_end_bs) {
ret = vpu_DecUpdateBitstreamBuffer(handle,
STREAM_END_SIZE);
if (ret != RETCODE_SUCCESS) {
err_msg("vpu_DecUpdateBitstreamBuffer failed"
"\n");
return -1;
}
*fill_end_bs = 1;
}
}
return nread;
}
/*
* This function is to convert framebuffer from interleaved Cb/Cr mode
* to non-interleaved Cb/Cr mode.
*
* Note: This function does _NOT_ really store this framebuffer into file.
*/
static void
saveNV12ImageHelper(u8 *pYuv, struct decode *dec, u8 *buf)
{
int Y, Cb;
u8 *Y1, *Cb1, *Cr1;
int img_size;
int y, x;
u8 *tmp;
int height = dec->picheight;
int stride = dec->stride;
if (!pYuv || !buf) {
err_msg("pYuv or buf should not be NULL.\n");
return;
}
img_size = stride * height;
Y = (int)buf;
Cb = Y + img_size;
Y1 = pYuv;
Cb1 = Y1 + img_size;
Cr1 = Cb1 + (img_size >> 2);
memcpy(Y1, (u8 *)Y, img_size);
for (y = 0; y < (dec->picheight / 2); y++) {
tmp = (u8*)(Cb + dec->picwidth * y);
for (x = 0; x < dec->picwidth; x += 2) {
*Cb1++ = tmp[x];
*Cr1++ = tmp[x + 1];
}
}
}
/*
* This function is to store the framebuffer with Cropping size.
*
* Note: The output of picture width or height from VPU is always
* 4-bit aligned. For example, the Cropping information in one
* bit strea
评论0