ffmpeg avpicture_fill的一些使用

 

标签: ffmpegavpicture_fill

2013-05-17 10:03 4713人阅读 评论(1) 收藏 举报

 分类:

ffmpeg(3) 

这个FFMPEG我没找到详细的中文教程,只有将自己的使用心得记录。

1 int avpicture_fill(AVPicture *picture, uint8_t *ptr,

                   int pix_fmt, int width, int height);

这个函数的使用本质上是为已经分配的空间的结构体AVPicture挂上一段用于保存数据的空间,这个结构体中有一个指针数组data[4],挂在这个数组里。一般我们这么使用:

1) pFrameRGB=avcodec_alloc_frame();

2) numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height);

    buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

3) avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx-         >height);

以上就是为pFrameRGB挂上buffer。这个buffer是用于存缓冲数据的。

好,现在让我们来看一下tutorials里常出现的pFrame为什么不用fill空间。主要是下面这句:

avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,packet.data, packet.size);

这里根据我的瞎猜,很可能是pFrame已经挂上了packet.data,所以就不用fill了。

2 现在开始谈ffmpeg里的一些设备上下文,关于设备上下文,回顾一下它的定义:

Windows操作系统统一管理着诸如显示,打印等操作,将它们看作是一个个的设备,每一个设备都有一个复杂的数据结构来维护。所谓设备上下文就是指这个数据结构。然而,我们不能直接和这些设备上下文打交道,只能通过引用标识它的句柄(实际上是一个整数),让Windows去做相应的处理。

 

ffmpeg的两个设备上下文AVFormatContext和AVCodecContext,实际上是可以直接对其进行操作的。

AVFormatContext是FFMpeg格式转换过程中实现输入和输出功能、保存相关数据的主要结构。

AVCodecContext保存AVCodec指针和与codec相关的数据,如video的width、height,audio的sample rate等。

这里一些重要的数据结构可以参看:

http://www.sudu.cn/info/html/edu/20070101/287256.html

实际上AVCodecContext里的stream结构体中包含了一个AVCodecContext。所以码流对应的codec可以从这里取出。

 

3 用SDL_SetVideoMode创建一个且仅有一个的screen surface,相当于屏幕了,所有东西都往上画

 

4 struct SwsContext *sws_getContext

(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int 

flags,SwsFilter *srcFilter, SwsFilter *dstFilter, double *param);

获取用于转换在上下文,这里转换的概念包括视频的大小,像素格式。但这里只是获取了DC未开始转换

 

5 int sws_scale

(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY,

 int srcSliceH, uint8_t* dst[], int dstStride[]);

开始向目标转换,转换后可以用于显示,但转换之前必须指定dst的地址和行数,这样才知道数据以何种方式copy到dst中去。

 

6 关于声音,由于计算机方面知识比较单薄,故复习了一下队列多线程互斥体条件变量等概念,耽误了不少时间。

1)首先要给wanted_spec设置一堆声音播放的参数,其中最重要的就是控制播放速度的采样率和回调函数,接着fill给spec,这个spec猜测就是声卡。

2)初始化队列,开始播放声音同时开启callback。这些都是关于声音解码器的工作,在读入文件info后做完。 

3)接下来是读码流了,若是声音的码流,则执行packet_queue_put(&audioq, &packet),将直接将包放入队   列,同时发送条件变量通知packet_queue_get已经有数据了

4)现在来分析一直在进行中的回调函数audio_callback,这里面会调用audio_decode_frame,进入后是一个无限循环,顺序应是先执行packet_queue_get,待得到数据后再执行avcodec_decode_audio2解码

5)在packet_queue_get中将先上锁,等待packet_queue_put的通知(其间将解锁,睡眠,得到通知再上锁),后再解锁,上锁解锁是为了防止put和get同时操作队列

时间: 2025-01-17 15:05:09

ffmpeg avpicture_fill的一些使用的相关文章

FFMPEG:H264解码-SDL显示(RGB32、RGB24、YUV420P、YUV422)

FFMpeg对视频文件进行解码的大致流程 1. 注册所有容器格式: av_register_all()2. 打开文件: av_open_input_file()3. 从文件中提取流信息: av_find_stream_info()4. 穷举所有的流,查找其中种类为CODEC_TYPE_VIDEO5. 查找对应的解码器: avcodec_find_decoder()6. 打开编解码器: avcodec_open()7. 为解码帧分配内存: avcodec_alloc_frame()8. 不停地从码

android-Android 采集摄像头数据 , 通过ffmpeg推送流至服务器

问题描述 Android 采集摄像头数据 , 通过ffmpeg推送流至服务器 Android 采集摄像头数据 , 通过ffmpeg推送流, 通过AdobeMediaServer查看 , 为什么播放视频总是隔一段时间一缓冲 , 而且播放有延迟.求大神帮忙啊 AVFormatContext *ofmt_ctx; AVStream* video_st; //视音频流对应的结构体,用于视音频编解码. AVCodecContext* pCodecCtx; AVCodec* pCodec; AVPacket

FFMPEG 实现 YUV,RGB各种图像原始数据之间的转换(swscale)

FFMPEG中的swscale提供了视频原始数据(YUV420,YUV422,YUV444,RGB24...)之间的转换,分辨率变换等操作,使用起来十分方便,在这里记录一下它的用法. swscale主要用于在2个AVFrame之间进行转换. 下面来看一个视频解码的简单例子,这个程序完成了对"北京移动开发者大会茶歇视频2.flv"(其实就是优酷上的一个普通视频)的解码工作,并将解码后的数据保存为原始数据文件(例如YUV420,YUV422,RGB24等等).其中略去了很多的代码. 注:完

一个使用FFmpeg库读取3gp视频的例子-Android中使用FFmpeg媒体库(三)

原文:http://doandroid.info/?p=497 在续系列文章在32位的Ubuntu 11.04中为Android NDK r6编译FFmpeg0.8.1版-Android中使用FFmpeg媒体库(一)和在Android中通过jni方式使用编译好的FFmpeg库-Android中使用FFmpeg媒体库(二)文章后,本文将根据github中churnlabs的一个开源项目,来深入展开说明如何使用FFmpeg库进行多媒体的开发. 本文中的代码来自于https://github.com/

利用ffmpeg做视频解码的顺序

这几天在实验室捣鼓着用ffmpeg做视频解码,终于把数据解出来了,虽然还没有做显示部分,不知道解码解得对不对,但料想是不会有什么问题了.回头看看这几天的工作,其间也遇到了不少问题,主要还是对ffmpeg解码过程不熟悉,现总结了ffmpeg解码的顺序大致如下: 1.初始化解码器:avcodec_init(); 2.注册所有格式和解码器:av_register(); 3.打开文件:av_open_input_file(filename); 4.取出数据流信息:av_find_stream_info(

ffmpeg tutorial01--------提取视频图像

概要 电影文件有很多基本的组成部分.首先,文件本身被称为 容器Container,容器的类型决定了信息被存放在文件中的位置.AVI和Quicktime就是容器的例子.接着,你有一组流,例如,你经常有的是一个音频流和一个视频流.(一个流只是一种想像出来的词语,用来表示一连串的通过时间来串连的数据元素).在流中的数据元素被称为帧Frame. 每个流是由不同的编码器来编码生成的.编解码器描述了实际的数据是如何被编码Coded和解码DECoded的,因此它的名字叫做CODEC.Divx和 MP3就是编解

最新的 ffmpeg 2.8 其实连yuy2数据包都不能正确转换

问题描述 最新的 ffmpeg 2.8 其实连yuy2数据包都不能正确转换 说了你也不相信,我用 directx 采集到的数据是从web camera来的 yuy2 数据,我用自己写的转换程序可以成功转换正确的图像rgb24, yuy2 -> rgb24 -> I420 都可以,但是用ffmpeg的sws__scale 怎么也无法正确转换. sws__scale 的解码过程如下 void scaleYUY2toI420(const void *pSrc, int widthSrc, int h

FFMPEG内存操作(二)从内存中读取数及数据格式的转换

相关博客列表:     FFMPEG内存操作(一) avio_reading.c 回调读取数据到内存解析      FFMPEG内存操作(二)从内存中读取数及数据格式的转换      FFmpeg内存操作(三)内存转码器     在雷神的<最简单的基于FFmpeg的内存读写例子(内存播放器)>中,它是设计回调函数从输入文件中读取数据.与FFMPEG 官方给出的avio_reading.c不同的是,雷神给的例子是当需要数据的时候,回调函数才去从输入文件读取数据,而avio_reading.c 则

VS2008+ffmpeg SDK3.2调试tutorial01

最近研究ffmpeg,在ubuntu下感觉不太好调试,老是找不到函数的声明.所以我就把他移到windows下用vs2008分析 关于环境的搭建,我参考了 http://hi.baidu.com/forever803/blog/item/ba90cdd2cca917093af3cf9e.html ,这里我把步骤整理一下,顺便奉上图文 第1步: 下载ffmpeg SDK3.2:点击下载,并解压. 第2步: 打开vs2008新建一个空的vc++项目 第3步: 新建一个C++源文件,test.cpp,输