[haiku-commits] haiku: hrev52494 - src/add-ons/media/plugins/ffmpeg

  • From: waddlesplash@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 4 Nov 2018 12:04:09 -0500 (EST)

hrev52494 adds 1 changeset to branch 'master'
old head: ce402e82f271eef27be305a94b596935dc85cd47
new head: 5e14319a111a19eec5d92de92e2dedc8b05feb55
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=5e14319a111a+%5Ece402e82f271

----------------------------------------------------------------------------

5e14319a111a: ffmpeg: use new producer/consumer API for video decoding
  
  This API allows us to send whole packets no matter how the video is
  formatted, and get frames out as they are ready (sometimes multiple
  frames per packets, which did not work well with the previous API).
  
  Change-Id: I0bd7d4706e330bb11d87cb41e93cfc6995b4b3a5
  Reviewed-on: https://review.haiku-os.org/665
  Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

                             [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev52494
Commit:      5e14319a111a19eec5d92de92e2dedc8b05feb55
URL:         https://git.haiku-os.org/haiku/commit/?id=5e14319a111a
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Sun Nov  4 08:36:02 2018 UTC
Committer:   waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Sun Nov  4 17:04:06 2018 UTC

----------------------------------------------------------------------------

1 file changed, 54 insertions(+), 55 deletions(-)
.../media/plugins/ffmpeg/AVCodecDecoder.cpp      | 109 +++++++++----------

----------------------------------------------------------------------------

diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp 
b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
index aa462137f8..23fb6af38c 100644
--- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
+++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
@@ -1239,76 +1239,75 @@ AVCodecDecoder::_UpdateMediaHeaderForAudioFrame()
 status_t
 AVCodecDecoder::_DecodeNextVideoFrame()
 {
-       while (true) {
-               status_t loadingChunkStatus
-                       = _LoadNextChunkIfNeededAndAssignStartTime();
-               if (loadingChunkStatus == B_LAST_BUFFER_ERROR)
-                       return _FlushOneVideoFrameFromDecoderBuffer();
-               if (loadingChunkStatus != B_OK) {
-                       TRACE("AVCodecDecoder::_DecodeNextVideoFrame(): error 
from "
-                               "GetNextChunk(): %s\n", 
strerror(loadingChunkStatus));
-                       return loadingChunkStatus;
-               }
+       int error;
+       int send_error;
 
 #if DO_PROFILING
-               bigtime_t startTime = system_time();
+       bigtime_t startTime = system_time();
 #endif
 
-               // NOTE: In the FFMPEG 0.10.2 code example decoding_encoding.c, 
the
-               // length returned by avcodec_decode_video2() is used to update 
the
-               // packet buffer size (here it is fTempPacket.size). This way 
the
-               // packet buffer is allowed to contain incomplete frames so we 
are
-               // required to buffer the packets between different calls to
-               // _DecodeNextVideoFrame().
-               int gotVideoFrame = 0;
-               int encodedDataSizeInBytes = 
avcodec_decode_video2(fCodecContext,
-                       fRawDecodedPicture, &gotVideoFrame, &fTempPacket);
-               if (encodedDataSizeInBytes < 0) {
-                       TRACE("[v] AVCodecDecoder: ignoring error in decoding 
frame %lld:"
-                               " %d\n", fFrame, encodedDataSizeInBytes);
-                       // NOTE: An error from avcodec_decode_video2() is 
ignored by the
-                       // FFMPEG 0.10.2 example decoding_encoding.c. Only the 
packet
-                       // buffers are flushed accordingly
+       error = avcodec_receive_frame(fCodecContext, fRawDecodedPicture);
+
+       if (error == AVERROR(EAGAIN)) {
+               do {
+                       status_t loadingChunkStatus
+                               = _LoadNextChunkIfNeededAndAssignStartTime();
+                       if (loadingChunkStatus == B_LAST_BUFFER_ERROR)
+                               return _FlushOneVideoFrameFromDecoderBuffer();
+                       if (loadingChunkStatus != B_OK) {
+                               TRACE("[v] 
AVCodecDecoder::_DecodeNextVideoFrame(): error from "
+                                       "GetNextChunk(): %s\n", 
strerror(loadingChunkStatus));
+                               return loadingChunkStatus;
+                       }
+
+                       char timestamp[AV_TS_MAX_STRING_SIZE];
+                       av_ts_make_time_string(timestamp,
+                               fTempPacket.dts, &fCodecContext->time_base);
+                       TRACE("[v] Feed %d more bytes (dts %s)\n", 
fTempPacket.size,
+                               timestamp);
+
+                       send_error = avcodec_send_packet(fCodecContext, 
&fTempPacket);
+                       if (send_error < 0 && send_error != AVERROR(EAGAIN)) {
+                               TRACE("[v] AVCodecDecoder: ignoring error in 
decoding frame "
+                               "%lld: %d\n", fFrame, error);
+                       }
+
+                       // Packet is consumed, clear it
                        fTempPacket.data = NULL;
                        fTempPacket.size = 0;
-                       continue;
-               }
 
-               fTempPacket.size -= encodedDataSizeInBytes;
-               fTempPacket.data += encodedDataSizeInBytes;
+                       error = avcodec_receive_frame(fCodecContext, 
fRawDecodedPicture);
+                       if (error != 0 && error != AVERROR(EAGAIN)) {
+                               TRACE("[v] frame %lld - decoding error, error 
code: %d, "
+                                       "chunk size: %ld\n", fFrame, error, 
fChunkBufferSize);
+                       }
 
-               bool gotNoVideoFrame = gotVideoFrame == 0;
-               if (gotNoVideoFrame) {
-                       TRACE("frame %lld - no picture yet, 
encodedDataSizeInBytes: %d, "
-                               "chunk size: %ld\n", fFrame, 
encodedDataSizeInBytes,
-                               fChunkBufferSize);
-                       continue;
-               }
+               } while (error != 0);
+       }
 
 #if DO_PROFILING
-               bigtime_t formatConversionStart = system_time();
+       bigtime_t formatConversionStart = system_time();
 #endif
 
-               status_t handleStatus = 
_HandleNewVideoFrameAndUpdateSystemState();
-               if (handleStatus != B_OK)
-                       return handleStatus;
+       status_t handleStatus = _HandleNewVideoFrameAndUpdateSystemState();
+       if (handleStatus != B_OK)
+               return handleStatus;
 
 #if DO_PROFILING
-               bigtime_t doneTime = system_time();
-               decodingTime += formatConversionStart - startTime;
-               conversionTime += doneTime - formatConversionStart;
-               profileCounter++;
-               if (!(fFrame % 5)) {
-                       printf("[v] profile: d1 = %lld, d2 = %lld (%lld) 
required %Ld\n",
-                               decodingTime / profileCounter, conversionTime / 
profileCounter,
-                               fFrame, bigtime_t(1000000LL / 
fOutputFrameRate));
-                       decodingTime = 0;
-                       conversionTime = 0;
-                       profileCounter = 0;
-               }
-#endif
-               return B_OK;
+       bigtime_t doneTime = system_time();
+       decodingTime += formatConversionStart - startTime;
+       conversionTime += doneTime - formatConversionStart;
+       profileCounter++;
+       if (!(fFrame % 5)) {
+               printf("[v] profile: d1 = %lld, d2 = %lld (%lld) required 
%Ld\n",
+                       decodingTime / profileCounter, conversionTime / 
profileCounter,
+                       fFrame, bigtime_t(1000000LL / fOutputFrameRate));
+               decodingTime = 0;
+               conversionTime = 0;
+               profileCounter = 0;
        }
+#endif
+       return error;
 }
 
 


Other related posts:

  • » [haiku-commits] haiku: hrev52494 - src/add-ons/media/plugins/ffmpeg - waddlesplash