首页 > 代码库 > 嵌入式专题: S5PV210 - H264硬件解码(MFC)
嵌入式专题: S5PV210 - H264硬件解码(MFC)
先说一下编码的例子好像找不到了,只提供一下解码的例子吧。淡疼的三星要是能以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;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。