Huge hack to load the mp3 reader and decoder.
Soundplay loads it and can play a crackling mp3, but MediaPlayer doesn't git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5572 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "ReaderPlugin.h"
|
||||
#include "DecoderPlugin.h"
|
||||
#include <TList.h>
|
||||
#include <Locker.h>
|
||||
|
||||
status_t _CreateReader(Reader **reader, int32 *streamCount, media_file_format *mff, BDataIO *source);
|
||||
status_t _CreateDecoder(Decoder **decoder, media_codec_info *mci, const media_format *format);
|
||||
@@ -10,4 +12,34 @@ status_t _CreateDecoder(Decoder **decoder, media_codec_info *mci, const media_fo
|
||||
void _DestroyReader(Reader *reader);
|
||||
void _DestroyDecoder(Decoder *decoder);
|
||||
|
||||
status_t _PublishDecoder(DecoderPlugin *decoderplugin,
|
||||
const char *meta_description,
|
||||
const char *short_name,
|
||||
const char *pretty_name,
|
||||
const char *default_mapping /* = 0 */);
|
||||
|
||||
class PluginManager
|
||||
{
|
||||
public:
|
||||
PluginManager();
|
||||
~PluginManager();
|
||||
|
||||
MediaPlugin * GetPlugin(const char *name);
|
||||
void PutPlugin(MediaPlugin *plugin);
|
||||
|
||||
private:
|
||||
bool LoadPlugin(const char *name, MediaPlugin **plugin, image_id *image);
|
||||
|
||||
struct plugin_info
|
||||
{
|
||||
char name[260];
|
||||
int usecount;
|
||||
MediaPlugin *plugin;
|
||||
image_id image;
|
||||
};
|
||||
|
||||
List<plugin_info> *fPluginList;
|
||||
BLocker *fLocker;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -114,6 +114,7 @@ mp3DecoderPlugin::RegisterPlugin()
|
||||
PublishDecoder("audiocodec/mpeg2.5layer1", "mp3", "MPEG 2.5 audio layer 1 decoder, based on mpeg123 mpglib");
|
||||
PublishDecoder("audiocodec/mpeg2.5layer2", "mp3", "MPEG 2.5 audio layer 2 decoder, based on mpeg123 mpglib");
|
||||
PublishDecoder("audiocodec/mpeg2.5layer3", "mp3", "MPEG 2.5 audio layer 3 decoder, based on mpeg123 mpglib");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "DecoderPlugin.h"
|
||||
#include "PluginManager.h"
|
||||
#include <MediaFormats.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -35,18 +36,5 @@ DecoderPlugin::PublishDecoder(const char *meta_description,
|
||||
const char *pretty_name,
|
||||
const char *default_mapping /* = 0 */)
|
||||
{
|
||||
/*
|
||||
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;
|
||||
|
||||
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;
|
||||
return _PublishDecoder(this, meta_description, short_name, pretty_name, default_mapping);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "MediaExtractor.h"
|
||||
#include "PluginManager.h"
|
||||
#include "debug.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
MediaExtractor::MediaExtractor(BDataIO * source, int32 flags)
|
||||
{
|
||||
CALLED();
|
||||
fSource = source;
|
||||
fStreamInfo = 0;
|
||||
fStreamCount = 0;
|
||||
@@ -47,13 +49,27 @@ MediaExtractor::MediaExtractor(BDataIO * source, int32 flags)
|
||||
fStreamInfo[i].status = B_ERROR;
|
||||
printf("MediaExtractor::MediaExtractor: GetStreamInfo for stream %ld failed\n", i);
|
||||
}
|
||||
|
||||
char sz[1024];
|
||||
string_for_format(fStreamInfo[i].encodedFormat, sz, sizeof(sz));
|
||||
printf("MediaExtractor::MediaExtractor: stream %d has format %s\n", i, sz);
|
||||
fStreamInfo[i].encodedFormat.type = B_MEDIA_ENCODED_AUDIO;
|
||||
fStreamInfo[i].encodedFormat.u.encoded_audio.encoding = (enum media_encoded_audio_format::audio_encoding) 1;
|
||||
fStreamInfo[i].encodedFormat.u.encoded_audio.bit_rate = 128000;
|
||||
fStreamInfo[i].encodedFormat.u.encoded_audio.frame_size = 3000;
|
||||
fStreamInfo[i].encodedFormat.u.encoded_audio.output.frame_rate = 44100;
|
||||
fStreamInfo[i].encodedFormat.u.encoded_audio.output.channel_count = 2;
|
||||
fStreamInfo[i].encodedFormat.u.encoded_audio.output.format = 2;
|
||||
fStreamInfo[i].encodedFormat.u.encoded_audio.output.byte_order = B_MEDIA_LITTLE_ENDIAN;
|
||||
fStreamInfo[i].encodedFormat.u.encoded_audio.output.buffer_size = 8 * 1024;
|
||||
string_for_format(fStreamInfo[i].encodedFormat, sz, sizeof(sz));
|
||||
printf("MediaExtractor::MediaExtractor: stream %d has new format %s\n", i, sz);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
MediaExtractor::~MediaExtractor()
|
||||
{
|
||||
CALLED();
|
||||
// free all stream cookies
|
||||
for (int32 i = 0; i < fStreamCount; i++) {
|
||||
if (fStreamInfo[i].cookie)
|
||||
@@ -70,18 +86,21 @@ MediaExtractor::~MediaExtractor()
|
||||
status_t
|
||||
MediaExtractor::InitCheck()
|
||||
{
|
||||
CALLED();
|
||||
return fErr;
|
||||
}
|
||||
|
||||
void
|
||||
MediaExtractor::GetFileFormatInfo(media_file_format *mfi) const
|
||||
{
|
||||
CALLED();
|
||||
*mfi = fMff;
|
||||
}
|
||||
|
||||
int32
|
||||
MediaExtractor::StreamCount()
|
||||
{
|
||||
CALLED();
|
||||
return fStreamCount;
|
||||
}
|
||||
|
||||
@@ -94,6 +113,7 @@ MediaExtractor::EncodedFormat(int32 stream)
|
||||
int64
|
||||
MediaExtractor::CountFrames(int32 stream) const
|
||||
{
|
||||
CALLED();
|
||||
int64 frameCount;
|
||||
bigtime_t duration;
|
||||
media_format format;
|
||||
@@ -108,6 +128,7 @@ MediaExtractor::CountFrames(int32 stream) const
|
||||
bigtime_t
|
||||
MediaExtractor::Duration(int32 stream) const
|
||||
{
|
||||
CALLED();
|
||||
int64 frameCount;
|
||||
bigtime_t duration;
|
||||
media_format format;
|
||||
@@ -135,12 +156,14 @@ status_t
|
||||
MediaExtractor::Seek(int32 stream, uint32 seekTo,
|
||||
int64 *frame, bigtime_t *time)
|
||||
{
|
||||
CALLED();
|
||||
status_t result;
|
||||
result = fReader->Seek(fStreamInfo[stream].cookie, seekTo, frame, time);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
// clear buffered chunks
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
@@ -148,6 +171,7 @@ MediaExtractor::GetNextChunk(int32 stream,
|
||||
void **chunkBuffer, int32 *chunkSize,
|
||||
media_header *mediaHeader)
|
||||
{
|
||||
CALLED();
|
||||
// get buffered chunk
|
||||
|
||||
// XXX this should be done in a different thread, and double buffered for each stream
|
||||
@@ -157,6 +181,7 @@ MediaExtractor::GetNextChunk(int32 stream,
|
||||
status_t
|
||||
MediaExtractor::CreateDecoder(int32 stream, Decoder **decoder, media_codec_info *mci)
|
||||
{
|
||||
CALLED();
|
||||
if (fStreamInfo[stream].status != B_OK) {
|
||||
printf("MediaExtractor::CreateDecoder can't create decoder for stream %ld\n", stream);
|
||||
return B_ERROR;
|
||||
|
||||
@@ -137,6 +137,7 @@ BMediaFile::ReleaseTrack(BMediaTrack *track)
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
printf("BMediaFile::ReleaseTrack track %p not found\n", track);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -305,8 +305,8 @@ _get_format_for_description(media_format *out_format, const media_format_descrip
|
||||
|
||||
request.description = in_desc;
|
||||
|
||||
if (B_OK != QueryServer(SERVER_GET_FORMAT_FOR_DESCRIPTION, &request, sizeof(request), &reply, sizeof(reply)))
|
||||
return B_ERROR;
|
||||
// if (B_OK != QueryServer(SERVER_GET_FORMAT_FOR_DESCRIPTION, &request, sizeof(request), &reply, sizeof(reply)))
|
||||
// return B_ERROR;
|
||||
|
||||
*out_format = reply.format;
|
||||
return B_OK;
|
||||
@@ -320,8 +320,8 @@ _get_meta_description_for_format(media_format_description *out_desc, const media
|
||||
|
||||
request.format = in_format;
|
||||
|
||||
if (B_OK != QueryServer(SERVER_GET_META_DESCRIPTION_FOR_FORMAT, &request, sizeof(request), &reply, sizeof(reply)))
|
||||
return B_ERROR;
|
||||
// if (B_OK != QueryServer(SERVER_GET_META_DESCRIPTION_FOR_FORMAT, &request, sizeof(request), &reply, sizeof(reply)))
|
||||
// return B_ERROR;
|
||||
|
||||
*out_desc = reply.description;
|
||||
return B_OK;
|
||||
|
||||
@@ -54,7 +54,7 @@ BMediaTrack::EncodedFormat(media_format *out_format) const
|
||||
return B_NO_INIT;
|
||||
|
||||
out_format = fExtractor->EncodedFormat(fStream);
|
||||
|
||||
printf("encoded format\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,77 @@
|
||||
#include <Path.h>
|
||||
#include <image.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "PluginManager.h"
|
||||
|
||||
PluginManager _plugin_manager;
|
||||
|
||||
status_t
|
||||
_CreateReader(Reader **reader, int32 *streamCount, media_file_format *mff, BDataIO *source)
|
||||
{
|
||||
printf("_CreateReader enter\n");
|
||||
|
||||
MediaPlugin *plugin;
|
||||
ReaderPlugin *readerplugin;
|
||||
|
||||
plugin = _plugin_manager.GetPlugin("mp3_reader");
|
||||
if (!plugin) {
|
||||
printf("_CreateReader: GetPlugin failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
readerplugin = dynamic_cast<ReaderPlugin *>(plugin);
|
||||
if (!readerplugin) {
|
||||
printf("_CreateReader: dynamic_cast failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
*reader = readerplugin->NewReader();
|
||||
if (! *reader) {
|
||||
printf("_CreateReader: NewReader failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
(*reader)->Setup(source);
|
||||
|
||||
if (B_OK != (*reader)->Sniff(streamCount)) {
|
||||
printf("_CreateReader: Sniff failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
printf("_CreateReader leave\n");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
_CreateDecoder(Decoder **decoder, media_codec_info *mci, const media_format *format)
|
||||
{
|
||||
printf("_CreateDecoder enter\n");
|
||||
|
||||
MediaPlugin *plugin;
|
||||
DecoderPlugin *decoderplugin;
|
||||
|
||||
plugin = _plugin_manager.GetPlugin("mp3_decoder");
|
||||
if (!plugin) {
|
||||
printf("_CreateDecoder: GetPlugin failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
decoderplugin = dynamic_cast<DecoderPlugin *>(plugin);
|
||||
if (!decoderplugin) {
|
||||
printf("_CreateDecoder: dynamic_cast failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
*decoder = decoderplugin->NewDecoder();
|
||||
if (! *decoder) {
|
||||
printf("_CreateDecoder: NewReader failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
printf("_CreateDecoder leave\n");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -23,3 +85,147 @@ void
|
||||
_DestroyDecoder(Decoder *decoder)
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
_PublishDecoder(DecoderPlugin *decoderplugin,
|
||||
const char *meta_description,
|
||||
const char *short_name,
|
||||
const char *pretty_name,
|
||||
const char *default_mapping /* = 0 */)
|
||||
{
|
||||
printf("_PublishDecoder: meta_description \"%s\", short_name \"%s\", pretty_name \"%s\", default_mapping \"%s\"\n",
|
||||
meta_description, short_name, pretty_name, default_mapping);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PluginManager::PluginManager()
|
||||
{
|
||||
fLocker = new BLocker;
|
||||
fPluginList = new List<plugin_info>;
|
||||
}
|
||||
|
||||
|
||||
PluginManager::~PluginManager()
|
||||
{
|
||||
while (!fPluginList->IsEmpty()) {
|
||||
plugin_info *info;
|
||||
fPluginList->Get(fPluginList->CountItems() - 1, &info);
|
||||
printf("PluginManager: Error, unloading PlugIn %s with usecount %d\n", info->name, info->usecount);
|
||||
delete info->plugin;
|
||||
unload_add_on(info->image);
|
||||
fPluginList->Remove(fPluginList->CountItems() - 1);
|
||||
}
|
||||
delete fLocker;
|
||||
}
|
||||
|
||||
|
||||
MediaPlugin *
|
||||
PluginManager::GetPlugin(const char *name)
|
||||
{
|
||||
fLocker->Lock();
|
||||
|
||||
MediaPlugin *plugin;
|
||||
plugin_info *pinfo;
|
||||
plugin_info info;
|
||||
|
||||
for (fPluginList->Rewind(); fPluginList->GetNext(&pinfo); ) {
|
||||
if (0 == strcmp(name, pinfo->name)) {
|
||||
plugin = pinfo->plugin;
|
||||
pinfo->usecount++;
|
||||
fLocker->Unlock();
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
|
||||
if (!LoadPlugin(name, &info.plugin, &info.image)) {
|
||||
printf("PluginManager: Error, loading PlugIn %s failed\n", name);
|
||||
fLocker->Unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(info.name, name);
|
||||
info.usecount = 1;
|
||||
fPluginList->Insert(info);
|
||||
|
||||
printf("PluginManager: PlugIn %s loaded\n", name);
|
||||
|
||||
plugin = info.plugin;
|
||||
|
||||
fLocker->Unlock();
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PluginManager::PutPlugin(MediaPlugin *plugin)
|
||||
{
|
||||
fLocker->Lock();
|
||||
|
||||
plugin_info *pinfo;
|
||||
|
||||
for (fPluginList->Rewind(); fPluginList->GetNext(&pinfo); ) {
|
||||
if (plugin == pinfo->plugin) {
|
||||
pinfo->usecount--;
|
||||
if (pinfo->usecount == 0) {
|
||||
delete pinfo->plugin;
|
||||
unload_add_on(pinfo->image);
|
||||
}
|
||||
fPluginList->RemoveCurrent();
|
||||
fLocker->Unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("PluginManager: Error, can't put PlugIn %p\n", plugin);
|
||||
|
||||
fLocker->Unlock();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PluginManager::LoadPlugin(const char *name, MediaPlugin **plugin, image_id *image)
|
||||
{
|
||||
const char *searchdir[] = {
|
||||
"/boot/home/config/add-ons/media/plugins",
|
||||
"/boot/beos/system/add-ons/media/plugins",
|
||||
"/boot/home/develop/openbeos/current/distro/x86.R1/beos/system/add-ons/media/plugins",
|
||||
NULL
|
||||
};
|
||||
|
||||
for (int i = 0; searchdir[i]; i++) {
|
||||
BPath p(searchdir[i], name);
|
||||
|
||||
printf("PluginManager: LoadPlugin trying to load %s\n", p.Path());
|
||||
|
||||
image_id id;
|
||||
id = load_add_on(p.Path());
|
||||
if (id < 0)
|
||||
continue;
|
||||
|
||||
MediaPlugin *(*instantiate_plugin_func)();
|
||||
|
||||
if (get_image_symbol(id, "instantiate_plugin", B_SYMBOL_TYPE_TEXT, (void**)&instantiate_plugin_func) < B_OK) {
|
||||
printf("PluginManager: Error, LoadPlugin can't find instantiate_plugin in %s\n", p.Path());
|
||||
unload_add_on(id);
|
||||
continue;
|
||||
}
|
||||
|
||||
MediaPlugin *pl;
|
||||
|
||||
pl = (*instantiate_plugin_func)();
|
||||
if (pl == 0) {
|
||||
printf("PluginManager: Error, LoadPlugin instantiate_plugin in %s returned 0\n", p.Path());
|
||||
unload_add_on(id);
|
||||
continue;
|
||||
}
|
||||
|
||||
*plugin = pl;
|
||||
*image = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user