[haiku-commits] r34650 - haiku/trunk/src/kits/media

Author: dlmcpaul
Date: 2009-12-13 13:09:17 +0100 (Sun, 13 Dec 2009)
New Revision: 34650
Changeset: http://dev.haiku-os.org/changeset/34650/haiku

Modified:
   haiku/trunk/src/kits/media/ChunkCache.cpp
   haiku/trunk/src/kits/media/ChunkCache.h
   haiku/trunk/src/kits/media/MediaExtractor.cpp
Log:
switch to use STL containers, limit to 10 cache entries, don't clear cache on 
findkeyframe, removed inflight list as it was not needed, report error 
conditions better.  This makes video work again

Modified: haiku/trunk/src/kits/media/ChunkCache.cpp
===================================================================
--- haiku/trunk/src/kits/media/ChunkCache.cpp   2009-12-13 00:23:07 UTC (rev 
34649)
+++ haiku/trunk/src/kits/media/ChunkCache.cpp   2009-12-13 12:09:17 UTC (rev 
34650)
@@ -10,24 +10,8 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <Debug.h>
+#include "debug.h"
 
-
-chunk_buffer::chunk_buffer()
-       :
-       buffer(NULL),
-       size(0),
-       capacity(0)
-{
-}
-
-
-chunk_buffer::~chunk_buffer()
-{
-       rtm_free(buffer);
-}
-
-
 // #pragma mark -
 
 
@@ -62,8 +46,11 @@
 {
        ASSERT(IsLocked());
 
-       fUnusedChunks.MoveFrom(&fChunks);
-
+       while (!fChunkCache.empty()) {
+               RecycleChunk(fChunkCache.front());
+               fChunkCache.pop();
+       }
+       
        release_sem(fWaitSem);
 }
 
@@ -73,18 +60,31 @@
 {
        ASSERT(IsLocked());
 
+       if (fChunkCache.size() >= CACHE_MAX_ENTRIES) {
+               return false;
+       }
+
+       // If there is no more memory we are likely to fail soon after
        return sizeof(chunk_buffer) + 2048 < rtm_available(fRealTimePool);
 }
 
 
 chunk_buffer*
-ChunkCache::NextChunk()
+ChunkCache::NextChunk(Reader* reader, void* cookie)
 {
        ASSERT(IsLocked());
 
-       chunk_buffer* chunk = fChunks.RemoveHead();
-       if (chunk != NULL) {
-               fInFlightChunks.Add(chunk);
+       chunk_buffer* chunk = NULL;
+
+       if (fChunkCache.empty()) {
+               TRACE("ChunkCache is empty, going direct to reader\n");
+               if (ReadNextChunk(reader, cookie)) {
+                       return NextChunk(reader, cookie);
+               }
+       } else {
+               chunk = fChunkCache.front();
+               fChunkCache.pop();
+               
                release_sem(fWaitSem);
        }
 
@@ -92,7 +92,7 @@
 }
 
 
-/*!    Moves the specified chunk from the in-flight list to the unused list.
+/*     Moves the specified chunk to the unused list.
        This means the chunk data can be overwritten again.
 */
 void
@@ -100,8 +100,11 @@
 {
        ASSERT(IsLocked());
 
-       fInFlightChunks.Remove(chunk);
-       fUnusedChunks.Add(chunk);
+       rtm_free(chunk->buffer);
+       chunk->capacity = 0;
+       chunk->size = 0;
+       chunk->buffer = NULL;
+       fUnusedChunks.push_back(chunk);
 }
 
 
@@ -111,14 +114,22 @@
        ASSERT(IsLocked());
 
        // retrieve chunk buffer
-       chunk_buffer* chunk = fUnusedChunks.RemoveHead();
-       if (chunk == NULL) {
+       chunk_buffer* chunk = NULL;
+       if (fUnusedChunks.empty()) {
                // allocate a new one
                chunk = (chunk_buffer*)rtm_alloc(fRealTimePool, 
sizeof(chunk_buffer));
-               if (chunk == NULL)
+               if (chunk == NULL) {
+                       ERROR("RTM Pool empty allocating chunk buffer 
structure");
                        return false;
+               }
+               
+               chunk->size = 0;
+               chunk->capacity = 0;
+               chunk->buffer = NULL;
 
-               new(chunk) chunk_buffer;
+       } else {
+               chunk = fUnusedChunks.front();
+               fUnusedChunks.pop_front();
        }
 
        const void* buffer;
@@ -133,6 +144,7 @@
                        chunk->buffer = rtm_alloc(fRealTimePool, 
chunk->capacity);
                        if (chunk->buffer == NULL) {
                                rtm_free(chunk);
+                               ERROR("RTM Pool empty allocating chunk 
buffer\n");
                                return false;
                        }
                }
@@ -141,6 +153,6 @@
                chunk->size = bufferSize;
        }
 
-       fChunks.Add(chunk);
+       fChunkCache.push(chunk);
        return chunk->status == B_OK;
 }

Modified: haiku/trunk/src/kits/media/ChunkCache.h
===================================================================
--- haiku/trunk/src/kits/media/ChunkCache.h     2009-12-13 00:23:07 UTC (rev 
34649)
+++ haiku/trunk/src/kits/media/ChunkCache.h     2009-12-13 12:09:17 UTC (rev 
34650)
@@ -9,23 +9,19 @@
 #include <Locker.h>
 #include <MediaDefs.h>
 #include <RealtimeAlloc.h>
+#include <queue>
+#include <deque>
 
-#include <kernel/util/DoublyLinkedList.h>
-
 #include "ReaderPlugin.h"
 
 
 namespace BPrivate {
 namespace media {
 
+// Limit to 10 entries, we might want to instead limit to a length of time
+#define CACHE_MAX_ENTRIES 10
 
-struct chunk_buffer;
-typedef DoublyLinkedList<chunk_buffer> ChunkList;
-
-struct chunk_buffer : public DoublyLinkedListLinkImpl<chunk_buffer> {
-       chunk_buffer();
-       ~chunk_buffer();
-
+struct chunk_buffer {
        void*                   buffer;
        size_t                  size;
        size_t                  capacity;
@@ -33,6 +29,8 @@
        status_t                status;
 };
 
+typedef queue<chunk_buffer*> ChunkQueue;
+typedef deque<chunk_buffer*> ChunkList;
 
 class ChunkCache : public BLocker {
 public:
@@ -44,7 +42,7 @@
                        void                            MakeEmpty();
                        bool                            SpaceLeft() const;
 
-                       chunk_buffer*           NextChunk();
+                       chunk_buffer*           NextChunk(Reader* reader, void* 
cookie);
                        void                            
RecycleChunk(chunk_buffer* chunk);
                        bool                            ReadNextChunk(Reader* 
reader, void* cookie);
 
@@ -52,9 +50,8 @@
                        rtm_pool*                       fRealTimePool;
                        sem_id                          fWaitSem;
                        size_t                          fMaxBytes;
-                       ChunkList                       fChunks;
+                       ChunkQueue                      fChunkCache;
                        ChunkList                       fUnusedChunks;
-                       ChunkList                       fInFlightChunks;
 };
 
 

Modified: haiku/trunk/src/kits/media/MediaExtractor.cpp
===================================================================
--- haiku/trunk/src/kits/media/MediaExtractor.cpp       2009-12-13 00:23:07 UTC 
(rev 34649)
+++ haiku/trunk/src/kits/media/MediaExtractor.cpp       2009-12-13 12:09:17 UTC 
(rev 34650)
@@ -274,16 +274,7 @@
        if (info.status != B_OK)
                return info.status;
 
-       BAutolock _(info.chunkCache);
-
-       status_t status = fReader->FindKeyFrame(info.cookie, seekTo, _frame, 
_time);
-       if (status != B_OK)
-               return status;
-
-       // clear buffered chunks after seek
-       info.chunkCache->MakeEmpty();
-
-       return B_OK;
+       return fReader->FindKeyFrame(info.cookie, seekTo, _frame, _time);
 }
 
 
@@ -307,13 +298,7 @@
        _RecycleLastChunk(info);
 
        // Retrieve next chunk - read it directly, if the cache is drained
-       chunk_buffer* chunk;
-       do {
-               chunk = info.chunkCache->NextChunk();
-               if (chunk == NULL
-                       && !info.chunkCache->ReadNextChunk(fReader, 
info.cookie))
-                       break;
-       } while (chunk == NULL);
+       chunk_buffer* chunk = info.chunkCache->NextChunk(fReader, info.cookie);
 
        if (chunk == NULL)
                return B_NO_MEMORY;


Other related posts: