解码比编码要省心一些,唯一让人操心的是,在初始化的时候要用编码器生成的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)
时间: 2024-10-12 11:51:31