基于ffmpeg的内存数据UDP直播推流

原创 2016年06月01日 10:39:29

最近在做基于ffmpeg的数字电视信号直播推流的工作。在参考大神的博客文章后,http://blog.csdn.net/leixiaohua1020/article/details/39803457,中间碰到点问题,总结一下。


1.推送内存中的视频数据

要完成的工作是arm从dvb_ip网关FPGA寄存器中读取数字电视ts流,进行直播推流。所以要从内存地址中读取输入的ts流,采取回调函数进行,相关工作基本参考大神文章 http://blog.csdn.net/leixiaohua1020/article/details/12980423,关键要在avformat_open_input()之前初始化一个AVIOContext,而且将原本的AVFormatContext的指针pb(AVIOContext类型)指向这个自行初始化AVIOContext。

  1. unsigned char * iobuffer=(unsigned char *)av_malloc(32768);  
  2. AVIOContext *avio =avio_alloc_context(iobuffer, 32768,0,NULL,fill_iobuffer,NULL,NULL);  
  3. ic->pb=avio;  
  4. err = avformat_open_input(&ic, "nothing", NULL, NULL); 

而主要在于avio_alloc_context回调函数。
2
3
4
5
6
7
8
9

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));
回调函数
extern int fill_iobuffer(void *opaque, unsigned char *buf, int buf_size)
{
	int totSize = 0;	
	int i;	
	
	unsigned short *len_addr,*data_addr;	
	len_addr = (unsigned short*)(*(unsigned int*)opaque);
	data_addr = (unsigned short*)(*((unsigned int*)opaque+1));

	while(totSize < buf_size)
	{	
		unsigned short len = *len_addr;	

		for (i = 0; i < len & (totSize < buf_size); i++)
		{
			unsigned short data = *data_addr;
			buf[totSize++] = (unsigned char)(data >> 8);
			buf[totSize++] = (unsigned char)(data);						
		}	

	}
	
	//printf("the size is%d\n",totSize);
	return totSize;	
}
将buf_size大小的数据读到buf中,并返回buf大小,buf大小参照VLC设置为32k,自己可以设置。(读取过程中,出现一级错误,可能FPGA寄存器和读取速度不匹配导致,或者GPMC被占用,速率不足导致,具体原因后续分析)。


2.推流程序
基本与参考文章中一致。主要修改了2个部分。



(1)去除了流控延时部分

由于是实时流,就取消了延时部分。并且由于GPMC速率登问题,采集的原始stream会有一级错误,在做延时处理的时候,会报错而无法推流成功。


(2)屏蔽dts>pts的错误

在计算dts的时候,开始dts的计算简单地等于pts,由于B帧的存在,dts是小于pts的。稍作改进,下一帧的dts是上一帧的pts就可以了。

程序在调试的时候会出现这样的错误,application provided invalid,non monotonically increasing dts to muxer in stream 0


网上有说音视频的duration不同而导致的,有说出现的包导致dts>pts。错误处理程序compute_pkt_fields2(),函数的定义位于libavformat\mux.c,错误处理部分如下所示。


从中可以看到,ffmpeg在检查dts、pts合理性时,若出现dts>pts的情况,会报错,停止推流。简单的处理,就是规避合理性检查。从源头中解决出现这种错误,还需再做研究。



版权声明:本文为博主原创文章,未经博主允许不得转载。

FFmpeg发送流媒体的命令(UDP,RTP,RTMP)

这两天研究了FFmpeg发送流媒体的命令,在此简单记录一下以作备忘。1.      UDP1.1. 发送H.264裸流至组播地址(注:组播地址指的范围是224.0.0.0—239.255.255.25...

利用ffmpeg 推送及播放udp rtp

推送:ffmpeg -re -i test.264 -vcodec copy -f h264 udp://10.0.192.82:6970 拉取:ffplay -f h264 udp://10.0.1...

ffmpeg h264+ts +udp传输

本文转载自  ffmpeg h264+ts +udp传输 http://www.cnblogs.com/pengkunfan/p/3501187.html http:...

FFmpeg 命令行推流 传视频到组播①

把视频传到组播,这里我用的是h264视频流,所以视频要先用命令行转为.h264文件...

VLC搭建UDP直播流,图文介绍

实现的效果:       将一个视频通过vlc播放器推送到另外一个vlc播放器上,并且实现播放       window电脑为服务器,也就是推送端,ip地址不需要考虑       Mac电脑为客户端,...
  • taoerit
  • taoerit
  • 2017年07月15日 15:38
  • 1145

视频技术系列(2):基于UDP和TCP的RTSP推流

对于视频直播流传输来讲,RTMP和RTSP是常用的2种上行传输方式(这里暂时不讨论基于HTTP的Living方式),通常熟悉的应用方式是RTMP推流,RTSP拉流。但实际上,RTSP也是可以方便实现推...
  • gmer1
  • gmer1
  • 2016年11月07日 11:06
  • 1256

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

搭建rtmp直播流服务之2:使用java实现ffmpeg命令接口化调用(用java执行ffmpeg命令)

一、环境搭建 1、安装ffmpeg 下载对应系统的ffmpeg安装包,个人采用windows平台进行开发,所以安装了windows版本(各平台ffmpeg命令都是一样的,无须纠结) 2、ffmpeg的...
  • eguid_1
  • eguid_1
  • 2016年06月28日 17:50
  • 10479

javaCV开发详解之3:收流器实现,录制流媒体服务器的rtsp/rtmp视频文件(基于javaCV-FFMPEG)

javacv系列文章: javacv开发详解之1:调用本机摄像头视频(使用图片进行视频模拟) javaCV开发详解之2:推流器实现和摄像头录制视频功能(支持windows/linux/mac/Andr...
  • eguid_1
  • eguid_1
  • 2016年09月27日 15:16
  • 7568

ffmpeg推送rtsp交互流程--udp

OPTIONS rtsp://10.10.27.222:554/push.sdp RTSP/1.0 CSeq: 1 User-Agent: Lavf57.29.100 RTSP/1.0 200 O...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:基于ffmpeg的内存数据UDP直播推流
举报原因:
原因补充:

(最多只允许输入30个字)