解码比编码要省心一些,唯一让人操心的是,在初始化的时候要用编码器生成的head数据来初始化的。就是说,在编码的时候,是生成一个head数据,这个数据是用来在解码的时候用的。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "../mfc/SsbSipMfcApi.h"
#include "../mfc/MfcConvert.h"
#include "Bitmap.h"
#include "../mm/MMClock.h"
#include "../vout/Vout.h"
int test_dec_mpeg4()
{
Vout vo;
vo.Open(640,480, 640, 480);
SSBSIP_MFC_ERROR_CODE ret = MFC_RET_OK;
// 打开
unsigned int buf_type = CACHE;
void* handle = SsbSipMfcDecOpen();
if(handle == NULL)
{
printf("failed to open mfc device!\n");
return -1;
}
printf("== SsbSipMfcDecOpen OK \n");
int maxFrameSize = 256 * 1024;
/* 得到 输入缓冲区信息 */
void* virInBuf = NULL;
void* phyInBuf = NULL;
virInBuf = SsbSipMfcDecGetInBuf(handle, &phyInBuf, maxFrameSize);
printf("== SsbSipMfcDecGetInBuf OK \n");
printf("virInBuf=%08X, phyInBuf=%08X \n", virInBuf, phyInBuf);
/* 配置: 暂不需要设置 */
// int configValue = 2; // the number that you want to delay
// SsbSipMfcDecSetConfig(handle, MFC_DEC_SETCONF_DISPLAY_DELAY,
// &configValue);
/* 读取初始化数据到输入缓冲区,此数据在编码的时候生成 */
FILE* fp = fopen("a00.mpeg4", "rb");
int hdr_size = fread(virInBuf, 1, maxFrameSize, fp);
printf("init data: %d bytes \n", hdr_size);
fclose(fp);
/* 初始化 */
ret = SsbSipMfcDecInit(handle, MPEG4_DEC, hdr_size);
if(ret != MFC_RET_OK)
{
printf("failed to init mfc!\n");
return -1;
}
else
{
/* 检查是否初始化成功 */
SSBSIP_MFC_DEC_OUTPUT_INFO out;
SSBSIP_MFC_DEC_OUTBUF_STATUS status = SsbSipMfcDecGetOutBuf(handle, &out);
if(out.img_width <= 0 || out.img_height <= 0)
{
printf("bad image size, should init again!\n");
return -1;
}
}
/* 检查输出缓冲区 */
printf("== SsbSipMfcDecInit OK \n");
SSBSIP_MFC_DEC_OUTPUT_INFO out;
SSBSIP_MFC_DEC_OUTBUF_STATUS status;
status = SsbSipMfcDecGetOutBuf(handle, &out);
printf("output: status = %d , image(%dx%d), buf(%dx%d), crop(%d,%d,%d,%d) \n",
status,
out.img_width, out.img_height,
out.buf_width, out.buf_height,
out.crop_left_offset, out.crop_top_offset,
out.crop_right_offset, out.crop_bottom_offset);
printf("-------------------------------\n");
int count = 0;
while(count ++ < 2)
{
/* 打开输入数据:已经编码的mpeg4数据 */
char filename[128];
sprintf(filename, "a%02d.mpeg4", count);
printf(">>> input file: %s \n", filename);
FILE* fp = fopen(filename, "rb");
int inDataLen = fread(virInBuf, 1, maxFrameSize, fp);
fclose(fp);
/* 解码 */
ret = SsbSipMfcDecExe(handle, inDataLen);
if(ret != MFC_RET_OK)
{
printf("failed decoding (%d) \n", ret);
return -1;
}
/* 输出缓冲区 */
SSBSIP_MFC_DEC_OUTPUT_INFO out;
SSBSIP_MFC_DEC_OUTBUF_STATUS status;
status = SsbSipMfcDecGetOutBuf(handle, &out);
printf("<<< output: status = %d , image(%dx%d), buf(%dx%d), crop(%d,%d,%d,%d) \n",
status,
out.img_width, out.img_height,
out.buf_width, out.buf_height,
out.crop_left_offset, out.crop_top_offset,
out.crop_right_offset, out.crop_bottom_offset);
if(status == MFC_GETOUTBUF_DISPLAY_DECODING
|| status == MFC_GETOUTBUF_DISPLAY_ONLY)
{
printf("y_addr = %08X, cbcr_addr = %08X \n",
out.YVirAddr, out.CVirAddr);
//vo.DrawNV12T(out.YPhyAddr, out.CPhyAddr);
vo.DrawNV12T(out.YVirAddr, out.CVirAddr);
sleep(1);
#if 0
// 存储为NV12-T
if(1)
{
//vo.DrawNV12T(out.YPhyAddr, out.CPhyAddr);
int y_size = out.buf_width * out.buf_height;
int uv_size = y_size / 2;
char yuvname[128];
sprintf(yuvname, "t%02d.nv12t", count);
FILE* fp_y = fopen(yuvname, "wb");
fwrite(out.YVirAddr, 1, y_size, fp_y);
fwrite(out.CVirAddr, 1, uv_size, fp_y);
fclose(fp_y);
}
#endif
#if 0
// 存储为YUV420P
if(1)
{
// tile -> linear
int y_size = out.buf_width * out.buf_height;
int uv_size = y_size / 2;
unsigned char* y = new unsigned char[y_size];
unsigned char* uv = new unsigned char[uv_size];
printf("y buff: %08X, %d\n", y, y_size);
// tile_to_linenar_y((char*)out.YVirAddr, (char*)y, out.buf_width, out.buf_height);
Y_tile_to_linear_4x2(y, (unsigned char*)out.YVirAddr, out.buf_width, out.buf_height);
CbCr_tile_to_linear_4x2(uv, (unsigned char*)out.CVirAddr, out.buf_width, out.buf_height);
// tile_to_linear_64x32_4x2_neon(y, (unsigned char*)out.YVirAddr, out.buf_width, out.buf_height);
// tile_to_linear_64x32_4x2_uv_neon(uv, (unsigned char*)out.CVirAddr, out.buf_width, out.buf_height/2);
//nv_2_uv((char*)out.CVirAddr, (char*)uv , (char*)uv + y_size/4, out.buf_width, out.buf_height);
char yuvname[128];
sprintf(yuvname, "c%02d.yuv420", count);
FILE* fp_y = fopen(yuvname, "wb");
fwrite(y, 1, y_size, fp_y);
fwrite(uv, 1, uv_size, fp_y);
fclose(fp_y);
//printf("haha\n");
delete [] y;
delete [] uv;
}
#endif
#if 0
if(0)
{
// tile to rgb
int width = out.buf_width;
int height = out.buf_height;
Bitmap bmp;
bmp.Create(width, height, 24);
tile64x32_to_rgb24((unsigned char*)out.YVirAddr, (unsigned char*)out.CVirAddr,
bmp.m_Data,
width, height);
printf("write to bmp file \n");
char outname[128];
sprintf(outname, "%s.bmp", filename);
bmp.SaveToFile(outname);
}
#endif
}
}
getchar();
vo.Close();
// 关闭
SsbSipMfcDecClose(handle);
return 0;
}
嵌入式专题: S5PV210 - MPEG4解码(MFC),布布扣,bubuko.com
原文:http://blog.csdn.net/iamshaofa/article/details/37693371