2015-05-18 3 views
2

Я использую MediaExtractor/MediaCodec для декодирования видео и рендеринга его в TextureView. В качестве шаблона я использовал код от: https://github.com/vecio/MediaCodecDemo/blob/master/src/io/vec/demo/mediacodec/DecodeActivity.javaПропустить кадры при воспроизведении видео с помощью MediaExtractor и MediaCodec

Я хотел был бы иметь возможность воспроизвести видео на скорости 2x. К счастью, кодирование/декодирование носителей достаточно быстро, поэтому я могу это сделать, разрешив MediaCodec декодировать каждый кадр, а затем отображать только каждый кадр на экран. Однако это не похоже на отличное решение, особенно если вы хотите увеличить воспроизведение на произвольное значение. Например, при скоростях 10x кодек не способен декодировать кадры достаточно быстро, чтобы воспроизводить каждый 10-й кадр со скоростью 30 кадров в секунду.

Так что я бы хотел контролировать воспроизведение, несколько раз перезывая MediaExtractor.advance(), чтобы пропускать кадры, которые не нужно декодировать. Например:

 ... 
     mDecoder.queueInputBuffer(inIndex, 0, sampleSize, mExtractor.getSampleTime(), 0); 
     for (i = 0; i < playbackSpeedIncrease; i++) { 
       mExtractor.advance(); 
     } 
     ... 

С помощью этого кода, в теории экстрактор должен извлечь только каждый энный кадр, где п определяется переменной «playbackSpeedIncrease». Например, если n = 5, это должно продвигать предыдущие кадры 1-4 и извлекать только рамку 5.

Однако это не работает на практике. Когда я запускаю этот код, изображение, отображаемое на экране, искажается: enter image description here

Кто-нибудь знает, почему это так? Любые предложения по лучшим способам воспроизведения видео с произвольной скоростью увеличиваются?

ответ

6

Вы не можете вообще делать это с видео AVC.

Закодированное видео имеет «ключевые» (или «синхронизирующие» или «I») кадры, которые содержат полные изображения, но кадры между ключевыми кадрами «разнятся» из предыдущих кадров. Вы можете найти некоторые статьи в википедии о методах кодирования видео, например. this one. Вы получаете неприятное видео, потому что вы пропустили ключевой фрейм, и теперь разности вычисляются против неправильного изображения.

Если вы когда-либо видели видео быструю перемотку плавно, но быстро обращались, например, на TiVo, вот почему: видеодекодер играет вперед, но в обратном порядке он просто воспроизводит I-кадры, удерживая их на экране достаточно долго, чтобы получить желаемую скорость. При «более быстрой» перемотке вперед/назад он выравнивается, потому что устройство просто воспроизводит I-кадры. Вы можете сделать что-то подобное, наблюдая за флагом SAMPLE_FLAG_SYNC в кадрах, которые вы получаете от MediaExtractor.

В общем, вы ограничены либо воспроизведением видео так же быстро, как устройство может его декодировать или играть только ключевые кадры. (Если вы знаете достаточно о макете конкретного видео в определенной кодировке, вы можете сделать лучше, например, играть I и P, но не B, но я не уверен, что это возможно даже в AVC.)

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

 Смежные вопросы

  • Нет связанных вопросов^_^