使用libav转换mp4-ts

时间:2015-04-20 15:07:16

标签: c video ffmpeg libav

我尝试使用 libav 将mp4文件转换为mpegts。代码有效,但输出的文件无法被任何播放器播放。

以下是input file(仅限视频,无音频)

这是我到目前为止的代码:

int convert(const char *input, const char *output)
{
AVFormatContext *inputContext = NULL;
AVFormatContext *outputContext = NULL;
AVCodecContext *input_codec_context = NULL;
AVCodecContext *output_codec_context = NULL;
AVCodec *output_codec = NULL;
AVCodec *input_codec = NULL;
AVStream *stream = NULL;
AVIOContext *avioContext = NULL;

av_register_all();
avformat_network_init();
avformat_alloc_output_context2(&outputContext, NULL, "mpegts", output);
avio_open(&avioContext, output, AVIO_FLAG_WRITE);
outputContext->pb = avioContext;
stream = avformat_new_stream(outputContext, output_codec);

avformat_open_input(&inputContext, input, NULL, NULL);

input_codec_context = inputContext->streams[0]->codec;
input_codec = avcodec_find_decoder(inputContext->streams[0]->codec->codec_id);
avcodec_open2(inputContext->streams[0]->codec, input_codec, NULL);
avformat_find_stream_info(inputContext, NULL);
outputContext->oformat = av_guess_format(NULL, output, NULL);
output_codec = input_codec;

output_codec_context = avcodec_alloc_context3(NULL);
avcodec_copy_context(output_codec_context, input_codec_context);

avcodec_open2(output_codec_context, output_codec, NULL);

AVPacket packet;
av_init_packet(&packet);

avformat_write_header(outputContext, NULL);
while (!av_read_frame(inputContext, &packet)) {

    av_write_frame(outputContext, &packet);
}
av_free_packet(&packet);

av_write_trailer(outputContext);
avformat_close_input(&inputContext);
avformat_free_context(inputContext);
avformat_free_context(outputContext);

return 0;
}

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:1)

mp4mpegts假设h264采用不同的比特流格式。

您需要插入h264_mp4toannexb以重新格式化您正在获取的AVPacket。

分配上下文

    AVBitStreamFilterContext *bsf = av_bitstream_filter_init("h264_mp4toannexb");
你的demux循环中的

    AVPacket new_pkt = *pkt;
    int ret = av_bitstream_filter_filter(bsfc, avctx, NULL,
                                         &new_pkt.data, &new_pkt.size,
                                         pkt->data, pkt->size,
                                         pkt->flags & AV_PKT_FLAG_KEY);
    if (ret > 0) {
        // non-zero positive, you have new memory allocated, 
        // keep it referenced in the AVBuffer
        av_free_packet(pkt);
        new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
                                       av_buffer_default_free, NULL, 0);
        // handle memory error here

    } else if (ret < 0) {
        // handle failure here

    }
    // ret == 0, no problems, nothing else to do
    *pkt = new_pkt;