2014-01-09 2 views
6

Я пытаюсь реализовать функцию приостановки/возобновления для своего приложения, которое записывает захват изображений с помощью MediaCodec. Я пробовал делать mEncoder.stop(), а затем mEncoder.start() без вызова mEncoder.release(), но это не сработало. При вызове mEncoder.start() я получаю IllegalStateException. Прямо сейчас я реализовал обходной путь, я объединяю видеоролики после завершения захвата, но для слияния требуется очень долгое время. Может ли кто-нибудь помочь мне с этим? Может быть, кто-то уже реализовал эту вещь?Пауза/Резюме MediaCodec

Initialazation:

MediaCodec mEncoder; 
    mEncoder = MediaCodec.createEncoderByType(Preferences.MIME_TYPE); 
    mEncoder.configure(mFormat, null, null, 
      MediaCodec.CONFIGURE_FLAG_ENCODE); 
    mInputSurface = new InputSurface(mEncoder.createInputSurface(), 
      mSavedEglContext); 
    mEncoder.start(); 
    try { 
     String fileId = String.valueOf(System.currentTimeMillis()); 
     mMuxer = new MediaMuxer(dir.getPath() + "/Video" 
       + fileId + ".mp4", 
       MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); 
     videoParts.add(fileId); 
    } catch (IOException ioe) { 
     throw new RuntimeException("MediaMuxer creation failed", ioe); 
    } 
    isRecording = true; 

Пауза:

public void pauseRecordPressed() { 
    if (isRecording){ 
     isRecording = false; 
     drainEncoder(false); 

     if (mEncoder != null) { 
      mEncoder.stop(); 
     } 
    } 
} 

Возобновить:

public void resumeRecordPressed() { 
    mEncoder.start(); 
    isRecording = true; 
} 

Исключение:

01-09 15:34:27.980: E/AndroidRuntime(21467): FATAL EXCEPTION: main 
01-09 15:34:27.980: E/AndroidRuntime(21467): Process: com.example.poc, PID: 21467 
01-09 15:34:27.980: E/AndroidRuntime(21467): java.lang.IllegalStateException: start failed 
01-09 15:34:27.980: E/AndroidRuntime(21467): at android.media.MediaCodec.start(Native Method) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at com.example.poc.MyRenderer.resumeRecordPressed(MyRenderer.java:501) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at com.example.poc.MyGLSurfaceView.resumeRecordPressed(MyGLSurfaceView.java:243) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at com.example.poc.MainActivity.onClick(MainActivity.java:775) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at android.view.View.performClick(View.java:4438) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at android.view.View$PerformClick.run(View.java:18422) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at android.os.Handler.handleCallback(Handler.java:733) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at android.os.Handler.dispatchMessage(Handler.java:95) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at android.os.Looper.loop(Looper.java:136) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at android.app.ActivityThread.main(ActivityThread.java:5017) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at java.lang.reflect.Method.invokeNative(Native Method) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at java.lang.reflect.Method.invoke(Method.java:515) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
01-09 15:34:27.980: E/AndroidRuntime(21467): at dalvik.system.NativeStart.main(Native Method) 

MediaFormat:

mFormat = createMediaFormat(); 

    private static MediaFormat createMediaFormat() { 
    MediaFormat format = MediaFormat.createVideoFormat(
      Preferences.MIME_TYPE, mScreenWidth, mScreenHeight); 
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT, 
      MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); 
    format.setInteger(MediaFormat.KEY_BIT_RATE, Preferences.BIT_RATE); 
    format.setInteger(MediaFormat.KEY_FRAME_RATE, Preferences.FRAME_RATE); 
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 
      Preferences.IFRAME_INTERVAL); 
    return format; 
} 
+0

Некоторые из ваших кодов помогут нам выяснить проблему –

+0

См. Мое обновление – Alexey

+0

'mFormat' где это вы можете поместить этот код? –

ответ

6

MediaCodec сбрасывает свою конфигурацию при остановленном, так что вам нужно будет позвонить configure() снова. Я не уверен, почему вы пытаетесь перезапустить его, хотя вы можете просто оставить его активным, не загружая его.

Например, см. CameraCaptureActivity в документе Grafika, в результате чего кодер находится в активном состоянии при перезапуске активности. Если вы не хотите иметь паузу в видео во время перезагрузки, вам нужно будет отслеживать, как долго было приостановлено кодирование, а затем отрегулировать метки времени, которые подаются в мультиплексор.

+0

Я делаю это из-за этого мира информации: http: //developer.android.com/reference/android/media/MediaCodec.html#start(). stop() Завершите сеанс декодирования/кодирования, обратите внимание, что экземпляр кодека остается активным и готов к запуску() снова. Но спасибо за предложение, я попробую! – Alexey

+0

Не могли бы вы привести несколько примеров того, как настроить временные метки для захвата видео в MediaCodec. Это очень помогло бы мне. Заранее спасибо! – Alexey

+0

Я не думал, что это был тест CTS, который выполнял это (что обычно приравнивается к «он не работает»), но получается, что http://bigflake.com/mediacodec/#DecoderTest делает. Вам просто нужно снова вызвать 'configure()' снова [ответить обновлено]. Для временных меток записывайте текущее время в 'onPause()' и 'onResume()', чтобы выяснить, как долго вы спали, а затем вычтите это из каждой отметки времени, которую вы отправляете с этого момента. Убедитесь, что вы правильно набрали временной масштаб (микросекунды против милли- или нано-), или могут произойти сумасшедшие вещи. – fadden

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