0

I use MediaCodec and MediaExtractor classes from android NDK for decoding mp3 files. For comparison input file(mp3) and outputfile(wav - it`s my decoded format) i look at tracks duration and i exactly see difference of duration 50 milliseconds. I check it on anothers tracks and this difference always present. So, i lost first near 50 milliseconds of my input track.

Algorithm of decoding used like in androin ndk-samples(native-codec) decoding fragment is below

ssize_t bufidx = -1;
if (!d->sawInputEOS) 
{
    bufidx = AMediaCodec_dequeueInputBuffer(codec, 2000);
    LOGV("input buffer %zd", bufidx);
    if (bufidx >= 0) 
    {
        size_t bufsize;
        uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize);
        ssize_t sampleSize = AMediaExtractor_readSampleData(ex, buf, bufsize);
        if (sampleSize < 0) 
        {
            sampleSize = 0;
            d->sawInputEOS = true;
            LOGV("EOS");
        }
        int64_t presentationTimeUs = AMediaExtractor_getSampleTime(extractor);
        AMediaCodec_queueInputBuffer(codec, bufidx, 0, sampleSize, presentationTimeUs,
d->sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0);
        AMediaExtractor_advance(ex);
    }
}
if (!d->sawOutputEOS) 
{
    AMediaCodecBufferInfo info;
    ssize_t status = AMediaCodec_dequeueOutputBuffer(codec, &info, 0);
    if (status >= 0) 
    {
        if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) 
        {
            LOGV("output EOS");
            d->sawOutputEOS = true;
        }

    AMediaCodec_releaseOutputBuffer(codec, status, info.size != 0);
} 
else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
LOGV("output buffers changed");
} else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
AMediaFormat *format = NULL;
format = AMediaCodec_getOutputFormat(d->codec);
LOGV("format changed to: %s", AMediaFormat_toString(format));
AMediaFormat_delete(format);
} else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
LOGV("no output buffer right now");
} else {
LOGV("unexpected info code: %zd", status);
}

}

This code provided with "native codec" sample in NDK.

How can i fix it? because of loss data are unacceptable

Maksym
  • 11
  • 4

1 Answers1

0

It looks like you do not read out buffered frames from decoder. When you leaves the decoding loop you need to check for dequeueOutputBuffer till the flag BUFFER_FLAG_END_OF_STREAM on the BufferInfo returned in dequeueOutputBuffer(MediaCodec.BufferInfo, long)

Once the client reaches the end of the input data it signals the end of the input stream by specifying a flag of BUFFER_FLAG_END_OF_STREAM in the call to queueInputBuffer(int, int, int, long, int). The codec will continue to return output buffers until it eventually signals the end of the output stream by specifying the same flag (BUFFER_FLAG_END_OF_STREAM) on the BufferInfo returned in dequeueOutputBuffer(MediaCodec.BufferInfo, long). Do not submit additional input buffers after signaling the end of the input stream, unless the codec has been flushed, or stopped and restarted.

Marlon
  • 1,473
  • 11
  • 13
  • i did`t submit additional input buffers i check it by flag if (!d->sawInputEOS). For Details i open input and output files in the "audacity" And i have seen the problem is in output file - the start 50 ms is lost, and other sound-signal buffers will be displaced to begining of track of same 50ms. And i think problem is not with using BUFFER_FLAG_END_OF_STREAM. – Maksym Oct 24 '14 at 13:37