码迷,mamicode.com
首页 > 其他好文 > 详细

ffmpeg转码之TS转PS

时间:2015-01-13 16:11:25      阅读:1177      评论:0      收藏:0      [点我收藏+]

标签:ffmpeg

写了一个ts转ps的demo。ts数据从文件中读取。

ffmpeg怎么从从内存中获取看这篇博文http://blog.csdn.net/rootusers/article/details/42551935

然后将ts流转换为ps流,存储在内存中。

下面是代码:

<pre name="code" class="cpp">extern "C"
{
#include "libavformat/avformat.h"
}
FILE *file = NULL;
int write_packet(void *opaque, uint8_t *buf, int buf_size)
{
	//printf("write data\n");
	if (file)
		fwrite(buf, buf_size, 1, file);//可以写文件,也可以通过协议发出去
	return 0;
}

int main(int argc, char **argv)
{
	fopen_s(&file, "output.dat", "ab+");//输出ps数据到文件
	if (file == NULL)
		printf("open output file failed\n");

	AVIOContext* pb = NULL;
	AVOutputFormat *ofmt = (AVOutputFormat*)av_mallocz(sizeof(AVOutputFormat));//输出格式
	
	AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
	AVPacket pkt;
	const char *in_filename, *out_filename;
	int ret, i;


	in_filename = "nihao.ts";//源文件

	av_register_all();

	if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
		fprintf(stderr, "Could not open input file '%s'", in_filename);
		goto end;
	}

	if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
		fprintf(stderr, "Failed to retrieve input stream information");
		goto end;
	}
	av_dump_format(ifmt_ctx, 0, in_filename, 0);

	uint8_t* buf = (uint8_t*)av_mallocz(sizeof(uint8_t)* 32768);
	pb = avio_alloc_context(buf, 32768, 0, NULL, NULL, write_packet, NULL);//
	
	avformat_alloc_output_context2(&ofmt_ctx, NULL, "dvd", NULL/*out_filename*/);//设置输出视频的格式为Mpegs-ps,在ffmpeg定义为dvd
	if (!ofmt_ctx) {
		fprintf(stderr, "Could not create output context\n");
		ret = AVERROR_UNKNOWN;
		goto end;
	}
	ofmt_ctx->pb = pb;//这个是关键,指定ps输出的方式
	//ofmt_ctx->flags = AVFMT_FLAG_CUSTOM_IO;
	//dvd
	printf("output format:%s[%s]\n", ofmt_ctx->oformat->name, ofmt_ctx->oformat->long_name);
	ofmt = ofmt_ctx->oformat;
	//输出环境上下文的初始化
	for (i = 0; i < ifmt_ctx->nb_streams; i++) {
		AVStream *in_stream = ifmt_ctx->streams[i];
		//Add a new stream to a media file
		AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
		if (!out_stream) {
			fprintf(stderr, "Failed allocating output stream\n");
			ret = AVERROR_UNKNOWN;
			goto end;
		}

		ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
		if (ret < 0) {
			fprintf(stderr, "Failed to copy context from input to output stream codec context\n");
			goto end;
		}
		out_stream->codec->codec_tag = 0;
		if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
			out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
	}
	av_dump_format(ofmt_ctx, 0, NULL, 1);

	ret = avformat_write_header(ofmt_ctx, NULL);
	if (ret < 0) {
		fprintf(stderr, "Error occurred when opening output file\n");
		goto end;
	}
	//实现REMUXING
	while (1) {
		AVStream *in_stream, *out_stream;
		
		ret = av_read_frame(ifmt_ctx, &pkt);
		if (ret < 0)
			break;

		in_stream = ifmt_ctx->streams[pkt.stream_index];
		out_stream = ofmt_ctx->streams[pkt.stream_index];

		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;
		
		ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
		if (ret < 0) {
			fprintf(stderr, "Error muxing packet\n");
			break;
		}
		av_free_packet(&pkt);
	}

	av_write_trailer(ofmt_ctx);
end:

	avformat_close_input(&ifmt_ctx);

	/* close output */
	if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
		avio_close(ofmt_ctx->pb);
	avformat_free_context(ofmt_ctx);

	if (ret < 0 && ret != AVERROR_EOF) {
		return 1;
	}

	return 0;
}



ffmpeg转码之TS转PS

标签:ffmpeg

原文地址:http://blog.csdn.net/rootusers/article/details/42675577

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!