首页 > 代码库 > 嵌入式专题: S5PV210 - MFC硬件解码
嵌入式专题: S5PV210 - MFC硬件解码
嵌入式就是瞎折腾。奉献一些过时的代码,让嵌入式的兄弟少折腾一些吧。
这一篇是怎么解码的,本篇用的MPEG2VIDEO解码。
头文件
#ifndef _HW_MPV2_DECODER#define _HW_MPV2_DECODERclass HwMpv2Decoder{public: HwMpv2Decoder(); ~HwMpv2Decoder(); int Open(unsigned int width, unsigned int height); void Close(); int Decode(int keyframe, void* data, int len, void** phyY, void** phyCbCr, bool save);private: int InitCodec(void* data, int len);private: void* m_pHandle; void* m_pVirInBuf; // 解码芯片的缓冲区 int m_nMaxFrameSize; // 最大的输入帧大小 bool m_bInitOK;public: char* pYuvPicture; int nYuvSize; int nImgWidth, nImgHeight; int nBufWidth, nBufHeight; //void* pPhyY, *pPhyC; // 初始化时得到的物理地址};#endif
cpp文件
#include <stdio.h>#include <string.h>#include "HwMpv2Decoder.h"#include "../mfc/SsbSipMfcApi.h"#include "../mfc/MfcConvert.h"#include "../osapi/osapi.h"HwMpv2Decoder::HwMpv2Decoder(){ m_pHandle = NULL;}HwMpv2Decoder::~HwMpv2Decoder(){ Close();}int HwMpv2Decoder::Open(unsigned int width, unsigned int height){ // 打开设备 m_pHandle = SsbSipMfcDecOpen(); if(m_pHandle == NULL) { gLogger.e("failed to open mfc device!\n"); return -1; } m_nMaxFrameSize = 1024 * 1024; // 获取缓冲区 void* phyInBuf = NULL; m_pVirInBuf = SsbSipMfcDecGetInBuf(m_pHandle, &phyInBuf, m_nMaxFrameSize); if(m_pVirInBuf == NULL) { gLogger.e("failed to get virtual buffer address!\n"); return -1; } // 初始化 unsigned char seqhdr[12] = { 0 ,0 ,1 ,0xB3 ,0x40 ,0x03 ,0x00 ,0x13 ,0xFF ,0xFF ,0xE0 ,0x88}; seqhdr[4] = width >> 4; seqhdr[5] = width << 4; seqhdr[5] += height >> 8; seqhdr[6] = height; if(InitCodec(seqhdr, sizeof(seqhdr)) < 0) { printf("Failed to init hardware codec !\n"); return -1; } // 未初化 m_bInitOK = false; printf("HW decoder init ok !\n"); return 0;}void HwMpv2Decoder::Close(){ if(m_pHandle) { // 关闭设备 SsbSipMfcDecClose(m_pHandle); m_pHandle = NULL; }}int HwMpv2Decoder::InitCodec(void* data, int len){ gLogger.d("try to init device ...\n"); memcpy (m_pVirInBuf, data, len); SSBSIP_MFC_ERROR_CODE ret = SsbSipMfcDecInit(m_pHandle, MPEG2_DEC, len); if(ret != MFC_RET_OK) { gLogger.e("failed to init mfc, try again!\n"); return -1; } else { // 检查是否初始化成功,检测分辨率 SSBSIP_MFC_DEC_OUTPUT_INFO out; SSBSIP_MFC_DEC_OUTBUF_STATUS status = SsbSipMfcDecGetOutBuf(m_pHandle, &out); if(out.img_width <= 0 || out.img_height <= 0) { gLogger.e("mfc bad image size, should init again!\n"); return -1; } // 保存图片尺寸及缓冲区尺寸 nImgWidth = out.img_width; nImgHeight = out.img_height; nBufWidth = out.buf_width; nBufHeight = out.buf_height; gLogger.i("image size: %dx%d \n", out.img_width, out.img_height); // 保存初始化时、输出缓存的物理地址, 外界可能要使用 // pPhyY = out.YPhyAddr;// pPhyC = out.CPhyAddr; } return 0;}int HwMpv2Decoder::Decode(int keyframe, void* data, int len, void** phyY, void** phyCbCr, bool save){// if(!m_bInitOK)// {// if(keyframe) m_bInitOK = true;// else return 0;// } memcpy(m_pVirInBuf, data, len); SSBSIP_MFC_ERROR_CODE ret = SsbSipMfcDecExe(m_pHandle, len); if(ret != MFC_RET_OK) { gLogger.e("mfc exe failed: %d \n", ret); return -1; } SSBSIP_MFC_DEC_OUTPUT_INFO out; SSBSIP_MFC_DEC_OUTBUF_STATUS status; status = SsbSipMfcDecGetOutBuf(m_pHandle, &out); if(status == MFC_GETOUTBUF_DISPLAY_DECODING || status == MFC_GETOUTBUF_DISPLAY_ONLY) { //printf("status: %d \n", status); // UV像素 *phyY = out.YPhyAddr; *phyCbCr = out.CPhyAddr;// *phyY = out.YVirAddr;// *phyCbCr = out.CVirAddr; if(save) { int y_size = 512 * 320; int uv_size = y_size / 2; unsigned char* y = new unsigned char[y_size]; unsigned char* uv = new unsigned char[uv_size]; 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); static int count = 0; char filename[64]; sprintf(filename, "NV12-T.%d", count++); FILE* fp = fopen(filename, "wb"); fwrite(y, 1, y_size, fp); fwrite(uv, 1, uv_size, fp); fclose(fp); printf("save to picture: %s \n", filename); //printf("haha\n"); delete [] y; delete [] uv; } return 1; } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。