大家好,又見面了,我是你們的朋友全棧君。
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