大家好,又见面了,我是你们的朋友全栈君。
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 codecn”);
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 %dn”, frame);
exit(1);
}
if (got_picture)
{
printf(“saving frame =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