diff --git a/headers/private/media/DecoderPlugin.h b/headers/private/media/DecoderPlugin.h index a484d47a86..a380fa5f6f 100644 --- a/headers/private/media/DecoderPlugin.h +++ b/headers/private/media/DecoderPlugin.h @@ -1,4 +1,5 @@ #include +#include #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; - diff --git a/headers/private/media/MediaPlugin.h b/headers/private/media/MediaPlugin.h index 856faa141a..54bf3f6050 100644 --- a/headers/private/media/MediaPlugin.h +++ b/headers/private/media/MediaPlugin.h @@ -1,6 +1,9 @@ #ifndef _MEDIA_PLUGIN_H #define _MEDIA_PLUGIN_H +#include +#include + namespace BPrivate { namespace media { class MediaPlugin @@ -8,6 +11,8 @@ class MediaPlugin public: MediaPlugin(); virtual ~MediaPlugin(); + + virtual status_t RegisterPlugin(); }; class Decoder; diff --git a/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.cpp b/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.cpp index 766a1ac69d..8f2649078d 100644 --- a/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.cpp +++ b/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #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() { diff --git a/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.h b/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.h index 46bd8980a9..fcd541fbf1 100644 --- a/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.h +++ b/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.h @@ -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(); diff --git a/src/add-ons/media/plugins/mp3_reader/MP3ReaderPlugin.cpp b/src/add-ons/media/plugins/mp3_reader/MP3ReaderPlugin.cpp index 88275493d0..9056386eec 100644 --- a/src/add-ons/media/plugins/mp3_reader/MP3ReaderPlugin.cpp +++ b/src/add-ons/media/plugins/mp3_reader/MP3ReaderPlugin.cpp @@ -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; diff --git a/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.cpp b/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.cpp index c09c999c0c..c9196615b1 100644 --- a/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.cpp +++ b/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.cpp @@ -1,4 +1,5 @@ #include +#include #include #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() { diff --git a/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.h b/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.h index 6cad06540b..99ab6dcb25 100644 --- a/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.h +++ b/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.h @@ -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(); diff --git a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp index b90f4065c2..055c1d2167 100644 --- a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp +++ b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp @@ -204,9 +204,13 @@ WavReader::GetNextChunk(void *cookie, wavdata *data = reinterpret_cast(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; diff --git a/src/kits/media/DecoderPlugin.cpp b/src/kits/media/DecoderPlugin.cpp index 3d9502a912..9d46e69702 100644 --- a/src/kits/media/DecoderPlugin.cpp +++ b/src/kits/media/DecoderPlugin.cpp @@ -1,4 +1,7 @@ #include "DecoderPlugin.h" +#include +#include +#include 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; +} diff --git a/src/kits/media/MediaPlugin.cpp b/src/kits/media/MediaPlugin.cpp index bb3f246817..439e518068 100644 --- a/src/kits/media/MediaPlugin.cpp +++ b/src/kits/media/MediaPlugin.cpp @@ -8,3 +8,7 @@ MediaPlugin::~MediaPlugin() { } +status_t +MediaPlugin::RegisterPlugin() +{ +}