这里也直接给出代码:
h264dec.h:
#pragma once #include "tdll.h" #include "avcodec.h" #include "postprocess.h" //#include "EMVideoCodec.h" class h264dec /*: public IH264Decoder*/ { public: virtual bool InitH264Deocder(int width,int height); virtual bool H264Decode(unsigned char * inbuf, const int & inlen,unsigned char * outbuf,int & outlen); virtual void StopH264Decoder(); virtual void ReleaseConnection(); public: h264dec(void); virtual ~h264dec(void); private: Tdll *dll; bool LoadDllFun(); void (*avcodec_init)(void); void (*avcodec_register_all)(void); AVCodecContext* (*avcodec_alloc_context)(void); AVFrame* (*avcodec_alloc_frame)(void); AVCodec *(*avcodec_find_decoder)(enum CodecID id); int (*avcodec_decode_video)(AVCodecContext *avctx, AVFrame *picture,int *got_picture_ptr, uint8_t *buf, int buf_size); int (*avcodec_open)(AVCodecContext *avctx, AVCodec *codec); int (*avcodec_close)(AVCodecContext *avctx); void (*av_free)(void *ptr); bool InitPostproc(int w,int h); void ClosePostproc(); pp_context_t *(*pp_get_context)(int width, int height, int flags); void (*pp_free_context)(pp_context_t *ppContext); void (*pp_free_mode)(pp_mode_t *mode); pp_mode_t *(*pp_get_mode_by_name_and_quality)(char *name, int quality); void (*pp_postprocess)(uint8_t * src[3], int srcStride[3], uint8_t * dst[3], int dstStride[3], int horizontalSize, int verticalSize, QP_STORE_T *QP_store, int QP_stride, pp_mode_t *mode, pp_context_t *ppContext, int pict_type); private: AVCodec *pdec; AVCodecContext *pdecContext; AVFrame *pdecFrame; int m_width; int m_height; Tdll* prodll; pp_context_t *pp_context; pp_mode_t *pp_mode; };
#include "StdAfx.h" #include ".\h264dec.h" h264dec::h264dec(void) :dll(NULL) ,pdec(NULL) ,pdecContext(NULL) ,pdecFrame(NULL) ,pp_context(NULL) ,pp_mode(NULL) ,prodll(NULL) { } h264dec::~h264dec(void) { } bool h264dec::LoadDllFun() { dll=new Tdll(L"libavcodec.dll"); dll->loadFunction((void**)&avcodec_init,"avcodec_init"); dll->loadFunction((void**)&avcodec_register_all,"avcodec_register_all"); dll->loadFunction((void**)&avcodec_alloc_context,"avcodec_alloc_context"); dll->loadFunction((void**)&avcodec_alloc_frame,"avcodec_alloc_frame"); dll->loadFunction((void**)&avcodec_find_decoder,"avcodec_find_decoder"); dll->loadFunction((void**)&avcodec_open,"avcodec_open"); dll->loadFunction((void**)&avcodec_decode_video,"avcodec_decode_video"); dll->loadFunction((void**)&avcodec_close,"avcodec_close"); dll->loadFunction((void**)&av_free,"av_free"); if (!dll->ok) return false; prodll = new Tdll(L"postproc.dll"); prodll->loadFunction((void**)&pp_get_context,"pp_get_context"); prodll->loadFunction((void**)&pp_free_context,"pp_free_context"); prodll->loadFunction((void**)&pp_free_mode,"pp_free_mode"); prodll->loadFunction((void**)&pp_get_mode_by_name_and_quality,"pp_get_mode_by_name_and_quality"); prodll->loadFunction((void**)&pp_postprocess,"pp_postprocess"); if(!prodll->ok) return false; avcodec_init(); avcodec_register_all(); return true; } bool h264dec::InitH264Deocder(int width,int height) { if(!LoadDllFun()) return false; if(!InitPostproc(width,height)) return false; m_width=width; m_height=height; pdec = avcodec_find_decoder(CODEC_ID_H264); if (pdec == NULL ) return false; pdecContext = avcodec_alloc_context(); pdecFrame = avcodec_alloc_frame(); pdecContext->width = width; pdecContext->height = height; pdecContext->pix_fmt = PIX_FMT_YUV420P; /* open it */ if (avcodec_open(pdecContext, pdec) < 0) { return false; } return true; } bool h264dec::InitPostproc(int w,int h) { int i_flags = 0; i_flags |= PP_CPU_CAPS_MMX | PP_CPU_CAPS_MMX2 | PP_FORMAT_420; pp_context = pp_get_context( w, h, i_flags ); if(!pp_context) return false; pp_mode = pp_get_mode_by_name_and_quality( "default", 6 ); if(!pp_mode) return false; return true; } bool h264dec::H264Decode(unsigned char * inbuf, const int & inlen,unsigned char * outbuf,int & outlen) { int got_frame; BYTE* showImage[3]; int showheight[3],showLx[3]; int len; len=avcodec_decode_video(pdecContext, pdecFrame, &got_frame, inbuf, inlen); if(len < 0) return false; if(got_frame) { showImage[0]=outbuf; showImage[1]=showImage[0]+m_width*m_height; showImage[2]=showImage[1]+m_width*m_height/4; showLx[0]=m_width;showLx[1]=m_width>>1;showLx[2]=m_width>>1; showheight[0]=m_height;showheight[1]=m_height>>1;showheight[2]=m_height>>1; pp_postprocess(pdecFrame->data,pdecFrame->linesize,showImage,showLx,m_width,m_height,pdecFrame->qscale_table, pdecFrame->qstride,pp_mode,pp_context,pdecFrame->pict_type); //GetImage( pdecFrame->data, // showImage, // pdecFrame->linesize, // showLx, // showheight); outlen=m_width*m_height*3/2; } else { outlen = 0; } return true; } void h264dec::StopH264Decoder() { if (pdecContext != NULL) { avcodec_close(pdecContext); av_free( pdecContext ); pdecContext = NULL; if(pdecFrame){ av_free(pdecFrame); pdecFrame = NULL; } } if(dll){ delete dll; dll=0; } ClosePostproc(); } void h264dec::ClosePostproc() { if(pp_mode){ pp_free_mode( pp_mode ); pp_mode=0; } if(pp_context){ pp_free_context(pp_context); pp_context=0; } if(prodll){ delete prodll; prodll=0; } } void h264dec::ReleaseConnection() { delete this; }
#ifndef _TDLL_ #define _TDLL_ class Tdll { private: HMODULE hdll; void loadDll(const char *dllName); public: bool ok; Tdll(const TCHAR *dllName1) { hdll=LoadLibrary(dllName1); if (!hdll) { hdll=NULL; } ok=(hdll!=NULL); }; ~Tdll() { if (hdll) FreeLibrary(hdll); } void loadFunction(void **fnc,const char *name) { *fnc=GetProcAddress(hdll,name); ok&=(*fnc!=NULL); }; }; #endif
#include "stdafx.h" #include "h264dec.h" #include "postprocess.h" #define INBUF_SIZE 100 * 1024; static int FindStartCode (unsigned char *Buf, int zeros_in_startcode) { int info; int i; info = 1; for (i = 0; i < zeros_in_startcode; i++) { if(Buf[i] != 0) info = 0; } if(Buf[i] != 1) info = 0; return info; } static bool Check_StartCode(unsigned char *Buf, int pos) { int info3 = 0; info3 = FindStartCode(&Buf[pos-4], 3); return info3 == 1; } static int getNextNal(FILE* inpf, unsigned char* Buf) { int pos = 0; int StartCodeFound = 0; int info2 = 0; int info3 = 0; int nCount = 0; while(!feof(inpf) && ++nCount <= 4) { Buf[pos++]=fgetc(inpf); } if(!Check_StartCode(Buf, pos)) { return 0; } while(!feof(inpf) && (Buf[pos++]=fgetc(inpf))==0); while (!StartCodeFound) { if (feof (inpf)) { // return -1; return pos-1; } Buf[pos++] = fgetc (inpf); StartCodeFound = Check_StartCode(Buf, pos); } fseek (inpf, -4, SEEK_CUR); return pos - 4; } int main(int argc, char* argv[]) { if (argc != 5) { printf("please input: PP_Demo.exe filename1[input] Width Height filename2[output]\n"); } //params set unsigned short usWidth = atoi(argv[2]); unsigned short usHeight = atoi(argv[3]); //create dec&pp h264dec *pdec = new h264dec; if(!pdec->InitH264Deocder(usWidth, usHeight)) { return false; } unsigned char *p_In_Frame = new unsigned char[usWidth * usHeight * 3/2]; unsigned char *p_Out_Frame = new unsigned char[usWidth * usHeight * 3/2]; FILE* ifp = fopen(argv[1],"rb"); FILE* ofp = fopen(argv[4],"wb"); bool b_continue = true; int nReadUnit = usWidth * usHeight * 3/2; while(!feof(ifp)) { int nCount = getNextNal(ifp, p_In_Frame); if(nCount == 0) { continue; } unsigned char *ptr = p_In_Frame; int n_Outlen = 0; pdec->H264Decode(ptr, nCount, p_Out_Frame, n_Outlen); if(n_Outlen > 0) { fwrite(p_Out_Frame, 1, n_Outlen, ofp); } } //realse delete []p_In_Frame; delete []p_Out_Frame; pdec->StopH264Decoder(); pdec->ReleaseConnection(); fclose(ifp); fclose(ofp); return 0; }