背景

在学习ffmpeg时,由于文档老旧以及ffmpeg新旧版本对于一些api的改动,导致学习受阻。

本来可以直接下载老的库,使用老的源码进行学习,但本人觉得,一味地守旧并不是一种好的方法。

ffmpeg 文档:

ffmpeg-在线文档 : v4.1

使用 Doxygen 生成文档 (以FFmpeg 4.1.1 为例)

思路

由于对于FFmpeg的了解还比较皮毛,所以我们使用一些旧的例程,将提示过时的方法改为新的方法。

首先,我们查看一份过时的例程

下面的代码基于 ffmpeg v4.0 编译,为了保证编译通过,已经事先做了小部分的更改。

// ffmpeg v4.0
#include <stdio.h> #define __STDC_CONSTANT_MACROS //Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>
#include <libswscale/swscale.h>
//#include <libavutil/imgutils.h>
#ifdef __cplusplus
};
#endif void SaveFrame (AVFrame * pFrame, int width, int height, int iFrame)
{
FILE *pFile;
char szFilename[32];
int y;
// open file
sprintf(szFilename, "frame%d.ppm", iFrame);
pFile = fopen(szFilename, "wb");
if(pFile == NULL) return;
fprintf(pFile, "p6 \n %d %d\n", width, height);
for (y=0; y< height;y++)
{
fwrite(pFrame->data[0]+ y*pFrame->linesize[0], 1, width*3, pFile);
}
// Close file
fclose(pFile);
} int main(int argc, char *argv[])
{
AVFormatContext *pFormatCtx;
int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVFrame *pFrameRGB;
AVPacket packet;
int frameFinished;
int numBytes;
uint8_t *buffer;
if (argc <2 )
{
printf("Please provide a movie file\n");
return -1;
}
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context(); // Open the media file and read the header
if (avformat_open_input(&pFormatCtx, argv[1], NULL,NULL)!=0)
{
printf("Couldn't open file\n");
return -1;
}
// retrieve stream information
if(avformat_find_stream_info(pFormatCtx, NULL) < 0)
return -1;
// dump information about file into stand error
av_dump_format(pFormatCtx, -1, argv[1], 0); // Find the first video stream
videoStream = -1;
for(i =0; i< pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
printf("First stream is [%d]\n", videoStream);
break;
}
}
if (videoStream == -1)
return -1;
// Get a pointer to the codec context for the video stream
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec == NULL)
{
fprintf(stderr, "unsupported codec\n");
return -1;
}
// Open codec
if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
return -1;
// allocate video frame
pFrame = av_frame_alloc();
if (NULL == pFrame) return -1;
// allocate an avframe structure
pFrameRGB = av_frame_alloc();
if(pFrameRGB == NULL) return -1;
// Determine required buffer size and allocate buffer
numBytes = avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
printf("avpicture isze is %d\n", numBytes);
buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
avpicture_fill((AVPicture *)pFrameRGB, buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
i = 0;
while(av_read_frame(pFormatCtx, &packet) >= 0)
{
if(packet.stream_index ==videoStream)
{
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); if(frameFinished)
{
struct SwsContext * img_convert_ctx = NULL;
img_convert_ctx = sws_getCachedContext(img_convert_ctx, pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC,
NULL, NULL, NULL); if (!img_convert_ctx)
{
fprintf(stderr, "Cannot initalize sws conversion context\n");
exit (-1); }
sws_scale(img_convert_ctx, pFrame->data,
pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
if(i ++ < 50)
SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
}
}
av_packet_unref(&packet);
} // Free the RGB image
av_free(buffer);
av_free(pFrameRGB);
av_free(pFrame);
avcodec_close(pCodecCtx);
//av_close_input_file(pFormatCtx);
avformat_close_input(&pFormatCtx); return 0;
}

编译,除了一堆警告以外,没有什么错误。

开始修改

先将每一个警告消除。

  1. 变量类型的不匹配

    for(i =0; i< pFormatCtx->nb_streams; i++)出现问题

    查阅有关的数据结构发现,是变量类型不匹配,将i改成 uint。

  2. 成员改名

    if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) 提示codec过气

    同样,查阅以后,将codec修改为codecpar

  3. 处理方式不同

    pCodecCtx = pFormatCtx->streams[videoStream]->codec;

之前的版本

    pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);

之后的版本

    pCodecCtx = avcodec_alloc_context3(NULL);
pCodecCtx = pFormatCtx->streams[videoStream]->codec; if (pCodecCtx == NULL)
{
// printf("Could not allocate AVCodecContext\n");
return -1;
} if (pFormatCtx->streams[i]/*视音频流*/->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
// 处理音频
}
avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar);
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
  1. 过气函数 avpicture_get_size

    官方文档已经在 libavcodec/avcodec.h 说明:

/**
* @deprecated use av_image_get_buffer_size() instead.
*/
attribute_deprecated int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height);

由于没有在文档中很快找到 av_image_get_buffer_size,于是我在 头文件目录下搜索grep -nR av_image_get_buffer_size,找到是 libavutil这里的函数

libavcodec/avcodec.h:5650: * @deprecated use av_image_get_buffer_size() instead.
libavutil/imgutils.h:181:int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align);
libavutil/imgutils.h:186: * av_image_get_buffer_size() can be used to compute the required size

ffmpeg 学习: 004-参考文档进行的开发的更多相关文章

  1. Mongoose学习参考文档——基础篇

    Mongoose学习参考文档 前言:本学习参考文档仅供参考,如有问题,师请雅正 一.快速通道 1.1 名词解释 Schema : 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 Model ...

  2. [转载]正则表达式参考文档 - Regular Expression Syntax Reference.

    正则表达式参考文档 - Regular Expression Syntax Reference. [原创文章,转载请保留或注明出处:http://www.regexlab.com/zh/regref. ...

  3. MongoDB学习笔记:文档Crud Shell

    MongoDB学习笔记:文档Crud Shell   文档插入 一.插入语法 db.collection.insertOne() 将单个文档插入到集合中.db.collection.insertMan ...

  4. 数据库 PSU,SPU(CPU),Bundle Patches 和 Patchsets 补丁号码快速参考 (文档 ID 1922396.1)

    数据库 PSU,SPU(CPU),Bundle Patches 和 Patchsets 补丁号码快速参考 (文档 ID 1922396.1)

  5. css参考文档; 官方英文说明!! 1 margin padding 百分比参照物 2 margin值为auto时的说明 3 div在div里垂直居中方法 4 dispaly:flex说明

    css参考文档        http://css.doyoe.com/ 两篇很好的文章:(下面的css官方英文说明链接 有时间可以研究下 http://www.w3.org/TR/css3-box/ ...

  6. oracle数据库 PSU,SPU(CPU),Bundle Patches 和 Patchsets 补丁号码快速参考 (文档 ID 1922396.1)

    数据库 PSU,SPU(CPU),Bundle Patches 和 Patchsets 补丁号码快速参考 (文档 ID 1922396.1) 文档内容   用途   详细信息   Patchsets ...

  7. html5 兼容参考文档 与 浏览器hack兼容参考文档

    移动端兼容参考文档 http://mobilehtml5.org/ 浏览器hack http://browserhacks.com/ 附上部分截图

  8. phpmyadmin-您可能正在上传很大的文件,请参考文档来寻找解决方法

    phpmyadmin-您可能正在上传很大的文件,请参考文档来寻找解决方法   实这个很简单的只要更改php.ini里三个配置即可.(见下面加粗部分,改成你自己的需求即可) ; Maximum allo ...

  9. m_Orchestrate learning system---四、多看参考文档很多事情很轻松就解决了

    m_Orchestrate learning system---四.多看参考文档很多事情很轻松就解决了 一.总结 一句话总结:多看参考文档啊 1.面包屑导航如何实现? 1 <ol class=& ...

随机推荐

  1. Linux kali安装或更新之后出现乱码

    打开终端,输入以下命令,之后重启. apt-get install ttf-wqy-zenhei

  2. Nginx笔试题!

    1.Nginx实现HTTP及TCP负载均衡的模块?HTTP就是工作在七层协议TCP工作在四层协议 Nginx七层负载:七层通过虚拟的URL或主机名接收请求在server里面配置location反向代理 ...

  3. jenkins windows 2.204版,免安装,推荐插件齐备.

    windows专用,已安装好推荐插件, 更新了安装源为清华源,也就是说只要官方的插件,你都可以秒速下载了.香不? 解压到一个文件夹,管理员模式运行cmdcd 文件夹名jenkins install这样 ...

  4. pagehelper 分页不生效,总页数总是1解决方案

    问题: 后台查询后的数据只有1页,已经设置了PageHelper也没用 PageHelper.startPage(pageNum,pageSize); ModelAndView mv=new Mode ...

  5. Python 爬取 热词并进行分类数据分析-[拓扑数据]

    日期:2020.01.29 博客期:137 星期三 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入] c.[拓扑 ...

  6. HDU 2680 最短路 迪杰斯特拉算法 添加超级源点

    Choose the best route Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  7. CSP2019 滚粗记

    目录 CSP 2019 游记 DAY 0 DAY 1 DAY 2 CSP总结 自测之后 CSP 2019 游记 坐标:GD,GZ 人物:hyf 组别:J和S 任务:划水 目标:划水 任务奖励:退役证书 ...

  8. Java8新特性——Optional

    前言 在开发中,我们常常需要对一个引用进行判空以防止空指针异常的出现.Java8引入了Optional类,为的就是优雅地处理判空等问题.现在也有很多类库在使用Optional封装返回值,比如Sprin ...

  9. centos将celery写入系统服务

    第一步: 在/etc/下创建目录 celery/celery.conf 代码如下: CELERYD_NODES='w1 w2 w3' # 启动的celery进程的进程名 CELERY_BIN='/ro ...

  10. 【python-leetcode25-翻转链表】K 个一组翻转链表

    问题描述: 给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度. 如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序. 示例 ...