ffmpeg库进行解码
代码
1 | /* |
【运行结果】
(一)
1 | auto codec = avcodec_find_decoder(codec_id); |
【作用】:这行代码的作用是通过给定的编解码器 ID 来查找并返回一个指向相应解码器的指针。它是 FFmpeg 中用于初始化解码操作的第一步。
参数 codec_id
:
codec_id
是一个枚举类型AVCodecID
,用于标识你想要使用的具体编解码器。例如,AV_CODEC_ID_H264
是 H.264 解码器的标识符。- 在这段代码中,
codec_id
是通过提前定义或通过某种方式传递进来的,代表需要使用的解码器类型。
返回值 codec
:
avcodec_find_decoder(codec_id)
返回一个const AVCodec*
类型的指针,指向找到的解码器(AVCodec
)结构体。- 如果成功找到解码器,返回一个有效的指针;如果没有找到对应的解码器,返回
NULL
。
1 | auto c = avcodec_alloc_context3(codec); |
【作用】:这行代码的作用是为指定的编解码器(编码器或解码器)分配并初始化一个编解码器上下文(AVCodecContext
)。这个上下文将包含编解码操作所需的所有配置信息和状态。
参数 codec
:
codec
是一个指向AVCodec
结构体的指针,表示你将要使用的具体编解码器(如 H.264、H.265 编解码器)。- 通过
avcodec_find_decoder()
或avcodec_find_encoder()
找到的AVCodec
指针会作为参数传递给avcodec_alloc_context3()
。 - 如果
codec
参数为NULL
,则函数会创建一个通用的AVCodecContext
,稍后可以通过其他方式设置编码器或解码器。
返回值 c
:
avcodec_alloc_context3()
返回一个指向AVCodecContext
结构体的指针,即c
。- 这个返回的
AVCodecContext
是新分配的,并初始化为默认值的上下文,它可以在后续操作中进行配置和使用。
1 | avcodec_open2(c, NULL, NULL); |
【作用】:用于打开一个编解码器(编码器或解码器),并将其与指定的编解码器上下文(AVCodecContext
)关联起来,使其准备好进行编码或解码操作。
参数解释
AVCodecContext *avctx
:- 这是一个指向
AVCodecContext
的指针,表示编解码器的上下文。上下文包含了编解码器运行所需的所有配置信息,例如比特率、分辨率、帧率等。 - 在调用
avcodec_open2
之前,AVCodecContext
通常已经通过avcodec_alloc_context3()
函数分配并初始化。
- 这是一个指向
const AVCodec *codec
:- 这是一个指向
AVCodec
的指针,表示要使用的具体编解码器(如 H.264、H.265 等)。 - 在这段代码中,
codec
参数被传递为NULL
,表示使用上下文avctx
中已经设置的编解码器。这意味着AVCodecContext
必须在调用之前已经正确设置了编解码器。
- 这是一个指向
AVDictionary **options
:- 这是一个指向
AVDictionary
的指针,用于传递给编解码器的额外选项,可以设置一些特殊的编码或解码参数。 - 在这段代码中,
options
被传递为NULL
,表示不传递任何额外选项。
- 这是一个指向
返回值
int
函数的返回值类型为int
- 如果返回值为
0
,表示编解码器成功打开并准备好进行操作。- 如果返回负值,则表示出现错误。具体错误原因可以通过返回的错误代码进行判断。
(二)
1 | auto parser = av_parser_init(codec_id); |
【作用】:
-
使用
av_parser_init(codec_id)
初始化一个解析器,用于解析特定编码格式的数据流。解析器的类型由codec_id
决定,如AV_CODEC_ID_H264
对应 H.264 格式。 -
初始化完成后,
parser
可以与其他函数配合使用,比如av_parser_parse2()
,来处理输入的编码数据流,并将其分割成一个个完整的帧或其他数据包。
参数 codec_id
:
codec_id
是一个AVCodecID
枚举值,用于标识你希望解析的具体编解码器类型(如 H.264、H.265 等)。- 这个参数告诉解析器它即将处理的是哪种格式的数据流,从而选择适当的解析方式。
返回值 parser
:
av_parser_init(codec_id)
返回一个指向AVCodecParserContext
的指针,即parser
。- 如果初始化成功,
parser
是一个有效的指针,表示解析器已经准备好使用。如果初始化失败,返回值为NULL
。
AVCodecParserContext
结构体:
AVCodecParserContext
是 FFmpeg 中用于解析原始数据流的结构体。- 它负责将连续的字节流解析成独立的帧或包,供解码器进一步处理。这个过程对于处理实时流媒体或分割数据包非常重要。
(三)
1 | // 【注】data数据为unsigned char,data_size数据为int |
【作用】:使用 FFmpeg 的解析器 (parser
) 对原始的编码数据流(如 H.264 数据)进行解析,并从中提取出一帧或多个帧的数据包。这个函数会处理输入的数据,并将解析出的帧数据存储在 AVPacket
结构中,以便后续的解码使用。
参数解释
AVCodecParserContext *s(parser)
:- 这是解析器上下文,
parser
是通过av_parser_init()
初始化的。它持有解析器的状态信息,并在多次调用过程中保持。
- 这是解析器上下文,
AVCodecContext *avctx (c)
:- 这是编解码器上下文,包含了解析器关联的编解码器信息(如 H.264 解码器)。这个上下文用于配置和管理解码器的状态和参数。
uint8_t poutbuf(&pkt->data)
和int poutbuf_size (&pkt->size)
:- 这些是输出参数,用于存储解析出的帧数据。
poutbuf
指向数据输出缓冲区的指针,poutbuf_size
是该缓冲区的大小。 pkt->data
和pkt->size
分别存储了解析后的一帧或部分帧的数据和大小。
- 这些是输出参数,用于存储解析出的帧数据。
const uint8_t *buf (data)
和int buf_size (data_size)
:- 这些是输入参数,指向输入数据缓冲区(具体指向输入数据缓冲区的起始位置,如从文件或网络流中读取的数据)及其大小。
data
是指向数据缓冲区的指针,data_size
是该缓冲区的大小。
- 这些是输入参数,指向输入数据缓冲区(具体指向输入数据缓冲区的起始位置,如从文件或网络流中读取的数据)及其大小。
int64_t pts (AV_NOPTS_VALUE), int64_t dts (AV_NOPTS_VALUE), int64_t pos (0)
:- 这些是时间戳和位置信息,通常用于解码过程中同步音视频流。这里传入
AV_NOPTS_VALUE
和0
表示没有特定的时间戳或位置需要处理。
- 这些是时间戳和位置信息,通常用于解码过程中同步音视频流。这里传入
返回值 ret
- 函数返回值
ret
表示处理的数据量(以字节为单位)。ret
值告诉你在当前调用中解析了多少字节的数据。 - 如果
ret
为负值,则表示解析过程中出现了错误。
(四)
解码后的操作
调用这个函数ret = avcodec_receive_frame(c, frame);
意味着将一帧的数据通过函数处理后,传递给了frame
这个参数,此时的frame
就有这一帧的所有信息
比如:format
,height
,width
等
之后就可以通过XSDL进行窗口初始化,以及Draw()
函数的处理,之后调用XVideoView中的DrawFrame()
函数将这一帧数据显示在窗口上