使用 libav 转换 mp4-ts

convert mp4-ts using 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;
}

感谢任何帮助。

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

您需要插入 h264_mp4toannexb 以重新格式化您收到的 AVPacket。

分配上下文

    AVBitStreamFilterContext *bsf = av_bitstream_filter_init("h264_mp4toannexb");

在你的多路分解循环中

    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;