2016-09-19 19 views
7

Użyłem biblioteki Android MediaCodec transkodowanie plików wideo (głównie zmiany rozdzielczości Sample code here)Obetnij wideo z MediaCodec

Inną rzeczą, którą chcemy osiągnąć jest obciąć film - tylko brać początek 15 sekund. Logika polega na sprawdzeniu, czy jest ona większa niż 15 sekund, po prostu napiszę EOS do bufora dekodera.

Ale otrzymuję wyjątek Caused by: android.media.MediaCodec$CodecException: Error 0xfffffff3

Oto mój kod:

 while ((!videoEncoderDone) || (!audioEncoderDone)) { 
     while (!videoExtractorDone 
       && (encoderOutputVideoFormat == null || muxing)) { 
      int decoderInputBufferIndex = videoDecoder.dequeueInputBuffer(TIMEOUT_USEC); 
      if (decoderInputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) 
       break; 

      ByteBuffer decoderInputBuffer = videoDecoderInputBuffers[decoderInputBufferIndex]; 
      int size = videoExtractor.readSampleData(decoderInputBuffer, 0); 
      long presentationTime = videoExtractor.getSampleTime(); 

      if (size >= 0) { 
       videoDecoder.queueInputBuffer(
         decoderInputBufferIndex, 
         0, 
         size, 
         presentationTime, 
         videoExtractor.getSampleFlags()); 
      } 
      videoExtractorDone = !videoExtractor.advance(); 

      if (!videoExtractorDone && videoExtractor.getSampleTime() > mVideoDurationLimit * 1000000) { 
       videoExtractorDone = true; 
      } 

      if (videoExtractorDone) 
       videoDecoder.queueInputBuffer(decoderInputBufferIndex, 
         0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); 
      break; 
     } 

pełny kod źródłowy można znaleźć here.

+1

jeśli chcesz, zajrzyj do [Google's ExoPlayer] (https://github.com/google/ExoPlayer). ma prostsze API – Crocodilys

+0

Czy możesz opublikować swój pełny wynik logcat? – Willis

+0

@crocodilys Czy exoplayer jest tylko graczem? Nie sądzę, że może transkodować wideo. Czy się mylę? – Qylin

Odpowiedz

0

Nie jestem pewien, czy to jest źródło błędu, czy nie, ale myślę, że nie jest bezpieczne zapisanie EOS do bufora dekodera w dowolnym punkcie.

Powód jest taki, że gdy wideo wejściowe korzysta z profilu głównego H264 lub wyższego, pkt może nie być w porządku rosnącym (ponieważ istnienie ramki B), więc możesz pominąć kilka klatek na końcu wideo. Również, gdy ostatnią ramką, którą wyślesz do dekodera jest B-ramka, dekoder może oczekiwać następnego pakietu, ale wyślesz flagę EOS i wygenerujesz błąd (nie do końca pewny).

Co możesz zrobić, możesz wysłać flagę EOS do kodera, używając videoEncoder.signalEndOfInputStream() po osiągnięciu żądanej klatki, (liczba wyjść dekodera jest gwarantowana w kolejności rosnącej, przynajmniej po wersji Android> = 4.3 ?)

Powiązane problemy