2015-03-26 7 views
1

Я делаю запись видео с помощью mediacodec + mediamuxer, и теперь могу записывать видео и генерировать файл mp4, который можно воспроизвести. Проблема в том, что я нахожу, что записанное видео хватит примерно на одну секунду. Поэтому я запустил traceview, и я обнаружил, что проблема MediaMuxer.nativeWriteSampleData(). Иногда эта функция выполняется очень быстро и возвращается в течение нескольких микросекунд, но иногда эта функция очень медленная и будет потреблять около одной секунды или около того, а видео-блоки в это время. Я не знаю, почему эта функция будет меняться время от времени. Целевой файл записи находится на внешней SDCard или внутренней памяти, и проблема существует на обоих носителях.MediaMuxer.nativeWriteSampleData всегда загиб в течение одной секунды во время видеозаписи

Neo

+0

Какое устройство? Какая версия Android? – fadden

+0

AllWinner A80, Optimus Board, Android 4.4.2 –

+0

Может ли кто-нибудь дать мне подсказку, как решить эту проблему? Также приветствуется только общая методология. –

ответ

1

Это проблема, которая возникает в основном на устройствах с более низким скоростями записи флэш или если вы пытаетесь записать на SD-карту. Решение состоит в том, чтобы скопировать закодированные данные во временный ByteBuffer, вернуть данные в MediaCodec и асинхронно вызывать writeSampleData в выделенном потоке.

Таким образом, если предположить, что у вас есть нить для дренирования выводе MediaCodec и один для кормления MediaMuxer, это возможное решение:

// this runs on the MediaCodec's draining thread 
public void writeSampleData(final MediaCodec mediaCodec, final int trackIndex, final int bufferIndex, final ByteBuffer encodedData, final MediaCodec.BufferInfo bufferInfo) { 
    final ByteBuffer data = ByteBuffer.allocateDirect(bufferInfo.size); // allocate a temp ByteBuffer 
    data.put(encodedData); // copy the data over 
    mediaCodec.releaseOutputBuffer(bufferIndex, false); // return the packet to MediaCodec 

    mWriterHandler.post(new Runnable() { 
     // this runs on the Muxer's writing thread 
     @Override 
     public void run() { 
      mMuxer.writeSampleData(trackIndex, data, bufferInfo); // feed the packet to MediaMuxer 
     }); 
} 

Проблема с этим подходом является то, что мы выделяем новый ByteBuffer для каждого входящего пакет. Было бы лучше, если бы мы могли повторно использовать большой круговой буфер для регистрации и удаления новых данных. Я написал сообщение об этом вопросе, а также предложил решение, которое довольно подробно объясняет здесь. Вы можете read it here.