Android Точный поиск видео

Я борюсь с точным поиском, используя MediaExtractor's seekTo(), Хотя я могу стремиться синхронизировать кадры без проблем, я хотел бы стремиться к определенному времени. Этот вопрос привел меня к некоторым идеям, как это сделать, но я не уверен, что они действительны. По сути, мне нужно искать ближайший предыдущий кадр синхронизации, а затем advance() экстрактор, пока не будет достигнуто целевое время. Каждый кадр в процессе будет подан на декодер, то есть первый I-кадр и остальные P-кадры. Это фрагмент кода (на основе MoviePlayer от Google / grafika):

extractor.seekTo((long) seekTarget[threadNr], MediaExtractor.SEEK_TO_PREVIOUS_SYNC);

...

while (extractor.getSampleTime() < (long) seekTarget[threadNr]) {
    Log.d(TAG, "Thread " + threadNr + " advanced to timestamp " + extractor.getSampleTime());

    int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
    if (inputBufIndex >= 0) {
        ByteBuffer inBufer = decoderInputBuffers[inputBufIndex];
        int chunkSize = extractor.readSampleData(inBufer, 0);

        if (chunkSize < 0) {
            // End of stream -- send empty frame with EOS flag set.
            decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L,
                    MediaCodec.BUFFER_FLAG_END_OF_STREAM);
            inputDone = true;
            if (VERBOSE) Log.d(TAG, "sent input EOS");
        } else {
            if (extractor.getSampleTrackIndex() != trackIndex) {
                Log.w(TAG, "WEIRD: got sample from track " +
                        extractor.getSampleTrackIndex() + ", expected " + trackIndex);
            }

            long presentationTimeUs = extractor.getSampleTime();
            decoder.queueInputBuffer(inputBufIndex, 0, chunkSize,
                    presentationTimeUs, 0 /*flags*/);
            if (VERBOSE) {
                Log.d(TAG, "submitted frame " + inputChunk + " to dec, size=" +
                        chunkSize + " inputBufIndex: " + inputBufIndex);
            }
            inputChunk++;
            extractor.advance();
        }
    }
}

Как вы можете себе представить, обычно я ставлю в очередь большое количество кадров, но пока я в порядке с потреблением памяти или возможной задержкой. Проблема в том, что dequeueInputBuffer() Метод работает только в течение некоторого времени в цикле, в конечном итоге застревает при возврате -1, что в соответствии с документацией означает, что буфер недоступен. Если бы я изменил TIMEOUT_USEC в -1 Получаю бесконечный цикл.

Может кто-нибудь сказать мне, если этот подход является правильным или почему в какой-то момент я не могу получить доступ к inputBuffer?

1 ответ

Решение

Похоже, вы не тянете буферы со стороны вывода. Декодер MediaCodec не пропускает кадры, поэтому, когда его внутренние буферы заполнятся, он перестанет передавать вам входные буферы.

Вы должны истощить декодер, запрашивая выходные буферы. Когда вы освобождаете буфер, установите флаг "render" в false, чтобы он не появлялся на экране.

Другие вопросы по тегам