ffmpeg解码内存缓冲区

只贴出部分代码,重在说明过程。

与解码文件的大致过程类似,只不过自定义了AVFormatContext

struct IOData
    {
        char* data;
        size_t len;
    };

int FrVideoAcqHT::io_get_data(void *opaque, uint8_t *buf, int buf_size)
{
    FrVideoAcqHT* acq = (FrVideoAcqHT*)opaque;

     //以下为通过缓冲区读文件解码方式
    /*if (!feof(acq->f))
    {
        int true_size = fread(buf, 1, 1024, acq->f);
        printf("read:%d\n", true_size);
        return true_size;
    }
    else
    {
        printf("read failed\n");
        return -1;
    }*/

     //不断读取数据
    while (true)
    {
        IOData data;
        if (acq->data_queue.Pop(data))
        {
            memcpy(buf, data.data, data.len);
            return data.len;
        }
        else
        {
            Sleep(1000);
        }
    }

}

av_register_all();

AVFormatContext* fctx = avformat_alloc_context();
av_buf = av_malloc(AV_IO_BUF_LEN);
avio = avio_alloc_context((uchar*)av_buf, AV_IO_BUF_LEN, 0, this, io_get_data, NULL, NULL);
fctx->pb = avio;

err = avformat_open_input(&fctx, "none", NULL, NULL);

printf("open input:%d\n", err);

err = avformat_find_stream_info(fctx, NULL);

printf("find stream info:%d, streams:%d\n", err, fctx->nb_streams);

int video_id = -1;
for (int i = 0; i < fctx->nb_streams; i++)    //区分视频流和音频流
{
    if (fctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) //找到视频流,这里也可以换成音频
    {
        video_id = i;
        break;
    }
}

printf("video_id:%d\n", video_id);

AVCodec* codec = avcodec_find_decoder(fctx->streams[video_id]->codec->codec_id);
AVCodecContext* cctx = fctx->streams[video_id]->codec;
err = avcodec_open2(cctx, codec, NULL);    // 打开解码器

printf("open codec:%d\n", err);

int width = cctx->width;
int height = cctx->height;

printf("width:%d, height:%d\n", width, height);

AVRational frame_rate = fctx->streams[video_id]->r_frame_rate;

AVPicture pc;
AVPicture* pic = &pc;
avpicture_alloc(pic, PIX_FMT_RGB24, width, height);
AVFrame* frame = av_frame_alloc();

SwsContext* sctx = sws_getContext(width, height, cctx->pix_fmt, width, height, (PixelFormat)PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL);

IplImage* img = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 3);
img->imageSize = pic->linesize[0];
img->imageData = (char *)pic->data[0];

int id = 0;
AVPacket* pck = new AVPacket;
while (av_read_frame(fctx, pck) >= 0)
{
    if (pck->stream_index == video_id)
    {
        int got;
        err = avcodec_decode_video2(cctx, frame, &got, pck);
        if (err < 0)
        {
            printf("decode err:%d\n", err);
            return;
        }

        if (got)
        {
            printf("got img:%d\n", id);
            sws_scale(sctx, frame->data, frame->linesize, 0, height, pic->data, pic->linesize);

            char fname[100];
            sprintf(fname, "./img/%d.jpg", id);
            cvSaveImage(fname, img);

            id++;
        }
    }
}
时间: 2024-11-09 03:09:31

ffmpeg解码内存缓冲区的相关文章

ffmpeg解码流程

来源:http://www.xuebuyuan.com/807209.html ffmpeg解码流程 . 2013年08月20日 ⁄ 综合 ⁄ 共 14054字 ⁄ 字号 小 中 大 ⁄ 评论关闭 文章目录 1. 注册所有容器格式和CODEC:av_register_all() 2. 打开文件:av_open_input_file() 3. 从文件中提取流信息:av_find_stream_info() 4. 穷举所有的流,查找其中种类为CODEC_TYPE_VIDEO 5. 查找对应的解码器:

FFmpeg解码H264及swscale缩放详解

本文概要: 本文介绍著名开源音视频编解码库ffmpeg如何解码h264码流,比较详细阐述了其h264码流输入过程,解码原理,解码过程.同时,大部分应用环境下,以原始码流视频大小展示并不是最佳方式,因此,开发者不仅仅需要对视频流解码,并且需要缩放图像以展示于不同窗体下. 综上,本文除介绍ffmpeg解码h264,同时阐述如何使用swscale缩放视频流. 文章使用的开发环境Ubuntu12.04..交流邮箱:[email protected]. 转载请注明出处 CSDN--固本培元. ffmpeg

ffmpeg 从内存中读取数据

http://blog.csdn.net/leixiaohua1020/article/details/12980423 ffmpeg一般情况下支持打开一个本地文件,例如"C:\test.avi" 或者是一个流媒体协议的URL,例如"rtmp://222.31.64.208/vod/test.flv" 其打开文件的函数是avformat_open_input(),直接将文件路径或者流媒体URL的字符串传递给该函数就可以了. 但其是否支持从内存中读取数据呢?这个问题困

FFMPEG解码264文件步骤

FFMPEG解码264文件步骤: http://www.360doc.com/userhome.aspx?userid=13084517&cid=3# 转载地址:http://www.360doc.com/content/13/0906/18/13084517_312677466.shtml 本文以H264视频流为例,讲解解码流数据的步骤. 为突出重点,本文只专注于讨论解码视频流数据,不涉及其它(如开发环境的配置等).如果您需要这方面的信息,请和我联系. 准备变量 定义AVCodecContex

最简单的基于FFmpeg的内存读写的例子:内存转码器

上篇文章记录了一个基于FFmpeg的内存播放器,可以使用FFmpeg读取并播放内存中的数据.这篇文章记录一个基于FFmpeg的内存转码器.该转码器可以使用FFmpeg读取内存中的数据,转码为H.264之后再将数据输出到内存.关于如何从内存读取数据,以及如何将数据输出到内存,可以参考文章: ffmpeg 从内存中读取数据(或将数据输出到内存) FFmpeg读写内存的关键点有2个:1.       初始化自定义的AVIOContext,指定自定义的回调函数.2.       自己写回调函数.注意函数

最简单的基于FFmpeg的内存读写的例子:内存播放器

打算记录两个最简单的FFmpeg进行内存读写的例子.之前的所有有关FFmpeg的例子都是对文件进行操作的.例如<100行代码实现最简单的基于FFMPEG+SDL的视频播放器>播放的是一个视频的文件.而<最简单的基于FFMPEG的转码程序>也是将一个视频文件转换为另一个视频文件.<最简单的基于FFmpeg的视频编码器(YUV编码为H.264)>也是最后编码得到一个H.264视频文件.实际上,并不是所有视频的编码,解码都是针对文件进行处理的.有的时候需要的解码的视频数据在一

(转)最简单的基于FFmpeg的内存读写的例子:内存播放器

ffmpeg内存播放解码 目录(?)[+] ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的例子:内存播放器 最简单的基于FFmpeg的内存读写的例子:内存转码器 ===================================================== 打算记录两个最简单的FFmpeg进行内存读写的例子.之前的所有有关FFmpe

ffmpeg解码RTSP/TCP视频流H.264(QT界面显示视频画面)

我用的ffmpeg版本为 ffmpeg-2.1.8.tar.bz2 版本低了恐怕有些头文件和API找不到. 在Linux下解压后编译,Linux下编译很简单,我这里生成的动态库: ./configure –enable-shared make 就能找到各个so动态库文件. 移动位置后,记得手动链接 一下: ln -s libavcodec.so.55 libavcodec.so ln -s libavdevice.so.55 libavdevice.so ln -s libavfilter.so

在iOS平台使用ffmpeg解码h264视频流

来源:http://www.aichengxu.com/view/37145 在iOS平台使用ffmpeg解码h264视频流,有需要的朋友可以参考下. 对于视频文件和rtsp之类的主流视频传输协议,ffmpeg提供avformat_open_input接口,直接将文件路径或URL传入即可打开.读取视频数据.解码器初始参数设置等,都可以通过调用API来完成. 但是对于h264流,没有任何封装格式,也就无法使用libavformat.所以许多工作需要自己手工完成. 这里的h264流指AnnexB,也