【FFmpeg】avcodec_receive_frame函数

目录

  • 1.avcodec_receive_frame
    • 1.1 返回解码帧(ff_decode_receive_frame)
    • 1.2 返回重建帧(ff_encode_receive_frame)
  • 2.小结

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函数

1.avcodec_receive_frame

函数的主要功能是从解码器或编码器返回解码后的输出数据(当使用AV_CODEC_FLAG_RECON_FRAME标志时)

/*** Return decoded output data from a decoder or encoder (when the* @ref AV_CODEC_FLAG_RECON_FRAME flag is used).** @param avctx codec context* @param frame This will be set to a reference-counted video or audio*              frame (depending on the decoder type) allocated by the*              codec. Note that the function will always call*              av_frame_unref(frame) before doing anything else.** @retval 0                success, a frame was returned* @retval AVERROR(EAGAIN)  output is not available in this state - user must*                          try to send new input* @retval AVERROR_EOF      the codec has been fully flushed, and there will be*                          no more output frames* @retval AVERROR(EINVAL)  codec not opened, or it is an encoder without the*                          @ref AV_CODEC_FLAG_RECON_FRAME flag enabled* @retval "other negative error code" legitimate decoding errors*/
int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{av_frame_unref(frame);// 1.如果是解码器,返回decoded frame(一般情况)if (av_codec_is_decoder(avctx->codec))return ff_decode_receive_frame(avctx, frame);// 2.如果是编码器,返回重建帧return ff_encode_receive_frame(avctx, frame);
}

1.1 返回解码帧(ff_decode_receive_frame)

函数的主要功能是返回解码的帧,定义位于libavcodec\avcodec.c中。如果代码需要从已编码的缓冲区中取出数据,会调用这个函数。这个函数的主要流程是检查缓冲区是否有数据,如果有则直接取出,否则尝试进行解码,随后会进行一些其他的检查和处理

/*** avcodec_receive_frame() implementation for decoders.*/
int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{AVCodecInternal *avci = avctx->internal;int ret;if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))return AVERROR(EINVAL);// 1.如果缓冲区有数据,则直接取出if (avci->buffer_frame->buf[0]) {av_frame_move_ref(frame, avci->buffer_frame);} else {// 2.如果缓冲区没有数据,尝试进行解码ret = decode_receive_frame_internal(avctx, frame);if (ret < 0)return ret;}// 3.确保返回给调用者的帧是有效的// 主要是检查frame的format, width, height这些信息ret = frame_validate(avctx, frame);if (ret < 0)goto fail;if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {// Video decode only// 4.某些视频编解码器支持裁剪,这意味着只有被解码帧的子矩形用于显示, 这个选项控制libavcodec如何处理裁剪ret = apply_cropping(avctx, frame);if (ret < 0)goto fail;}avctx->frame_num++;#if FF_API_DROPCHANGED// AV_CODEC_FLAG_DROPCHANGED表示不要输出与流中第一个解码帧参数不同的帧if (avctx->flags & AV_CODEC_FLAG_DROPCHANGED) {if (avctx->frame_num == 1) {avci->initial_format = frame->format;switch(avctx->codec_type) {case AVMEDIA_TYPE_VIDEO:avci->initial_width  = frame->width;avci->initial_height = frame->height;break;case AVMEDIA_TYPE_AUDIO:avci->initial_sample_rate = frame->sample_rate ? frame->sample_rate :avctx->sample_rate;ret = av_channel_layout_copy(&avci->initial_ch_layout, &frame->ch_layout);if (ret < 0)goto fail;break;}}if (avctx->frame_num > 1) {int changed = avci->initial_format != frame->format;switch(avctx->codec_type) {case AVMEDIA_TYPE_VIDEO:changed |= avci->initial_width  != frame->width ||avci->initial_height != frame->height;break;case AVMEDIA_TYPE_AUDIO:changed |= avci->initial_sample_rate    != frame->sample_rate ||avci->initial_sample_rate    != avctx->sample_rate ||av_channel_layout_compare(&avci->initial_ch_layout, &frame->ch_layout);break;}if (changed) {avci->changed_frames_dropped++;av_log(avctx, AV_LOG_INFO, "dropped changed frame #%"PRId64" pts %"PRId64" drop count: %d \n",avctx->frame_num, frame->pts,avci->changed_frames_dropped);ret = AVERROR_INPUT_CHANGED;goto fail;}}}
#endifreturn 0;
fail:av_frame_unref(frame);return ret;
}

1.2 返回重建帧(ff_encode_receive_frame)

如果不是decoder,会进入到下面函数,去调重建帧

/*** avcodec_receive_frame() implementation for encoders.*/
int ff_encode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{AVCodecInternal *avci = avctx->internal;// 不存在重建帧,报错if (!avci->recon_frame)return AVERROR(EINVAL);if (!avci->recon_frame->buf[0])return avci->draining_done ? AVERROR_EOF : AVERROR(EAGAIN);// 返回重建帧av_frame_move_ref(frame, avci->recon_frame);return 0;
}

2.小结

avcodec_receive_frame函数比较简单,可以概述为从已编码的缓冲区buffer中将frame取出,使用的函数是av_frame_move_ref,这个在其他文中记录过,不再记录

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/874861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3.0有什么更新——前端面试

1、监测机制改变 带来基于代理proxy的observer实现&#xff0c;提供全语言覆盖的反应性跟踪 消除 Vue2中 基于Object.defineProperty的实现 所存在的许多限制 2、只能监测属性&#xff0c;不能监测对象 检测属性的 添加和删除 检测 数组索引和长度的变更 支持 Map、Set …

nginx 如何做针对 ip 的限流

限流策略的背景&#xff1a; 限流可以在单体应用或分布式应用中实现。可以使用API网关如Zuul、Kong等实现限流&#xff0c;避免在业务应用中实现限流逻辑。 使用Nginx进行限流的优势&#xff1a; Nginx或openResty可以配置限流&#xff0c;无需修改应用代码。通过Nginx配置实现…

阿里云图片文件上传

一,官网地址 https://help.aliyun.com/document_detail/84781.html一切依据于官网 二,导入依赖 <dependencies><!-- 阿里云oss依赖 --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId>&l…

redis原理之底层数据结构-跳表

1.什么是跳表 1.1 链表及其不足 链表是在程序设计中最常见的数据结构之一&#xff0c;它通过指针将多个链表节点连接起来&#xff0c;这样就可以将逻辑上同一类的数据存储到不连续的内存空间上。链表结构如下&#xff1a; 但是链表有一个问题&#xff0c;就是当链表需要查询一…

Windows系统网络流量监控与限制攻略

在现代互联网生活中&#xff0c;网络宽带流量管理变得越来越重要。特别是在家庭或小型办公环境中&#xff0c;有限的宽带流量需要被合理分配和有效利用。Windows系统提供了一些内置的工具和方法&#xff0c;可以帮助我们监控和限制电脑的网络宽带流量。 一、监控网络宽带流量 …

3.1 FreeRTOS详细移植步骤(自己的实操)

[TOC](3.1 FreeRTOS详细移植步骤(自己的实操)) 自己使用阿波罗F767的内存管理实验和定时器实验&#xff0c;进行复刻。 FreeRTOS源码版本是FreeRTOS 202212.01。官网和Github都有下载。 按照STM32F767FreeRTOS开发手册V1.1进行移植复刻。 注:这个开发手册不是开发指南。跟视频里…

关于Qt部署CMake导致“Failed to set working directory to”的问题

2024年7月23日补充&#xff1a;该目录过深的情况只在Win10上有发现&#xff0c;Win11则没有问题&#xff0c;且Win11可以在DevHome中设置LongPath。 --------------------------------------------------------------------------------------------------------------- 使用qt…

ADetailer模型+Stable Diffusion的inpainting功能是如何对遮罩区域进行修复生成的ADetailer

模型选则&#xff1a; face_yolov8n.pt 和 face_yolov8s.pt&#xff1a; 用途&#xff1a;用于人脸检测。特点&#xff1a;YOLOv8n 是轻量级版本&#xff0c;适合资源有限的设备&#xff1b;YOLOv8s 是标准版本&#xff0c;检测精度更高。 hand_yolov8n.pt&#xff1a; 用途&am…

Spark_Oracle_II_Spark高效处理Oracle时间数据:通过JDBC桥接大数据与数据库的分析之旅

接前文背景&#xff0c; 当需要从关系型数据库&#xff08;如Oracle&#xff09;中读取数据时&#xff0c;Spark提供了JDBC连接功能&#xff0c;允许我们轻松地将数据从Oracle等数据库导入到Spark DataFrame中。然而&#xff0c;在处理时间字段时&#xff0c;可能会遇到一些挑战…

分布式Apollo配置中心搭建实战

文章目录 环境要求第一步、软件下载第二步、创建数据库参考文档 最近新项目启动&#xff0c;采用Apollo作为分布式的配置中心&#xff0c;在本地搭建huanj 实现原理图如下所示。 环境要求 Java版本要求&#xff1a;JDK1.8 MySql版本要求&#xff1a;5.6.5 Apollo版本要求&…

第八讲:Sysmac Studio控制器设置

控制器设置 一、控制器设定-操作设置 1、启动模式(运行模式/编程模式) 控制器上电后,希望程序运行还是不运行。如果说希望程序运行,那么就选择运行模式。如果说希望上电后程序不运行就选择编程模式。 通常情况下选运行模式可能会比较多一些。 2、SD内存卡设置 当控制…

银河麒麟(arm64)环境下通过docker安装postgis3,并实现数据整体迁移

银河麒麟(arm64)环境下通过docker安装postgis3,并实现数据整体迁移 硬件配置:麒麟9006C 系统环境:银河麒麟桌面版v10 sp1 数据库:postgresql11+postgis3.0 具体的步骤参考https://blog.csdn.net/qq_34817440/article/details/103914574 -----主要操作-----------------…

QSqlTableModel操作数据库单表使用总结

本文记录使用QSqlTableModel等组件实现单表的数据库操作。 QSqlTableModel是一个模型类&#xff0c;它的实例可以作为一个数据表的模型。使用QSqlTableModel模型和QTableView组件构成模型/视图结构&#xff0c;就可以实现数据表的数据显示和编辑。 目录 所需的类及定义 表格控…

简化数据流:Apache SeaTunnel实现多表同步的高效指南

Apache SeaTunnel除了单表之间的数据同步之外&#xff0c;也支持单表同步到多表&#xff0c;多表同步到单表&#xff0c;以及多表同步到多表&#xff0c;下面简单举例说明如何实现这些功能。 单表 to 单表 一个source&#xff0c;一个sink。 从mysql同步到mysql&#xff0c;…

Pytorch TensorBoard的使用

from torch.utils.tensorboard import SummaryWriter writer SummaryWriter("logs")for i in range(100):writer.add_scalar("yx",i,i) writer.close() 第一个参数 y2x: 这是图表的标题或标签。它会显示在TensorBoard界面中,帮助你识别这条曲线。 第二个参…

(35)远程识别(又称无人机识别)(二)

文章目录 前言 4 ArduRemoteID 5 终端用户数据的设置和使用 6 测试 7 为OEMs添加远程ID到ArduPilot系统的视频教程 前言 在一些国家&#xff0c;远程 ID 正在成为一项法律要求。以下是与 ArduPilot 兼容的设备列表。这里(here)有一个关于远程 ID 的很好解释和常见问题列表…

【数据结构】排序算法——Lesson2

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

uni-app pinia搭建

1.新建store文件 新建index.js&#xff0c;代码&#xff1a; // import { // createPinia // } from pinia //const store createPinia() import * as Pinia from pinia const pinia Pinia.createPinia() export * from "./modules/user" export * from ".…

计算机网络 6.1Internet概念

第六章 Internet基础 第一节 Internet概念 一、认识Internet 1.定义&#xff1a;集现代计算机技术、通信技术于一体的全球性计算机互联网。 2.地位&#xff1a;当今世界上规模最大的计算机互联网。 3.使用协议&#xff1a;TCP/IP。 4.基本结构&#xff1a; ​ ①主干网…

vscode 寻找全部分支的提交

vscode 寻找全部分支的提交 Git Graph