我想说不台的平台,如tiny210和x210,它们的头文件是有略微差别的。我这个是x210下的代码。但都需要注意的是NV12T与NV12的问题,默认要求输入的图片是NV12T,经过调整之后,可以允许用NV12。
即便如此,NV12格式的图片也不好拿到啊。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "../mfc/SsbSipMfcApi.h"
#include "../mfc/MfcConvert.h"
#include "../mm/MMClock.h"
int test_enc_mpeg4()
{
MMClock clock;
clock.Adjust(1000);
SSBSIP_MFC_ERROR_CODE ret = MFC_RET_OK;
// 打开
unsigned int buf_type = CACHE;
void* handle = SsbSipMfcEncOpen();
if(handle == NULL)
{
printf("failed to open mfc device!\n");
return -1;
}
printf("== SsbSipMfcDecOpen OK \n");
int img_width = 640;
int img_height = 480;
// 初始化
SSBSIP_MFC_ENC_MPEG4_PARAM param;
memset(¶m, 0, sizeof(param));
param.codecType = MPEG4_ENC;
param.SourceWidth = img_width;
param.SourceHeight = img_height;
param.FrameMap = NV12_LINEAR; // 使用linear
param.IDRPeriod = 20; // 可以大于3吗?
param.SliceMode = 0;
param.SliceArgument = 1;
param.RandomIntraMBRefresh = 0; // ?
// 不使用frame based rate control
param.EnableFRMRateControl = 1;
param.TimeIncreamentRes = 1000;
param.VopTimeIncreament = 40;
param.Bitrate = 4000000;
param.FrameQp = 1;
param.FrameQp_P = 1;
param.FrameQp_B = 1;
param.QSCodeMax = 45;
param.QSCodeMin = 20;
param.CBRPeriodRf = 2;
// 不使用自定义padding
param.PadControlOn = 0;
param.LumaPadVal = 0;
param.CbPadVal = 0;
param.CrPadVal = 0;
param.ProfileIDC = 66;
param.LevelIDC = 22;
param.NumberBFrames = 0;
param.DisableQpelME = 0;
if(SsbSipMfcEncInit(handle, ¶m) != MFC_RET_OK)
{
printf("failed to init encoder !\n");
return -1;
}
/* 得到输入缓冲区地址 */
SSBSIP_MFC_ENC_INPUT_INFO inbuf;
if(SsbSipMfcEncGetInBuf (handle, &inbuf) != MFC_RET_OK)
{
printf("failed to get in buf !\n");
return 0;
}
printf("in buf: Y (addr=%08X, size=%d), CbCr (addr=%08X, size=%d) \n"
, inbuf.YVirAddr, inbuf.YSize
, inbuf.CVirAddr, inbuf.CSize
);
/* 得到header */
SSBSIP_MFC_ENC_OUTPUT_INFO outbuf;
ret = SsbSipMfcEncGetOutBuf (handle, &outbuf);
if(ret != MFC_RET_OK)
{
printf("failed to get output (%d) \n", ret);
return -1;
}
printf("saving header: %d bytes \n", outbuf.headerSize);
if(1)
{
FILE* fp = fopen("a00.mpeg4", "wb");
fwrite(outbuf.StrmVirAddr, 1, outbuf.headerSize, fp);
fclose(fp);
}
int y_size = img_width * img_height;
int c_size = y_size / 2;
/* 读取图像 */
FILE* fp = fopen("k00.nv12", "rb");
int n1 = fread(inbuf.YVirAddr, 1, y_size, fp);
int n2 = fread(inbuf.CVirAddr, 1, c_size, fp);
printf("read bytes: n1=%d, n2=%d \n", n1, n2);
int count = 0;
while(count ++ < 3)
{
printf("... times: %d , now %d ...\n", count, (int) clock.PtsTime());
/* 编码 */
ret = SsbSipMfcEncExe(handle);
if(ret != MFC_RET_OK)
{
printf("failed encoding (%d) \n", ret);
return -1;
}
/* 输出结果 */
SSBSIP_MFC_ENC_OUTPUT_INFO outbuf;
ret = SsbSipMfcEncGetOutBuf (handle, &outbuf);
if(ret != MFC_RET_OK)
{
printf("failed to get output (%d) \n", ret);
return -1;
}
printf("output: frame type=%d, size=%d, header size=%d \n"
, outbuf.frameType
, outbuf.dataSize
, outbuf.headerSize);
/* 保存成文件*/
char filename[128];
sprintf(filename, "a%02d.mpeg4", count);
FILE* fp = fopen(filename, "wb");
fwrite(outbuf.StrmVirAddr, 1, outbuf.dataSize, fp);
fclose(fp);
}
SsbSipMfcEncClose(handle);
return 0;
}