Remux:无损的取出HD-DVD和BluRay-DVD里面的视频和音频数据,重新封装到另一种容器。
根据ffmpeg的sample例子remuxing写了一个ts转ps的例子。
写了一个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;
-
}