Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MediaCodec audio/video muxing issues ond Android

I am transcoding videos based on the example given by Google (https://android.googlesource.com/platform/cts/+/master/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java)

Basically, transocding of MP4 files works, but on some phones I get some weird results. If for example I transcode a video with audio on an HTC One, the code won't give any errors but the file cannot play afterward on the phone. If I have a 10 seconds video it jumps to almost the last second and you only here some crackling noise. If you play the video with VLC the audio track is completely muted.

I did not alter the code in terms of encoding/decoding and the same code gives correct results on a Nexus 5 or MotoX for example.

Anybody having an idea why it might fail on that specific device?

Best regard and thank you, Florian

like image 395
Florian Avatar asked Oct 22 '14 09:10

Florian


1 Answers

I made it work in Android 4.4.2 devices by following changes:

  • Set AAC profile to AACObjectLC instead of AACObjectHE
private static final int OUTPUT_AUDIO_AAC_PROFILE = MediaCodecInfo.CodecProfileLevel.AACObjectLC;
  • During creation of output audio format, use sample rate and channel count of input format instead of fixed values
MediaFormat outputAudioFormat = MediaFormat.createAudioFormat(OUTPUT_AUDIO_MIME_TYPE,
inputFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE),
inputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
  • Put a check just before audio muxing audio track to control presentation timestamps. (To avoid timestampUs X < lastTimestampUs X for Audio track error)
    if (audioPresentationTimeUsLast == 0) { // Defined in the begining of method
      audioPresentationTimeUsLast = audioEncoderOutputBufferInfo.presentationTimeUs;
    } else {
      if (audioPresentationTimeUsLast > audioEncoderOutputBufferInfo.presentationTimeUs) {
        audioEncoderOutputBufferInfo.presentationTimeUs = audioPresentationTimeUsLast + 1;
      }
      audioPresentationTimeUsLast = audioEncoderOutputBufferInfo.presentationTimeUs;
    }

    // Write data

    if (audioEncoderOutputBufferInfo.size != 0) {
       muxer.writeSampleData(outputAudioTrack, encoderOutputBuffer, audioEncoderOutputBufferInfo);
    }

Hope this helps...

like image 196
Efe Kahraman Avatar answered Nov 17 '22 18:11

Efe Kahraman