another round of codec API changes
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5458 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include <MediaTrack.h>
|
||||
#include <MediaFormats.h>
|
||||
#include "MediaPlugin.h"
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
@@ -9,13 +10,13 @@ public:
|
||||
Decoder();
|
||||
virtual ~Decoder();
|
||||
|
||||
// Sniff get's called with the data from Reader::GetStreamInfo
|
||||
virtual status_t Sniff(media_format *format, void **infoBuffer, int32 *infoSize) = 0;
|
||||
// Setup get's called with the info data from Reader::GetStreamInfo
|
||||
virtual status_t Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
|
||||
const void *infoBuffer, int32 infoSize) = 0;
|
||||
|
||||
virtual status_t GetOutputFormat(media_format *format) = 0;
|
||||
|
||||
virtual status_t Seek(media_seek_type seekTo,
|
||||
int64 *frame, bigtime_t *time) = 0;
|
||||
int64 seekFrame, int64 *frame,
|
||||
bigtime_t seekTime, bigtime_t *time) = 0;
|
||||
|
||||
virtual status_t Decode(void *buffer, int64 *frameCount,
|
||||
media_header *mediaHeader, media_decode_info *info) = 0;
|
||||
@@ -32,12 +33,14 @@ private:
|
||||
class DecoderPlugin : public MediaPlugin
|
||||
{
|
||||
public:
|
||||
virtual Decoder *NewDecoder() = 0;
|
||||
};
|
||||
DecoderPlugin();
|
||||
|
||||
MediaPlugin *instantiate_plugin();
|
||||
virtual Decoder *NewDecoder() = 0;
|
||||
|
||||
status_t PublishDecoder(const char *short_name, const char *pretty_name, const media_format_description &fmt_desc, media_type fmt_type);
|
||||
status_t PublishDecoder(const char *short_name, const char *pretty_name, const media_format &fmt);
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef _MEDIA_PLUGIN_H
|
||||
#define _MEDIA_PLUGIN_H
|
||||
|
||||
#include <BeBuild.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class MediaPlugin
|
||||
@@ -8,6 +11,8 @@ class MediaPlugin
|
||||
public:
|
||||
MediaPlugin();
|
||||
virtual ~MediaPlugin();
|
||||
|
||||
virtual status_t RegisterPlugin();
|
||||
};
|
||||
|
||||
class Decoder;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <DataIO.h>
|
||||
#include <Locker.h>
|
||||
#include <MediaFormats.h>
|
||||
#include "mp3DecoderPlugin.h"
|
||||
|
||||
#define TRACE_THIS 1
|
||||
@@ -10,7 +11,7 @@
|
||||
#define TRACE ((void)0)
|
||||
#endif
|
||||
|
||||
#define OUTPUT_BUFFER_SIZE 65536
|
||||
#define OUTPUT_BUFFER_SIZE 32768
|
||||
|
||||
mp3Decoder::mp3Decoder()
|
||||
{
|
||||
@@ -24,28 +25,24 @@ mp3Decoder::~mp3Decoder()
|
||||
|
||||
|
||||
status_t
|
||||
mp3Decoder::Sniff(media_format *format, void **infoBuffer, int32 *infoSize)
|
||||
mp3Decoder::Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
|
||||
const void *infoBuffer, int32 infoSize)
|
||||
{
|
||||
fFormat.type = B_MEDIA_RAW_AUDIO;
|
||||
fFormat.u.raw_audio.frame_rate = 44100;
|
||||
fFormat.u.raw_audio.channel_count = 2;
|
||||
fFormat.u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT;
|
||||
fFormat.u.raw_audio.byte_order = B_MEDIA_LITTLE_ENDIAN;
|
||||
fFormat.u.raw_audio.buffer_size = OUTPUT_BUFFER_SIZE;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mp3Decoder::GetOutputFormat(media_format *format)
|
||||
{
|
||||
*format = fFormat;
|
||||
memset(ioDecodedFormat, 0, sizeof(*ioDecodedFormat));
|
||||
ioDecodedFormat->type = B_MEDIA_RAW_AUDIO;
|
||||
ioDecodedFormat->u.raw_audio.frame_rate = 44100;
|
||||
ioDecodedFormat->u.raw_audio.channel_count = 2;
|
||||
ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT;
|
||||
ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_LITTLE_ENDIAN;
|
||||
ioDecodedFormat->u.raw_audio.buffer_size = OUTPUT_BUFFER_SIZE;
|
||||
ioDecodedFormat->u.raw_audio.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
mp3Decoder::Seek(media_seek_type seekTo,
|
||||
int64 *frame, bigtime_t *time)
|
||||
int64 seekFrame, int64 *frame,
|
||||
bigtime_t seekTime, bigtime_t *time)
|
||||
{
|
||||
ExitMP3(&fMpgLibPrivate);
|
||||
InitMP3(&fMpgLibPrivate);
|
||||
@@ -91,7 +88,6 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
Decoder *
|
||||
mp3DecoderPlugin::NewDecoder()
|
||||
{
|
||||
@@ -106,6 +102,32 @@ mp3DecoderPlugin::NewDecoder()
|
||||
return new mp3Decoder;
|
||||
}
|
||||
|
||||
status_t
|
||||
mp3DecoderPlugin::RegisterPlugin()
|
||||
{
|
||||
struct {
|
||||
const char *short_name;
|
||||
const char *pretty_name;
|
||||
uint32 id;
|
||||
} descs[] = {
|
||||
{ "mpeg1 audio layer1", "MPEG 1 audio layer 1 decoder, based on mpeg123 mpglib", B_MPEG_1_AUDIO_LAYER_1 },
|
||||
{ "mpeg1 audio layer2", "MPEG 1 audio layer 2 decoder, based on mpeg123 mpglib", B_MPEG_1_AUDIO_LAYER_2 },
|
||||
{ "mpeg1 audio layer3", "MPEG 1 audio layer 3 decoder, based on mpeg123 mpglib", B_MPEG_1_AUDIO_LAYER_3 },
|
||||
{ "mpeg2 audio layer1", "MPEG 2 audio layer 1 decoder, based on mpeg123 mpglib", B_MPEG_2_AUDIO_LAYER_1 },
|
||||
{ "mpeg2 audio layer2", "MPEG 2 audio layer 2 decoder, based on mpeg123 mpglib", B_MPEG_2_AUDIO_LAYER_2 },
|
||||
{ "mpeg2 audio layer3", "MPEG 2 audio layer 3 decoder, based on mpeg123 mpglib", B_MPEG_2_AUDIO_LAYER_3 },
|
||||
{ "mpeg2.5 audio layer1", "MPEG 2.5 audio layer 1 decoder, based on mpeg123 mpglib", B_MPEG_2_5_AUDIO_LAYER_1 },
|
||||
{ "mpeg2.5 audio layer2", "MPEG 2.5 audio layer 2 decoder, based on mpeg123 mpglib", B_MPEG_2_5_AUDIO_LAYER_2 },
|
||||
{ "mpeg2.5 audio layer3", "MPEG 2.5 audio layer 3 decoder, based on mpeg123 mpglib", B_MPEG_2_5_AUDIO_LAYER_3 }
|
||||
};
|
||||
for (int i = 0; i < (int)(sizeof(descs) / sizeof(descs[i])); i++) {
|
||||
media_format_description fmt_desc;
|
||||
fmt_desc.family = B_MPEG_FORMAT_FAMILY;
|
||||
fmt_desc.u.mpeg.id = descs[i].id;
|
||||
PublishDecoder(descs[i].short_name, descs[i].pretty_name, fmt_desc, B_MEDIA_ENCODED_AUDIO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MediaPlugin *instantiate_plugin()
|
||||
{
|
||||
|
||||
@@ -8,17 +8,17 @@ public:
|
||||
mp3Decoder();
|
||||
~mp3Decoder();
|
||||
|
||||
status_t Sniff(media_format *format, void **infoBuffer, int32 *infoSize);
|
||||
|
||||
status_t GetOutputFormat(media_format *format);
|
||||
status_t Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
|
||||
const void *infoBuffer, int32 infoSize);
|
||||
|
||||
status_t Seek(media_seek_type seekTo,
|
||||
int64 *frame, bigtime_t *time);
|
||||
int64 seekFrame, int64 *frame,
|
||||
bigtime_t seekTime, bigtime_t *time);
|
||||
|
||||
|
||||
status_t Decode(void *buffer, int64 *frameCount,
|
||||
media_header *mediaHeader, media_decode_info *info);
|
||||
private:
|
||||
media_format fFormat;
|
||||
struct mpstr fMpgLibPrivate;
|
||||
};
|
||||
|
||||
@@ -26,7 +26,6 @@ private:
|
||||
class mp3DecoderPlugin : public DecoderPlugin
|
||||
{
|
||||
public:
|
||||
Decoder *NewDecoder();
|
||||
Decoder * NewDecoder();
|
||||
status_t RegisterPlugin();
|
||||
};
|
||||
|
||||
MediaPlugin *instantiate_plugin();
|
||||
|
||||
@@ -80,8 +80,11 @@ struct mp3data
|
||||
char * chunkBuffer;
|
||||
|
||||
int64 duration; // usec
|
||||
|
||||
int32 framesPerFrame; // PCM frames in each mpeg frame
|
||||
int64 frameCount; // PCM frames
|
||||
int32 frameRate;
|
||||
int64 framePosition;
|
||||
|
||||
media_format format;
|
||||
};
|
||||
@@ -193,6 +196,9 @@ mp3Reader::AllocateCookie(int32 streamNumber, void **cookie)
|
||||
|
||||
TRACE("mp3Reader::AllocateCookie: frameRate %ld, frameCount %Ld, duration %.6f\n",
|
||||
data->frameRate, data->frameCount, data->duration / 1000000.0);
|
||||
|
||||
data->framePosition = 0;
|
||||
data->framesPerFrame = frame_sample_count_table[layer_index];
|
||||
|
||||
BMediaFormats formats;
|
||||
media_format_description description;
|
||||
@@ -314,6 +320,9 @@ mp3Reader::GetNextChunk(void *cookie,
|
||||
if (maxbytes < 4)
|
||||
return B_ERROR;
|
||||
|
||||
mediaHeader->start_time = (data->framePosition * 1000000) / data->frameCount;
|
||||
mediaHeader->file_pos = data->position;
|
||||
|
||||
if (4 != Source()->ReadAt(fDataStart + data->position, data->chunkBuffer, 4)) {
|
||||
TRACE("mp3Reader::GetNextChunk: unexpected read error\n");
|
||||
return B_ERROR;
|
||||
@@ -336,6 +345,8 @@ mp3Reader::GetNextChunk(void *cookie,
|
||||
return B_ERROR;
|
||||
}
|
||||
data->position += size;
|
||||
|
||||
data->framePosition += data->framesPerFrame;
|
||||
|
||||
*chunkBuffer = data->chunkBuffer;
|
||||
*chunkSize = size + 4;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <DataIO.h>
|
||||
#include "RawDecoderPlugin.h"
|
||||
|
||||
@@ -9,36 +10,29 @@
|
||||
#define TRACE ((void)0)
|
||||
#endif
|
||||
|
||||
RawDecoder::RawDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
RawDecoder::~RawDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RawDecoder::Sniff(media_format *format, void **infoBuffer, int32 *infoSize)
|
||||
RawDecoder::Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
|
||||
const void *infoBuffer, int32 infoSize)
|
||||
{
|
||||
if (format->type != B_MEDIA_RAW_AUDIO)
|
||||
if (ioEncodedFormat->type != B_MEDIA_RAW_AUDIO && ioEncodedFormat->type != B_MEDIA_RAW_VIDEO)
|
||||
return B_ERROR;
|
||||
|
||||
fFormat = *format;
|
||||
if (ioEncodedFormat->type == B_MEDIA_RAW_VIDEO)
|
||||
fFrameSize = ioEncodedFormat->u.raw_video.display.line_count * ioEncodedFormat->u.raw_video.display.bytes_per_row;
|
||||
else
|
||||
fFrameSize = (ioEncodedFormat->u.raw_audio.format & 0xf) * ioEncodedFormat->u.raw_audio.channel_count;
|
||||
|
||||
*ioDecodedFormat = *ioEncodedFormat;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RawDecoder::GetOutputFormat(media_format *format)
|
||||
{
|
||||
*format = fFormat;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
RawDecoder::Seek(media_seek_type seekTo,
|
||||
int64 *frame, bigtime_t *time)
|
||||
int64 seekFrame, int64 *frame,
|
||||
bigtime_t seekTime, bigtime_t *time)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
@@ -48,6 +42,14 @@ status_t
|
||||
RawDecoder::Decode(void *buffer, int64 *frameCount,
|
||||
media_header *mediaHeader, media_decode_info *info)
|
||||
{
|
||||
void *chunkBuffer;
|
||||
int32 chunkSize;
|
||||
if (B_OK != GetNextChunk(&chunkBuffer, &chunkSize, mediaHeader))
|
||||
return B_ERROR;
|
||||
|
||||
memcpy(buffer, chunkBuffer, chunkSize);
|
||||
*frameCount = chunkSize / fFrameSize;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -58,6 +60,17 @@ RawDecoderPlugin::NewDecoder()
|
||||
return new RawDecoder;
|
||||
}
|
||||
|
||||
status_t
|
||||
RawDecoderPlugin::RegisterPlugin()
|
||||
{
|
||||
media_format fmt;
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
fmt.type = B_MEDIA_RAW_AUDIO;
|
||||
PublishDecoder("raw audio", "RAW audio decoder", fmt);
|
||||
fmt.type = B_MEDIA_RAW_VIDEO;
|
||||
PublishDecoder("raw video", "RAW video decoder", fmt);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
MediaPlugin *instantiate_plugin()
|
||||
{
|
||||
|
||||
@@ -3,27 +3,23 @@
|
||||
class RawDecoder : public Decoder
|
||||
{
|
||||
public:
|
||||
RawDecoder();
|
||||
~RawDecoder();
|
||||
status_t Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
|
||||
const void *infoBuffer, int32 infoSize);
|
||||
|
||||
status_t Sniff(media_format *format, void **infoBuffer, int32 *infoSize);
|
||||
|
||||
status_t GetOutputFormat(media_format *format);
|
||||
|
||||
status_t Seek(media_seek_type seekTo,
|
||||
int64 *frame, bigtime_t *time);
|
||||
int64 seekFrame, int64 *frame,
|
||||
bigtime_t seekTime, bigtime_t *time);
|
||||
|
||||
status_t Decode(void *buffer, int64 *frameCount,
|
||||
media_header *mediaHeader, media_decode_info *info);
|
||||
private:
|
||||
media_format fFormat;
|
||||
int32 fFrameSize;
|
||||
};
|
||||
|
||||
|
||||
class RawDecoderPlugin : public DecoderPlugin
|
||||
{
|
||||
public:
|
||||
Decoder *NewDecoder();
|
||||
Decoder * NewDecoder();
|
||||
status_t RegisterPlugin();
|
||||
};
|
||||
|
||||
MediaPlugin *instantiate_plugin();
|
||||
|
||||
@@ -204,9 +204,13 @@ WavReader::GetNextChunk(void *cookie,
|
||||
wavdata *data = reinterpret_cast<wavdata *>(cookie);
|
||||
status_t result = B_OK;
|
||||
|
||||
int32 readsize = data->datasize - data->position;
|
||||
if (readsize > data->buffersize) {
|
||||
readsize = data->buffersize;
|
||||
mediaHeader->start_time = ((data->position / data->framesize) * 1000000LL) / data->fps;
|
||||
mediaHeader->file_pos = 44 + data->position;
|
||||
|
||||
int64 maxreadsize = data->datasize - data->position;
|
||||
int32 readsize = data->buffersize;
|
||||
if (maxreadsize < readsize) {
|
||||
readsize = maxreadsize;
|
||||
result = B_LAST_BUFFER_ERROR;
|
||||
}
|
||||
|
||||
@@ -215,14 +219,6 @@ WavReader::GetNextChunk(void *cookie,
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (mediaHeader) {
|
||||
// memset(mediaHeader, 0, sizeof(*mediaHeader));
|
||||
// mediaHeader->type = B_MEDIA_RAW_AUDIO;
|
||||
// mediaHeader->size_used = buffersize;
|
||||
// mediaHeader->start_time = ((data->position / data->framesize) * 1000000LL) / data->fps;
|
||||
// mediaHeader->file_pos = 44 + data->position;
|
||||
}
|
||||
|
||||
data->position += readsize;
|
||||
*chunkBuffer = data->buffer;
|
||||
*chunkSize = readsize;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#include "DecoderPlugin.h"
|
||||
#include <MediaFormats.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
Decoder::Decoder()
|
||||
{
|
||||
@@ -20,3 +23,32 @@ Decoder::Setup(BMediaTrack *reader)
|
||||
{
|
||||
fReader = reader;
|
||||
}
|
||||
|
||||
|
||||
DecoderPlugin::DecoderPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
DecoderPlugin::PublishDecoder(const char *short_name, const char *pretty_name, const media_format_description &fmt_desc, media_type fmt_type)
|
||||
{
|
||||
media_format fmt;
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
fmt.type = fmt_type;
|
||||
BMediaFormats formats;
|
||||
if (B_OK != formats.MakeFormatFor(&fmt_desc, 1, &fmt))
|
||||
return B_ERROR;
|
||||
return PublishDecoder(short_name, pretty_name, fmt);
|
||||
}
|
||||
|
||||
status_t
|
||||
DecoderPlugin::PublishDecoder(const char *short_name, const char *pretty_name, const media_format &fmt)
|
||||
{
|
||||
char s[1024];
|
||||
string_for_format(fmt, s, sizeof(s));
|
||||
printf("DecoderPlugin::PublishDecoder: short_name \"%s\", pretty_name \"%s\", format %s\n",
|
||||
short_name, pretty_name, s);
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -8,3 +8,7 @@ MediaPlugin::~MediaPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
MediaPlugin::RegisterPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user