* ChunkCache::fLocker is now aggregated.

* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34239 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-11-25 11:51:24 +00:00
parent 40fddd06d6
commit 608d959d73
4 changed files with 229 additions and 235 deletions

View File

@ -1,78 +1,85 @@
/*
* Copyright 2004-2007, Marcus Overhagen. All rights reserved.
* Copyright 2008, Maurice Kalinowski. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _MEDIA_EXTRACTOR_H
#define _MEDIA_EXTRACTOR_H
#include "ReaderPlugin.h"
#include "DecoderPlugin.h"
namespace BPrivate {
namespace media {
class ChunkCache;
struct stream_info
{
struct stream_info {
status_t status;
void * cookie;
void* cookie;
bool hasCookie;
const void * infoBuffer;
const void* infoBuffer;
size_t infoBufferSize;
ChunkCache * chunkCache;
ChunkCache* chunkCache;
media_format encodedFormat;
};
class MediaExtractor
{
class MediaExtractor {
public:
MediaExtractor(BDataIO * source, int32 flags);
~MediaExtractor();
MediaExtractor(BDataIO* source, int32 flags);
~MediaExtractor();
status_t InitCheck();
status_t InitCheck();
void GetFileFormatInfo(media_file_format *mfi) const;
void GetFileFormatInfo(
media_file_format* fileFormat) const;
int32 StreamCount();
int32 StreamCount();
const char* Copyright();
const char* Copyright();
const media_format * EncodedFormat(int32 stream);
int64 CountFrames(int32 stream) const;
bigtime_t Duration(int32 stream) const;
const media_format* EncodedFormat(int32 stream);
int64 CountFrames(int32 stream) const;
bigtime_t Duration(int32 stream) const;
status_t Seek(int32 stream, uint32 seekTo,
int64 *frame, bigtime_t *time);
status_t FindKeyFrame(int32 stream, uint32 seekTo,
int64 *frame, bigtime_t *time) const;
status_t Seek(int32 stream, uint32 seekTo, int64* _frame,
bigtime_t* _time);
status_t FindKeyFrame(int32 stream, uint32 seekTo,
int64* _frame, bigtime_t* _time) const;
status_t GetNextChunk(int32 stream,
const void **chunkBuffer, size_t *chunkSize,
media_header *mediaHeader);
status_t GetNextChunk(int32 stream,
const void** _chunkBuffer,
size_t* _chunkSize,
media_header* mediaHeader);
status_t CreateDecoder(int32 stream, Decoder **decoder,
media_codec_info *mci);
status_t CreateDecoder(int32 stream, Decoder** _decoder,
media_codec_info* codecInfo);
private:
static int32 extractor_thread(void *arg);
void ExtractorThread();
static int32 _ExtractorEntry(void* arg);
void _ExtractorThread();
private:
status_t fErr;
status_t fInitStatus;
sem_id fExtractorWaitSem;
thread_id fExtractorThread;
volatile bool fTerminateExtractor;
sem_id fExtractorWaitSem;
thread_id fExtractorThread;
volatile bool fTerminateExtractor;
BDataIO *fSource;
Reader *fReader;
BDataIO* fSource;
Reader* fReader;
stream_info * fStreamInfo;
int32 fStreamCount;
stream_info* fStreamInfo;
int32 fStreamCount;
media_file_format fMff;
media_file_format fFileFormat;
};
}; // namespace media
}; // namespace BPrivate
} // namespace media
} // namespace BPrivate
using namespace BPrivate::media;
#endif
#endif // _MEDIA_EXTRACTOR_H

View File

@ -1,42 +1,26 @@
/*
* Copyright (c) 2004, Marcus Overhagen
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* Copyright 2004, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <string.h>
#include <Locker.h>
#include "ChunkCache.h"
#include <string.h>
#include <Autolock.h>
#include "debug.h"
ChunkCache::ChunkCache()
:
fLocker("media chunk cache locker")
{
fLocker = new BLocker("media chunk cache locker");
// fEmptyChunkCount must be one less than the real chunk count,
// because the buffer returned by GetNextChunk must be preserved
// until the next call of that function, and must not be overwritten.
fEmptyChunkCount = CHUNK_COUNT - 1;
fReadyChunkCount = 0;
fNeedsRefill = 1;
@ -45,13 +29,14 @@ ChunkCache::ChunkCache()
fNextPut = &fChunkInfos[0];
fNextGet = &fChunkInfos[0];
for (int i = 0; i < CHUNK_COUNT; i++) {
fChunkInfos[i].next = (i == CHUNK_COUNT -1) ? &fChunkInfos[0] : &fChunkInfos[i + 1];
fChunkInfos[i].next = i == CHUNK_COUNT - 1
? &fChunkInfos[0] : &fChunkInfos[i + 1];
fChunkInfos[i].buffer = NULL;
fChunkInfos[i].sizeUsed = 0;
fChunkInfos[i].sizeMax = 0;
fChunkInfos[i].err = B_ERROR;
fChunkInfos[i].status = B_ERROR;
}
}
@ -59,7 +44,7 @@ ChunkCache::ChunkCache()
ChunkCache::~ChunkCache()
{
delete_sem(fGetWaitSem);
delete fLocker;
for (int i = 0; i < CHUNK_COUNT; i++) {
free(fChunkInfos[i].buffer);
}
@ -69,13 +54,13 @@ ChunkCache::~ChunkCache()
void
ChunkCache::MakeEmpty()
{
fLocker->Lock();
BAutolock _(fLocker);
fEmptyChunkCount = CHUNK_COUNT - 1;
fReadyChunkCount = 0;
fNextPut = &fChunkInfos[0];
fNextGet = &fChunkInfos[0];
atomic_or(&fNeedsRefill, 1);
fLocker->Unlock();
}
@ -85,48 +70,53 @@ ChunkCache::NeedsRefill()
return atomic_or(&fNeedsRefill, 0);
}
status_t
ChunkCache::GetNextChunk(const void **chunkBuffer, size_t *chunkSize, media_header *mediaHeader)
ChunkCache::GetNextChunk(const void** _chunkBuffer, size_t* _chunkSize,
media_header* mediaHeader)
{
uint8 retry_count = 0;
uint8 retryCount = 0;
// printf("ChunkCache::GetNextChunk: %p fEmptyChunkCount %ld, fReadyChunkCount %ld\n", fNextGet, fEmptyChunkCount, fReadyChunkCount);
retry:
acquire_sem(fGetWaitSem);
fLocker->Lock();
BAutolock locker(fLocker);
if (fReadyChunkCount == 0) {
fLocker->Unlock();
locker.Unlock();
printf("ChunkCache::GetNextChunk: %p retrying\n", fNextGet);
// Limit to 5 retries
retry_count++;
if (retry_count > 4) {
retryCount++;
if (retryCount > 4)
return B_ERROR;
}
goto retry;
}
fEmptyChunkCount++;
fReadyChunkCount--;
atomic_or(&fNeedsRefill, 1);
fLocker->Unlock();
*chunkBuffer = fNextGet->buffer;
*chunkSize = fNextGet->sizeUsed;
locker.Unlock();
*_chunkBuffer = fNextGet->buffer;
*_chunkSize = fNextGet->sizeUsed;
*mediaHeader = fNextGet->mediaHeader;
status_t err = fNextGet->err;
status_t status = fNextGet->status;
fNextGet = fNextGet->next;
return err;
return status;
}
void
ChunkCache::PutNextChunk(const void *chunkBuffer, size_t chunkSize, const media_header &mediaHeader, status_t err)
ChunkCache::PutNextChunk(const void* chunkBuffer, size_t chunkSize,
const media_header& mediaHeader, status_t status)
{
// printf("ChunkCache::PutNextChunk: %p fEmptyChunkCount %ld, fReadyChunkCount %ld\n", fNextPut, fEmptyChunkCount, fReadyChunkCount);
if (err == B_OK) {
if (status == B_OK) {
if (fNextPut->sizeMax < chunkSize) {
// printf("ChunkCache::PutNextChunk: %p resizing from %ld to %ld\n", fNextPut, fNextPut->sizeMax, chunkSize);
free(fNextPut->buffer);
@ -136,18 +126,18 @@ ChunkCache::PutNextChunk(const void *chunkBuffer, size_t chunkSize, const media_
memcpy(fNextPut->buffer, chunkBuffer, chunkSize);
fNextPut->sizeUsed = chunkSize;
}
fNextPut->mediaHeader = mediaHeader;
fNextPut->err = err;
fNextPut->status = status;
fNextPut = fNextPut->next;
fLocker->Lock();
fLocker.Lock();
fEmptyChunkCount--;
fReadyChunkCount++;
if (fEmptyChunkCount == 0)
atomic_and(&fNeedsRefill, 0);
fLocker->Unlock();
fLocker.Unlock();
release_sem(fGetWaitSem);
}

View File

@ -1,78 +1,64 @@
/*
* Copyright (c) 2004, Marcus Overhagen
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* Copyright 2004, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _CHUNK_CACHE_H
#define _CHUNK_CACHE_H
#include <Locker.h>
#include <MediaDefs.h>
namespace BPrivate {
namespace media {
struct chunk_info
{
chunk_info * next;
void * buffer;
struct chunk_info {
chunk_info* next;
void* buffer;
size_t sizeUsed;
size_t sizeMax;
media_header mediaHeader;
status_t err;
status_t status;
};
class ChunkCache
{
class ChunkCache {
public:
ChunkCache();
~ChunkCache();
ChunkCache();
~ChunkCache();
void MakeEmpty();
bool NeedsRefill();
status_t GetNextChunk(const void** _chunkBuffer,
size_t* _chunkSize,
media_header* mediaHeader);
void PutNextChunk(const void* chunkBuffer,
size_t chunkSize,
const media_header& mediaHeader,
status_t status);
void MakeEmpty();
bool NeedsRefill();
status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize, media_header *mediaHeader);
void PutNextChunk(const void *chunkBuffer, size_t chunkSize, const media_header &mediaHeader, status_t err);
private:
enum { CHUNK_COUNT = 5 };
chunk_info * fNextPut;
chunk_info * fNextGet;
chunk_info fChunkInfos[CHUNK_COUNT];
sem_id fGetWaitSem;
int32 fEmptyChunkCount;
int32 fReadyChunkCount;
int32 fNeedsRefill;
BLocker * fLocker;
chunk_info* fNextPut;
chunk_info* fNextGet;
chunk_info fChunkInfos[CHUNK_COUNT];
sem_id fGetWaitSem;
int32 fEmptyChunkCount;
int32 fReadyChunkCount;
int32 fNeedsRefill;
BLocker fLocker;
};
}; // namespace media
}; // namespace BPrivate
} // namespace media
} // namespace BPrivate
using namespace BPrivate::media;
#endif
#endif // _CHUNK_CACHE_H

View File

@ -6,22 +6,48 @@
#include "MediaExtractor.h"
#include "PluginManager.h"
#include "ChunkCache.h"
#include "debug.h"
#include <new>
#include <stdio.h>
#include <string.h>
#include <Autolock.h>
#include <stdio.h>
#include <string.h>
#include <new>
#include "debug.h"
#include "ChunkCache.h"
#include "PluginManager.h"
// should be 0, to disable the chunk cache set it to 1
#define DISABLE_CHUNK_CACHE 0
MediaExtractor::MediaExtractor(BDataIO *source, int32 flags)
class MediaExtractorChunkProvider : public ChunkProvider {
public:
MediaExtractorChunkProvider(MediaExtractor* extractor, int32 stream)
:
fExtractor(extractor),
fStream(stream)
{
}
virtual status_t GetNextChunk(const void** _chunkBuffer, size_t* _chunkSize,
media_header *mediaHeader)
{
return fExtractor->GetNextChunk(fStream, _chunkBuffer, _chunkSize,
mediaHeader);
}
private:
MediaExtractor* fExtractor;
int32 fStream;
};
// #pragma mark -
MediaExtractor::MediaExtractor(BDataIO* source, int32 flags)
{
CALLED();
fSource = source;
@ -30,8 +56,9 @@ MediaExtractor::MediaExtractor(BDataIO *source, int32 flags)
fExtractorWaitSem = -1;
fTerminateExtractor = false;
fErr = _plugin_manager.CreateReader(&fReader, &fStreamCount, &fMff, source);
if (fErr) {
fInitStatus = _plugin_manager.CreateReader(&fReader, &fStreamCount,
&fFileFormat, source);
if (fInitStatus != B_OK) {
fStreamCount = 0;
fReader = NULL;
return;
@ -66,11 +93,13 @@ MediaExtractor::MediaExtractor(BDataIO *source, int32 flags)
for (int32 i = 0; i < fStreamCount; i++) {
if (fStreamInfo[i].status != B_OK)
continue;
int64 frameCount;
bigtime_t duration;
if (B_OK != fReader->GetStreamInfo(fStreamInfo[i].cookie, &frameCount,
if (fReader->GetStreamInfo(fStreamInfo[i].cookie, &frameCount,
&duration, &fStreamInfo[i].encodedFormat,
&fStreamInfo[i].infoBuffer, &fStreamInfo[i].infoBufferSize)) {
&fStreamInfo[i].infoBuffer, &fStreamInfo[i].infoBufferSize)
!= B_OK) {
fStreamInfo[i].status = B_ERROR;
ERROR("MediaExtractor::MediaExtractor: GetStreamInfo for "
"stream %ld failed\n", i);
@ -80,8 +109,8 @@ MediaExtractor::MediaExtractor(BDataIO *source, int32 flags)
#if DISABLE_CHUNK_CACHE == 0
// start extractor thread
fExtractorWaitSem = create_sem(1, "media extractor thread sem");
fExtractorThread = spawn_thread(extractor_thread, "media extractor thread",
10, this);
fExtractorThread = spawn_thread(_ExtractorEntry, "media extractor thread",
40, this);
resume_thread(fExtractorThread);
#endif
}
@ -117,15 +146,15 @@ status_t
MediaExtractor::InitCheck()
{
CALLED();
return fErr;
return fInitStatus;
}
void
MediaExtractor::GetFileFormatInfo(media_file_format *mfi) const
MediaExtractor::GetFileFormatInfo(media_file_format* fileFormat) const
{
CALLED();
*mfi = fMff;
*fileFormat = fFileFormat;
}
@ -144,7 +173,7 @@ MediaExtractor::Copyright()
}
const media_format *
const media_format*
MediaExtractor::EncodedFormat(int32 stream)
{
return &fStreamInfo[stream].encodedFormat;
@ -161,7 +190,7 @@ MediaExtractor::CountFrames(int32 stream) const
int64 frameCount;
bigtime_t duration;
media_format format;
const void *infoBuffer;
const void* infoBuffer;
size_t infoSize;
fReader->GetStreamInfo(fStreamInfo[stream].cookie, &frameCount, &duration,
@ -193,8 +222,7 @@ MediaExtractor::Duration(int32 stream) const
status_t
MediaExtractor::Seek(int32 stream, uint32 seekTo,
int64 *frame, bigtime_t *time)
MediaExtractor::Seek(int32 stream, uint32 seekTo, int64* frame, bigtime_t* time)
{
CALLED();
if (fStreamInfo[stream].status != B_OK)
@ -214,22 +242,21 @@ MediaExtractor::Seek(int32 stream, uint32 seekTo,
status_t
MediaExtractor::FindKeyFrame(int32 stream, uint32 seekTo, int64 *frame,
bigtime_t *time) const
MediaExtractor::FindKeyFrame(int32 stream, uint32 seekTo, int64* _frame,
bigtime_t* _time) const
{
CALLED();
if (fStreamInfo[stream].status != B_OK)
return fStreamInfo[stream].status;
return fReader->FindKeyFrame(fStreamInfo[stream].cookie,
seekTo, frame, time);
seekTo, _frame, _time);
}
status_t
MediaExtractor::GetNextChunk(int32 stream,
const void **chunkBuffer, size_t *chunkSize,
media_header *mediaHeader)
MediaExtractor::GetNextChunk(int32 stream, const void** _chunkBuffer,
size_t* _chunkSize, media_header* mediaHeader)
{
if (fStreamInfo[stream].status != B_OK)
return fStreamInfo[stream].status;
@ -237,68 +264,51 @@ MediaExtractor::GetNextChunk(int32 stream,
#if DISABLE_CHUNK_CACHE > 0
static BLocker locker("media extractor next chunk");
BAutolock lock(locker);
return fReader->GetNextChunk(fStreamInfo[stream].cookie, chunkBuffer,
chunkSize, mediaHeader);
return fReader->GetNextChunk(fStreamInfo[stream].cookie, _chunkBuffer,
_chunkSize, mediaHeader);
#endif
status_t err;
err = fStreamInfo[stream].chunkCache->GetNextChunk(chunkBuffer, chunkSize,
mediaHeader);
status_t status = fStreamInfo[stream].chunkCache->GetNextChunk(_chunkBuffer,
_chunkSize, mediaHeader);
release_sem(fExtractorWaitSem);
return err;
return status;
}
class MediaExtractorChunkProvider : public ChunkProvider {
private:
MediaExtractor * fExtractor;
int32 fStream;
public:
MediaExtractorChunkProvider(MediaExtractor * extractor, int32 stream)
{
fExtractor = extractor;
fStream = stream;
}
virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
media_header *mediaHeader)
{
return fExtractor->GetNextChunk(fStream, chunkBuffer, chunkSize,
mediaHeader);
}
};
status_t
MediaExtractor::CreateDecoder(int32 stream, Decoder **out_decoder,
media_codec_info *mci)
MediaExtractor::CreateDecoder(int32 stream, Decoder** _decoder,
media_codec_info* codecInfo)
{
CALLED();
status_t res;
Decoder *decoder;
res = fStreamInfo[stream].status;
if (res != B_OK) {
status_t status = fStreamInfo[stream].status;
if (status != B_OK) {
ERROR("MediaExtractor::CreateDecoder can't create decoder for "
"stream %ld\n", stream);
return res;
"stream %ld: %s\n", stream, strerror(status));
return status;
}
// TODO Here we should work out a way so that if there is a setup failure we can try the next decoder
res = _plugin_manager.CreateDecoder(&decoder,
// TODO: Here we should work out a way so that if there is a setup
// failure we can try the next decoder
Decoder* decoder;
status = _plugin_manager.CreateDecoder(&decoder,
fStreamInfo[stream].encodedFormat);
if (res != B_OK) {
if (status != B_OK) {
#if DEBUG
char formatString[256];
string_for_format(fStreamInfo[stream].encodedFormat, formatString,
256);
sizeof(formatString));
ERROR("MediaExtractor::CreateDecoder _plugin_manager.CreateDecoder "
"failed for stream %ld, format: %s\n", stream, formatString);
return res;
"failed for stream %ld, format: %s: %s\n", stream, formatString,
strerror(status));
#endif
return status;
}
ChunkProvider *chunkProvider
ChunkProvider* chunkProvider
= new(std::nothrow) MediaExtractorChunkProvider(this, stream);
if (!chunkProvider) {
if (chunkProvider == NULL) {
_plugin_manager.DestroyDecoder(decoder);
ERROR("MediaExtractor::CreateDecoder can't create chunk provider "
"for stream %ld\n", stream);
@ -307,64 +317,65 @@ MediaExtractor::CreateDecoder(int32 stream, Decoder **out_decoder,
decoder->SetChunkProvider(chunkProvider);
res = decoder->Setup(&fStreamInfo[stream].encodedFormat,
status = decoder->Setup(&fStreamInfo[stream].encodedFormat,
fStreamInfo[stream].infoBuffer, fStreamInfo[stream].infoBufferSize);
if (res != B_OK) {
if (status != B_OK) {
_plugin_manager.DestroyDecoder(decoder);
ERROR("MediaExtractor::CreateDecoder Setup failed for stream %ld: "
"%ld (%s)\n", stream, res, strerror(res));
return res;
ERROR("MediaExtractor::CreateDecoder Setup failed for stream %ld: %s\n",
stream, strerror(status));
return status;
}
res = _plugin_manager.GetDecoderInfo(decoder, mci);
if (res != B_OK) {
status = _plugin_manager.GetDecoderInfo(decoder, codecInfo);
if (status != B_OK) {
_plugin_manager.DestroyDecoder(decoder);
ERROR("MediaExtractor::CreateDecoder GetCodecInfo failed for stream "
"%ld: %ld (%s)\n", stream, res, strerror(res));
return res;
"%ld: %s\n", stream, strerror(status));
return status;
}
*out_decoder = decoder;
*_decoder = decoder;
return B_OK;
}
int32
MediaExtractor::extractor_thread(void *arg)
status_t
MediaExtractor::_ExtractorEntry(void* extractor)
{
static_cast<MediaExtractor *>(arg)->ExtractorThread();
return 0;
static_cast<MediaExtractor*>(extractor)->_ExtractorThread();
return B_OK;
}
void
MediaExtractor::ExtractorThread()
MediaExtractor::_ExtractorThread()
{
for (;;) {
while (true) {
acquire_sem(fExtractorWaitSem);
if (fTerminateExtractor)
return;
bool refill_done;
bool refillDone;
do {
refill_done = false;
refillDone = false;
for (int32 stream = 0; stream < fStreamCount; stream++) {
if (fStreamInfo[stream].status != B_OK)
continue;
if (fStreamInfo[stream].chunkCache->NeedsRefill()) {
media_header mediaHeader;
const void *chunkBuffer;
const void* chunkBuffer;
size_t chunkSize;
status_t err;
err = fReader->GetNextChunk(fStreamInfo[stream].cookie,
&chunkBuffer, &chunkSize, &mediaHeader);
status_t status = fReader->GetNextChunk(
fStreamInfo[stream].cookie, &chunkBuffer, &chunkSize,
&mediaHeader);
fStreamInfo[stream].chunkCache->PutNextChunk(chunkBuffer,
chunkSize, mediaHeader, err);
refill_done = true;
chunkSize, mediaHeader, status);
refillDone = true;
}
}
if (fTerminateExtractor)
return;
} while (refill_done);
} while (refillDone);
}
}