近期由于工作任务,需要开发一个跨平台视频聊天系统,其中就用到了ffmpeg进行采集与编码,网上找了一大堆的资料,虽然都有一些有用的东西,但实在太碎片化了,这几天一直在整理和实验这些资料,边整理,边做一个总结,今天先总结一下采集的步骤,我是在linux平台下进行试验的,操作系统是ubuntu13.04 64bit,ffmpeg的版本是2.0.1,采用C语言开发,我的目标是从摄像头采集到1帧视频,然后用容器输出这帧的图像并把图像保存为bmp文件。整个采集的步骤是:连接视频源->获取视频流->demux(解复用)视频格式->匹配解码器->解码->转换->输出,这个是步骤的概述,下面针对ffmpeg的具体操作逐一进行一个讲解:

连接视频源

使用av_find_input_format函数连接v4l2(video4linux2)摄像头设备,大部分的摄像头设备在Linux下都是v4l2类型的,这个函数返回AVInputFromat*类型的数据。

我的代码:AVInputFormat *inputFmt=av_find_input_format("video4linux2");

获取视频流

使用avformat_open_input函数打开上一步骤的摄像头设备获取视频流.

我的代码:avformat_open_input(&fmtCtx,"/dev/video0",inputFmt,NULL);

代码备注:fmtCtx是一个AVFormatContext*对象,是一个视频格式处理的上下文对象,很重要,里面有这个采集的视频的元数据,"/dev/video0"是摄像头的映射路径,这部分是Linux基础,不是本文的重点,inputFmt就是第一步得到的AVInputFormat*对象,inputFmt不是必须的参数,NULL也可以,如果是NULL,则会自动检测。

demux(解复用)视频格式

fmtCtx里面包含了采集到的视频流的视频格式,如果是摄像头的话,应该是RAWVIDEO类型的数据,codec_id=14。

我的代码:fmtCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO

代码备注:fmtCtx->streams实际上是一个二维数组或数组指针,因为fmtCtx->streams数组内每一个元素都指向一个一维数组,每一个一维数组都有可能有数据,比如音频、视频、字幕等,因此这里的理想处理方式应该是用一个循环匹配每一个的fmtCtx->streams,因为我们这里只关心视频,因此我们只需要匹配codec_type==AVMEDIA_TYPE_VIDEO的数据就可以了。

匹配解码器

既然上一步已经经过解复用知道了视频流的格式是RAWVIDEO类型了,接下来要做的就是找到对应的解码器进行解码了,这里用到了函数avcodec_find_decoder,返回AVCodec*类型数据,就是一个解码器对象。

我的代码:avcodec_find_decoder(fmtCtx->streams[i]->codec->codec_id)

以下部分开始暂时我自己代码还没完成,完成后会贴上来,所以我只是会说明以下采用哪些函数,至于函数怎么用我暂时不提供,大家可以等待我近期更新或自行去ffmpeg官网开api documentation

解码

所谓解码,就是用上一步得到的解码器打开视频流帧(帧是视频的最小单位),这里用到函数是av_read_frame与avcodec_decode_video2,av_read_frame从视频流中读取一帧,但这个函数返回的不是帧对象AVFrame*,而是Packet对象AVPacket,要经过avcodec_decode_video2这个解码函数才能得到AVFrame*对象,这里说明一下,AVPacket最多可能包含一个帧,而一个AVFrame可能会包含很多个AVPacket,二者的区别请读者请自行Google,以后我也许会专门开篇说明。

我的代码:有点复杂,稍后我整理好贴上来

转换

经过解码后得到的是YUYV422格式的视频帧,这种格式如果要进行网络传输比如视频聊天,要进行H264编码,而H264编码目前输入源必须是YUV420格式的,YUYV422与YUV420格式间的转换我后面会补上,我自己的代码也刚写到这个位置,我稍后确认代码没问题后会贴上来,这里暂且不讨论网络传输和H264部分,这里就讨论怎么把YUYV422输出到容器或者保存成图片文件呢,要进行一次YUV格式到RGB24格式的转换,采用函数sws_scale进行转换。

输出

到这步前,实际上我们已经得到了RGB24格式的数据了,接下来输出分2种情况,一种是采用容器的方式输出,这种方式的话可以直接把RGB24格式的数据源作为容器的输入源即可了,比如IOS下可以采用UIIMAGEVIEW作为容器,还有一种是保存成bmp图,以图片的形式输出,如果保存成bmp图片的话,在C语言下不用任何第三方库的前提下,需要自己建立bmp数据结构来生成bmp文件。

转自:http://www.cnblogs.com/babystudio/archive/2013/09/08/3308965.html

[转载] ffmpeg摄像头视频采集-采集步骤概述并采集一帧视频的更多相关文章

  1. ffmpeg摄像头采集h264编码RTP发送

    一. 相关API说明 1. av_register_all 2. avformat_network_init 不管是流媒体发送还是流媒体接收, 需要先执行该函数. 3. avformat_alloc_ ...

  2. 3D图片采集与展示(SurfaceView 自适应 Camera, 录制视频, 抽取帧)

    最近在做一个3D图片采集与展示. 主要功能为:自定义Camera(google 已经摈弃了Camera, 推荐使用Camera2,后续篇幅,我将会用Camera2取代Camera),围绕一个物体360 ...

  3. FFmpeg命令行工具和批处理脚本进行简单的音视频文件编辑

    FFmpeg_Tutorial FFmpeg工具和sdk库的使用demo 一.使用FFmpeg命令行工具和批处理脚本进行简单的音视频文件编辑 1.基本介绍 对于每一个从事音视频技术开发的工程师,想必没 ...

  4. [转载]FFmpeg完美入门[3] - FFmpeg功能及使用说明

    1 ffplay对多媒体的支持能力验证 一.视频3gp 177X144 支持播放,在windows下播放正常,但是在linux下面偶有BUG 如果发现画面无法显示而声音可以播放的情况下可以试着切换全屏 ...

  5. Android开发:实时处理摄像头预览帧视频------浅析PreviewCallback,onPreviewFrame,AsyncTask的综合应用(转)

    原文地址:http://blog.csdn.net/yanzi1225627/article/details/8605061# 很多时候,android摄像头模块不仅预览,拍照这么简单,而是需要在预览 ...

  6. [转载]FFmpeg完美入门[2] - FFmpeg参数说明

     1 通用选项 -L license -h 帮助 -fromats 显示可用的格式,编解码的,协议的. -f fmt 强迫采用格式fmt -i filename 输入文件 -y 覆盖输出文件 -t d ...

  7. [转载] FFMPEG结构体分析:AVFrame

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrameFFMPEG结构体分析:AVFormatContextFFMPEG结构体分析:AVCodecContext ...

  8. [转载] ffmpeg函数介绍

    本文对在使用ffmpeg进行音视频编解码时使用到的一些函数做一个简单介绍,我当前使用的ffmpeg版本为:0.8.5,因为本人发现在不同的版本中,有些函数名称会有点小改动,所以在此有必要说明下ffmp ...

  9. 短视频技术详解:Android端的短视频开发技术

    在 <如何快速实现移动端短视频功能?>中,我们主要介绍了当前短视频的大热趋势以及开发一个短视频应用所涉及到的功能和业务.在本篇文章中,我们主要谈一谈短视频在Android端上的具体实现技术 ...

随机推荐

  1. BKDRHash函数

    unsigned int BKDRHash(char*str) { unsigned ;// 31 131 1313 13131 131313 etc.. unsigned ; while(*str) ...

  2. 关于获得MFC窗口其它类指针的方法(csdn)

    转自:http://tieba.baidu.com/p/252804018 访问应用程序的其它类 获得CWinApp: -在CMainFrame,CChildFrame,CDocument,CView ...

  3. 出入Spring boot(六)数据访问

    Spring Data提供了使用统一的API进行数据访问操作,这是Spring通过提供Spring DataCommons项目来实现的,它是Spring data的依赖Spring Data Comm ...

  4. nginx+tomcat网页动静分离配置

    1.环境描述 nginx server (Proxy):192.168.1.135(作为代理服务器)WEB server1: 192.168.1.138(使用tomcat作为web容器)WEB ser ...

  5. mysql CMD命令窗连接 - 转载

    cmd连接mysql的方法详解 首先需要进入mysql的安装文件夹bin目录下:cd + C:\Program Files\MySQL\MySQL Server 5.5\bin 连接:mysql -h ...

  6. 有意思的随机数 Random

    今天看到stackoverflow上一篇关于随机数的提问,关于如何用随机数生成 "hello world"的有趣问题 : 大家都知道JDK里面的Random类生成随机数其实并不是真 ...

  7. Java中的equals学习小结

    Java中的equals是十分重要的,和= =要区别开来,现在小结其主要内容,而且要将 = =和 equals列为重要的对比概念来学习 1.声明格式    public  boolean equals ...

  8. git branch 常用语句详解

    删除远程分支 git push origin --delete <branchName> 查看本地分支 git branch 创建本地新分支 git branch <branchNa ...

  9. Pandas数据结构

    Pandas处理以下三个数据结构 - 系列(Series) 数据帧(DataFrame) 面板(Panel) 这些数据结构构建在Numpy数组之上,这意味着它们很快. 维数和描述 考虑这些数据结构的最 ...

  10. Java多线程 - 线程组

    Java使用ThreadGroup来表示线程组,用以对一批线程进行分类管理. Java允许程序对线程组直接进行控制,对线程组的控制相当于同时控制这批线程: 用户创建的所有线程都属于指定线程组,如果程序 ...