【FFmpeg】avcodec_receive_packet函数

目录

FFmpeg相关记录:

示例工程:
【FFmpeg】调用ffmpeg库实现264软编
【FFmpeg】调用ffmpeg库实现264软解
【FFmpeg】调用ffmpeg库进行RTMP推流和拉流
【FFmpeg】调用ffmpeg库进行SDL2解码后渲染

流程分析:
【FFmpeg】编码链路上主要函数的简单分析
【FFmpeg】解码链路上主要函数的简单分析

结构体分析:
【FFmpeg】AVCodec结构体
【FFmpeg】AVCodecContext结构体
【FFmpeg】AVStream结构体
【FFmpeg】AVFormatContext结构体
【FFmpeg】AVIOContext结构体
【FFmpeg】AVPacket结构体

函数分析:

【通用】
【FFmpeg】avcodec_find_encoder和avcodec_find_decoder
【FFmpeg】关键结构体的初始化和释放(AVFormatContext、AVIOContext等)
【FFmpeg】avcodec_open2函数
【FFmpeg】内存分配和释放(av_malloc、av_realloc等)

【推流】
【FFmpeg】avformat_open_input函数
【FFmpeg】avformat_find_stream_info函数
【FFmpeg】avformat_alloc_output_context2函数
【FFmpeg】avio_open2函数
【FFmpeg】avformat_write_header函数
【FFmpeg】av_write_frame函数

【编码】
【FFmpeg】avcodec_send_frame函数

【解码】
【FFmpeg】avcodec_send_packet函数
【FFmpeg】avcodec_receive_frame函数

1.avcodec_receive_packet

c 复制代码
/**
 * Read encoded data from the encoder.
 *
 * @param avctx codec context
 * @param avpkt This will be set to a reference-counted packet allocated by the
 *              encoder. Note that the function will always call
 *              av_packet_unref(avpkt) before doing anything else.
 * @retval 0               success
 * @retval AVERROR(EAGAIN) output is not available in the current state - user must
 *                         try to send input
 * @retval AVERROR_EOF     the encoder has been fully flushed, and there will be no
 *                         more output packets
 * @retval AVERROR(EINVAL) codec not opened, or it is a decoder
 * @retval "another negative error code" legitimate encoding errors
 */
// 从encoder当中读取已经编码的数据
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);

函数的定义位于libavcodec\encode.c中,如下所示,其中核心的函数是av_packet_move_ref,用于获取已经编码的pkt

c 复制代码
int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
{
    AVCodecInternal *avci = avctx->internal;
    int ret;
	// 减少avpkt的引用次数
    av_packet_unref(avpkt);

    if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec))
        return AVERROR(EINVAL);
	// buffer_pkt是编解码内部的数据缓冲区,用来存放压缩之后的数据
    if (avci->buffer_pkt->data || avci->buffer_pkt->side_data) {
    	// 将buffer_pkt的引用给到avpkt上,同时将buffer_pkt的信息清零
        av_packet_move_ref(avpkt, avci->buffer_pkt); 
    } else {
   		// 如果缓冲区没有数据,需要进行编码操作
        ret = encode_receive_packet_internal(avctx, avpkt);
        if (ret < 0)
            return ret;
    }

    return 0;
}

这里的av_packet_move_ref的作用是取出avci这个内部(internal)结构体中缓冲区的数据,并且赋值给到avpkt中,随后将avci->buffer_pkt中的信息设置为默认值。如果缓冲区中没有数据,则需要重新进行编码操作,使用encode_receive_packet_internal函数,在其他文中记录过,不再多记录

av_packet_move_ref的定义如下,先进行内容的拷贝,随后将src设置为初始值

c 复制代码
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
{
    *dst = *src;
    get_packet_defaults(src);
}

get_packet_defaults的定义如下,就是将AVPacket全部设置成为默认值

c 复制代码
static void get_packet_defaults(AVPacket *pkt)
{
    memset(pkt, 0, sizeof(*pkt));

    pkt->pts             = AV_NOPTS_VALUE;
    pkt->dts             = AV_NOPTS_VALUE;
    pkt->pos             = -1;
    pkt->time_base       = av_make_q(0, 1);
}

CSDN : https://blog.csdn.net/weixin_42877471
Github : https://github.com/DoFulangChen

相关推荐
wuqingshun31415925 分钟前
蓝桥杯 11. 最大距离
数据结构·c++·算法·职场和发展·蓝桥杯
Dovis(誓平步青云)32 分钟前
【数据结构】励志大厂版·初阶(复习+刷题):栈与队列
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
留在街角33 分钟前
<c++>使用detectMultiScale的时候出现opencv.dll冲突
开发语言·c++·opencv
机器视觉知识推荐、就业指导1 小时前
Qt/C++面试【速通笔记五】—子线程与GUI线程安全交互
c++·qt·面试·gui·子线程
大魔王(已黑化)1 小时前
LeetCode —— 94. 二叉树的中序遍历
数据结构·c++·算法·leetcode·职场和发展
南玖yy1 小时前
解锁 C++26 的未来:从语言标准演进到实战突破
开发语言·数据库·c++·人工智能·c++23·c++基础语法
六点半8882 小时前
【蓝桥杯】第十六届蓝桥杯C/C++大学B组个人反思总结
c语言·c++·算法·蓝桥杯
✿ ༺ ོIT技术༻2 小时前
笔试强训:Day3
c++·笔记·算法
让我们一起加油好吗4 小时前
【C++】类和对象(中)——默认成员函数详解(万字)
开发语言·c++·visualstudio·类和对象
fhqlongteng4 小时前
一种动态分配内存错误的解决办法
运维·服务器·网络·c++