写了一个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; }
时间: 2024-11-14 13:17:48