天天看點

ffmpeg h264解碼器提取

大家好,又見面了,我是你們的朋友全棧君。

ffmpeg包含了很多的音視訊解碼器,本文試圖通過對ffmpeg的簡單分析提取h264解碼器.

使用ffmpeg解碼可以參考ffmpeg源碼下的doc/examples/decoding_encoding.c

1.首先設定解碼器參數(

avcodec_find_decoder(CODEC_ID_H264)

将decode函數指針為

h264_decoder,

AVCodec ff_h264_decoder = {

.name = “h264”,

.type = AVMEDIA_TYPE_VIDEO,

.id = CODEC_ID_H264,

.priv_data_size = sizeof(H264Context),

.init = ff_h264_decode_init,

.close = ff_h264_decode_end,

.decode = decode_frame,

.capabilities = /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS,

.flush= flush_dpb,

.long_name = NULL_IF_CONFIG_SMALL(“H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10”),

.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),

.update_thread_context = ONLY_IF_THREADS_ENABLED(decode_update_thread_context),

.profiles = NULL_IF_CONFIG_SMALL(profiles),

.priv_class = &h264_class,};

2.調用avcodec_decode_video()

函數進行解碼

avcodec_decode_video通過調avctx->codec->decode函數來完成具體解碼器的調用

其中

avctx為

AVCodecContext類型,codec為AVCodec類型,decode為一個函數指針,

是以真正進行解碼的函數為h264.c中的

decode_frame

根據以上分析提取264解碼器:

extern AVCodec ff_h264_decoder;//在h264.c中定義

AVCodec *codec = &ff_h264_decoder;//

AVCodecContext *avctx= NULL;//AVCodecContext在AVCodec.c中定義

AVFrame *picture;

DSPContext dsp;

H264Context *h; //h264.h中定義

MpegEncContext *s //Mpegvideo.h中定義

void decode_init()

{

avcodec_init();

avctx= avcodec_alloc_context();

picture= avcodec_alloc_frame();

if(codec->capabilities&CODEC_CAP_TRUNCATED)

c->flags|= CODEC_FLAG_TRUNCATED;

if (avcodec_open(c, codec) < 0) {

fprintf(stderr, “could not open codec\n”);

exit(1);

}

//H264Context *h = c->priv_data; //這兩行為ff_h264_decode_init的頭兩行

//MpegEncContext *s = &h->s;

s->dsp.idct_permutation_type =1;

ff_h264_decode_init(&avctx)

dsputil_init(&dsp, avctx);

}

void decode(unsigned char* buf,int buf_size)

{

int size=buf_size;

unsigned char* inbuf_ptr=buf;

//tips for buf: set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams)

//#define INBUF_SIZE 4096

//#define FF_INPUT_BUFFER_PADDING_SIZE 16

//uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;

//memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);

//size = fread(inbuf, 1, INBUF_SIZE, fin);

//inbuf_ptr = inbuf;

int len=0,got_picture=0;

while (size> 0)

{

len = decode_frame(avctx, picture, &got_picture,inbuf_ptr, size);

if (len < 0)

{

fprintf(stderr, “Error while decoding frame %d\n”, frame);

exit(1);

}

if (got_picture)

{

printf(“saving frame %3d\n”, frame);

fflush(stdout);

//data

frame++;

}

size -= len;

inbuf_ptr += len;

}

len = avcodec_decode_video(c, picture, &got_picture,

inbuf_ptr, 0);

if (got_picture)

{

//

}

}

void decode_end()

{

avcodec_close(c);

av_free(c);

av_free(picture);

//int ff_h264_decode_end(avctx)

}

釋出者:全棧程式員棧長,轉載請注明出處:https://javaforall.cn/148844.html原文連結:https://javaforall.cn