FFmpeg完美入门【8】-FFmpeg架构之Decoder/Encoder模块

本文介绍了FFmpeg中编解码模块的核心概念与工作流程,包括AVCodec、AVCodecContext等关键数据结构的作用及初始化过程,同时解析了如何通过CodecID匹配对应的编解器。

http://it6655.com/2012/09/ffmpeg-8-decoderencoder-html

1概述

编解码模块主要包含的数据结构为:AVCodec、AVCodecContext每一个解码类型都会有自己的Codec静态对像,Codec的int priv_data_size记录该解码器上下文的结构大小,如MsrleContext。这些都是编译时确定的,程序运行时通过avcodec_register_all()将所有的解码器注册成一个链表。在av_open_input_stream()函数中调用AVInputFormat的read_header()中读文件头信息时,会读出数据流的CodecID,即确定了他的解码器Codec。

在main()函数中除了解析传入参数并初始化demuxer与muxer的parse_options( )函数以外,其他的功能都是在av_encode( )函数里完成的。在libavcodec\utils.c中有如下二个函数:AVCodec *avcodec_find_encoder(enum CodecID id)和AVCodec *avcodec_find_decoder(enum CodecID id)他们的功能就是根据传入的CodecID,找到匹配的encoder和decoder。在av_encode( )函数的开头,首先初始化各个AVInputStream和AVOutputStream,然后分别调用上述二个函数,并将匹配上的encoder与decoder分别保存在:

AVInputStream->AVStream *st->AVCodecContext *codec->struct AVCodec *codec

与AVOutputStream->AVStream *st->AVCodecContext *codec->struct AVCodec *codec变量。

2 相关数据结构的初始化

AVCodecContext结构 AVCodecContext保存AVCodec指针和与codec相关数据,如video的width、height,audio的sample rate等。 AVCodecContext中的codec_type,codec_id二个变量对于encoder/decoder的匹配来说,最为重要。

enum CodecType codec_type; /* see CODEC_TYPE_xxx */

enum CodecID codec_id; /* see CODEC_ID_xxx */

如上所示,codec_type保存的是CODEC_TYPE_VIDEO,CODEC_TYPE_AUDIO等媒体类型,codec_id保存的是CODEC_ID_FLV1,CODEC_ID_VP6F等编码方式。 以支持flv格式为例,在前述的av_open_input_file(…… ) 函数中,匹配到正确的AVInputFormat demuxer后,通过av_open_input_stream( )函数中调用AVInputFormat的read_header接口来执行flvdec.c中的flv_read_header( )函数。flv_read_header( )函数内,根据文件头中的数据,创建相应的视频或音频AVStream,并设置AVStream中AVCodecContext的正确的codec_type值。codec_id值是在解码过程。flv_read_packet( )函数执行时根据每一个packet头中的数据来设置的。 以avidec为例有如下初始化,我们主要知道的就是code_id和code_type 该字段关联具体的解码器,和解码类型(音视频或subtitle)

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if  (st - >codec - >stream_codec_tag  == AV_RL32 ( "Axan" ) ) 
{ 
st - >codec - >codec_id  = CODEC_ID_XAN_DPCM ; 
st - >codec - >codec_tag  =  0 ; 
} 
if  (amv_file_format ) 
{ 
st - >codec - >codec_id  = CODEC_ID_ADPCM_IMA_AMV ; ast - >dshow_block_align  =  0 ; 
} 
break ; 
case AVMEDIA_TYPE_SUBTITLE : 
st - >codec - >codec_type  = AVMEDIA_TYPE_SUBTITLE ; 
st - >request_probe =  1 ; 
break ; 
default : 
st - >codec - >codec_type  = AVMEDIA_TYPE_DATA ; 
st - >codec - >codec_id = CODEC_ID_NONE ; 
st - >codec - >codec_tag =  0 ; 
avio_skip (pb, size ) ;

./configure --prefix=~/ffmpeg-build/output/arm64-v8a --target-os=android --arch=arm64 --cpu=armv8-a --cc=/home/lzh/android-ndk/android-ndk-r27d/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android35-clang --cxx=/home/lzh/android-ndk/android-ndk-r27d/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android35-clang++ --ld=/home/lzh/android-ndk/android-ndk-r27d/toolchains/llvm/prebuilt/linux-x86_64/bin/ld.lld --ar=/home/lzh/android-ndk/android-ndk-r27d/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar --ranlib=/home/lzh/android-ndk/android-ndk-r27d/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib --strip=/home/lzh/android-ndk/android-ndk-r27d/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip --nm=/home/lzh/android-ndk/android-ndk-r27d/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-nm --disable-static --enable-shared --disable-all --enable-avcodec --enable-avformat --enable-avutil --enable-swscale --enable-swresample --enable-decoder=h264 --enable-encoder=h264 --enable-muxer=mp4 --enable-demuxer=mp4 --disable-doc --disable-ffplay --disable-ffprobe --disable-symver --disable-programs --disable-debug --enable-small --enable-cross-compile --sysroot=/home/lzh/android-ndk/android-ndk-r27d/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags="-Os -fPIC -DANDROID -march=armv8-a -DHAVE_CBRT=1 -DHAVE_CBRTF=1 -DHAVE_COPYSIGN=1 -DHAVE_ERF=1 -DHAVE_HYPOT=1 -DHAVE_RINT=1 -DHAVE_LRINT=1 -DHAVE_LRINTF=1 -DHAVE_ROUND=1 -DHAVE_ROUNDF=1 -DHAVE_TRUNC=1 -DHAVE_TRUNCF=1 -DHAVE_ISNAN=1 -DHAVE_ISFINITE=1 -Uisnan -Uisfinite" --extra-ldflags="-L/home/lzh/android-ndk/android-ndk-r27d/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/35"上述config有什么问题
最新发布
12-20
ffmpeg version 5.1 Copyright (c) 2000-2022 the FFmpeg developers built with gcc 7.5.0 (Linaro GCC 7.5-2019.12) configuration: --prefix=/home/wxy/work/ffmpeg/ffmpeg-install-arm --cross-prefix=aarch64-linux-gnu- --arch=aarch64 --target-os=linux --enable-cross-compile --enable-gpl --enable-version3 --enable-nonfree --enable-libass --enable-libfreetype --enable-libx264 --enable-libfdk-aac --enable-libmp3lame --enable-libopus --enable-encoder='libx264,libfdk_aac,mp3lame,opus' --enable-decoder='h264,hevc,aac,mp3,opus' --enable-parser='h264,hevc,aac' --enable-demuxer='rtsp,rtmp,hls,mov,mp4,mpegts,flv' --enable-muxer='rtsp,rtmp,hls,mp4,mpegts,flv' --enable-protocol='file,rtmp,rtsp,rtp,tcp,udp,http,https' --enable-filter='drawtext,subtitles,scale' --extra-cflags=-I/home/wxy/work/ffmpeg/ffmpeg-install-arm/include --extra-ldflags='-L/home/wxy/work/ffmpeg/ffmpeg-install-arm/lib -static' --pkg-config=pkg-config --pkg-config-flags=--static --disable-shared --enable-static --disable-debug --disable-doc --disable-vulkan libavutil 57. 28.100 / 57. 28.100 libavcodec 59. 37.100 / 59. 37.100 libavformat 59. 27.100 / 59. 27.100 libavdevice 59. 7.100 / 59. 7.100 libavfilter 8. 44.100 / 8. 44.100 libswscale 6. 7.100 / 6. 7.100 libswresample 4. 7.100 / 4. 7.100 libpostproc 56. 6.100 / 56. 6.100 Devices: D. = Demuxing supported .E = Muxing supported -- DE fbdev Linux framebuffer D lavfi Libavfilter virtual input device DE oss OSS (Open Sound System) playback DE video4linux2,v4l2 Video4Linux2 output device 所以支持hdmi rx么
12-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值