2003-11-24 01:19:21 +03:00
|
|
|
#include "MediaExtractor.h"
|
2003-12-02 02:33:35 +03:00
|
|
|
#include "PluginManager.h"
|
2003-12-05 04:18:51 +03:00
|
|
|
#include "debug.h"
|
2003-11-24 02:50:27 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2003-11-24 01:19:21 +03:00
|
|
|
MediaExtractor::MediaExtractor(BDataIO * source, int32 flags)
|
|
|
|
{
|
2003-12-05 04:18:51 +03:00
|
|
|
CALLED();
|
2003-11-24 02:50:27 +03:00
|
|
|
fSource = source;
|
|
|
|
fStreamInfo = 0;
|
|
|
|
fStreamCount = 0;
|
|
|
|
fReader = 0;
|
|
|
|
|
|
|
|
fErr = _CreateReader(&fReader, &fStreamCount, &fMff, source);
|
|
|
|
if (fErr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
fStreamInfo = new stream_info[fStreamCount];
|
|
|
|
|
|
|
|
// initialize stream infos
|
|
|
|
for (int32 i = 0; i < fStreamCount; i++) {
|
|
|
|
fStreamInfo[i].status = B_OK;
|
|
|
|
fStreamInfo[i].cookie = 0;
|
|
|
|
fStreamInfo[i].infoBuffer = 0;
|
|
|
|
fStreamInfo[i].infoBufferSize = 0;
|
|
|
|
memset(&fStreamInfo[i].encodedFormat, 0, sizeof(fStreamInfo[i].encodedFormat));
|
|
|
|
}
|
|
|
|
|
|
|
|
// create all stream cookies
|
|
|
|
for (int32 i = 0; i < fStreamCount; i++) {
|
|
|
|
if (B_OK != fReader->AllocateCookie(i, &fStreamInfo[i].cookie)) {
|
|
|
|
fStreamInfo[i].cookie = 0;
|
|
|
|
fStreamInfo[i].status = B_ERROR;
|
|
|
|
printf("MediaExtractor::MediaExtractor: AllocateCookie for stream %ld failed\n", i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// get info for all streams
|
|
|
|
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, &duration,
|
|
|
|
&fStreamInfo[i].encodedFormat,
|
|
|
|
&fStreamInfo[i].infoBuffer,
|
|
|
|
&fStreamInfo[i].infoBufferSize)) {
|
|
|
|
fStreamInfo[i].status = B_ERROR;
|
|
|
|
printf("MediaExtractor::MediaExtractor: GetStreamInfo for stream %ld failed\n", i);
|
|
|
|
}
|
|
|
|
}
|
2003-11-24 01:19:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
MediaExtractor::~MediaExtractor()
|
|
|
|
{
|
2003-12-05 04:18:51 +03:00
|
|
|
CALLED();
|
2003-12-06 01:11:52 +03:00
|
|
|
|
2003-11-24 02:50:27 +03:00
|
|
|
// free all stream cookies
|
|
|
|
for (int32 i = 0; i < fStreamCount; i++) {
|
|
|
|
if (fStreamInfo[i].cookie)
|
|
|
|
fReader->FreeCookie(fStreamInfo[i].cookie);
|
|
|
|
}
|
|
|
|
|
2003-12-02 02:33:35 +03:00
|
|
|
if (fReader)
|
|
|
|
_DestroyReader(fReader);
|
|
|
|
|
2003-12-06 01:11:52 +03:00
|
|
|
delete [] fStreamInfo;
|
2003-12-06 01:27:17 +03:00
|
|
|
// fSource is owned by the BMediaFile
|
2003-11-24 01:19:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
status_t
|
|
|
|
MediaExtractor::InitCheck()
|
|
|
|
{
|
2003-12-05 04:18:51 +03:00
|
|
|
CALLED();
|
2003-11-24 02:50:27 +03:00
|
|
|
return fErr;
|
2003-11-24 01:19:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MediaExtractor::GetFileFormatInfo(media_file_format *mfi) const
|
|
|
|
{
|
2003-12-05 04:18:51 +03:00
|
|
|
CALLED();
|
2003-11-24 02:50:27 +03:00
|
|
|
*mfi = fMff;
|
2003-11-24 01:19:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int32
|
|
|
|
MediaExtractor::StreamCount()
|
|
|
|
{
|
2003-12-05 04:18:51 +03:00
|
|
|
CALLED();
|
2003-11-24 02:50:27 +03:00
|
|
|
return fStreamCount;
|
2003-11-24 01:19:21 +03:00
|
|
|
}
|
|
|
|
|
2003-12-07 02:21:23 +03:00
|
|
|
const media_format *
|
2003-11-24 01:19:21 +03:00
|
|
|
MediaExtractor::EncodedFormat(int32 stream)
|
|
|
|
{
|
2003-11-24 02:50:27 +03:00
|
|
|
return &fStreamInfo[stream].encodedFormat;
|
2003-11-24 01:19:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int64
|
|
|
|
MediaExtractor::CountFrames(int32 stream) const
|
|
|
|
{
|
2003-12-05 04:18:51 +03:00
|
|
|
CALLED();
|
2003-11-24 02:50:27 +03:00
|
|
|
int64 frameCount;
|
|
|
|
bigtime_t duration;
|
|
|
|
media_format format;
|
|
|
|
void *infoBuffer;
|
|
|
|
int32 infoSize;
|
|
|
|
|
|
|
|
fReader->GetStreamInfo(fStreamInfo[stream].cookie, &frameCount, &duration, &format, &infoBuffer, &infoSize);
|
|
|
|
|
|
|
|
return frameCount;
|
2003-11-24 01:19:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bigtime_t
|
|
|
|
MediaExtractor::Duration(int32 stream) const
|
|
|
|
{
|
2003-12-05 04:18:51 +03:00
|
|
|
CALLED();
|
2003-11-24 02:50:27 +03:00
|
|
|
int64 frameCount;
|
|
|
|
bigtime_t duration;
|
|
|
|
media_format format;
|
|
|
|
void *infoBuffer;
|
|
|
|
int32 infoSize;
|
|
|
|
|
|
|
|
fReader->GetStreamInfo(fStreamInfo[stream].cookie, &frameCount, &duration, &format, &infoBuffer, &infoSize);
|
|
|
|
|
|
|
|
return duration;
|
2003-11-24 01:19:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
status_t
|
|
|
|
MediaExtractor::Seek(int32 stream, uint32 seekTo,
|
|
|
|
int64 *frame, bigtime_t *time)
|
|
|
|
{
|
2003-12-05 04:18:51 +03:00
|
|
|
CALLED();
|
2003-11-24 02:50:27 +03:00
|
|
|
status_t result;
|
|
|
|
result = fReader->Seek(fStreamInfo[stream].cookie, seekTo, frame, time);
|
|
|
|
if (result != B_OK)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
// clear buffered chunks
|
2003-12-05 04:18:51 +03:00
|
|
|
return B_OK;
|
2003-11-24 01:19:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
status_t
|
|
|
|
MediaExtractor::GetNextChunk(int32 stream,
|
|
|
|
void **chunkBuffer, int32 *chunkSize,
|
|
|
|
media_header *mediaHeader)
|
|
|
|
{
|
2003-12-06 01:11:52 +03:00
|
|
|
//CALLED();
|
2003-11-24 02:50:27 +03:00
|
|
|
// get buffered chunk
|
2003-11-29 01:34:14 +03:00
|
|
|
|
|
|
|
// XXX this should be done in a different thread, and double buffered for each stream
|
|
|
|
return fReader->GetNextChunk(fStreamInfo[stream].cookie, chunkBuffer, chunkSize, mediaHeader);
|
2003-11-24 01:19:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
status_t
|
|
|
|
MediaExtractor::CreateDecoder(int32 stream, Decoder **decoder, media_codec_info *mci)
|
2003-11-24 02:50:27 +03:00
|
|
|
{
|
2003-12-05 04:18:51 +03:00
|
|
|
CALLED();
|
2003-11-24 02:50:27 +03:00
|
|
|
if (fStreamInfo[stream].status != B_OK) {
|
|
|
|
printf("MediaExtractor::CreateDecoder can't create decoder for stream %ld\n", stream);
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (B_OK != _CreateDecoder(decoder, mci, &fStreamInfo[stream].encodedFormat)) {
|
|
|
|
printf("MediaExtractor::CreateDecoder failed for stream %ld\n", stream);
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
2003-12-07 02:21:23 +03:00
|
|
|
(*decoder)->Setup(this, stream);
|
2003-11-24 02:50:27 +03:00
|
|
|
|
2003-12-07 02:21:23 +03:00
|
|
|
status_t res;
|
|
|
|
res = (*decoder)->Setup(&fStreamInfo[stream].encodedFormat, fStreamInfo[stream].infoBuffer , fStreamInfo[stream].infoBufferSize);
|
|
|
|
if (res != B_OK) {
|
|
|
|
printf("MediaExtractor::CreateDecoder Setup failed for stream %ld\n", stream);
|
|
|
|
}
|
|
|
|
return res;
|
2003-11-24 02:50:27 +03:00
|
|
|
}
|
|
|
|
|