热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ffmpeg解码出现问题,v1.2.1版本,v2.1版本有问题,v0.6.0版本没有问题

1)当Live555收到的数据中连续来两个I帧,然后P帧,ffmpeg解码有问题;解决办法:当presntationTime不同时候&#

1)当Live555收到的数据中连续来两个I帧,然后P帧,ffmpeg解码有问题;

解决办法:

      当presntationTime不同时候,将以前存的buffer(已经是完整一帧)传给avcodec_decode_video2解码; 根据时间戳组帧将sps pps I 帧 I帧的组成一帧,交个ffmpeg解码,搞定;

 

2) 通过live555将阿波罗的相机的h264码流录制成avi,然后通过ffmpeg转成.h264,在用live555的testDemandRtspServer例子做服务器,然后通过testRtspClient做客户端进行接收,实时解码,发现前面一个GOP的数据解码不出来;前面一个GOP也是有sps pps I帧,然后若干P帧的,但是过了一个GOP后,解码就正常了。诧异!

avcodec_decode_video2返回值=-1;got_picture=0;

错误如下:

 

第一个Gop的第一个I帧 的sps,pps,I帧 的包是分别丢给解码器的,ffmpeg提示错误是no frame!

 

后面接着的一个P帧,就解码不出来,提示错误Missing reference picture. default is 0

 

第2个P帧开始的P帧提示错误:non-existing PPS 0 referenced.

 

调试记录:

1)根据时间戳不同组包,交给ffmpeg,也是前面一个Gop解码不出来;

2)后面尝试第一次从SDP从获取sps和pps信息,即第一帧数据是sps pps sps pps I帧,然后是若干个P帧,接着sps pps I帧,这样也是第一个GOP不能解码;

3)将第一帧的I帧反复交给ffmpeg,是可以解码的;

 

 

解决方案:

1)原因ffmpeg v1.2.1 版本,换成老的ffmpeg V0.6.0解决;

为什么会有问题,还需要分析ffmpeg v1.2.1版本的源码,是不是它需要缓冲多少帧,造成前面的一个GOP的图像解码不出来。

继续定位发现:v1.2.1 版本的第一个I帧解码 avcodec_decode_video2返回值为一帧数据的size,但是

len = avcodec_decode_video2(DecodecContext, m_pFrame, &got_picture,&avpkt);

gop_picture的值=0;

 

 

环境搭建:

1)  live555 做服务器;客户端使用live555接收数据流;然后将接收到的数据帧插入到一个队列;另外一个显示线程从队列中取一帧数据进行解码,显示;

2)  从2个队列做缓冲区,首先是一个空的队列,在上面分配内存,形成一个链表;收到一帧数据后,从链表的头取一个节点,将一帧数据拷贝到该个节点上,然后插入到另外一个H264数据帧队列,一定要记得到H264数据帧队列的尾部;

3)  显示线程从H264队列的头取一个节点(一定要从头开始取节点);然后解码显示;

 

 

出现过的问题:

1)  插入H264队列时,插入到队列的头,取H264帧的时候也从头开始取,这样造成后来的数据显取了,解码出错;

 

现象:

Live555 sink 的afterGettingFrame函数中进行数据组帧,入队列操作,由于live555已经将rtp包头丢掉了,得到的一帧的数据,有可能有4种包,sps pps I 帧,p帧;

 

组帧策略:

按时间组帧,首先将时间戳相同的数据包组成一帧,然后插入到队列;

直接在数据到帧前加00 00 00 01 头后,插入到队列;

 

 

结论:

两种方法,ffmpeg都可以解码;使用的是ffmpeg 1.2.1 的版本;但是前面有一个GOP不能解码,原因不详;换成v0.6.0版本的ffmpeg库进行测试;解码正常!

有谁知道是什么原因的,麻烦告诉我下,谢谢!

 

今天又下载了一个最新的版本V2.1进行测试,还是发现前面一个GOP的图像解码失败,难道要用回老的版本v0.6.0

 

问题搞定:

      是初始化解码器的分辨率和实际图像的分辨率不一致的问题;本来解码器是讲H264数据解码成Yuv数据的,但是我将yuv数据转换到RGB了,给RGB分配了内存,在解码器初始化函数里面:


#ifdef OUTPUT_RGB

 m_pFrameRGB = avcodec_alloc_frame();
 if(m_pFrameRGB == NULL)
 {
  return false;   
 }

 int numBytes=avpicture_get_size(PIX_FMT_RGB24, DecodecContext->width, DecodecContext->height);
 m_Rgbbuffer=new uint8_t[numBytes];   

 // Assign appropriate parts of buffer to image planes in pFrameRGB
 avpicture_fill((AVPicture *)m_pFrameRGB, m_Rgbbuffer, PIX_FMT_RGB24, DecodecContext->width, DecodecContext->height);

 img_convert_ctx = sws_getContext(DecodecContext->width, DecodecContext->height, DecodecContext->pix_fmt,
  DecodecContext->width, DecodecContext->height, PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL);

 if(img_convert_ctx == NULL)
 {
  fprintf(stderr, "Cannot initialize the conversion context!\n");
  return false;
 }

 iDecodeWidth=DecodecContext->width;
 iDecodeHeight=DecodecContext->height;

#endif

 

实际上,如果不转RGB是跟分辨率没有关系的,转RGB后分配的内存和分辨率有关系,所以在解码后,判断分辨率和我设置的分辨率不一致时,有调用了反解码器函数,释放ffmpeg的资源,然后在重新调用解码器初始化函数,这样就出现了前面一个GOP不能解码的问题;

 

 


推荐阅读
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文探讨了如何在iOS开发环境中,特别是在Xcode 6.1中,设置和应用自定义文本样式。我们将详细介绍实现方法,并提供一些实用的技巧。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 深入探讨CPU虚拟化与KVM内存管理
    本文详细介绍了现代服务器架构中的CPU虚拟化技术,包括SMP、NUMA和MPP三种多处理器结构,并深入探讨了KVM的内存虚拟化机制。通过对比不同架构的特点和应用场景,帮助读者理解如何选择最适合的架构以优化性能。 ... [详细]
  • 对象自省自省在计算机编程领域里,是指在运行时判断一个对象的类型和能力。dir能够返回一个列表,列举了一个对象所拥有的属性和方法。my_list[ ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 本文探讨了如何通过预处理器开关选择不同的类实现,并解决在特定情况下遇到的链接器错误。 ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
author-avatar
729453686_5be5b9
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有