在做一个数据通道

要求有两个

1.支持打开实时流,解码得到图片

2.支持打开视频文件,得到解码图片

第一个要求前任已经实现

 bool FfmpegStreamChr::Open(const char *pstrFilename)
{
Close();
avformat_network_init();
av_register_all(); std::string tempfile = pstrFilename;
AVDictionary* options = NULL;
if (tempfile.size() > )
{
if (memcmp(tempfile.c_str() + tempfile.size() - , "#tcp", ) == )
{
av_dict_set(&options, "rtsp_transport", "tcp", );
tempfile.erase(tempfile.size() - );
}
} //format_context_ = avformat_alloc_cotext(); av_dict_set(&options, "stimeout","", );
if (avformat_open_input(&format_context_, tempfile.c_str(), NULL, &options) < )
return false; if (avformat_find_stream_info(format_context_, nullptr) < )
return false; av_dump_format(format_context_, , tempfile.c_str(), ); video_stream_index_ = -; pts_first = true;
duration = format_context_->duration / AV_TIME_BASE; int video_stream_idx = av_find_best_stream(format_context_, AVMEDIA_TYPE_VIDEO, -, -, NULL, );
video_st = format_context_->streams[video_stream_idx]; for (unsigned int i = ; i < format_context_->nb_streams; i++)
{
AVCodecParameters *enc = format_context_->streams[i]->codecpar;
if (!enc)
continue;
if (AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream_index_ < )
{
width_ = enc->width;
height_ = enc->height; codec_ = avcodec_find_decoder(enc->codec_id);
if (!codec_)
return false;
codec_context_ = avcodec_alloc_context3(codec_);
if (!codec_context_)
return false;
if (avcodec_open2(codec_context_, codec_, NULL) < )
{
avcodec_free_context(&codec_context_);
return false;
} if (width_ && (enc->width != width_))
enc->width = width_; if (height_ && (enc->height != height_)) enc->height = height_; video_stream_index_ = i;
}
}
if (video_stream_index_ == -)
return false; yuv_frame_ = av_frame_alloc();
memset(rgb_data_, , sizeof(uint8_t *) * );
memset(rgb_line_size_, , sizeof(int) * );
rgb_line_size_[] = * width_;
DecodeToImage();
return true;
}
bool FfmpegStreamChr::DecodeToImage(){
if (!format_context_ ||!codec_context_)
return false;
int count_no_video_stream = ;
int continue_counts = ;
const int max_number_of_attempts = ;
// const int max_number_of_video_stream_attempts = 1 << 16;
for (;;)
{
TempImg = cv::Mat();
if (continue_counts > max_number_of_attempts)
return false; // opt_time = GetTickCount();
int ret = av_read_frame(format_context_, &packet_); if (ret == AVERROR(EAGAIN))
{
++continue_counts;
continue;
}
if (ret < )
continue; if (packet_.stream_index != video_stream_index_)
{
// count_no_video_stream++;
//if (count_no_video_stream > max_number_of_video_stream_attempts)
// return false;
av_packet_unref(&packet_);
TempImg.release();
continue;
} // std::chrono::system_clock::time_point t1 = std::chrono::system_clock::now();
ret = avcodec_send_packet(codec_context_, &packet_); if (avcodec_receive_frame(codec_context_, yuv_frame_) == )
{
//std::chrono::system_clock::time_point t2 = std::chrono::system_clock::now();
if (!y2r_sws_context_)
{
y2r_sws_context_ = sws_getContext(width_, height_,
codec_context_->pix_fmt, codec_context_->width, codec_context_->height, /*video_stream_->codec->pix_fmt*/ AV_PIX_FMT_BGR24, /*SWS_BICUBIC*/ SWS_BILINEAR, NULL, NULL, NULL);
if (!y2r_sws_context_)
{
av_packet_unref(&packet_);
TempImg.release();
continue;
}
} if (!TempImg.data)
TempImg.create(height_, width_, CV_8UC3);
rgb_data_[] = TempImg.data; if (sws_scale(y2r_sws_context_, yuv_frame_->data, yuv_frame_->linesize, , codec_context_->height, rgb_data_, rgb_line_size_) <= )
{
av_packet_unref(&packet_);
TempImg.release();
av_frame_unref(yuv_frame_);
return false;
} // std::chrono::system_clock::time_point t3 = std::chrono::system_clock::now();
//printf("decode : %d , switch : %d\n", std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count(), std::chrono::duration_cast<std::chrono::milliseconds>(t3 - t2).count());
if (pts_first)
{
bg_pts = packet_.pts;
pts_first = false;
}
//timestamp = yuv_frame_->pts*av_q2d(video_st->time_base);
// timestamp = (packet_.pts - bg_pts)*av_q2d(video_st->time_base);
// durationstamp = duration; av_packet_unref(&packet_);
av_frame_unref(yuv_frame_);
// return true;
LOG_DEBUG() << "SendToAll \n";
SendToAll(TempImg); } ++continue_counts;
av_packet_unref(&packet_);
} }

解码文件的时候报如下错

Error splitting the input into NAL units

加入如下代码添加到open函数的54行后面,正常解码文件

        //TODO:: add to hanldle file
if (avcodec_parameters_to_context(codec_context_, enc) < ){
return false;
}

ffempg支持文件解码的更多相关文章

  1. RPC基于http协议通过netty支持文件上传下载

    本人在中间件研发组(主要开发RPC),近期遇到一个需求:RPC基于http协议通过netty支持文件上传下载 经过一系列的资料查找学习,终于实现了该功能 通过netty实现文件上传下载,主要在编解码时 ...

  2. CListCtrlEx:一个支持文件拖放和实时监视的列表控件——用未公开API函数实现Shell实时监视

    一.需求无论何时,当你在Explorer窗口中创建.删除或重命名一个文件夹/文件,或者插入拔除移动存储器时,Windows总是能非常快速地更新它所有的视图.有时候我们的程序中也需要这样的功能,以便当用 ...

  3. HDFS只支持文件append操作, 而依赖HDFS的HBase如何完成数据的增删改查

    转:http://www.th7.cn/db/nosql/201510/135382.shtml 1. HDFS的文件append功能 早期版本的HDFS不支持任何的文件更新操作,一旦一个文件创建.写 ...

  4. Openresty + nginx-upload-module支持文件上传

    0. 说明 这种方式其实复杂,麻烦!建议通过这个方式搭建Openresty文件上传和下载服务器:http://www.cnblogs.com/lujiango/p/9056680.html 1. 包下 ...

  5. 修改Typora的代码以支持文件夹和文件混合排序

    用Markdown文件写笔记,用文件夹做分类,整个笔记文档项目构成了一个树形结构.笔记文章之间.文章与分类之间经常有特定的先后顺序,于是就在文件名前面加上数字前缀来控制排序.但是,Windows的文件 ...

  6. java nio 写一个完整的http服务器 支持文件上传 chunk传输 gzip 压缩 使用过程 和servlet差不多

    java nio 写一个完整的http服务器  支持文件上传   chunk传输    gzip 压缩      也仿照着 netty处理了NIO的空轮询BUG        本项目并不复杂 代码不多 ...

  7. 【Linux_Fedora_应用系列】_2_如何安装视频播放器和视频文件解码

    在前面的一篇博文中,我们进行了音乐播放器的安装和解码器的安装.[Linux_Fedora_应用系列]_1_如何安装音乐播放器和mp3解码 这里我们来进行视频播放器的安装.我们还是通过yum方式安装. ...

  8. FFmpeg4.0笔记:本地媒体文件解码、帧格式转换、重采样、编码、封装、转封装、avio、硬解码等例子

    Github https://github.com/gongluck/FFmpeg4.0-study/blob/master/official%20example/my_example.cpp #in ...

  9. springmvc学习笔记--支持文件上传和阿里云OSS API简介

    前言: Web开发中图片上传的功能很常见, 本篇博客来讲述下springmvc如何实现图片上传的功能. 主要讲述依赖包引入, 配置项, 本地存储和云存储方案(阿里云的OSS服务). 铺垫: 文件上传是 ...

随机推荐

  1. python处理csv文件问题解决贴

    实际工作中,碰到这么个问题:有个软件跑在linux系统上,其中用到一个数据库是csv格式的,但要向这个数据库添加600行新的数据,数据源同样是一个csv格式的文件. 有了目标,开始干活.首先想到的是, ...

  2. gulp入门详细教程

    简介:gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成:使用她,我们不仅可以很愉快的编写代码, ...

  3. 时间紧任务重---extjs的学习就这么开始吧

    我们的extjs借助了一个模板引擎--artTemplate,它是一个开源的项目,不多说,给个链接吧:http://aui.github.io/artTemplate/ 直接上代码: <!DOC ...

  4. loadrunner 录制TCP协议脚本操作

    测试TCP协议的项目,涉及到登陆.发送实时数据.指令.登出等,直接写报文工作量太大,所以需要录制报文. 操作方法如下: 1.启动服务端程序 2.使用winsocket协议 3.选择应用程序 4.录制选 ...

  5. hdu1570(排列和组合公式的应用)

    题意: 给出字符A.则求全排列 A(n,m)=n!/(n-m)! 给出字符C.则求全组合 C(n,m)=n!/(m!*(n-m)!) http://acm.hdu.edu.cn/showproblem ...

  6. 用JAVA自己画一张二维码

    我们都知道,最近2年移动支付在中国堪称新四大发明之一. 二维码无处不在,特别是最近的支付宝扫码领红包,微信,qq,到处在发,阿里有点攻占腾讯移动支付市场的势头啊~博主忽然就对二维码是怎么画的有了点好奇 ...

  7. cookie和session(一)

    先来谈谈我对session和cookie的理解,事实上,只要你去面试web开发,面试官十有八九会问这个问题. cookie和session经常被放在一起问,其实在我看来这两个东西完全是两个不一样的. ...

  8. springboot整合系列

    Spring Boot 系列 博客原文:http://blog.csdn.net/isea533/article/details/50412212 Spring Boot 入门 Spring Boot ...

  9. git忽略文件

    .gitignore文件配置 ###################### # Project Specific ###################### /src/main/webapp/dis ...

  10. 虚拟机修改静态ip

    1.设置虚拟机的网络选择方式,使用NAT模式,选择这个模式后网段与主机的网段不是一个网段,一般选择桥接模式 2.选择VMnet8, 去掉 使用本地DHCP服务将ip分配给虚拟机 这个选项,不然设置ip ...