先说一下编码的例子好像找不到了,只提供一下解码的例子吧。淡疼的三星要是能以YUV420P为基本图像格式就好了,这样结合FFmpeg来开发,各种应用都比较方法。再设计一个RGB/YUV硬件转码单元,最好。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "../mfc/SsbSipMfcApi.h"
#include "../mfc/MfcConvert.h"
int test_dec_h264()
{
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("h264/hdr.h264", "rb");
int hdr_size = fread(virInBuf, 1, maxFrameSize, fp);
printf("init data: %d bytes \n", hdr_size);
fclose(fp);
/* 初始化 */
ret = SsbSipMfcDecInit(handle, H264_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 ++ < 100)
{
/* 打开输入数据:已经编码的mpeg4数据 */
char filename[128];
sprintf(filename, "h264/%08d.h264", 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);
#if 1
// 存储为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, "nv12t/ttt%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();
// 关闭
SsbSipMfcDecClose(handle);
return 0;
}