Несовместимое время выборки / время представления во время декодирования видео

Я пишу приложение, которое может кодировать видео по входу камеры и обрабатывать видео с помощью шагов декодирования-редактирования-кодирования. Для камеры я использую класс Camera, а не Intent для настройки параметров камеры. Затем я передаю кадры камеры кодеру (MediaCodec в API 16) и мультиплексору (я использую мультиплексор ffmpeg, поскольку хочу работать на устройствах 4.1).

Я измеряю временной код кадров камеры по системному нано-времени и выбираю подмножество кадров, чтобы соответствовать желаемому FPS (в настоящее время 15). Есть некоторые небольшие «шумы» в значениях времени, например (в мс): 0, 60718, 135246, 201049, ... вместо 0, 66000, 133000, 200000, ....

После некоторых попыток правильно настроить мультиплексор (какэтот вопрос), Я могу создать видео (с кодеком AVC), которое может воспроизводиться видеопроигрывателем на устройствах. Скорость воспроизведения правильная, поэтому я думаю, что видео должно иметь правильную информацию о времени кадров.

Однако у меня возникла проблема при попытке декодировать видео для выполнения процесса редактирования видео. Я использую стандартные шаги извлечения / декодирования видео какэти образцы, как это:

int decode_input_index = decoder.dequeueInputBuffer(TIMEOUT_USEC);
if (decode_input_index >= 0)
{
    ByteBuffer decoder_input_buffer = decode_input_buffers[decode_input_index];
    int sample_size = extractor.readSampleData(decoder_input_buffer, 0);
    if (sample_size < 0)
    {
        decoder.queueInputBuffer(decode_input_index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
        is_decode_input_done = true;
    }
    else
    {
        long sample_time = extractor.getSampleTime();
        decoder.queueInputBuffer(decode_input_index, 0, sample_size, sample_time, 0);
        extractor.advance();
    }
}
else
{
    Log.v(TAG, "Decoder dequeueInputBuffer timed out! Try again later");
}

Время выборки из getSampleTime () имеет правильное значение при кодировании видео. (например, они равны 0, 60718, 135246, 201049, ... у нас). Это также время представления на входе decoder.queueInputBuffer (). Когда декодер продолжает декодировать этот кадр, я получаю время кадра следующим образом:

int decode_output_index = decoder.dequeueOutputBuffer(decode_buffer_info, TIMEOUT_USEC);
switch (decode_output_index)
{
    ....
    (some negative-value flags in MediaCodec)
    ....
    default:
    {
        ByteBuffer decode_output_buffer = decode_output_buffers[decode_output_index];
        long ptime_us = decode_buffer_info.presentationTimeUs;
        boolean is_decode_EOS = ((decode_buffer_info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0);

        ....
    }
}

Я ожидаю установить ту же временную последовательность, что и на входе декодера, но я получаю много нулей из BufferInfo на выходе декодера. Содержимое декодированного кадра кажется правильным, но большинство значений времени представления равно 0. Только последние несколько кадров имеют правильное время представления.

Я тестирую весь тот же процесс на устройстве с Android 4.3 (даже с тем же мультиплексором ffmpeg, а не MediaMuxer в API 18), и все выглядит хорошо. На устройствах 4.1 / 4.2, если я снимаю видео встроенным приложением камеры на устройстве, а затем декодирую видео, тогда время представления также является правильным, хотя значения времени также имеют шумы из-за задержки камеры.

Что не так с видео или процессом декодирования, когда видео можно воспроизводить и декодировать нормально, но с правильным временем выборки и плохим временем представления? Возможно, мне придется использовать обходной путь, чтобы измерить время представления по времени выборки (это легко с помощью очереди), но я хочу выяснить, есть ли какая-либо пропущенная часть в моей работе.

Ответы на вопрос(1)

Ваш ответ на вопрос