FFmpeg 获取h264裸码流

有时候我们需要获取h264裸码流进行分析。本文介绍如何通过FFmpeg 获取h264 码流。获取到的h264码流文件 可以直接通过vlc 等播放器直接播放。

如下图 是通过WinHex工具 分析的一个h264文件

ffmpeg 获取h264 思路如下:

1,写4位头(00,00,00,01)

2,写sps

3,写4位头(00,00,00,01)

4,写pps

5,将读到的AVPacket.data 的前4位替换成(00,00,00,01)写文件。

sps pps的获取参考上篇博文。

详细代码如下:

int GetH264Stream()
{
	int ret;
	AVFormatContext *ic=NULL;
	AVFormatContext *oc=NULL;

	uint8_t sps[100];
	uint8_t pps[100];
	int spsLength=0;
	int ppsLength=0;
	uint8_t startcode[4]={00,00,00,01};
	FILE *fp;

	fp=fopen("123.h264","wb+"); 

	char *InputFileName="11111.mp4";

	if ((ret = avformat_open_input(&ic, InputFileName, NULL, NULL)) < 0)
	{
		return ret;
	}

	if ((ret = avformat_find_stream_info(ic, NULL)) < 0)
	{
		avformat_close_input(&ic);
		return ret;
	}  

	spsLength=ic->streams[0]->codec->extradata[6]*0xFF+ic->streams[0]->codec->extradata[7];

	ppsLength=ic->streams[0]->codec->extradata[8+spsLength+1]*0xFF+ic->streams[0]->codec->extradata[8+spsLength+2];

	for (int i=0;i<spsLength;i++)
	{
		sps[i]=ic->streams[0]->codec->extradata[i+8];
	}

	for (int i=0;i<ppsLength;i++)
	{
		pps[i]=ic->streams[0]->codec->extradata[i+8+2+1+spsLength];
	}

	for(int i=0;i<ic->nb_streams;i++)
	{
		if(ic->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
		{
			videoindex=i;
		}
		else if(ic->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO)
		{
			audioindex=i;
		}
	}

	AVOutputFormat *ofmt = NULL;
	AVPacket pkt;

	avformat_alloc_output_context2(&oc, NULL, NULL, OutPutPath);

	if (!oc)
	{
		printf( "Could not create output context\n");
		ret = AVERROR_UNKNOWN;
	}
	ofmt = oc->oformat;
	int i;

	for (i = 0; i < ic->nb_streams; i++)
	{
		AVStream *in_stream = ic->streams[i];
		AVStream *out_stream = avformat_new_stream(oc, in_stream->codec->codec);

		if (!out_stream)
		{
			printf( "Failed allocating output stream\n");
			ret = AVERROR_UNKNOWN;
		}
		ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
		if (ret < 0)
		{
			printf( "Failed to copy context from input to output stream codec context\n");
		}
		out_stream->codec->codec_tag = 0;
		if (oc->oformat->flags & AVFMT_GLOBALHEADER)
			out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
	}

	if (!(ofmt->flags & AVFMT_NOFILE))
	{
		ret = avio_open(&oc->pb, OutPutPath, AVIO_FLAG_WRITE);
		if (ret < 0)
		{
			printf( "Could not open output file '%s'", OutPutPath);

		}
	}
	ret = avformat_write_header(oc, NULL);

	int frame_index=0;
	int flag=1;

	av_init_packet(&pkt);
	pkt.data = NULL;
	pkt.size = 0;

	while (1)
	{
		AVStream *in_stream, *out_stream;

		ret = av_read_frame(ic, &pkt);

		if (ret < 0)
			break;
		in_stream  = ic->streams[pkt.stream_index];
		out_stream = oc->streams[pkt.stream_index];

		AVPacket tmppkt;
		if (in_stream->codec->codec_type==AVMEDIA_TYPE_VIDEO )
		{

			if (flag)
			{
				fwrite(startcode,4,1,fp);
				fwrite(sps,spsLength,1,fp);
				fwrite(startcode,4,1,fp);
				fwrite(pps,ppsLength,1,fp);

				pkt.data[0]=0x00;
				pkt.data[1]=0x00;
				pkt.data[2]=0x00;
				pkt.data[3]=0x01;
				fwrite(pkt.data,pkt.size,1,fp);

				flag=0;
			}
			else
			{
				pkt.data[0]=0x00;
				pkt.data[1]=0x00;
				pkt.data[2]=0x00;
				pkt.data[3]=0x01;
				fwrite(pkt.data,pkt.size,1,fp);
			}

			pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
			pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
			pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
			pkt.pos = -1;

			pkt.stream_index=0;
			ret = av_interleaved_write_frame(oc, &pkt);
		}

		av_free_packet(&pkt);
	}

	fclose(fp);
	fp=NULL;

	av_write_trailer(oc);
	return 0;
}
时间: 2025-01-17 16:35:10

FFmpeg 获取h264裸码流的相关文章

C# 播放H264裸码流

要播放H264裸码流,可以分拆为以下三个工作: 1.解码H264裸码流获取YUV数据 2.将YUV数据转换为RGB数据填充图片 3.将获取的图片进行显示 要完成工作1,我们可以直接使用海思的解码库,由于海思的解码库是C++的动态库,要完成在C#中进行调用可以参考海思h264解码库这篇文章,介绍的很详细.但是对于该博文只介绍了一种帧解码的方法,并没有介绍真正实用的流式解码方法.自己根据解码库的参考文档写了一份C#版的流式解码算法. //初始化 // 这是解码器输出图像信息 hiH264_DEC_F

例程:如何使用PX2硬解码H.264裸码流 [CODE_PX2]Decode_RAW_H264_FILE

Rayeager PX2开发板具有非常强大的多媒体处理能力,如果需要调用硬件加速针对普通媒体文件/码流进行解码,只需按照安卓标准调用多媒体相关接口即可. 针对一些行业用户的特殊需求,Rayeager PX2实际上也开放了接口可以对H.264等裸码流进行解码. 这里提供一份代码即可实现H.264裸码流的解码,如果您具有一定的Android系统开发经验,很快就能理解并进行相关改写.使用方法: 在PX2的Android编译环境根目录下将代码解压,并进入ChipSPARK_PX2_H264_DECODE

利用ffmpeg0.6.1把.h264纯码流打包成.mp4 .avi等格式 (转载)

转自:http://cache2.weidaohang.org/h/index.php?q=aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1cWluZ183MzkvYXJ0aWNsZS9kZXRhaWxzLzY2MzY4NTc= 一直比较困惑一个问题,都说ffmpeg功能很强大,但是自己一直没有去研究一下,今天终于见识了一下它的强大之处了! 首先当然是在linux下编译和安装成功ffmpeg,关于具体的安装流程,可以参考我前面的一篇博文! 这里就直接介绍怎么把.h264纯码流打包

Wireshark Lua: 一个从RTP抓包里导出H.264 Payload,变成264裸码流文件(xxx.264)的Wireshark插件

Wireshark Lua: 一个从RTP抓包里导出H.264 Payload,变成264裸码流文件(xxx.264)的Wireshark插件 在win7-64, wireshark Version 2.0.2 (v2.0.2-0-ga16e22e from master-2.0)是可用的,老版本1.0.x未找到对应的tools选项卡

转:ffmpeg学习(二) 通过rtsp获取H264裸流并保存到mp4文件

本篇将使用上节http://www.cnblogs.com/wenjingu/p/3977015.html中编译好的库文件通过rtsp获取网络上的h464裸流并保存到mp4文件中. 1.VS2010建立VC++  win32控制台项目 2.在工程目录下建立lib目录和include目录,将已编译好的lib拷打lib下,include拷到include下,dll拷到Debug目录下 3.工程属性--配置属性--VC++目录--包含目录,添加ffmpeg头文件目录及其他第三方头文件目录 链接器--常

OpenCV采集的视频流转化成H264格式裸码流

本文通过OpenCV库采集摄像头视频,随后通过libx264库把帧转化成264格式的码流. 头文件: #ifndef _X264_ENCODER_H #define _X264_ENCODER_H #include <stdint.h> #include "x264.h" #include "opencv/cv.h" #include "opencv/highgui.h" struct x264_encoder{ x264_param

MP4box 封装媒体裸码流

MP4BOX是MP4文件封装工具,仅支持命令行方式调用.以下是其支持的字幕封装参数的调用实例: mp4box -add 1.srt:lang=zh:name=Caption:hdlr=sbtl:font="微软雅黑":size=22 -new 1.srt.mp4 如果需要支持iPhone/iTouch/iPod/iPad等设备,可以添加参数“-ipod”: mp4box -ipod -add 1.srt:lang=zh:name=Caption:hdlr=sbtl:font="

ffmpeg推送rtsp码流到rtmp服务器

HIKVISION DS-2CD23RZ admin 12345 rtsp://admin:[email protected]:554/H.264/ch1/main/av_stream ffmpeg -i "rtsp://admin:[email protected]:554/H.264/ch1/main/av_stream" -f flv -r 25 -s 1920x1080 -an "rtmp://182.61.45.149:1935/live/movie" f

H264码流中SPS PPS详解&lt;转&gt;

转载地址:https://zhuanlan.zhihu.com/p/27896239 1 SPS和PPS从何处而来? 2 SPS和PPS中的每个参数起什么作用? 3 如何解析SDP中包含的H.264的SPS和PPS串? 1 客户端抓包 在做客户端视频解码时,一般都会使用Wireshark抓包工具对接收的H264码流进行分析,如下所示: 在这里我们可以看到对解码视频起关键作用的SPS和PPS. 双击SPS内容如下: 双击PPS内容如下: 那么从上面的sps中我们知道图像的宽,高. 宽=(19+1