media_kit: Dynamic allocation of ChunkCache based on media

* The "default" of 3MiB wasn't enough for modern larger media
  formats, resulting in inability to play 4k video no matter
  how much horse power you threw at Haiku. (4k is ~8MiB)
* This dynamically calculates the ChunkCache based on the
  video framesize * 2.
* 4k video now plays smoothly on my Ryzen 1800x.

Change-Id: I65bf6bd6fa60ac3196ea70eeeb5e655d43c10bcd
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3598
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
Alexander von Gluck IV 2021-01-03 09:58:41 -06:00 committed by Alex von Gluck IV
parent 162f0ea529
commit 6b49a15b64
3 changed files with 29 additions and 10 deletions

View File

@ -79,6 +79,7 @@ private:
void _RecycleLastChunk(stream_info& info);
static int32 _ExtractorEntry(void* arg);
void _ExtractorThread();
size_t _CalculateChunkBuffer(int32 stream);
private:
status_t fInitStatus;

View File

@ -4,6 +4,7 @@ AddResources libmedia.so : libmedia.rdef ;
UsePrivateHeaders app media shared ;
UsePrivateHeaders [ FDirName media experimental ] ;
UsePrivateHeaders [ FDirName interface ] ;
if $(CHECK_MALLOC) {
SubDirC++Flags -D_NO_INLINE_ASM -fcheck-memory-usage ;

View File

@ -14,9 +14,11 @@
#include <string.h>
#include <Autolock.h>
#include <InterfacePrivate.h>
#include "ChunkCache.h"
#include "MediaDebug.h"
#include "MediaMisc.h"
#include "PluginManager.h"
@ -24,9 +26,6 @@
#define DISABLE_CHUNK_CACHE 0
static const size_t kMaxCacheBytes = 3 * 1024 * 1024;
class MediaExtractorChunkProvider : public ChunkProvider {
public:
MediaExtractorChunkProvider(MediaExtractor* extractor, int32 stream)
@ -93,15 +92,9 @@ MediaExtractor::_Init(BDataIO* source, int32 flags)
fStreamInfo[i].hasCookie = false;
fStreamInfo[i].infoBuffer = 0;
fStreamInfo[i].infoBufferSize = 0;
fStreamInfo[i].chunkCache
= new ChunkCache(fExtractorWaitSem, kMaxCacheBytes);
fStreamInfo[i].lastChunk = NULL;
fStreamInfo[i].chunkCache = NULL;
fStreamInfo[i].encodedFormat.Clear();
if (fStreamInfo[i].chunkCache->InitCheck() != B_OK) {
fInitStatus = B_NO_MEMORY;
return;
}
}
// create all stream cookies
@ -131,6 +124,15 @@ MediaExtractor::_Init(BDataIO* source, int32 flags)
ERROR("MediaExtractor::MediaExtractor: GetStreamInfo for "
"stream %" B_PRId32 " failed\n", i);
}
// Allocate our ChunkCache
size_t chunkCacheMaxBytes = _CalculateChunkBuffer(i);
fStreamInfo[i].chunkCache
= new ChunkCache(fExtractorWaitSem, chunkCacheMaxBytes);
if (fStreamInfo[i].chunkCache->InitCheck() != B_OK) {
fInitStatus = B_NO_MEMORY;
return;
}
}
#if !DISABLE_CHUNK_CACHE
@ -433,6 +435,21 @@ MediaExtractor::_ExtractorEntry(void* extractor)
}
size_t
MediaExtractor::_CalculateChunkBuffer(int32 stream)
{
const media_format* format = EncodedFormat(stream);
size_t cacheSize = 3 * 1024 * 1024;
int32 rowSize = BPrivate::get_bytes_per_row(format->ColorSpace(),
format->Width());
if (rowSize > 0) {
// Frame size, multipled by 2 for good measure
cacheSize = rowSize * format->Height() * 2;
}
return ROUND_UP_TO_PAGE(cacheSize);
}
void
MediaExtractor::_ExtractorThread()
{