[haiku-commits] r38806 - haiku/trunk/src/add-ons/media/plugins/ffmpeg

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 24 Sep 2010 18:40:56 +0200 (CEST)

Author: stippi
Date: 2010-09-24 18:40:56 +0200 (Fri, 24 Sep 2010)
New Revision: 38806
Changeset: http://dev.haiku-os.org/changeset/38806

Modified:
   haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
   haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
Log:
 * Renamed fAudioTempPacket to fTempPacket and use it for calling
   the new video decoding function. This just avoids a warning
   generated from the libavcodec sources. The function used before
   did the exact same thing...
 * Maintain fStartTime correctly in _DecodeVideo(). Don't overwrite
   it with a calculated starttime in Decode(). This will allow drift
   to bubble up to the higher layers.
 * Do not use the previously required hack to close and reopen the
   AVCodec after seeking. avcodec_flush_buffers() seems to work
   fine now, and for certain stream types (MPEG1, MPEG2 video for
   example) the keyframe is correctly used after seeking.


Modified: haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp
===================================================================
--- haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp     
2010-09-24 16:35:11 UTC (rev 38805)
+++ haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp     
2010-09-24 16:40:56 UTC (rev 38806)
@@ -105,6 +105,10 @@
        fOutputBufferSize(0)
 {
        TRACE("AVCodecDecoder::AVCodecDecoder()\n");
+
+       fContext->error_recognition = FF_ER_CAREFUL;
+       fContext->error_concealment = 3;
+       avcodec_thread_init(fContext, 1);
 }
 
 
@@ -241,18 +245,8 @@
 {
        status_t ret = B_OK;
        // Reset the FFmpeg codec to flush buffers, so we keep the sync
-#if 1
-       if (fCodecInitDone) {
-               avcodec_close(fContext);
-               fCodecInitDone = avcodec_open(fContext, fCodec) >= 0;
-               if (!fCodecInitDone)
-                       ret = B_ERROR;
-       }
-#else
-       // For example, this doesn't work on the H.264 codec. :-/
        if (fCodecInitDone)
                avcodec_flush_buffers(fContext);
-#endif
 
        // Flush internal buffers as well.
        fChunkBuffer = NULL;
@@ -305,8 +299,6 @@
        else
                ret = _DecodeVideo(outBuffer, outFrameCount, mediaHeader, info);
 
-       fStartTime = (bigtime_t)(1000000LL * fFrame / fOutputFrameRate);
-
        return ret;
 }
 
@@ -400,7 +392,7 @@
        fOutputBufferOffset = 0;
        fOutputBufferSize = 0;
 
-       av_init_packet(&fAudioTempPacket);
+       av_init_packet(&fTempPacket);
 
        inOutFormat->require_flags = 0;
        inOutFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
@@ -586,18 +578,16 @@
                        }
                        fChunkBufferOffset = 0;
                        fStartTime = chunkMediaHeader.start_time;
-                       if (*outFrameCount == 0)
-                               mediaHeader->start_time = 
chunkMediaHeader.start_time;
                }
 
-               fAudioTempPacket.data = (uint8_t*)fChunkBuffer + 
fChunkBufferOffset;
-               fAudioTempPacket.size = fChunkBufferSize;
+               fTempPacket.data = (uint8_t*)fChunkBuffer + fChunkBufferOffset;
+               fTempPacket.size = fChunkBufferSize;
                // Initialize decodedBytes to the output buffer size.
                int decodedBytes = AVCODEC_MAX_AUDIO_FRAME_SIZE;
                int usedBytes = avcodec_decode_audio3(fContext,
-                       (int16*)fOutputBuffer, &decodedBytes, 
&fAudioTempPacket);
+                       (int16*)fOutputBuffer, &decodedBytes, &fTempPacket);
                if (usedBytes < 0 && !fAudioDecodeError) {
-                       // Failure
+                       // Report failure if not done already
                        printf("########### audio decode error, "
                                "fChunkBufferSize %ld, fChunkBufferOffset 
%ld\n",
                                fChunkBufferSize, fChunkBufferOffset);
@@ -608,12 +598,14 @@
                        // Skip the chunk buffer data entirely.
                        usedBytes = fChunkBufferSize;
                        decodedBytes = 0;
+                       // Assume the audio decoded until now is broken.
+                       memset(_buffer, 0, buffer - (uint8*)_buffer);
                } else {
                        // Success
                        fAudioDecodeError = false;
                }
 //printf("  chunk size: %d, decoded: %d, used: %d\n",
-//fAudioTempPacket.size, decodedBytes, usedBytes);
+//fTempPacket.size, decodedBytes, usedBytes);
 
                fChunkBufferOffset += usedBytes;
                fChunkBufferSize -= usedBytes;
@@ -622,6 +614,7 @@
        }
        fFrame += *outFrameCount;
        TRACE_AUDIO("  frame count: %lld current: %lld\n", *outFrameCount, 
fFrame);
+
        return B_OK;
 }
 
@@ -654,7 +647,8 @@
                        firstRun = false;
 
                        mediaHeader->type = B_MEDIA_RAW_VIDEO;
-//                     mediaHeader->start_time = chunkMediaHeader.start_time;
+                       mediaHeader->start_time = chunkMediaHeader.start_time;
+                       fStartTime = chunkMediaHeader.start_time;
                        mediaHeader->file_pos = 0;
                        mediaHeader->orig_size = 0;
                        mediaHeader->u.raw_video.field_gamma = 1.0;
@@ -681,9 +675,11 @@
                // packet buffers are supposed to contain complete frames only 
so we
                // don't seem to be required to buffer any packets because not 
the
                // complete packet has been read.
+               fTempPacket.data = (uint8_t*)data;
+               fTempPacket.size = size;
                int gotPicture = 0;
-               int len = avcodec_decode_video(fContext, fInputPicture, 
&gotPicture,
-                       (uint8_t*)data, size);
+               int len = avcodec_decode_video2(fContext, fInputPicture, 
&gotPicture,
+                       &fTempPacket);
                if (len < 0) {
                        TRACE("[v] AVCodecDecoder: error in decoding frame 
%lld: %d\n",
                                fFrame, len);

Modified: haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h
===================================================================
--- haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h       
2010-09-24 16:35:11 UTC (rev 38805)
+++ haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h       
2010-09-24 16:40:56 UTC (rev 38806)
@@ -102,7 +102,7 @@
                        int32                           fOutputBufferOffset;
                        int32                           fOutputBufferSize;
 
-                       AVPacket                        fAudioTempPacket;
+                       AVPacket                        fTempPacket;
 };
 
 #endif // AVCODEC_DECODER_H


Other related posts:

  • » [haiku-commits] r38806 - haiku/trunk/src/add-ons/media/plugins/ffmpeg - superstippi