2013-09-06 3 views
1

Я читаю документы Android о MediaCodec и других онлайн-уроках/примерах. Как я понимаю, как использовать MediaCodec, как это (например, декодер в псевдокоде):MediaCodec: как измерить производительность?

//-------- prepare audio decoder, format, buffers, and files -------- 
    MediaExtractor extractor; 
    MediaCodec codec; 
    ByteBuffer[] codecInputBuffers; 
    ByteBuffer[] codecOutputBuffers; 
    extractor = new MediaExtractor(); 
    extractor.setDataSource(); 
    MediaFormat format = extractor.getTrackFormat(0); 

    //---------------- start decoding ---------------- 
    codec = MediaCodec.createDecoderByType(mime); 
    codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */); 
    codec.start(); 
    codecInputBuffers = codec.getInputBuffers(); 
    codecOutputBuffers = codec.getOutputBuffers(); 
    extractor.selectTrack(0); 

    //---------------- decoder loop ---------------- 
    while (MP3_file_not_EOS) { 

     //-------- grasp control of input buffer from codec -------- 
     codec.dequeueInputBuffer(); 

     //---- fill input buffer with data from MP3 file ---- 
     extractor.readSampleData(); 

     //-------- release input buffer so codec can have it -------- 
     codec.queueInputBuffer(); 

     //-------- grasp control of output buffer from codec -------- 
     codec.dequeueOutputBuffer(); 

     //-- copy PCM samples from output buffer into another buffer -- 
     short[] PCMoutBuffer = copy_of(OutputBuffer); 

     //-------- release output buffer so codec can have it -------- 
     codec.releaseOutputBuffer(); 

     //-------- write PCMoutBuffer into a file, or play it ------- 
    } 

    //---------------- stop decoding ---------------- 
    codec.stop(); 
    codec.release(); 

Это правильный способ использовать MediaCodec? Если нет, пожалуйста, просветите меня с правильным подходом. Если это правильный способ, как я могу измерить производительность MediaCodec? Разница во времени между тем, когда возвращается codec.dequeueOutputBuffer() и когда возвращается codec.queueInputBuffer()? Мне нужна точность/точность микросекунд. Ваши идеи и мысли ценятся.

+1

Псевдокод кажется разумным, хотя дьявол часто находится в деталях. Вы не можете просто указать, сколько времени занимает одна буферная запись, потому что кодек может захотеть поставить в очередь более одного буфера, прежде чем что-либо делать. Вы должны измерять его в совокупности, определяя продолжительность полного декодирования файла с помощью 'System.nanoTime()'. Если вы перевернете 'copy_of' в no-op и просто отбросьте декодированные данные, вы оставите выходную сторону вне вычислений. – fadden

+0

@fadded: Спасибо за ответ. Другой вопрос: если я действительно хотел взять файл ввода/вывода из картинки, могу ли я обойти MediaExtractor? Я мог бы написать код для чтения исходного файла в большой буфер и скопировать большой буфер во входной буфер декодера, покадрово. Рекомендуется ли этот подход? – hubeir

+1

Это возможно, но может быть неудобным в зависимости от формата. Как отмечено в документах MediaCodec, кодированный ввод/вывод «не является потоком байтов, это поток блоков доступа». Таким образом, вам нужно будет заполнить все необходимые ключи кодека-данных в MediaFormat, а затем определить отдельные кадры ввода, чтобы вы могли правильно кормить кодек. Вместо этого можно сделать отдельный проход, где вы только что прочитали образцы данных, а затем вычтите это из общего времени, необходимого для чтения + декодирования. Это будет не совсем точно, но это будет достаточно близко. – fadden

ответ

2

(слияние комментариев и слегка расширяется)

Вы можете не просто время, как долго один буфер представления принимает, поскольку кодек может понадобиться в очереди более чем один буфер, прежде чем делать что-либо. Вам нужно будет измерить его в совокупности, рассчитав длительность полного декодирования файла с помощью System.nanoTime(). Если вы перевернете операцию copy_of в no-op и просто отбросьте декодированные данные, вы оставите выходную сторону (записывая декодированные данные на диск) из расчета.

Исключая ввод-вывод со стороны ввода, сложнее. Как отмечено в документах MediaCodec, кодированный ввод/вывод «не является потоком байтов, это поток блоков доступа». Таким образом, вам нужно будет заполнить все необходимые ключи кодека-данных в MediaFormat, а затем определить отдельные кадры ввода, чтобы вы могли правильно кормить кодек.

Простым, но менее точным подходом было бы проведение отдельного прохода, в котором вы набираете время, необходимое для чтения входных данных, а затем вычитаете это из общего времени. В вашем образце кода вы будете держать операции на extractor (например, readSampleData), но ничего не делайте с codec (может быть, удалить один буфер и просто повторно использовать его каждый раз). Таким образом, вы измеряете только MediaExtractor. Трюк здесь заключается в том, чтобы запустить его дважды, непосредственно перед полным тестом, и проигнорировать результаты первого - первый проход «разогревает» кэш диска.

Если вас интересуют различия в производительности между устройствами, может быть, разница в времени ввода-вывода, особенно из «теплого» кеша, достаточно схожа и достаточно мала, чтобы вы могли просто игнорировать его и не пройти всю дополнительную гимнастику.

+0

спасибо. Я определенно буду экспериментировать с этой идеей. – hubeir