I am in a time crunch and would appreciate a prompt reply for this…I’m amazed 
that it is this complicated to append an ADTS header to MPEG4 Audio.


> On Oct 3, 2019, at 5:44 PM, Ronak via Libav-user <[email protected]> 
> wrote:
> 
> 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".

_______________________________________________
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