当前位置: 首页 > news >正文

H264 视频文件如何缩放分辨率?

前几天在知识星球里面有位朋友请教问题:如何将 H264 视频缩放分辨率?

具体的问题详情如下:

8cfcff57225e0baa29afc167176761de.png

将 800x600 的 H264 文件缩放成 400x300 的,大概的流程是先解码,得到 AVFrame 后对其做缩放操作,然后再编码,得到 AVPacket 后写入文件即可。

思路没错的话,就可以看看这位同学的写法了,截取部分代码:

7594b7490f6f217802120d8039f682a2.png

大家一起来挑错,看看遇到问题一般解决思路是什么样的。

问题一

首先提问者一直在 av_parser_parse2 函数处报错。

遇到这种情况不要慌,必现的问题先断点一下看看输入参数是否正确。

IDE 的断点调试是常见操作了,工程师进阶必备。

我没有调试提问者的代码,但也怀疑输入参数 pkt 有异常,顺着代码往下看,果然在函数最末尾几行调用了 av_packet_free 方法。

一般通过 av_packet_alloc 去申请 AVPacket ,而 av_packet_free 就是直接释放并置 nullptr ,这样下次在执行 av_parser_parse2 方法肯定就挂了。

void av_packet_free(AVPacket **pkt)
{
    if (!pkt || !*pkt)
        return;

    av_packet_unref(*pkt);
    av_freep(pkt);
}

所以这里肯定有问题呀。

问题二

接着看其他问题,想要缩放分辨率,可是代码截图中并没有看到任何缩放的代码,直接将解码后的 AVFrame 送去编码就可以缩放吗?

我猜想,提问者应该在设置编码的 AVCodecContext 时就已经指定好了缩放后的分辨率 400x300 ,但送去编码的 AVFrame 还是 800x600 的,这样编码的结果会是缩放的吗?

经过试验证明,编码的视频确实是 400x300 的,但画面却是从 800x600 截取的一部分,并没有显示完全,所以这样是不能起到缩放效果的。

要缩放还是得用 FFmpeg 中 SwsContext 提供的方法。

// 初始化
swsCtx = sws_getContext(800,600,AV_PIX_FMT_YUV420P,400,300,AV_PIX_FMT_YUV420P,SWS_BILINEAR, nullptr, nullptr,nullptr);
// 缩放
sws_scale(swsCtx,decodeFrame->data,decodeFrame->linesize,0,decodeFrame->height,encodeFrame->data,encodeFrame->linesize);

将缩放后的 AVFrame 送去编码就可以得到正确的效果了。

问题三

再仔细看提问者的代码,有必要在解码 avcodec_receive_frame 之前调用 av_frame_make_writable 吗?

由于提问者的代码本身不对,其实也不用调用 av_frame_make_writable 的,正常的缩放应该要两个 AVFrame 的,解码的 AVFrame 不需要,反而编码的 AVFrame 需要保证可写。

以上就是关于这次提问的一些问题反馈了,我自己也实现了一个简单的 H264 视频文件缩放分辨率的例子,完整的代码就放在知识星球里了。

关于播放器实践的专栏,后续大部分进展都会放在知识星球里面了,尤其是源码会在星球内同步更新,当然也会挑一些干货在公众号同步。

目前 音视频开发进阶知识星球 还在让利中,非常低的价格就可以获得业内一线开发人员的答疑解惑

与其在群里面提问石沉大海,不如来星球有问必答,而且这个价格还是管一年的哦,一年的时间可以说是相当划算了。

同时星球内非常欢迎大家提问,尤其是我不会的问题,我会去找业内好朋友请教,既回答了你的问题又帮助了我提高。

想要加入的可以通过扫如下二维码进星球哦,iPhone 用户如果不能访问小程序的话,也可以加我微信 ezglumes 拉你进星球。

2a659a8fef0941cb1bf498f5d6a34483.png

一个音视频领域专业问答的小圈子!

加我微信 ezglumes 拉你入技术交流群

推荐阅读:

音视频开发工作经验分享 || 视频版

OpenGL ES 学习资源分享

开通专辑 | 细数那些年写过的技术文章专辑

Android NDK 免费视频在线学习!!!

你想要的音视频开发资料库来了

推荐几个堪称教科书级别的 Android 音视频入门项目

觉得不错,点个在看呗~

25222a2238e035ebffba773f69fd87f4.gif

相关文章:

  • 也许可以少走弯路的职场建议
  • FFmpeg 中 AVPacket 与 AVFrame 中数据的传递与释放
  • 头条都在用的边下边播方案
  • YUV 与 颜色空间转换
  • 原创干货 | 入门或者转行音视频,应该要怎么做?
  • 上手 GAMES 104 课程 Pilot 游戏引擎~~
  • 关于音视频里面的 解码帧率 和 渲染帧率
  • 将音视频中的花屏、绿屏、黑屏问题一网打尽
  • 关于直播、WebRTC、FFmpeg 的那些事~~
  • 干货 | 快速抽取缩略图是怎么练成的?
  • 没有操作系统程序可以运行起来吗?
  • 重学音视频?认识 MP4 视频(上)
  • 重学音视频?认识 MP4 视频(下)
  • 关于 Android 渲染你应该了解的知识点
  • Android 视频编辑解析库 MP4Parser
  • [译] 怎样写一个基础的编译器
  • Angularjs之国际化
  • css布局,左右固定中间自适应实现
  • Docker: 容器互访的三种方式
  • Redis学习笔记 - pipline(流水线、管道)
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 跨域
  • 微信公众号开发小记——5.python微信红包
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 延迟脚本的方式
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • ​​​​​​​​​​​​​​Γ函数
  • (1) caustics\
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (二)springcloud实战之config配置中心
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)springboot教学评价 毕业设计 641310
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (四)linux文件内容查看
  • (转)程序员技术练级攻略
  • ./configure,make,make install的作用
  • .gitignore文件---让git自动忽略指定文件
  • .net core 依赖注入的基本用发
  • .net 简单实现MD5
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • /dev/VolGroup00/LogVol00:unexpected inconsistency;run fsck manually
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)
  • [ActionScript][AS3]小小笔记
  • [android] 请求码和结果码的作用
  • [BZOJ1010] [HNOI2008] 玩具装箱toy (斜率优化)
  • [C#]winform部署PaddleOCRV3推理模型
  • [C++从入门到精通] 14.虚函数、纯虚函数和虚析构(virtual)
  • [C语言]——函数递归
  • [Flex] PopUpButton系列 —— 控制弹出菜单的透明度、可用、可选择状态
  • [Flutter] extends、implements、mixin和 abstract、extension的使用介绍说明