implement MediaDecoder, MediaExtractor using added ChunkProvider
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6137 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -6,24 +6,26 @@
|
|||||||
|
|
||||||
Decoder::Decoder()
|
Decoder::Decoder()
|
||||||
{
|
{
|
||||||
|
fChunkProvider = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Decoder::~Decoder()
|
Decoder::~Decoder()
|
||||||
{
|
{
|
||||||
|
delete fChunkProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Decoder::GetNextChunk(void **chunkBuffer, int32 *chunkSize,
|
Decoder::GetNextChunk(void **chunkBuffer, int32 *chunkSize,
|
||||||
media_header *mediaHeader)
|
media_header *mediaHeader)
|
||||||
{
|
{
|
||||||
return fExtractor->GetNextChunk(fStream, chunkBuffer, chunkSize, mediaHeader);
|
return fChunkProvider->GetNextChunk(chunkBuffer, chunkSize, mediaHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Decoder::Setup(MediaExtractor *extractor, int32 stream)
|
Decoder::Setup(ChunkProvider *provider)
|
||||||
{
|
{
|
||||||
fExtractor = extractor;
|
delete fChunkProvider;
|
||||||
fStream = stream;
|
fChunkProvider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderPlugin::DecoderPlugin()
|
DecoderPlugin::DecoderPlugin()
|
||||||
|
|||||||
+110
-25
@@ -4,6 +4,7 @@
|
|||||||
* DESCR:
|
* DESCR:
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
#include <MediaDecoder.h>
|
#include <MediaDecoder.h>
|
||||||
|
#include <DecoderPlugin.h>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
@@ -12,84 +13,160 @@
|
|||||||
|
|
||||||
BMediaDecoder::BMediaDecoder()
|
BMediaDecoder::BMediaDecoder()
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
fDecoder = NULL;
|
||||||
|
fDecoderPlugin = NULL;
|
||||||
|
fInitStatus = B_NO_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
BMediaDecoder::BMediaDecoder(const media_format *in_format,
|
BMediaDecoder::BMediaDecoder(const media_format *in_format,
|
||||||
const void *info,
|
const void *info,
|
||||||
size_t info_size)
|
size_t info_size)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
fDecoder = NULL;
|
||||||
|
fDecoderPlugin = NULL;
|
||||||
|
SetTo(in_format,info,info_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
BMediaDecoder::BMediaDecoder(const media_codec_info *mci)
|
BMediaDecoder::BMediaDecoder(const media_codec_info *mci)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
fDecoder = NULL;
|
||||||
|
fDecoderPlugin = NULL;
|
||||||
|
SetTo(mci);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */
|
/* virtual */
|
||||||
BMediaDecoder::~BMediaDecoder()
|
BMediaDecoder::~BMediaDecoder()
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
delete fDecoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMediaDecoder::InitCheck() const
|
BMediaDecoder::InitCheck() const
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
return fInitStatus;
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DecoderPlugin * GetDecoderPlugin(int32 id)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
// if our decoder plugin area id is not valid,
|
||||||
|
// ask the server for a new one.
|
||||||
|
// retrieve the id'th plugin here.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ask the server for a good decoder for the arguments
|
||||||
|
// GETS THE CODEC for in_format->type + in_format->u.x.encoding
|
||||||
status_t
|
status_t
|
||||||
BMediaDecoder::SetTo(const media_format *in_format,
|
BMediaDecoder::SetTo(const media_format *in_format,
|
||||||
const void *info,
|
const void *info,
|
||||||
size_t info_size)
|
size_t info_size)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
return B_OK;
|
return fInitStatus = B_NO_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ask the server for a good decoder for the arguments
|
||||||
|
// GETS THE CODEC for mci->id, mci->sub_id
|
||||||
|
// fails if the mci->id = 0
|
||||||
status_t
|
status_t
|
||||||
BMediaDecoder::SetTo(const media_codec_info *mci)
|
BMediaDecoder::SetTo(const media_codec_info *mci)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
class MediaDecoderChunkProvider : public ChunkProvider {
|
||||||
return B_OK;
|
private:
|
||||||
|
BMediaDecoder * fDecoder;
|
||||||
|
public:
|
||||||
|
MediaDecoderChunkProvider(BMediaDecoder * decoder) {
|
||||||
|
fDecoder = decoder;
|
||||||
|
}
|
||||||
|
virtual status_t GetNextChunk(void **chunkBuffer, int32 *chunkSize,
|
||||||
|
media_header *mediaHeader) {
|
||||||
|
const void ** buffer = const_cast<const void**>(chunkBuffer);
|
||||||
|
size_t * size = reinterpret_cast<size_t*>(chunkSize);
|
||||||
|
return fDecoder->GetNextChunk(buffer,size,mediaHeader);
|
||||||
|
}
|
||||||
|
} * provider = new MediaDecoderChunkProvider(this);
|
||||||
|
if (provider == NULL) {
|
||||||
|
return fInitStatus = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
DecoderPlugin * plugin = GetDecoderPlugin(mci->id);
|
||||||
|
if (plugin == NULL) {
|
||||||
|
return fInitStatus = B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
Decoder * decoder = plugin->NewDecoder();
|
||||||
|
if (decoder == NULL) {
|
||||||
|
return fInitStatus = B_ERROR;
|
||||||
|
}
|
||||||
|
decoder->Setup(provider);
|
||||||
|
delete fDecoder;
|
||||||
|
fDecoderPluginID = mci->id;
|
||||||
|
fDecoderPlugin = plugin;
|
||||||
|
fDecoderID = mci->sub_id;
|
||||||
|
fDecoder = decoder;
|
||||||
|
return fInitStatus = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SetInputFormat() sets the input data format to in_format.
|
||||||
|
Unlike SetTo(), the SetInputFormat() function does not
|
||||||
|
select a codec, so the currently-selected codec will
|
||||||
|
continue to be used. You should only use SetInputFormat()
|
||||||
|
to refine the format settings if it will not require the
|
||||||
|
use of a different decoder. */
|
||||||
status_t
|
status_t
|
||||||
BMediaDecoder::SetInputFormat(const media_format *in_format,
|
BMediaDecoder::SetInputFormat(const media_format *in_format,
|
||||||
const void *in_info,
|
const void *in_info,
|
||||||
size_t in_size)
|
size_t in_size)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
if (fInitStatus != B_OK) {
|
||||||
return B_OK;
|
return fInitStatus;
|
||||||
|
}
|
||||||
|
media_format format = *in_format;
|
||||||
|
return fDecoder->Setup(&format,in_info,in_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SetOutputFormat() sets the format the decoder should output.
|
||||||
|
On return, the output_format is changed to match the actual
|
||||||
|
format that will be output; this can be different if you
|
||||||
|
specified any wildcards. */
|
||||||
status_t
|
status_t
|
||||||
BMediaDecoder::SetOutputFormat(media_format *output_format)
|
BMediaDecoder::SetOutputFormat(media_format *output_format)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
if (fInitStatus != B_OK) {
|
||||||
return B_OK;
|
return fInitStatus;
|
||||||
|
}
|
||||||
|
return fDecoder->NegotiateOutputFormat(output_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set output format to closest acceptable format, returns the
|
/* Decodes a chunk of media data into the output buffer specified
|
||||||
// format used.
|
by out_buffer. On return, out_frameCount is set to indicate how
|
||||||
|
many frames of data were decoded, and out_mh is the header for
|
||||||
|
the decoded buffer. The media_decode_info structure info is used
|
||||||
|
on input to specify decoding parameters.
|
||||||
|
|
||||||
|
The amount of data decoded is part of the format determined by
|
||||||
|
SetTo() or SetInputFormat(). For audio, it's the buffer_size.
|
||||||
|
For video, it's one frame, which is height*row_bytes. The data
|
||||||
|
to be decoded will be fetched from the source by the decoder
|
||||||
|
add-on calling the derived class' GetNextChunk() function. */
|
||||||
status_t
|
status_t
|
||||||
BMediaDecoder::Decode(void *out_buffer,
|
BMediaDecoder::Decode(void *out_buffer,
|
||||||
int64 *out_frameCount,
|
int64 *out_frameCount,
|
||||||
media_header *out_mh,
|
media_header *out_mh,
|
||||||
media_decode_info *info)
|
media_decode_info *info)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
if (fInitStatus != B_OK) {
|
||||||
return B_OK;
|
return fInitStatus;
|
||||||
|
}
|
||||||
|
return fDecoder->Decode(out_buffer,out_frameCount,out_mh,info);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMediaDecoder::GetDecoderInfo(media_codec_info *out_info) const
|
BMediaDecoder::GetDecoderInfo(media_codec_info *out_info) const
|
||||||
{
|
{
|
||||||
|
if (fInitStatus != B_OK) {
|
||||||
|
return fInitStatus;
|
||||||
|
}
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -146,20 +223,23 @@ status_t BMediaDecoder::_Reserved_BMediaDecoder_15(int32 arg, ...) { return B_ER
|
|||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
|
||||||
BMediaBufferDecoder::BMediaBufferDecoder()
|
BMediaBufferDecoder::BMediaBufferDecoder()
|
||||||
|
: BMediaDecoder()
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
buffer_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BMediaBufferDecoder::BMediaBufferDecoder(const media_format *in_format,
|
BMediaBufferDecoder::BMediaBufferDecoder(const media_format *in_format,
|
||||||
const void *info,
|
const void *info,
|
||||||
size_t info_size)
|
size_t info_size)
|
||||||
|
: BMediaDecoder(in_format,info,info_size)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
buffer_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BMediaBufferDecoder::BMediaBufferDecoder(const media_codec_info *mci)
|
BMediaBufferDecoder::BMediaBufferDecoder(const media_codec_info *mci)
|
||||||
|
: BMediaDecoder(mci)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
buffer_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
@@ -170,8 +250,9 @@ BMediaBufferDecoder::DecodeBuffer(const void *input_buffer,
|
|||||||
media_header *out_mh,
|
media_header *out_mh,
|
||||||
media_decode_info *info)
|
media_decode_info *info)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
buffer = input_buffer;
|
||||||
return B_OK;
|
buffer_size = input_size;
|
||||||
|
return Decode(out_buffer,out_frameCount,out_mh,info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
@@ -183,7 +264,11 @@ status_t BMediaBufferDecoder::GetNextChunk(const void **chunkData,
|
|||||||
size_t *chunkLen,
|
size_t *chunkLen,
|
||||||
media_header *mh)
|
media_header *mh)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
if (!buffer_size) {
|
||||||
|
return B_LAST_BUFFER_ERROR;
|
||||||
|
}
|
||||||
|
*chunkData = buffer;
|
||||||
|
*chunkLen = buffer_size;
|
||||||
|
buffer_size = 0;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,21 @@ MediaExtractor::GetNextChunk(int32 stream,
|
|||||||
return fReader->GetNextChunk(fStreamInfo[stream].cookie, chunkBuffer, chunkSize, mediaHeader);
|
return fReader->GetNextChunk(fStreamInfo[stream].cookie, chunkBuffer, chunkSize, mediaHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MediaExtractorChunkProvider : public ChunkProvider {
|
||||||
|
private:
|
||||||
|
MediaExtractor * fExtractor;
|
||||||
|
int32 fStream;
|
||||||
|
public:
|
||||||
|
MediaExtractorChunkProvider(MediaExtractor * extractor, int32 stream) {
|
||||||
|
fExtractor = extractor;
|
||||||
|
fStream = stream;
|
||||||
|
}
|
||||||
|
virtual status_t GetNextChunk(void **chunkBuffer, int32 *chunkSize,
|
||||||
|
media_header *mediaHeader) {
|
||||||
|
return fExtractor->GetNextChunk(fStream,chunkBuffer,chunkSize,mediaHeader);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MediaExtractor::CreateDecoder(int32 stream, Decoder **decoder, media_codec_info *mci)
|
MediaExtractor::CreateDecoder(int32 stream, Decoder **decoder, media_codec_info *mci)
|
||||||
{
|
{
|
||||||
@@ -177,7 +192,7 @@ MediaExtractor::CreateDecoder(int32 stream, Decoder **decoder, media_codec_info
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*decoder)->Setup(this, stream);
|
(*decoder)->Setup(new MediaExtractorChunkProvider(this,stream));
|
||||||
|
|
||||||
res = (*decoder)->Setup(&fStreamInfo[stream].encodedFormat, fStreamInfo[stream].infoBuffer , fStreamInfo[stream].infoBufferSize);
|
res = (*decoder)->Setup(&fStreamInfo[stream].encodedFormat, fStreamInfo[stream].infoBuffer , fStreamInfo[stream].infoBufferSize);
|
||||||
if (res != B_OK) {
|
if (res != B_OK) {
|
||||||
|
|||||||
Reference in New Issue
Block a user