Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FFMPEG Malformed AAC bitstream detected : use the audio bitstream filter 'aac_adtstoasc' to fix it error

I am working with ffmpeg transcoding.c example. When i set video encoder codec to AV_CODEC_ID_H264 and audio encoder codec to AV_CODEC_ID_AAC I got following error.

enter image description here

How can i fix this problem.

like image 361
doğan Avatar asked Dec 25 '22 13:12

doğan


2 Answers

First of all, thanks for the answers.

Solution of the my problem is AVBitStreamFilterContext*. I added following lines into the "encode_write_frame" method and it is ok.

if(ifmt_ctx->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO && ifmt_ctx->streams[stream_index]->codec->codec_id == AV_CODEC_ID_H264){
    AVBitStreamFilterContext* h264BitstreamFilterContext = av_bitstream_filter_init("h264_mp4toannexb");
    av_bitstream_filter_filter(h264BitstreamFilterContext, ofmt_ctx->streams[stream_index]->codec, NULL, &enc_pkt.data, &enc_pkt.size, enc_pkt.data, enc_pkt.size, 0);
} else if(ifmt_ctx->streams[stream_index]->codec->codec_id == AV_CODEC_ID_AAC) {        
    AVBitStreamFilterContext* aacBitstreamFilterContext = av_bitstream_filter_init("aac_adtstoasc");
    av_bitstream_filter_filter(aacBitstreamFilterContext, ofmt_ctx->streams[stream_index]->codec, NULL, &enc_pkt.data, &enc_pkt.size, enc_pkt.data, enc_pkt.size, 0);
}
like image 161
doğan Avatar answered Dec 27 '22 03:12

doğan


Your aac audio frames still have adts headers when provided to a unit of processing which is expecting raw aac. Adts header allow you to dump AAC data directly to a file, call it foo.aac and open it with other program.

In this case the unit is the MP4 container code. MP4 container requires AV_CODEC_FLAG_GLOBAL_HEADER, which means all stream should contains stream data only, and other data is provided by setting AVCodecContext.extradata. Because MP4 has its own way of transporting metainformation (here transport info), writing that transport prefix before each frame will make the data unreadable.

Are you sure you have the following lines and that the flag CODEC_FLAG_GLOBAL_HEADER is set?

//ofmt_ctx is AVFormatContext
//enc_ctx is the AVCodecContext of the current stream 
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
    enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;

Without them the encoder may add the metadatas in the data which is sent to the container. For AAC it is the ADTS header, for H264 it is SPS and PPS data.

like image 44
UmNyobe Avatar answered Dec 27 '22 02:12

UmNyobe