您的位置:首页 > 编程语言

利用ffmpeg解码h264流的代码

2012-11-11 12:45 330 查看
利用ffmpeg解码h264流的代码
2012-07-14 10:30:57 我来说两句
收藏


我要投稿


这里也直接给出代码:

h264dec.h:

[cpp]

#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;

};

h264dec.cpp:

[cpp] view plaincopy

#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;

}

tdll.h:

[cpp]

#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

main.cpp:

[cpp]

#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;

作者:wchm_seu
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: