[haiku-commits] r38498 - haiku/trunk/src/apps/mediaplayer/supplier

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 1 Sep 2010 18:02:42 +0200 (CEST)

Author: stippi
Date: 2010-09-01 18:02:42 +0200 (Wed, 01 Sep 2010)
New Revision: 38498
Changeset: http://dev.haiku-os.org/changeset/38498

Modified:
   haiku/trunk/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.cpp
Log:
Several improvements that make the audio playback
much more robust:
 * Use a much larger buffer size, since we cache
   a lot anyway.
 * When reading uncached frames, don't trip over the
   situation that the seekable keyframe was very far
   away from where we want to read. Don't get caught
   up in a loop decoding an entire movie, but return
   a time-out error instead. This will get us back
   on track eventually.
 * Before seeking to a keyframe, check if the current
   track position is actually nearer.


Modified: haiku/trunk/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.cpp
===================================================================
--- haiku/trunk/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.cpp       
2010-09-01 15:58:22 UTC (rev 38497)
+++ haiku/trunk/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.cpp       
2010-09-01 16:02:42 UTC (rev 38498)
@@ -55,16 +55,17 @@
 
 MediaTrackAudioSupplier::MediaTrackAudioSupplier(BMediaTrack* mediaTrack,
                int32 trackIndex)
-       : AudioTrackSupplier(),
-         fMediaTrack(mediaTrack),
-         fBuffer(NULL),
-         fBufferOffset(0),
-         fBufferSize(0),
-         fBuffers(10),
-         fHasKeyFrames(false),
-         fCountFrames(0),
-         fReportSeekError(true),
-         fTrackIndex(trackIndex)
+       :
+       AudioTrackSupplier(),
+       fMediaTrack(mediaTrack),
+       fBuffer(NULL),
+       fBufferOffset(0),
+       fBufferSize(0),
+       fBuffers(10),
+       fHasKeyFrames(false),
+       fCountFrames(0),
+       fReportSeekError(true),
+       fTrackIndex(trackIndex)
 {
        _InitFromTrack();
 }
@@ -235,13 +236,18 @@
 void
 MediaTrackAudioSupplier::_InitFromTrack()
 {
+       TRACE("_InitFromTrack()\n");
+       // Try to suggest a big buffer size, we do a lot of caching...
+       fFormat.u.raw_audio.buffer_size = 16384;
        if (fMediaTrack && fMediaTrack->DecodedFormat(&fFormat) == B_OK
                && fFormat.type == B_MEDIA_RAW_AUDIO) {
 
                #ifdef TRACE_AUDIO_SUPPLIER
                        char formatString[256];
                        string_for_format(fFormat, formatString, 256);
-                       TRACE("MediaTrackAudioSupplier: format is: %s\n", 
formatString);
+                       TRACE("_InitFromTrack(): format is: %s\n", 
formatString);
+                       TRACE("_InitFromTrack(): buffer size: %ld\n",
+                               fFormat.u.raw_audio.buffer_size);
                #endif
 
                fBuffer = new (nothrow) char[fFormat.u.raw_audio.buffer_size];
@@ -263,9 +269,9 @@
                // get the length of the track
                fCountFrames = fMediaTrack->CountFrames();
 
-               TRACE("MediaTrackAudioSupplier: keyframes: %d, frame count: 
%lld\n",
+               TRACE("_InitFromTrack(): keyframes: %d, frame count: %lld\n",
                        fHasKeyFrames, fCountFrames);
-               printf("MediaTrackAudioSupplier: keyframes: %d, frame count: 
%lld\n",
+               printf("_InitFromTrack(): keyframes: %d, frame count: %lld\n",
                        fHasKeyFrames, fCountFrames);
        } else
                fMediaTrack = NULL;
@@ -384,7 +390,8 @@
 MediaTrackAudioSupplier::_FindUnusedBuffer() const
 {
        Buffer* buffer = NULL;
-       for (int32 i = 0; ((buffer = _BufferAt(i))) && buffer->size != 0; i++);
+       for (int32 i = 0; ((buffer = _BufferAt(i))) && buffer->size != 0; i++)
+               ;
        return buffer;
 }
 
@@ -418,7 +425,7 @@
 MediaTrackAudioSupplier::_FindUsableBufferFor(int64 position) const
 {
        Buffer* buffer = _FindBufferAtFrame(position);
-       if (!buffer)
+       if (buffer == NULL)
                buffer = _FindUsableBuffer();
        return buffer;
 }
@@ -471,7 +478,8 @@
 {
        status_t error = fMediaTrack->ReadFrames(buffer->data, &buffer->size);
 
-       TRACE("Read(%p, %lld): %s\n", buffer->data, buffer->size, 
strerror(error));
+       TRACE("_ReadBuffer(%p, %lld): %s\n", buffer->data, buffer->size,
+               strerror(error));
 
        buffer->offset = position;
        buffer->time_stamp = time;
@@ -542,16 +550,21 @@
        if (frames > 0) {
                error = _SeekToKeyFrameBackward(currentPos);
                TRACE("_ReadUncachedFrames() - seeked to position: %lld\n", 
currentPos);
+               if (position - currentPos > 100000)
+                       printf("MediaTrackAudioSupplier::_ReadUncachedFrames() 
- "
+                               "keyframe was far away: %lld -> %lld\n", 
position, currentPos);
        }
        // read the frames
+       // TODO: Calculate timeout, 0.25 times duration of "frames" seems good.
+       bigtime_t timeout = 10000;
        while (error == B_OK && frames > 0) {
                Buffer* cacheBuffer = _FindUsableBufferFor(currentPos);
-               TRACE("_ReadUncachedFrames() - usable buffer found: %p\n", 
cacheBuffer);
+               TRACE("_ReadUncachedFrames() - usable buffer found: %p, "
+                       "position: %lld/%lld\n", cacheBuffer, currentPos, 
position);
                error = _ReadBuffer(cacheBuffer, currentPos, time);
                if (error == B_OK) {
                        int64 size = min(position + frames,
-                                                        cacheBuffer->offset + 
cacheBuffer->size)
-                                                - position;
+                               cacheBuffer->offset + cacheBuffer->size) - 
position;
                        if (size > 0) {
                                _CopyFrames(cacheBuffer, buffer, position, 
position, size);
                                buffer = SkipFrames(buffer, size);
@@ -560,9 +573,13 @@
                        }
                        currentPos += cacheBuffer->size;
                }
+               if (system_time() - time > timeout) {
+                       error = B_TIMED_OUT;
+                       break;
+               }
        }
 
-#if 1
+#if 0
        // Ensure that all frames up to the next key frame are cached.
        // This avoids, that each read reaches the BMediaTrack.
        if (error == B_OK) {
@@ -652,21 +669,29 @@
 status_t
 MediaTrackAudioSupplier::_SeekToKeyFrameBackward(int64& position)
 {
-       if (position == fMediaTrack->CurrentFrame())
+       int64 currentPosition = fMediaTrack->CurrentFrame();
+       if (position == currentPosition)
                return B_OK;
 
        status_t error = B_OK;
        if (fHasKeyFrames) {
-               int64 oldPosition = position;
+               int64 wantedPosition = position;
                error = fMediaTrack->FindKeyFrameForFrame(&position,
                        B_MEDIA_SEEK_CLOSEST_BACKWARD);
+               if (error == B_OK && currentPosition > position
+                       && currentPosition < wantedPosition) {
+                       // The current position is before the wanted position,
+                       // but later than the keyframe, so seeking is worse.
+                       position = currentPosition;
+                       return B_OK;
+               }
                if (error == B_OK)
                        error = fMediaTrack->SeekToFrame(&position, 0);
                if (error != B_OK) {
                        position = fMediaTrack->CurrentFrame();
 //                     if (fReportSeekError) {
                                printf("  seek to key frame backward: %lld -> 
%lld (%lld) "
-                                       "- %s\n", oldPosition, position,
+                                       "- %s\n", wantedPosition, position,
                                        fMediaTrack->CurrentFrame(), 
strerror(error));
                                fReportSeekError = false;
 //                     }


Other related posts:

  • » [haiku-commits] r38498 - haiku/trunk/src/apps/mediaplayer/supplier - superstippi