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

  • From: coling@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 21 Aug 2014 00:48:53 +0200 (CEST)

hrev47719 adds 4 changesets to branch 'master'
old head: 37bea90971b01478dbd89d2d8165a6a6471be3cc
new head: b82ef8bc15614a52394f5f5626b719530e01cfa5
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=b82ef8b+%5E37bea90

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

54b392b: FFMPEG Plugin: Some cleanups.
  
  - Use name that correctly reflects the return value of 
avcodec_decode_video2().
  - Make DO_PROFILING code path of AVCodecDecoder compile again.
  - No functional change intended.

8537123: FFMPEG Plugin: Refactor audio decoding method into two.
  
  - First method is solely responsible to fill the audio output buffer with
    already decoded audio frames.
    Second method is solely responsible for decoding the encoded audio data and
    put it in the decoded audio output buffer for further processing with the
    first method.
    This prepares auto detection of audio frame properties for audio formats
    where the properties are contained within the encoded audio frame (e.g. 
MP3),
    instead within the audio container format (e.g. WMA). Implementing auto
    detection is scheduled for a later commit though.
  
  - Added documentation accordingly.
  
  - No functional change intended.

3bca609: FFMPEG Plugin: Rename some variables in audio path.
  
  - Make the difference between fDecodedData and fDecodedDataBuffer more clear.
  
  - No functional change intended.

b82ef8b: FFMPEG Plugin: Refactor scope of fTempPacket in audio path.
  
  - There are two main reasons for this refactoring:
      1. Prepare using FFMPEGs functionality of audio frame start time 
assignment
         (instead of rolling it ourself) like already done for the video path
         (see _LoadNextVideoChunkIfNeededAndAssignStartTime() for reference).
      2. Get rid of fChunkBufferOffset (this is a minor reason though).
  
  - Untangle some of the conditional checks to increase readability.
  
  - No functional change intended.

                                           [ Colin Günther <coling@xxxxxx> ]

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

2 files changed, 203 insertions(+), 127 deletions(-)
.../media/plugins/ffmpeg/AVCodecDecoder.cpp      | 316 ++++++++++++-------
.../media/plugins/ffmpeg/AVCodecDecoder.h        |  14 +-

############################################################################

Commit:      54b392b4cc060fffd7ae2cb10be7bea28ff8b301
URL:         http://cgit.haiku-os.org/haiku/commit/?id=54b392b
Author:      Colin Günther <coling@xxxxxx>
Date:        Wed Aug 20 10:45:01 2014 UTC

FFMPEG Plugin: Some cleanups.

- Use name that correctly reflects the return value of avcodec_decode_video2().
- Make DO_PROFILING code path of AVCodecDecoder compile again.
- No functional change intended.

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

diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp 
b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
index 28cc577..38d25c2 100644
--- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
+++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
@@ -771,9 +771,9 @@ AVCodecDecoder::_DecodeNextVideoFrame()
                // required to buffer the packets between different calls to
                // _DecodeNextVideoFrame().
                int gotVideoFrame = 0;
-               int decodedDataSizeInBytes = avcodec_decode_video2(fContext,
+               int encodedDataSizeInBytes = avcodec_decode_video2(fContext,
                        fRawDecodedPicture, &gotVideoFrame, &fTempPacket);
-               if (decodedDataSizeInBytes < 0) {
+               if (encodedDataSizeInBytes < 0) {
                        TRACE("[v] AVCodecDecoder: ignoring error in decoding 
frame %lld:"
                                " %d\n", fFrame, len);
                        // NOTE: An error from avcodec_decode_video2() is 
ignored by the
@@ -784,13 +784,13 @@ AVCodecDecoder::_DecodeNextVideoFrame()
                        continue;
                }
 
-               fTempPacket.size -= decodedDataSizeInBytes;
-               fTempPacket.data += decodedDataSizeInBytes;
+               fTempPacket.size -= encodedDataSizeInBytes;
+               fTempPacket.data += encodedDataSizeInBytes;
 
                bool gotNoVideoFrame = gotVideoFrame == 0;
                if (gotNoVideoFrame) {
-                       TRACE("frame %lld - no picture yet, 
decodedDataSizeInBytes: %d, "
-                               "chunk size: %ld\n", fFrame, 
decodedDataSizeInBytes,
+                       TRACE("frame %lld - no picture yet, 
encodedDataSizeInBytes: %d, "
+                               "chunk size: %ld\n", fFrame, 
encodedDataSizeInBytes,
                                fChunkBufferSize);
                        continue;
                }
@@ -807,19 +807,9 @@ AVCodecDecoder::_DecodeNextVideoFrame()
                conversionTime += doneTime - formatConversionStart;
                profileCounter++;
                if (!(fFrame % 5)) {
-                       if (info) {
-                               printf("[v] profile: d1 = %lld, d2 = %lld 
(%lld) required "
-                                       "%Ld\n",
-                                       decodingTime / profileCounter,
-                                       conversionTime / profileCounter,
-                                       fFrame, info->time_to_decode);
-                       } else {
-                               printf("[v] profile: d1 = %lld, d2 = %lld 
(%lld) required "
-                                       "%Ld\n",
-                                       decodingTime / profileCounter,
-                                       conversionTime / profileCounter,
-                                       fFrame, bigtime_t(1000000LL / 
fOutputFrameRate));
-                       }
+                       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;

############################################################################

Commit:      85371234ea80acd42cfbcc64d82ce0df79fb1e7b
URL:         http://cgit.haiku-os.org/haiku/commit/?id=8537123
Author:      Colin Günther <coling@xxxxxx>
Date:        Wed Aug 20 19:25:19 2014 UTC

FFMPEG Plugin: Refactor audio decoding method into two.

- First method is solely responsible to fill the audio output buffer with
  already decoded audio frames.
  Second method is solely responsible for decoding the encoded audio data and
  put it in the decoded audio output buffer for further processing with the
  first method.
  This prepares auto detection of audio frame properties for audio formats
  where the properties are contained within the encoded audio frame (e.g. MP3),
  instead within the audio container format (e.g. WMA). Implementing auto
  detection is scheduled for a later commit though.

- Added documentation accordingly.

- No functional change intended.

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

diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp 
b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
index 38d25c2..cfae30a 100644
--- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
+++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
@@ -545,17 +545,135 @@ 
AVCodecDecoder::_NegotiateVideoOutputFormat(media_format* inOutFormat)
 }
 
 
+/*! \brief Fills the outBuffer with one or more already decoded audio frames.
+
+       Besides the main duty described above, this method also fills out the 
other
+       output parameters as documented below.
+
+       \param outBuffer Pointer to the output buffer to copy the decoded audio
+               frames to.
+       \param outFrameCount Pointer to the output variable to assign the 
number of
+               copied audio frames (usually several audio frames at once).
+       \param mediaHeader Pointer to the output media header that contains the
+               properties of the decoded audio frame being the first in the 
outBuffer.
+       \param info Specifies additional decoding parameters. (Note: unused).
+
+       \returns B_OK Decoding audio frames succeeded.
+       \returns B_LAST_BUFFER_ERROR There are no more audio frames available.
+       \returns Other error codes
+*/
 status_t
-AVCodecDecoder::_DecodeAudio(void* _buffer, int64* outFrameCount,
+AVCodecDecoder::_DecodeAudio(void* outBuffer, int64* outFrameCount,
        media_header* mediaHeader, media_decode_info* info)
 {
        TRACE_AUDIO("AVCodecDecoder::_DecodeAudio(audio start_time %.6fs)\n",
                mediaHeader->start_time / 1000000.0);
 
-       *outFrameCount = 0;
+       status_t audioDecodingStatus
+               = fDecodedDataSizeInBytes > 0 ? B_OK : _DecodeNextAudioFrame();
+
+       if (audioDecodingStatus != B_OK)
+               return audioDecodingStatus;
+
+       *outFrameCount = fDecodedDataSizeInBytes / fOutputFrameSize;
+       memcpy(outBuffer, fDecodedData, fDecodedDataSizeInBytes);
+
+       fDecodedDataSizeInBytes = 0;
+
+       return B_OK;
+}
+
+
+/*! \brief Fills the outBuffer with an already decoded video frame.
+
+       Besides the main duty described above, this method also fills out the 
other
+       output parameters as documented below.
+
+       \param outBuffer Pointer to the output buffer to copy the decoded video
+               frame to.
+       \param outFrameCount Pointer to the output variable to assign the 
number of
+               copied video frames (usually one video frame).
+       \param mediaHeader Pointer to the output media header that contains the
+               decoded video frame properties.
+       \param info Specifies additional decoding parameters. (Note: unused).
+
+       \returns B_OK Decoding a video frame succeeded.
+       \returns B_LAST_BUFFER_ERROR There are no more video frames available.
+       \returns Other error codes
+*/
+status_t
+AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* outFrameCount,
+       media_header* mediaHeader, media_decode_info* info)
+{
+       status_t videoDecodingStatus
+               = fDecodedDataSizeInBytes > 0 ? B_OK : _DecodeNextVideoFrame();
+
+       if (videoDecodingStatus != B_OK)
+               return videoDecodingStatus;
+
+       *outFrameCount = 1;
+       *mediaHeader = fHeader;
+       memcpy(outBuffer, fDecodedData, mediaHeader->size_used);
+
+       fDecodedDataSizeInBytes = 0;
+
+       return B_OK;
+}
+
+
+/*!    \brief Decodes next audio frame.
 
-       uint8* buffer = reinterpret_cast<uint8*>(_buffer);
-       while (*outFrameCount < fOutputFrameCount) {
+       We decode at least one audio frame into fDecodedData. To achieve this 
goal,
+    we might need to request several chunks of encoded data resulting in a
+    variable execution time of this function.
+
+    The length of the decoded audio frame(s) is stored in
+    fDecodedDataSizeInBytes. If this variable is greater than zero you can
+    assert that all audio frames in fDecodedData are valid.
+
+       It is assumed that the number of expected audio frames is stored in
+       fOutputFrameCount. So _DecodeNextAudioFrame() must be called only after
+       fOutputFrameCount has been set.
+
+       Note: fOutputFrameCount contains the maximum number of frames a caller
+       of BMediaDecoder::Decode() expects to receive. There is a direct
+       relationship between fOutputFrameCount and the buffer size a caller of
+       BMediaDecoder::Decode() will provide so we make sure to respect this 
limit
+       for fDecodedDataSizeInBytes.
+
+       On return with status code B_OK the following conditions hold true:
+               1. fDecodedData contains as much audio frames as the caller of
+                  BMediaDecoder::Decode() expects.
+               2. fDecodedData contains lesser audio frames as the caller of
+                  BMediaDecoder::Decode() expects only when there are no more 
audio
+                  frames left. Consecutive calls to _DecodeNextAudioFrame will 
then
+                  result in the return of status code B_LAST_BUFFER_ERROR.
+               3. TODO: make the following statement hold true, too:
+                  fHeader is populated with the audio frame properties of the 
first
+                  audio frame in fDecodedData. Especially the start_time field 
of
+                  fHeader relates to that first audio frame. Start times of
+                  consecutive audio frames in fDecodedData have to be 
calculated
+                  manually (using the frame rate and the frame duration) if the
+                  caller needs them.
+                  
+
+       \returns B_OK when we successfully decoded enough audio frames
+       \returns B_LAST_BUFFER_ERROR when there are no more audio frames 
available.
+       \returns B_NO_MEMORY when we have no memory left for correct operation.
+       \returns Other Errors
+*/
+status_t
+AVCodecDecoder::_DecodeNextAudioFrame()
+{
+       fDecodedDataSizeInBytes = 0;
+       size_t maximumSizeOfDecodedData = fOutputFrameCount * fOutputFrameSize;
+       if (fDecodedData == NULL)
+               fDecodedData
+                       = 
static_cast<uint8_t*>(malloc(maximumSizeOfDecodedData));
+       uint8_t* decodedData = fDecodedData;
+
+       int64 currentFrameCount = 0;
+       while (currentFrameCount < fOutputFrameCount) {
                // Check conditions which would hint at broken code below.
                if (fOutputBufferSize < 0) {
                        fprintf(stderr, "Decoding read past the end of the 
output buffer! "
@@ -573,17 +691,17 @@ AVCodecDecoder::_DecodeAudio(void* _buffer, int64* 
outFrameCount,
                        // invokation, which start at fOutputBufferOffset
                        // and are of fOutputBufferSize. Copy those into the 
buffer,
                        // but not more than it can hold.
-                       int32 frames = min_c(fOutputFrameCount - *outFrameCount,
+                       int32 frames = min_c(fOutputFrameCount - 
currentFrameCount,
                                fOutputBufferSize / fOutputFrameSize);
                        if (frames == 0)
                                debugger("fOutputBufferSize not multiple of 
frame size!");
                        size_t remainingSize = frames * fOutputFrameSize;
-                       memcpy(buffer, fOutputFrame->data[0] + 
fOutputBufferOffset,
+                       memcpy(decodedData, fOutputFrame->data[0] + 
fOutputBufferOffset,
                                remainingSize);
                        fOutputBufferOffset += remainingSize;
                        fOutputBufferSize -= remainingSize;
-                       buffer += remainingSize;
-                       *outFrameCount += frames;
+                       decodedData += remainingSize;
+                       currentFrameCount += frames;
                        fStartTime += (bigtime_t)((1000000LL * frames) / 
fOutputFrameRate);
                        continue;
                }
@@ -632,7 +750,7 @@ AVCodecDecoder::_DecodeAudio(void* _buffer, int64* 
outFrameCount,
                        usedBytes = fChunkBufferSize;
                        fOutputBufferSize = 0;
                        // Assume the audio decoded until now is broken.
-                       memset(_buffer, 0, buffer - (uint8*)_buffer);
+                       memset(fDecodedData, 0, decodedData - fDecodedData);
                } else {
                        // Success
                        fAudioDecodeError = false;
@@ -652,45 +770,9 @@ AVCodecDecoder::_DecodeAudio(void* _buffer, int64* 
outFrameCount,
                fChunkBufferSize -= usedBytes;
                fOutputBufferOffset = 0;
        }
-       fFrame += *outFrameCount;
-       TRACE_AUDIO("  frame count: %lld current: %lld\n", *outFrameCount, 
fFrame);
-
-       return B_OK;
-}
-
-
-/*! \brief Fills the outBuffer with an already decoded video frame.
-
-       Besides the main duty described above, this method also fills out the 
other
-       output parameters as documented below.
-
-       \param outBuffer Pointer to the output buffer to copy the decoded video
-               frame to.
-       \param outFrameCount Pointer to the output variable to assign the 
number of
-               copied video frames (usually one video frame).
-       \param mediaHeader Pointer to the output media header that contains the
-               decoded video frame properties.
-       \param info TODO (not used at the moment)
-
-       \returns B_OK Decoding a video frame succeeded.
-       \returns B_LAST_BUFFER_ERROR There are no more video frames available.
-       \returns other error codes
-*/
-status_t
-AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* outFrameCount,
-       media_header* mediaHeader, media_decode_info* info)
-{
-       status_t videoDecodingStatus
-               = fDecodedDataSizeInBytes > 0 ? B_OK : _DecodeNextVideoFrame();
-
-       if (videoDecodingStatus != B_OK)
-               return videoDecodingStatus;
-
-       *outFrameCount = 1;
-       *mediaHeader = fHeader;
-       memcpy(outBuffer, fDecodedData, mediaHeader->size_used);
-
-       fDecodedDataSizeInBytes = 0;
+       fFrame += currentFrameCount;
+       fDecodedDataSizeInBytes = currentFrameCount * fOutputFrameSize;
+       TRACE_AUDIO("  frame count: %lld current: %lld\n", currentFrameCount, 
fFrame);
 
        return B_OK;
 }
@@ -948,7 +1030,7 @@ 
AVCodecDecoder::_LoadNextVideoChunkIfNeededAndAssignStartTime()
 
        Also update fChunkBufferSize to reflect the size of the contained video
        data (leaving out the padding).
-       
+
        \param chunk The chunk to copy.
        \param chunkSize Size of the chunk in bytes
 
diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h 
b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
index 8f00b95..40256bd 100644
--- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
+++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
@@ -60,6 +60,7 @@ private:
                        status_t        _DecodeVideo(void* outBuffer, int64* 
outFrameCount,
                                                        media_header* 
mediaHeader,
                                                        media_decode_info* 
info);
+                       status_t        _DecodeNextAudioFrame();
                        status_t        _DecodeNextVideoFrame();
                        void            
_ApplyEssentialVideoContainerPropertiesToContext();
                        status_t        
_LoadNextVideoChunkIfNeededAndAssignStartTime();

############################################################################

Commit:      3bca609810310998daf639e27fbdcaa22cf49210
URL:         http://cgit.haiku-os.org/haiku/commit/?id=3bca609
Author:      Colin Günther <coling@xxxxxx>
Date:        Wed Aug 20 19:54:42 2014 UTC

FFMPEG Plugin: Rename some variables in audio path.

- Make the difference between fDecodedData and fDecodedDataBuffer more clear.

- No functional change intended.

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

diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp 
b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
index cfae30a..7f18585 100644
--- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
+++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
@@ -111,9 +111,9 @@ AVCodecDecoder::AVCodecDecoder()
        fChunkBufferSize(0),
        fAudioDecodeError(false),
 
-       fOutputFrame(avcodec_alloc_frame()),
-       fOutputBufferOffset(0),
-       fOutputBufferSize(0)
+       fDecodedDataBuffer(avcodec_alloc_frame()),
+       fDecodedDataBufferOffset(0),
+       fDecodedDataBufferSize(0)
 {
        TRACE("AVCodecDecoder::AVCodecDecoder()\n");
 
@@ -149,7 +149,7 @@ AVCodecDecoder::~AVCodecDecoder()
        av_free(fPostProcessedDecodedPicture);
        av_free(fRawDecodedPicture);
        av_free(fContext);
-       av_free(fOutputFrame);
+       av_free(fDecodedDataBuffer);
 
 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
        if (fSwsContext != NULL)
@@ -271,8 +271,8 @@ AVCodecDecoder::SeekedTo(int64 frame, bigtime_t time)
        fChunkBuffer = NULL;
        fChunkBufferOffset = 0;
        fChunkBufferSize = 0;
-       fOutputBufferOffset = 0;
-       fOutputBufferSize = 0;
+       fDecodedDataBufferOffset = 0;
+       fDecodedDataBufferSize = 0;
        fDecodedDataSizeInBytes = 0;
 
        fFrame = frame;
@@ -418,8 +418,8 @@ AVCodecDecoder::_NegotiateAudioOutputFormat(media_format* 
inOutFormat)
        fChunkBufferOffset = 0;
        fChunkBufferSize = 0;
        fAudioDecodeError = false;
-       fOutputBufferOffset = 0;
-       fOutputBufferSize = 0;
+       fDecodedDataBufferOffset = 0;
+       fDecodedDataBufferSize = 0;
 
        _ResetTempPacket();
 
@@ -655,7 +655,7 @@ AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* 
outFrameCount,
                   consecutive audio frames in fDecodedData have to be 
calculated
                   manually (using the frame rate and the frame duration) if the
                   caller needs them.
-                  
+
 
        \returns B_OK when we successfully decoded enough audio frames
        \returns B_LAST_BUFFER_ERROR when there are no more audio frames 
available.
@@ -675,10 +675,10 @@ AVCodecDecoder::_DecodeNextAudioFrame()
        int64 currentFrameCount = 0;
        while (currentFrameCount < fOutputFrameCount) {
                // Check conditions which would hint at broken code below.
-               if (fOutputBufferSize < 0) {
-                       fprintf(stderr, "Decoding read past the end of the 
output buffer! "
-                               "%ld\n", fOutputBufferSize);
-                       fOutputBufferSize = 0;
+               if (fDecodedDataBufferSize < 0) {
+                       fprintf(stderr, "Decoding read past the end of the 
decoded data "
+                               "buffer! %ld\n", fDecodedDataBufferSize);
+                       fDecodedDataBufferSize = 0;
                }
                if (fChunkBufferSize < 0) {
                        fprintf(stderr, "Decoding read past the end of the 
chunk buffer! "
@@ -686,20 +686,20 @@ AVCodecDecoder::_DecodeNextAudioFrame()
                        fChunkBufferSize = 0;
                }
 
-               if (fOutputBufferSize > 0) {
+               if (fDecodedDataBufferSize > 0) {
                        // We still have decoded audio frames from the last
-                       // invokation, which start at fOutputBufferOffset
-                       // and are of fOutputBufferSize. Copy those into the 
buffer,
+                       // invokation, which start at fDecodedDataBufferOffset
+                       // and are of fDecodedDataBufferSize. Copy those into 
the buffer,
                        // but not more than it can hold.
                        int32 frames = min_c(fOutputFrameCount - 
currentFrameCount,
-                               fOutputBufferSize / fOutputFrameSize);
+                               fDecodedDataBufferSize / fOutputFrameSize);
                        if (frames == 0)
-                               debugger("fOutputBufferSize not multiple of 
frame size!");
+                               debugger("fDecodedDataBufferSize not multiple 
of frame size!");
                        size_t remainingSize = frames * fOutputFrameSize;
-                       memcpy(decodedData, fOutputFrame->data[0] + 
fOutputBufferOffset,
-                               remainingSize);
-                       fOutputBufferOffset += remainingSize;
-                       fOutputBufferSize -= remainingSize;
+                       memcpy(decodedData, fDecodedDataBuffer->data[0]
+                               + fDecodedDataBufferOffset, remainingSize);
+                       fDecodedDataBufferOffset += remainingSize;
+                       fDecodedDataBufferSize -= remainingSize;
                        decodedData += remainingSize;
                        currentFrameCount += frames;
                        fStartTime += (bigtime_t)((1000000LL * frames) / 
fOutputFrameRate);
@@ -733,10 +733,10 @@ AVCodecDecoder::_DecodeNextAudioFrame()
                fTempPacket.data = (uint8_t*)fChunkBuffer + fChunkBufferOffset;
                fTempPacket.size = fChunkBufferSize;
 
-               avcodec_get_frame_defaults(fOutputFrame);
+               avcodec_get_frame_defaults(fDecodedDataBuffer);
                int gotFrame = 0;
                int usedBytes = avcodec_decode_audio4(fContext,
-                       fOutputFrame, &gotFrame, &fTempPacket);
+                       fDecodedDataBuffer, &gotFrame, &fTempPacket);
                if (usedBytes < 0 && !fAudioDecodeError) {
                        // Report failure if not done already
                        printf("########### audio decode error, "
@@ -748,27 +748,27 @@ AVCodecDecoder::_DecodeNextAudioFrame()
                        // Error or failure to produce decompressed output.
                        // Skip the chunk buffer data entirely.
                        usedBytes = fChunkBufferSize;
-                       fOutputBufferSize = 0;
+                       fDecodedDataBufferSize = 0;
                        // Assume the audio decoded until now is broken.
                        memset(fDecodedData, 0, decodedData - fDecodedData);
                } else {
                        // Success
                        fAudioDecodeError = false;
                        if (gotFrame == 1) {
-                               fOutputBufferSize = 
av_samples_get_buffer_size(NULL,
-                                       fContext->channels, 
fOutputFrame->nb_samples,
+                               fDecodedDataBufferSize = 
av_samples_get_buffer_size(NULL,
+                                       fContext->channels, 
fDecodedDataBuffer->nb_samples,
                                        fContext->sample_fmt, 1);
-                               if (fOutputBufferSize < 0)
-                                       fOutputBufferSize = 0;
+                               if (fDecodedDataBufferSize < 0)
+                                       fDecodedDataBufferSize = 0;
                        } else
-                               fOutputBufferSize = 0;
+                               fDecodedDataBufferSize = 0;
                }
 //printf("  chunk size: %d, decoded: %d, used: %d\n",
 //fTempPacket.size, decodedBytes, usedBytes);
 
                fChunkBufferOffset += usedBytes;
                fChunkBufferSize -= usedBytes;
-               fOutputBufferOffset = 0;
+               fDecodedDataBufferOffset = 0;
        }
        fFrame += currentFrameCount;
        fDecodedDataSizeInBytes = currentFrameCount * fOutputFrameSize;
diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h 
b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
index 40256bd..cccd935 100644
--- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
+++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
@@ -121,9 +121,9 @@ private:
                        size_t                          fChunkBufferSize;
                        bool                            fAudioDecodeError;
 
-                       AVFrame*                        fOutputFrame;
-                       int32                           fOutputBufferOffset;
-                       int32                           fOutputBufferSize;
+                       AVFrame*                        fDecodedDataBuffer;
+                       int32                           
fDecodedDataBufferOffset;
+                       int32                           fDecodedDataBufferSize;
 
                        AVPacket                        fTempPacket;
 };

############################################################################

Revision:    hrev47719
Commit:      b82ef8bc15614a52394f5f5626b719530e01cfa5
URL:         http://cgit.haiku-os.org/haiku/commit/?id=b82ef8b
Author:      Colin Günther <coling@xxxxxx>
Date:        Wed Aug 20 22:32:21 2014 UTC

FFMPEG Plugin: Refactor scope of fTempPacket in audio path.

- There are two main reasons for this refactoring:
    1. Prepare using FFMPEGs functionality of audio frame start time assignment
       (instead of rolling it ourself) like already done for the video path
       (see _LoadNextVideoChunkIfNeededAndAssignStartTime() for reference).
    2. Get rid of fChunkBufferOffset (this is a minor reason though).

- Untangle some of the conditional checks to increase readability.

- No functional change intended.

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

diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp 
b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
index 7f18585..8031990 100644
--- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
+++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
@@ -107,7 +107,6 @@ AVCodecDecoder::AVCodecDecoder()
 
        fChunkBuffer(NULL),
        fVideoChunkBuffer(NULL),
-       fChunkBufferOffset(0),
        fChunkBufferSize(0),
        fAudioDecodeError(false),
 
@@ -269,7 +268,6 @@ AVCodecDecoder::SeekedTo(int64 frame, bigtime_t time)
                // responsible for freeing the chunk buffer, too.
        fVideoChunkBuffer = NULL;
        fChunkBuffer = NULL;
-       fChunkBufferOffset = 0;
        fChunkBufferSize = 0;
        fDecodedDataBufferOffset = 0;
        fDecodedDataBufferSize = 0;
@@ -415,7 +413,6 @@ AVCodecDecoder::_NegotiateAudioOutputFormat(media_format* 
inOutFormat)
                result, fOutputFrameSize, fOutputFrameCount, fOutputFrameRate);
 
        fChunkBuffer = NULL;
-       fChunkBufferOffset = 0;
        fChunkBufferSize = 0;
        fAudioDecodeError = false;
        fDecodedDataBufferOffset = 0;
@@ -665,7 +662,11 @@ AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* 
outFrameCount,
 status_t
 AVCodecDecoder::_DecodeNextAudioFrame()
 {
-       fDecodedDataSizeInBytes = 0;
+       assert(fTempPacket.size >= 0);
+       assert(fDecodedDataSizeInBytes == 0);
+               // _DecodeNextAudioFrame needs to be called on empty 
fDecodedData only!
+               // If this assert holds wrong we have a bug somewhere.
+
        size_t maximumSizeOfDecodedData = fOutputFrameCount * fOutputFrameSize;
        if (fDecodedData == NULL)
                fDecodedData
@@ -680,10 +681,10 @@ AVCodecDecoder::_DecodeNextAudioFrame()
                                "buffer! %ld\n", fDecodedDataBufferSize);
                        fDecodedDataBufferSize = 0;
                }
-               if (fChunkBufferSize < 0) {
-                       fprintf(stderr, "Decoding read past the end of the 
chunk buffer! "
-                               "%ld\n", fChunkBufferSize);
-                       fChunkBufferSize = 0;
+               if (fTempPacket.size < 0) {
+                       fprintf(stderr, "Decoding read past the end of the temp 
packet! "
+                               "%d\n", fTempPacket.size);
+                       fTempPacket.size = 0;
                }
 
                if (fDecodedDataBufferSize > 0) {
@@ -705,7 +706,7 @@ AVCodecDecoder::_DecodeNextAudioFrame()
                        fStartTime += (bigtime_t)((1000000LL * frames) / 
fOutputFrameRate);
                        continue;
                }
-               if (fChunkBufferSize == 0) {
+               if (fTempPacket.size == 0) {
                        // Time to read the next chunk buffer. We use a separate
                        // media_header, since the chunk header may not belong 
to
                        // the start of the decoded audio frames we return. For
@@ -726,50 +727,53 @@ AVCodecDecoder::_DecodeNextAudioFrame()
                                fChunkBufferSize = 0;
                                break;
                        }
-                       fChunkBufferOffset = 0;
+                       fTempPacket.data
+                               = 
static_cast<uint8_t*>(const_cast<void*>(fChunkBuffer));
+                       fTempPacket.size = fChunkBufferSize;
                        fStartTime = chunkMediaHeader.start_time;
                }
 
-               fTempPacket.data = (uint8_t*)fChunkBuffer + fChunkBufferOffset;
-               fTempPacket.size = fChunkBufferSize;
-
                avcodec_get_frame_defaults(fDecodedDataBuffer);
                int gotFrame = 0;
                int usedBytes = avcodec_decode_audio4(fContext,
                        fDecodedDataBuffer, &gotFrame, &fTempPacket);
                if (usedBytes < 0 && !fAudioDecodeError) {
                        // Report failure if not done already
+                       int32 chunkBufferOffset = fTempPacket.data
+                               - 
static_cast<uint8_t*>(const_cast<void*>(fChunkBuffer));
                        printf("########### audio decode error, "
-                               "fChunkBufferSize %ld, fChunkBufferOffset 
%ld\n",
-                               fChunkBufferSize, fChunkBufferOffset);
+                               "fTempPacket.size %d, fChunkBuffer data offset 
%ld\n",
+                               fTempPacket.size, chunkBufferOffset);
                        fAudioDecodeError = true;
                }
                if (usedBytes <= 0) {
                        // Error or failure to produce decompressed output.
-                       // Skip the chunk buffer data entirely.
-                       usedBytes = fChunkBufferSize;
-                       fDecodedDataBufferSize = 0;
+                       // Skip the temp packet data entirely.
+                       fTempPacket.size = 0;
                        // Assume the audio decoded until now is broken.
                        memset(fDecodedData, 0, decodedData - fDecodedData);
-               } else {
-                       // Success
-                       fAudioDecodeError = false;
-                       if (gotFrame == 1) {
-                               fDecodedDataBufferSize = 
av_samples_get_buffer_size(NULL,
-                                       fContext->channels, 
fDecodedDataBuffer->nb_samples,
-                                       fContext->sample_fmt, 1);
-                               if (fDecodedDataBufferSize < 0)
-                                       fDecodedDataBufferSize = 0;
-                       } else
-                               fDecodedDataBufferSize = 0;
+                       fDecodedDataBufferOffset = 0;
+                       continue;
                }
-//printf("  chunk size: %d, decoded: %d, used: %d\n",
-//fTempPacket.size, decodedBytes, usedBytes);
 
-               fChunkBufferOffset += usedBytes;
-               fChunkBufferSize -= usedBytes;
+               fAudioDecodeError = false;
+               fDecodedDataBufferSize = 0;
                fDecodedDataBufferOffset = 0;
+
+               fTempPacket.data += usedBytes;
+               fTempPacket.size -= usedBytes;
+
+               bool gotNoAudioFrame = gotFrame == 0;
+               if (gotNoAudioFrame)
+                       continue;
+
+               fDecodedDataBufferSize = av_samples_get_buffer_size(NULL,
+                       fContext->channels, fDecodedDataBuffer->nb_samples,
+                       fContext->sample_fmt, 1);
+               if (fDecodedDataBufferSize < 0)
+                       fDecodedDataBufferSize = 0;
        }
+
        fFrame += currentFrameCount;
        fDecodedDataSizeInBytes = currentFrameCount * fOutputFrameSize;
        TRACE_AUDIO("  frame count: %lld current: %lld\n", currentFrameCount, 
fFrame);
diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h 
b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
index cccd935..8a4dd2f 100644
--- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
+++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
@@ -114,10 +114,9 @@ private:
                        const void*                     fChunkBuffer;
                        uint8_t*                        fVideoChunkBuffer;
                                                                        // 
TODO: Remove and use fChunkBuffer again
-                                                                       // 
(with type uint8_t*) once the audio path is
-                                                                       // 
responsible for freeing the chunk buffer,
-                                                                       // too.
-                       int32                           fChunkBufferOffset;
+                                                                       // 
(with type uint8_t*) once the audio path
+                                                                       // is 
responsible for freeing the chunk
+                                                                       // 
buffer, too.
                        size_t                          fChunkBufferSize;
                        bool                            fAudioDecodeError;
 


Other related posts:

  • » [haiku-commits] haiku: hrev47719 - src/add-ons/media/plugins/ffmpeg - coling