[✔️]FFMpeg视频处理

简介: [✔️]FFMpeg视频处理

核心逻辑


while(av_read_frame()==0){
    // 成功读取到一帧的数据
    if(avcodec_send_packet()==0){
        // 成功发送获取数据包的请求后,需要循环接收数据包
        while(avcodec_receive_frame()==0){
            //成功接收到一帧的数据包
            // 处理一帧的音视频 
        }
    }
}


以上都是伪代码,言简意赅的说明了视频的处理流程。


av_read_frame


返回流的下一帧。此函数返回存储在文件中的内容,并且不会验证解码器有哪些有效帧。

它会分裂并为每个调用返回一个帧。不会的省略有效帧之间的无效数据,以便使解码器获得最大值可以解码的信息。


如果pkt->buf为NULL,则该数据包在下一个之前有效av_read_frame()或直到avformat_close_input()。否则,数据包无限期有效。在这两种情况下,必须使用不再需要av_packet_unref时。对于视频,数据包包含正好一帧。对于音频,如果每个帧帧具有已知的固定大小(例如PCM或ADPCM数据)。如果音频帧具有可变大小(例如MPEG音频),则它包含一帧。


pkt->pts、pkt->dts和pkt->持续时间始终设置为正确AVStream.time_base单位中的值(如果格式不能提供它们)。pkt->pts可以是AV_NOPTS_VALUE,如果视频格式具有B帧,因此如果没有,最好依赖pkt->dts解压缩有效载荷。


return 0(如果正常),在错误或文件结束时<0


avcodec_send_packet


avcodec_receive_frame


avformat_seek_file


int avformat_seek_file(
    AVFormatContext *s, // 媒体文件句柄
    // 流索引
    // 只有在 flags 包含 AVSEEK_FLAG_FRAME 的时候才是设置某个流的读取位置
    // 其他情况都是把这个流的time_base作为参考
    int stream_index, 
    int64_t min_ts, // 跳转到的最小的时间,或时间单位,或字节单位,或帧数序号(第几帧)
    int64_t ts, // 目标seek位置,单位同上,通常填INT64_MIN即可。
    int64_t max_ts, // 跳转到的最大的时间,单位同上,通常填 INT64_MAX 即可。
    // seek 方式
    // AVSEEK_FLAG_BYTE,按字节大小进行seek。
    // AVSEEK_FLAG_FRAME,按帧数大小进行seek。
    // AVSEEK_FLAG_ANY,会seek到非IDR,解码会出现马赛克、花屏现象。
    // AVSEEK_FLAG_BACKWARD,往 ts 后面找最近的IDR
    int flags);


返回值>=0成功,否则为错误码


seek之后,有时会发现read_frame的pts是0,frame竟然是起点,因为seek只能到关键帧,如果gop过长,也会导致回到起点,如果视频时长过短,也会因为gop多长导致这个问题


seek的timestrap参数的详细规则:


  • 当stream_index为-1时,会选择默认流,时间戳是以AV_TIME_BASE为基准


double sec = 1.25;//1.25秒 
int64_t timestamp = sec * AV_TIME_BASE; 
av_seek_frame(pFormatCtx,-1,timestamp,AVSEEK_FLAG_BACKWARD);


  • 当strea_index为索引流时,timestrap是packet.pts的时间戳


double sec = 1.25;
int64_t pts = sec / av_q2d(pFormatCtx->streams[vStreamIndex]->time_base);
av_seek_frame(pFormatCtx,vStreamIndex,pts,AVSEEK_FLAG_BACKWARD);


AVFrame


字段 解释
frame->pts Presentation timestamp in time_base units (time when frame should be shown to user).
可以作为帧时间的判断依据,注意单位是time_base
pkt_pts 废弃字段,同pts
pkt_dts 值来自触发此帧的packet.dts


目录
相关文章
|
编解码 NoSQL Java
|
Python Windows
moviepy:基于 ffmpeg 的视频处理模块
moviepy:基于 ffmpeg 的视频处理模块
521 0
|
编解码 索引 Windows
视频处理工具ffmpeg使用
开源视频处理工具使用实践
848 0
视频处理工具ffmpeg使用
|
Linux 开发工具 Android开发
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
ijkplayer是由Bilibili基于FFmpeg3.4研发并开源的播放器,适用于Android和iOS,支持本地视频及网络流媒体播放。本文详细介绍如何在新版Android Studio中导入并使用ijkplayer库,包括Gradle版本及配置更新、导入编译好的so文件以及添加直播链接播放代码等步骤,帮助开发者顺利进行App调试与开发。更多FFmpeg开发知识可参考《FFmpeg开发实战:从零基础到短视频上线》。
1419 2
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
|
编解码 语音技术 内存技术
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
《FFmpeg开发实战:从零基础到短视频上线》一书中的“5.1.2 把音频流保存为PCM文件”章节介绍了将媒体文件中的音频流转换为原始PCM音频的方法。示例代码直接保存解码后的PCM数据,保留了原始音频的采样频率、声道数量和采样位数。但在实际应用中,有时需要特定规格的PCM音频。例如,某些语音识别引擎仅接受16位PCM数据,而标准MP3音频通常采用32位采样,因此需将32位MP3音频转换为16位PCM音频。
420 0
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
|
XML Java Android开发
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
GSYVideoPlayer是一款国产移动端视频播放器,支持弹幕、滤镜、广告等功能,采用IJKPlayer、Media3(EXOPlayer)、MediaPlayer及AliPlayer多种内核。截至2024年8月,其GitHub星标数达2万。集成时需使用新版Android Studio,并按特定步骤配置依赖与权限。提供了NormalGSYVideoPlayer、GSYADVideoPlayer及ListGSYVideoPlayer三种控件,支持HLS、RTMP等多种直播链接。
542 18
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
|
XML 开发工具 Android开发
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
ExoPlayer最初是为了解决Android早期MediaPlayer控件对网络视频兼容性差的问题而推出的。现在,Android官方已将其升级并纳入Jetpack的Media3库,使其成为音视频操作的统一引擎。新版ExoPlayer支持多种协议,解决了设备和系统碎片化问题,可在整个Android生态中一致运行。通过修改`build.gradle`文件、布局文件及Activity代码,并添加必要的权限,即可集成并使用ExoPlayer进行网络视频播放。具体步骤包括引入依赖库、配置播放界面、编写播放逻辑以及添加互联网访问权限。
1130 1
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
281 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势