Hi,

I’m writing a C++ program to validate the integrity of a Fragmented MP4 file 
containing AAC audio.
This program would parse the FMP4 file, read each audio packet, attachment ADTS 
headers, and then try to decode the AAC using libfdk_aac.

I am using libavformat, and I am able to parse the MP4 atoms correctly, however 
I’m having issues figuring out the best way to attach the ADTS headers.

My current idea is to use a libavformat mp4 demuxed and send that to an adts 
muxer. I’ve written all the code to do it now; but I’m now getting errors like 
so:

[adts @ 0x7fae51001600] MPEG-4 AOT 0 is not allowed in ADTS

I’m not sure what to do now.

My code is as below:

AudioAssetReader::AudioAssetReader(const AudioAssetReaderInput &input) throw 
(invalid_argument):
                                input(input), 
segmentsIter(input.getBeginSegmentsIter()), audioBufferSize(409600), 
adtsPacketBufferSize(409600) {
        if (input.getSegments()->empty()) {
                throw invalid_argument("A reader must read at least 1 segment 
of audio!");
        }

        this->audioBuffer = new uint8_t[audioBufferSize];

        // create the main context used to parse the audio asset, segment by 
segment
        bool isBufferWritable = false;
        this->assetSegmentReaderContext = avio_alloc_context(this->audioBuffer, 
this->audioBufferSize, isBufferWritable, this, AudioAssetReader::readSegment, 
NULL, NULL);
        this->assetParsingContext = avformat_alloc_context();
        this->assetParsingContext->pb = this->assetSegmentReaderContext;
        this->assetParsingContext->flags = AVFMT_FLAG_CUSTOM_IO;

        // create another context used to append ADTS headers to the parsed 
segments, if we need them
        this->initializeADTSMuxerContext(input);
}

void AudioAssetReader::initializeADTSMuxerContext(const AudioAssetReaderInput 
&input) {

        this->adtsPacketBuffer = new uint8_t[adtsPacketBufferSize];
        this->adtsPacket = av_packet_alloc();

        // create another context used to append ADTS headers to the parsed 
segments, if we need them
        bool isBufferWritable = true;
        avformat_alloc_output_context2(&this->adtsMuxerContext, NULL, "adts", 
NULL);
        this->adtsMuxerWriterContext = 
avio_alloc_context(this->adtsPacketBuffer, this->adtsPacketBufferSize, 
isBufferWritable, this, NULL, AudioAssetReader::writeADTSPacket, NULL);
        this->adtsMuxerContext->pb = this->adtsMuxerWriterContext;

        // initialize an ADTS stream
        AVCodecID aacCodec = AVCodecID::AV_CODEC_ID_AAC;
        AVCodec *codec = avcodec_find_encoder(aacCodec);
        AVStream *stream = avformat_new_stream(this->adtsMuxerContext, codec);
        stream->id = this->adtsMuxerContext->nb_streams - 1;
        stream->time_base.den = input.getSampleRateHz();
        stream->time_base.num = 1;

        // configure the stream with the details of the AAC packets
        AVCodecParameters *codecParameters = stream->codecpar;
        codecParameters->codec_id = aacCodec;
        codecParameters->bit_rate = input.getBitrateBps();
        codecParameters->profile = 
this->getAACProfileForCodec(input.getCodec());
        codecParameters->sample_rate = input.getSampleRateHz();
        codecParameters->channels = input.getChannelCount();
        codecParameters->codec_type = AVMEDIA_TYPE_AUDIO;
        codecParameters->channel_layout = 
av_get_default_channel_layout(input.getChannelCount());

        uint8_t* header = new uint8_t[7];
        memset(header, 1, 7);
        //header[3] = 2 << 6;

        codecParameters->extradata = header;
        codecParameters->extradata_size = 7;

        // write out a header to the muxer; this is a no-op for our purposes
        const int result = avformat_write_header(this->adtsMuxerContext, NULL);
        if (result < 0) {
                char *message = new char[AV_ERROR_MAX_STRING_SIZE];
                av_make_error_string(message, AV_ERROR_MAX_STRING_SIZE, result);
                cerr<<endl<<"Failed to write the ADTS muxer header due to: 
"<<result<<": "<<message<<endl;
                delete[] message;
        }
}

Ronak
_______________________________________________
Libav-user mailing list
[email protected]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[email protected] with subject "unsubscribe".

Reply via email to