播放jpeg时,avformat_find_stream_info出现以下问题,排查:

[jpeg_pipe @ 0x146a80] Could not find codec parameters for stream 0 (Video: mjpeg, none(bt470bg/unknown/unknown)): unspecified size
Consider increasing the value for the 'analyzeduration' and 'probesize' options

1. 打印开启的codec信息,发现mjpeg codec已经开启

AVCodec * av_codec = av_codec_next(NULL);
while(av_codec)
{
printf("codec name:%s\n", av_codec->name);
av_codec = av_codec_next(av_codec);
}

检查demux的支持哪些format状况

AVInputFormat *av_i = av_iformat_next(NULL);
while(av_i)
{
printf("name:%s\n", av_i->name);
av_i = av_iformat_next(av_i);
}

2. 阅读avformat_find_stream_info代码,在里面加log确认卡住的地方

发现has_codec_parameters()check失败导致,然后就追查avctx->width为何没有赋值。

  

3.发现read_frame_internal()调用出错,导致没有try decode。然后trace flow

4.iformat->read_packet(),format已经知道为jpeg_pipe,可惜搜不到相应的demuxer。

好像是这里,可惜搜不到函数。wav有ff_wav_demuxer,但是image_jpeg_pipe没有ff_image_jpeg_pipe的变量定义。

此时你已经知道自己掉坑里了,没事,习惯就好了。

void av_register_all(void)
{
//...
/* image demuxers */
REGISTER_DEMUXER (IMAGE_JPEG_PIPE, image_jpeg_pipe);
REGISTER_DEMUXER (IMAGE_JPEGLS_PIPE, image_jpegls_pipe);
//...
}

最后发现定义在img2dec.c中,别问我怎么找到的,_pipe这个字符串不是很特别嘛,虽然也很多。。。

#define IMAGEAUTO_DEMUXER(imgname, codecid)\
static const AVClass imgname ## _class = {\
.class_name = AV_STRINGIFY(imgname) " demuxer",\
.item_name = av_default_item_name,\
.option = ff_img_options,\
.version = LIBAVUTIL_VERSION_INT,\
};\
AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
.name = AV_STRINGIFY(imgname) "_pipe",\
.long_name = NULL_IF_CONFIG_SMALL("piped " AV_STRINGIFY(imgname) " sequence"),\
.priv_data_size = sizeof(VideoDemuxData),\
.read_probe = imgname ## _probe,\
.read_header = ff_img_read_header,\
.read_packet = ff_img_read_packet,\
.priv_class = & imgname ## _class,\
.flags = AVFMT_GENERIC_INDEX, \
.raw_codec_id = codecid,\
}; IMAGEAUTO_DEMUXER(bmp, AV_CODEC_ID_BMP)
IMAGEAUTO_DEMUXER(dds, AV_CODEC_ID_DDS)
IMAGEAUTO_DEMUXER(dpx, AV_CODEC_ID_DPX)
IMAGEAUTO_DEMUXER(exr, AV_CODEC_ID_EXR)
IMAGEAUTO_DEMUXER(j2k, AV_CODEC_ID_JPEG2000)
IMAGEAUTO_DEMUXER(jpeg, AV_CODEC_ID_MJPEG)
IMAGEAUTO_DEMUXER(jpegls, AV_CODEC_ID_JPEGLS)
IMAGEAUTO_DEMUXER(pictor, AV_CODEC_ID_PICTOR)
IMAGEAUTO_DEMUXER(png, AV_CODEC_ID_PNG)
IMAGEAUTO_DEMUXER(qdraw, AV_CODEC_ID_QDRAW)
IMAGEAUTO_DEMUXER(sgi, AV_CODEC_ID_SGI)
IMAGEAUTO_DEMUXER(sunrast, AV_CODEC_ID_SUNRAST)
IMAGEAUTO_DEMUXER(tiff, AV_CODEC_ID_TIFF)
IMAGEAUTO_DEMUXER(webp, AV_CODEC_ID_WEBP)

4. 进入ff_img_read_packet分析,这个流程图就不画了(因为网上没搜到)

原因很简单我的avio不能seek,所以size[0]为-38,然后packet new不出来,然后就少了一个螺丝钉,然后就打仗打输了。

所以问题点就是我的avio不能seek?what?

    } else {
f[] = s1->pb;
if (avio_feof(f[]) && s->loop && s->is_pipe)
avio_seek(f[], , SEEK_SET);
if (avio_feof(f[]))
return AVERROR_EOF;
if (s->frame_size > ) {
size[] = s->frame_size;
} else if (!s1->streams[]->parser) {
size[] = avio_size(s1->pb);//执行到这咯,size[0]为-38
} else {
size[] = ;
}
}
//这个报错了,res为-22
res = av_new_packet(pkt, size[] + size[] + size[]);

5. avio不能seek是由于,这个avio是定制的(说白了,自己写的,自己给自己挖坑)

AVIOContext *avio_alloc_context(
unsigned char *buffer,
int buffer_size,
int write_flag,
void *opaque,
int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
int64_t (*seek)(void *opaque, int64_t offset, int whence)) //...
avio = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,
, &bd, &read_bs, NULL, NULL);

6.当然如果故事就这样结束了,我也会很happy。同样的图片解码的code,在另一个平台用得好好的,但在这个平台却非要实现一个seek不可?

7.然后在另一个ok的平台上调试,发现走的flow不一样。

在另一个平台上是有相应的parser的。

    } else {
f[] = s1->pb;
if (avio_feof(f[]) && s->loop && s->is_pipe)
avio_seek(f[], , SEEK_SET);
if (avio_feof(f[]))
return AVERROR_EOF;
if (s->frame_size > ) {
size[] = s->frame_size;
} else if (!s1->streams[]->parser) {
size[] = avio_size(s1->pb);
} else {
size[] = ;//我是走这的,笨蛋
}
} res = av_new_packet(pkt, size[] + size[] + size[]);

8. 最终原因很简单,该平台的mjpeg的parse没有开....

9.找到原因就结束了吗?!当然不是,我们还要认真反思。(被老板发现,一分钟就可以开好的配置,具体调试了一天,分分钟被抽死)

第一步就检查了配置,而且是在代码里加code,这样太不方便了。

./configure就会打印到底开了哪些,如果一开始就仔细检查是不是就不用这么花时间调试了。(假装自己是老板,严厉呵斥该码农)

Enabled programs:
ffmpeg ffprobe ffserver External libraries:
iconv zlib External libraries providing hardware acceleration:
cuda cuvid nvenc Libraries:
avcodec avdevice avfilter avformat avutil swresample swscale Enabled decoders:
aac adpcm_yamaha cpia fourxm mdec on2avc pjs srt vp3 Enabled encoders:
a64multi ass ffv1 mjpeg pcm_alaw pcm_s64be prores_aw srt vorbis
a64multi5 Enabled parsers:
aac cavsvideo dpx dvdsub h261 mjpeg mpegvideo rv30 vorbis
aac_latm

10. 还有第十步,不说了,今晚又得加班了...

ffmpeg jpeg图片播放失败之问题排查的更多相关文章

  1. jquery图片播放切换插件

    点击这里查看效果可自定义数字样式和左右点击按钮 这个更好:移入按钮切换版本 更多图片轮播 以下是HTML文件代码: <!DOCTYPE html PUBLIC "-//W3C//DTD ...

  2. ijg库解码超大型jpeg图片

    1. ijg库解码超大型jpeg图片(>100M)的时候,如何避免内存溢出. 采用边解码边压缩的策略,每次解码一行或者若干行图片数据,然后对于这些解码的数据,进行DQT(量化处理,过滤掉高频的数 ...

  3. Slider.js轻量级图片播放控件

    Slider.js基于HTML5和CSS3实现的Slideshow 1.Slider.js 是一个图片播放Slideshow引擎,采用jQuery.CSS3和HTML5 canvas技术实现. 2.可 ...

  4. 基于Live555,ffmpeg的RTSP播放器直播与点播

    基于Live555,ffmpeg的RTSP播放器直播与点播 多路RTSP高清视频播放器下载地址:http://download.csdn.net/detail/u011352914/6604437多路 ...

  5. 渐进式jpeg(progressive jpeg)图片及其相关 --图片的两种加载方式

    渐进式jpeg(progressive jpeg)图片及其相关   一.基本JPEG(baseline jpeg)和渐进JPEG 网络上那些色色的照片都是.jpg格式的("色色"指 ...

  6. 分享8款精美的jQuery图片播放插件

    本文将和大家一起分享8款精美的jQuery图片播放插件,每一款插件均有演示和源码下载,有兴趣的朋友可以下载使用和研究.废话不多说了,直接上这些插件. 1.3D轮播相册 这款3D相册插件利用了HTML5 ...

  7. HTML5动画图片播放器 高端大气

    我们见过很多图片播放插件(焦点图),很多都基于jQuery.今天介绍的HTML5图片播放器很特别,它不仅在图片间切换有过渡动画效果,而且在切换时图片中的元素也将出现动画效果,比如图中的文字移动.打散. ...

  8. WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放、图片立体轮播、图片倒影立体滚动)效果实现

    原文:WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放.图片立体轮播.图片倒影立体滚动)效果实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7 ...

  9. BMP图片转换为JPEG图片

    原文:BMP图片转换为JPEG图片 昨天在家学习,发现很多人把BMP图片转换为其它图片格式,有些人写得简单,有些人写得复杂. Insus.NET在想,一直在做文件上传,下载,或是图片剪切,都有进行过文 ...

随机推荐

  1. Linux各目录缩写含义

    Unix已经有35年历史了.许多人认为它开始于中世纪,这个中世纪是相对于计算机技术的产生和发展来说的.在过去的时间里,Unix和它的子分支Linux收集有许多的历史和一些完全古老的语言.在这篇技巧文章 ...

  2. KALI视频学习11-15

    KALI视频学习11-15 第十一集 看到openvas的主界面(web界面) ping靶机,看是否能正常连通 创建一个扫描目标Configuration-Targets,默认扫描目标为本机 添加一个 ...

  3. KALI LINUX系统初始化配置

    1.Kali Linux安装VirtualBox增强功能 VirtualBox增强功能介绍:物理机与虚拟机之间的文件共享.物理机与虚拟机之间的剪切板共享.虚拟机的direct3D支持,这样虚拟机窗口就 ...

  4. BZOJ 3192: [JLOI2013]删除物品 奇淫技巧&树状数组

    点我看题 这题十分奇淫技巧...QAQ因为知道是树状数组的题QAQ刚开始以为维护两个数组的树状数组然后模拟从大到小,然后发现不会打QAQ 于是悄悄咪咪翻开题解了. 实际上两个数组可以看做一个数组 如 ...

  5. scrapy之Pymongo

    用Pymongo保存数据 爬取豆瓣电影top250movie.douban.com/top250的电影数据,并保存在MongoDB中. items.py class DoubanspiderItem( ...

  6. 将应用注册为Linux的服务

    主流的Linux大多使用init.d或systemd来注册服务.下面以centos6.6演示init.d注册服务:以centos7.1演示systemd注册服务. 1. 基于Linux的init.d部 ...

  7. class.getResource()和getResourceAsStream的用法

    转自:http://blog.csdn.net/lcj8/article/details/3502849 class.getResource()的用法 用JAVA获取文件,听似简单,但对于很多像我这样 ...

  8. WinCE数据通讯之Web Service篇

    准备写个WinCE平台与数据库服务器数据通讯交互方面的专题文章,今天先整理个Web Service通讯方式. 公司目前的硬件产品平台是WinCE5.0,数据通讯是连接服务器与终端的桥梁,关系着终端的数 ...

  9. js 冒泡型事件

  10. Web应用体系结构

    容器 Servlet没有main()方法,它们受控于另一个Java应用,这个Java应用称为容器(Container).我们最常见的tomcat就是这样一个容器. Web服务器应用(如Apache)得 ...