我想說不台的平台,如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; // 使用linearparam.IDRPeriod = 20; // 可以大於3嗎。param.SliceMode = 0;param.SliceArgument = 1;param.RandomIntraMBRefresh = 0; // ?// 不使用frame based rate controlparam.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;// 不使用自訂paddingparam.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;}