FFMPEG系列课程(二)读取视频帧

再来介绍下如何读取视频帧,打开视频参考前面的文章,首先需要创建一个帧的存放对象

AVPacket pkt;

memset(&pkt, 0, sizeof(AVPacket));

再通过 int err = av_read_frame(ic, &pkt); 读取帧数据,其中ic是之前打开的视频流句柄。读取视频帧后要注意一点av_read_frame会自动给视频帧分配空间,返回值0表示成功。

可以通过 av_packet_unref(&pkt);删除packet的控制,注意这里删除的不是packet对象的空间,而是packet对象指向的数据空间。

通过判断pkt的stream_index 成员可以判断此帧数据是不是视频

if (pkt.stream_index == videoStream),

videoStream是打开视频时存放的视频流索引,大部分文件都是0,参考前一篇文章。

  1. extern "C"
  2. {
  3. #include<libavformat/avformat.h>
  4. }
  5. //引用lib库,也可以在项目中设置,打开视频只需要用到这三个库
  6. #pragma comment(lib,"avformat.lib")
  7. #pragma comment(lib,"avutil.lib")
  8. #pragma comment(lib,"avcodec.lib")
  9. #include <iostream>
  10. using namespace std;
  11. int main(int argc, char *argv[])
  12. {
  13. //初始化所以ffmpeg的解码器
  14. av_register_all();
  15. char path[1024] = "video.mp4";
  16. //用来存放打开的视频流信息
  17. AVFormatContext *ic = NULL;
  18. //用来存储视频流索引
  19. int videoStream = 0;
  20. //打开视频播放流
  21. //path参数表示打开的视频路径,这个路径可以包括各种视频文件
  22. //也包括rtsp和http网络视频流
  23. //第三个参数表示传入的视频格式,我这边不传递有FFmpeg内部获取
  24. //最后一个参数是设置,我们这里也不传递
  25. int re = avformat_open_input(&ic, path, 0, 0);
  26. if (re != 0)
  27. {
  28. //获取到FFmpeg的错误信息
  29. char errorbuf[1024] = { 0 };
  30. av_strerror(re, errorbuf, sizeof(errorbuf));
  31. printf("open %s failed: %s\n", path, errorbuf);
  32. return -1;
  33. }
  34. //遍历视频流,里面包含音频流,视频流,或者字母流,我们这里只处理视频
  35. for (int i = 0; i < ic->nb_streams; i++)
  36. {
  37. AVCodecContext *enc = ic->streams[i]->codec;
  38. //确认是视频流
  39. if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
  40. {
  41. //存放视频流索引,后面的代码要用到
  42. videoStream = i;
  43. //找到解码器,比如H264,解码器的信息也是ffmpeg内部获取的
  44. AVCodec *codec = avcodec_find_decoder(enc->codec_id);
  45. if (!codec)
  46. {
  47. printf("video code not find!\n");
  48. return -2;
  49. }
  50. //打开视频解码器,打开音频解码器用的也是同一个函数
  51. int err = avcodec_open2(enc, codec, NULL);
  52. if (err != 0)
  53. {
  54. char buf[1024] = { 0 };
  55. av_strerror(err, buf, sizeof(buf));
  56. printf(buf);
  57. return -3;
  58. }
  59. }
  60. }
  61. //创建视频帧对象
  62. AVPacket pkt;
  63. memset(&pkt, 0, sizeof(AVPacket));
  64. for (;;)
  65. {
  66. //读取视频帧
  67. int err = av_read_frame(ic, &pkt);
  68. if (err != 0)
  69. {
  70. //读到结尾或者出错
  71. char buf[1024] = { 0 };
  72. av_strerror(err, buf, sizeof(buf));
  73. printf(buf);
  74. break;
  75. }
  76. //判断是否是音频
  77. if (pkt.stream_index == videoStream)
  78. {
  79. printf("video pkt size is %d\n", pkt.size);
  80. //视频处理,解码或者存储
  81. }
  82. //视频帧数据空间
  83. av_packet_unref(&pkt);
  84. }
  85. }

更多的资料也可以关注我51CTO上的视频课程

夏老师的课堂 http://edu.51cto.com/lecturer/index/user_id-12016059.html

手把手教您开发视频播放器

http://edu.51cto.com/course/course_id-8059.html

时间: 2024-10-13 21:10:30

FFMPEG系列课程(二)读取视频帧的相关文章

solr与.net系列课程(二)solr的配置文件及其含义

 solr与.net系列课程(二)solr的配置文件及其含义  本节内容还是不会涉及到.net与数据库的内容,但是不要着急,这都是学时solr必学要掌握的东西,solr可不是像其他的dll文件一样,只需要引用就能调出方法与数据的,你不配置好是无法使用,前两节主要是起铺垫作用的,看起来会很枯燥无味的. 本章节内容是为下一节连接数据库做准备的,单拿出来看的话,会让人很迷糊,没关系,就当提前预习了,知道有这么个东西就行了,等下一节结合数据库后就好理解了 上一节我们已经完成了solr的基本配置,这里我们

FFMPEG系列课程(一)打开视频解码器

测试环境:windows10 开发工具:VS2013 从今天开始准备些FFmpeg的系列教程,今天是第一课我们研究下打开视频文件和视频解码器.演示环境在windows上,在linux上代码也是一样. windows上可以不编译ffmpeg源码,后面我会分别讲解在linux和在windows上如何编译ffmpeg,直接在FFmpeg官网下载已经编译好的dll和lib文件,下载地址https://ffmpeg.zeranoe.com/builds/ 里面有32位和64位的,我下载的32位. //引用

读取视频帧matlab

前言 视频处理分析的过程中,需要用到将视频一帧帧地读取,本文就涉及此问题. 系统环境 1.系统:win7_64 2.matlab版本:matlab2015a 测试代码 代码一: %To read video frames. clc clear close all fileName = 'E:\fatigue_detection\dataset\segVideosP1\1_5.avi'; obj = VideoReader(fileName); numFrames = obj.NumberOfFr

Android视频录制从不入门到入门系列教程(二)————显示视频图像

1.创建一个空的工程,注意声明下列权限: <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 2.布局文件 <?xml version="1.0" encoding="utf-8"

利用ffmpeg获取视频帧

如果要对视频帧进行处理,可以先把视频帧读取出来. sh文件代码如下: #!/usr/bin/env sh VIDEO=/home/xxx/video/ FRAMES=/home/xxx/frame/ echo "Extract Frames..." for avi in $VIDEO/*.avi do FOLDER=$(basename $avi.avi) rm -rf $FOLDER mkdir $FRAMES/$FOLDER ffmpeg -i $avi -q:v 2 -f ima

【EMGU】读取视频AVI文件+保存任意帧为图片

文章简介:对拍取的视频需要手动截取或者分帧截取图片,本文拟实现此功能.可多次.任意帧截取. 操作说明:空格键开始截取,回车键退出视频. 开发环境:EMGU2.4.9 + VS2010 +Win7(64). public void VideoCatch(string filepath) { try { IntPtr CatchFrame =CvInvoke.cvCreateFileCapture(filepath); CvInvoke.cvNamedWindow("打开视频"); //

采用ffmpeg和ffserver实现音视频直播和点播

一.嵌入式开发板采集音视频(远程) 音频采集程序:./audioc -i 222.222.222.222 -p 8888; 视频采集程序:./videoc -i 222.222.222.222 -p 9999; 音频采集程序利用alsa库,采集原始音频帧,发送至服务器进程(222.222.222.222,  8888); 视频采集程序利用v4l2库,采集原始视频帧,h.264硬编码后,发送至服务器进程(222.222.222.222, 9999); 二.Linux服务器接收音视频 音频接收程序:

&lt;从编程到(架构)设计之路&gt;的翻转式系列课程

<从编程到(架构)设计之路>的翻转式系列课程 课程(1):  从接口(Interface)出发:接口设计的技术和艺术 一個成功案例的實務傳承 高焕堂37年码农经验讲解 指导教练:高焕堂 1. 简介翻转式课堂 1.1  翻转式课堂的目标 萨尔曼·可汗 說:未来的世界是不确定的,因此重要的不是学到什么,而是学习新知识的能力.教育应该具有实践性,其目的应该是帮助学生掌握技能.取得信息,使他们能够谋生.教育应该具有实践性,其目的应该是帮助学生掌握技能.取得信息,使他们能够谋生.学徒制的基础是主动学习-

【FFmpeg】ffplay播放rtsp视频流花屏问题 (转)

问题描述:ffplay播放rtsp视频流时,播放过程中随机出现花屏现象. 基本流程学习:阅读ffplay源码,熟悉其播放rtsp视频流的基本流程. 在ffplay源码阅读和分析的基础上,画出了其播放rtsp的函数调用关系,如下图所示: avformat_open_input函数根据输入的文件名,与rtsp_read_packet关联. rtsp_read_packet完成每个rtp包的读取和解析,读取主要是利用rtp_read从缓冲区获取数据,解析主要是根据rtp协议,解析rtp包,得到h264