1、初始化FFmpeg

av_register_all(); //初始化FFMPEG  调用了这个才能正常使用编码器和解码器

  但是这个函数如今已经没什么用了,它的就是把你定义和系统初始化的编码器和解码器连接起来而已,然后就没有了。

  现在解码器和编码器的初始化都是通过定义全局变量来初始化的。与原来相比,唯一的改变就是使用数组替换链表完成解码器和编码器的初始化。

## 参考文章:https://www.jianshu.com/p/ebb219ec1c0f

2、分配一个AVFormatContext,FFMPEG所有的操作都要通过这个AVFormatContext数据结构来进行

AVFormatContext *pFormatCtx = avformat_alloc_context();

  AVFormatContext是一个贯穿始终的数据结构,很多函数都要用到它作为参数。

  此结构包含了一个视频流的格式内容:AVInputFormat(or AVOutputFormat同一时间AVFormatContext内只能存在其中一个),和AVStream、AVPacket这几个重要的数据结构以及一些其他的相关信息,比如title,author,copyright等。还有一些可能在编解码中会用到的信息,诸如:duration, file_size, bit_rate等。

3、打开视频文件:

char *file_path = "./movie/ifwithoutu.mp4";
avformat_open_input(&pFormatCtx, file_path, NULL, NULL);

  

4、视频打开之后,查找文件中的视频流

    ///循环查找视频中包含的流信息,直到找到视频类型的流
///便将其记录下来 保存到videoStream变量中
///这里我们现在只处理视频流 音频流先不管他
for (i = 0; i < pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
}
} ///如果videoStream为-1 说明没有找到视频流
if (videoStream == -1)
{
printf("Didn't find a video stream.");
return -1;
}

  

5、根据视频流,打开一个解码器来解码

    ///查找解码器
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if (pCodec == NULL)
{
printf("Codec not found.");
return -1;
} ///打开解码器
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
{
printf("Could not open codec.");
return -1;
}

  FFmpeg可以让我们根据查找到的视频流信息获取到解码器,不需要知道实际用到的是什么解码器

6、读取视频

     int y_size = pCodecCtx->width * pCodecCtx->height;
AVPacket *packet = (AVPacket *) malloc(sizeof(AVPacket)); //分配一个packet
av_new_packet(packet, y_size); //分配packet的数据 if (av_read_frame(pFormatCtx, packet) < 0)
{
break; //这里认为视频读取完了
}

  av_read_frame读取的是一帧视频,并存入一个AVPacket的结构中

7、视频里的数据是经过编码压缩的,需要将其解码

   if (packet->stream_index == videoStream)
{
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture,packet); if (ret < 0)
{
printf("decode error.");
return -1;
}
}

  

8、解码器解码之后得到的图像数据都是YUV420格式的,需要将其保存成图片文件,因此需要转换为RGB格式

    if (got_picture)
{
sws_scale( img_convert_ctx,
(uint8_t const * const *) pFrame->data,
pFrame->linesize,
0,
pCodecCtx->height,
pFrameRGB->data,
pFrameRGB->linesize
);
}

  

9、将RGB图片写入

SaveFrame(pFrameRGB,
pCodecCtx->width,
pCodecCtx->height,
index++
);

  

错误:

(1):改成  AV_PIX_FMT_RGB24

最新文章

  1. Ext3日记文件系统为什么文件系统还会损坏?
  2. 月四 周2 ii
  3. http_load
  4. Oracle 11g r2 安装
  5. javascrpt插入html中中文字符乱码问题记录
  6. StringBuilder和Append的一个程序及一个基础概念
  7. [工具类]文件或文件夹xx已存在,则重命名为xx(n)(2)
  8. iOS constraint被应用于view上的时间
  9. GridControl 继承写法修改自己的GridControl
  10. mapreduce 实现pagerank
  11. Web前端开发如何利用css样式来控制Html中的h1/h2/h3标签不换行
  12. 深入详解SQL中的Null
  13. 用NodeJs实现延迟调用,规避定时任务的闭包问题
  14. php版的求表达式的真值表-TrueValueTable
  15. 一步一步学习SignalR进行实时通信_9_托管在非Web应用程序
  16. javaScript中的一些知识
  17. iOS 倒出spa文件 打包
  18. 防止ajax重复提交
  19. git服务器配置http请求
  20. C# HelpPage 接口文档配置

热门文章

  1. kali linux 中实现beef和msf关联出现问题解决
  2. java中List的浅拷贝与深拷贝
  3. pip安装psycopg2报错Could not find a version that satisfies the requirement psycopg2
  4. C++ 手动实现队列(queue) (课后作业版)
  5. ubuntu 查看已安装软件命令
  6. Windows 11 调整工具 TweakNow WinSecret for Windows 11 3.2.0 中文汉化版
  7. go-fastdfs断点续传功能
  8. speedtest测速
  9. Java笔记_方法重载
  10. 「SOL」序列计数sequence (模拟赛)