码迷,mamicode.com
首页 > 其他好文 > 详细

ffmpeg解码内存缓冲区

时间:2014-12-01 14:23:35      阅读:893      评论:0      收藏:0      [点我收藏+]

标签:blog   io   ar   sp   for   文件   on   数据   2014   

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


与解码文件的大致过程类似,只不过自定义了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++;
        }
    }
}


ffmpeg解码内存缓冲区

标签:blog   io   ar   sp   for   文件   on   数据   2014   

原文地址:http://blog.csdn.net/tobacco5648/article/details/41646227

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!