2013-12-18 3 views
4

Я кодирую NV21 кадры, поступающие с предварительного просмотра камеры. По какой-то причине схема, работающая нормально на других устройствах, работает неправильно на Sony Xperia Z1 с Android 4.3. Он отправляет обратно закодированные кадры с неправильным (низким) качеством. ФорматНепоследовательное качество видео при кодировании кадров предварительного просмотра камеры с MediaCodec на Xperia Z1

MediaCodec «S является COLOR_FormatYUV420SemiPlanar который NV12 (преобразовать NV21 к NV12 путем замены U и V компоненты). Буферы вывода, отправленные мне обратно MediaCodec с очень низким размером, которые не соответствуют разрешению (1280x720) и битрейт (1000000) Я использую. Первые несколько кадров приходят с хорошим качеством, но это значительно снижается:

int encoderStatus = mMediaCodec.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC); 
// a few encoderStatus checks skipped 
ByteBuffer encodedData = outputBuffers[encoderStatus]; 
Log.i(Constants.TAG, "Buffer size " + mBufferInfo.size); 

Который дает мне следующий журнал на Xperia Z1:

Buffer size 26 
Buffer size 52172 
Buffer size 23650 
Buffer size 14394 
Buffer size 3591 
Buffer size 1849 
Buffer size 3908 

... 

Buffer size 1043 
Buffer size 248 
Buffer size 836 
Buffer size 518 
Buffer size 1112 

Пример журнал из Sony Xperia ZR, на котором это работает должным образом:

Buffer size 21 
Buffer size 51048 
Buffer size 21063 
Buffer size 24228 
Buffer size 28040 
... 
Buffer size 44959 
Buffer size 44972 
Buffer size 44957 
Buffer size 45004 
Buffer size 44999 
Buffer size 44957 

Любой совет будет оценен.

+1

Кодер Xperia Z1, по-видимому, обладает особым поведением, например. http://stackoverflow.com/questions/20475332/. Для 1280x720 вы, вероятно, хотите больше, чем 1 Мбит/с - при 30 кадров в секунду, это 4 КБ за кадр, а Xperia ZR выводит 10х. Таким образом, возможно, что ZR сломан, и Z1 делает то, что вы ему сказали. Увеличивает ли скорость передачи битов? – fadden

+0

Спасибо, fadden, ваш комментарий и ответ mstorsjo указали мне в правильном направлении. –

ответ

3

Вы уверены, что прошли отметки времени в правом блоке (микросекунды) - и что он установил разумную частоту кадров?

  • Некоторые датчики могут игнорировать временные метки и устанавливать фиксированный бюджет битрейта на кадр, основываясь на частоте кадров.

  • Другие могут попытаться рассчитать, сколько бит им разрешено использовать для каждого кадра на основе метки времени.

Если указаны временные метки, например. в миллисекундах вместо этого это может привести к тому, что кодер уменьшит размер закодированных кадров до нуля.

+0

В этом была проблема. Большое спасибо. Я передавал System.currentTimeMillis() в качестве 4-го параметра в mMediaCodec.queueInputBuffer(), в то время как то, что у меня должно было пройти, - System.nanoTime()/1000. –

+1

Связано: 'System.nanoTime()' - это время обработки кадра вами, а не временем создания кадра, а база времени может «размахивать» немного в зависимости от капризов планировщика задач. Вы можете использовать 'SurfaceTexture # getTimestamp()' для получения времени генерации кадра. – fadden

+0

Спасибо за информацию, @fadden К сожалению, я не использую 'SurfaceTexture'. Я получаю свои кадры в предварительном обратном вызове, установленном 'Camera.setPreviewCallbackWithBuffer()'. –

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