new MediaFormats. node monitoring codec plugin loading. codec mods to support new codec api to retrieve supported formats.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6465 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty 2004-02-02 05:26:40 +00:00
parent 5b25332a79
commit fa8dbc019d
26 changed files with 999 additions and 205 deletions

View File

@ -71,6 +71,9 @@ enum {
MEDIA_SERVER_SEND_NOTIFICATIONS,
MEDIA_SERVER_GET_FORMATS,
MEDIA_SERVER_MAKE_FORMAT_FOR,
MEDIA_SERVER_READY,
};
// Raw port based communication

View File

@ -49,8 +49,8 @@ class DecoderPlugin : public virtual MediaPlugin
public:
DecoderPlugin();
virtual Decoder *NewDecoder() = 0;
virtual status_t RegisterDecoder() = 0;
virtual Decoder *NewDecoder(uint index) = 0;
virtual status_t GetSupportedFormats(media_format ** formats, size_t * count) = 0;
};
} } // namespace BPrivate::media

View File

@ -1,4 +1,694 @@
/******************************************************************************
/
/ File: avCodec.cpp
/
/ Description: FFMpeg Generic Decoder for BeOS Release 5.
/
/ Disclaimer: This decoder is based on undocumented APIs.
/ Therefore it is likely, if not certain, to break in future
/ versions of BeOS. This piece of software is in no way
/ connected to or even supported by Be, Inc.
/
/ Copyright (C) 2001 François Revol. All Rights Reserved.
/ Some code from MPEG I Decoder from Carlos Hasan.
/ Had some help from Axeld
/
******************************************************************************/
void foo()
#include <Debug.h>
#include <OS.h>
#include <Bitmap.h>
#include <string.h>
#include "avcodec.h"
struct wave_format_ex
{
uint16 format_tag;
uint16 channels;
uint32 frames_per_sec;
uint32 avg_bytes_per_sec;
uint16 block_align;
uint16 bits_per_sample;
uint16 extra_size;
// extra_data[extra_size]
} _PACKED;
/* uncommenting will make Decode() set the current thread priority to time sharing, so it won't totally freeze
* if you busy-loop in there (to help debug with CD Manager
*/
//#define UNREAL
#define CLOSE_ON_RESET
const char *media_type_name(int type)
{
switch (type) {
case B_MEDIA_NO_TYPE:
return "B_MEDIA_NO_TYPE";
case B_MEDIA_RAW_AUDIO:
return "B_MEDIA_RAW_AUDIO";
case B_MEDIA_RAW_VIDEO:
return "B_MEDIA_RAW_VIDEO";
case B_MEDIA_VBL:
return "B_MEDIA_VBL";
case B_MEDIA_TIMECODE:
return "B_MEDIA_TIMECODE";
case B_MEDIA_MIDI:
return "B_MEDIA_MIDI";
case B_MEDIA_TEXT:
return "B_MEDIA_TEXT";
case B_MEDIA_HTML:
return "B_MEDIA_HTML";
case B_MEDIA_MULTISTREAM:
return "B_MEDIA_MULTISTREAM";
case B_MEDIA_PARAMETERS:
return "B_MEDIA_PARAMETERS";
case B_MEDIA_ENCODED_AUDIO:
return "B_MEDIA_ENCODED_AUDIO";
case B_MEDIA_ENCODED_VIDEO:
return "B_MEDIA_ENCODED_VIDEO";
case B_MEDIA_UNKNOWN_TYPE:
default:
return "B_MEDIA_UNKNOWN_TYPE";
}
}
char make_printable_char(uchar c)
{
// c &= 0x7F;
if (c >= 0x20 && c < 0x7F)
return c;
return '.';
}
void print_hex(unsigned char *buff, int len)
{
int i, j;
for(i=0; i<len+7;i+=8) {
for (j=0; j<8; j++) {
if (i+j < len)
printf("%02X", buff[i+j]);
else
printf(" ");
if (j==3)
printf(" ");
}
printf("\t");
for (j=0; j<8; j++) {
if (i+j < len)
printf("%c", make_printable_char(buff[i+j]));
else
printf(" ");
}
printf("\n");
}
}
void print_media_header(media_header *mh)
{
printf("media_header {%s, size_used: %ld, start_time: %lld (%02d:%02d.%02d), field_sequence=%lu, user_data_type: .4s, file_pos: %ld, orig_size: %ld, data_offset: %ld}\n",
media_type_name(mh->type), mh->size_used, mh->start_time,
int((mh->start_time / 60000000) % 60),
int((mh->start_time / 1000000) % 60),
int((mh->start_time / 10000) % 100),
(long)mh->u.raw_video.field_sequence,
//&(mh->user_data_type),
(long)mh->file_pos,
(long)mh->orig_size,
mh->data_offset);
}
void print_media_decode_info(media_decode_info *info)
{
if (info)
printf("media_decode_info {time_to_decode: %lld, file_format_data_size: %ld, codec_data_size: %ld}\n", info->time_to_decode, info->file_format_data_size, info->codec_data_size);
else
printf("media_decode_info (null)\n");
}
avCodec::avCodec()
: fHeader(),
fInfo(),
fInputFormat(),
fOutputVideoFormat(),
fOutputAudioFormat(),
fFrame(0),
isAudio(false),
fData(NULL),
fOffset(0L),
fSize(0L),
fCodec(NULL),
ffc(NULL),
fCodecInitDone(false),
conv_func(NULL),
fExtraData(NULL),
fExtraDataSize(0),
fBlockAlign(0),
fOutputBuffer(0)
{
PRINT(("[%c] avCodec::avCodec()\n", isAudio?('a'):('v')));
static volatile vint32 ff_init_count = 0;
static bool ff_init_done = false;
PRINT(("avCodec::register_decoder()\n"));
// prevent multiple inits
if (atomic_add(&ff_init_count, 1) > 1) {
puts("NOT first init !");
atomic_add(&ff_init_count, -1);
// spin until the thread that is initing is done
while (!ff_init_done)
snooze(20000);
} else {
puts("first init !");
avcodec_init();
avcodec_register_all();
ff_init_done = true;
}
// memset(&opicture, 0, sizeof(AVPicture));
ffc = avcodec_alloc_context();
ffpicture = avcodec_alloc_frame();
// ffpicture->type = FF_BUFFER_TYPE_USER;
opicture = avcodec_alloc_frame();
}
avCodec::~avCodec()
{
PRINT(("[%c] avCodec::~avCodec()\n", isAudio?('a'):('v')));
if(fCodecInitDone)
avcodec_close(ffc);
free(opicture);
free(ffpicture);
free(ffc);
delete [] fExtraData;
delete [] fOutputBuffer;
}
void avCodec::GetCodecInfo(media_codec_info *mci)
{
sprintf(mci->short_name, "ff:%s", fCodec->name);
sprintf(mci->pretty_name, "%s (libavcodec %s)", gCodecTable[ffcodec_index_in_table].prettyname, fCodec->name);
}
status_t avCodec::Setup(media_format *input_format, const void *in_info, int32 in_size)
{
if (input_format->type != B_MEDIA_ENCODED_AUDIO && input_format->type != B_MEDIA_ENCODED_VIDEO)
return B_ERROR;
isAudio = (input_format->type == B_MEDIA_ENCODED_AUDIO);
if (isAudio)
fOutputBuffer = new char[100000];
#if DEBUG
char buffer[1024];
string_for_format(*input_format, buffer, sizeof(buffer));
PRINT(("[%c] input_format=%s\n", isAudio?('a'):('v'), buffer));
PRINT(("[%c] in_info_size=%ld\n", isAudio?('a'):('v'), in_size));
print_hex((uchar *)in_info, in_size);
PRINT(("[%c] user_data_type=%08lx\n", isAudio?('a'):('v'), input_format->user_data_type));
print_hex((uchar *)input_format->user_data, 48);
// PRINT(("[%c] meta_data_size=%ld\n", isAudio?('a'):('v'), input_format->meta_data_size));
#else
(void)(in_info);
(void)(in_size);
#endif
media_format_description descr;
for (int32 i = 0; gCodecTable[i].id; i++)
{
ffcodec_index_in_table = i;
uint32 cid;
if(BMediaFormats().GetCodeFor(*input_format,gCodecTable[i].family,&descr) == B_OK
&& gCodecTable[i].type == input_format->type)
{
PRINT((" codec id = \"%c%c%c%c\"\n", (descr.u.avi.codec >> 24) & 0xff,
(descr.u.avi.codec >> 16) & 0xff,
(descr.u.avi.codec >> 8) & 0xff,
descr.u.avi.codec & 0xff));
switch(gCodecTable[i].family) {
case B_WAV_FORMAT_FAMILY:
cid = descr.u.wav.codec;
break;
case B_AVI_FORMAT_FAMILY:
cid = descr.u.avi.codec;
break;
case B_MPEG_FORMAT_FAMILY:
cid = descr.u.mpeg.id;
break;
case B_QUICKTIME_FORMAT_FAMILY:
cid = descr.u.quicktime.codec;
break;
default:
puts("ERR family");
return B_ERROR;
}
if (gCodecTable[i].family == descr.family && gCodecTable[i].fourcc == cid) {
fCodec = avcodec_find_decoder(gCodecTable[i].id);
if (!fCodec) {
printf("avCodec: unable to find the correct ffmpeg decoder (id = %d)!!!\n",gCodecTable[i].id);
return B_ERROR;
}
// ffc->codec_id = gCodecTable[i].id;
if (gCodecTable[i].family == B_WAV_FORMAT_FAMILY) {
const wave_format_ex *wfmt_data = (const wave_format_ex *)input_format->MetaData();
int wfmt_size = input_format->MetaDataSize();
if (wfmt_data && wfmt_size) {
fBlockAlign = wfmt_data->block_align;
fExtraDataSize = wfmt_data->extra_size;
printf("############# fExtraDataSize %d\n", fExtraDataSize);
printf("############# fBlockAlign %d\n", fBlockAlign);
printf("############# wfmt_size %d\n", wfmt_size);
printf("############# wave_format_ex %ld\n", sizeof(wave_format_ex));
if (fExtraDataSize) {
fExtraData = new char [fExtraDataSize];
memcpy(fExtraData, wfmt_data + 1, fExtraDataSize);
uint8 *p = (uint8 *)fExtraData;
printf("extra_data: %d: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
fExtraDataSize, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]);
}
// static const unsigned char wma_extradata[6] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 };
// fExtraData = (void *)wma_extradata;
// fExtraDataSize = 6;
}
}
fInputFormat = *input_format;
return B_OK;
}
}
}
printf("avCodec::Setup failed!\n");
return B_ERROR;
}
status_t avCodec::Seek(uint32 in_towhat,int64 in_requiredFrame, int64 *inout_frame,
bigtime_t in_requiredTime, bigtime_t *inout_time)
{
// reset the ffmpeg codec
// to flush buffers, so we keep the sync
#ifdef CLOSE_ON_RESET
if (isAudio && fCodecInitDone)
{
fCodecInitDone = false;
avcodec_close(ffc);
fCodecInitDone = (avcodec_open(ffc, fCodec) >= 0);
fData = NULL;
fSize = 0LL;
fOffset = 0;
}
#endif /* CLOSE_ON_RESET */
fFrame = *inout_frame;
return B_OK;
}
status_t avCodec::NegotiateOutputFormat(media_format *inout_format)
{
// int ffPixelFmt;
enum PixelFormat ffPixelFmt;
PRINT(("[%c] avCodec::Format()\n", isAudio?('a'):('v')));
#if DEBUG
char buffer[1024];
string_for_format(*inout_format, buffer, sizeof(buffer));
PRINT(("[%c] in_format=%s\n", isAudio?('a'):('v'), buffer));
#endif
// close any previous instance
if (fCodecInitDone) {
fCodecInitDone = false;
avcodec_close(ffc);
}
if (isAudio) {
fOutputAudioFormat = media_raw_audio_format::wildcard;
fOutputAudioFormat.format = media_raw_audio_format::B_AUDIO_SHORT;
fOutputAudioFormat.byte_order = B_MEDIA_HOST_ENDIAN;
fOutputAudioFormat.frame_rate = fInputFormat.u.encoded_audio.output.frame_rate;
fOutputAudioFormat.channel_count = fInputFormat.u.encoded_audio.output.channel_count;
fOutputAudioFormat.buffer_size = 1024 * fInputFormat.u.encoded_audio.output.channel_count;
inout_format->type = B_MEDIA_RAW_AUDIO;
inout_format->u.raw_audio = fOutputAudioFormat;
ffc->bit_rate = (int) fInputFormat.u.encoded_audio.bit_rate;
ffc->sample_rate = (int) fInputFormat.u.encoded_audio.output.frame_rate;
ffc->channels = fInputFormat.u.encoded_audio.output.channel_count;
ffc->block_align = fBlockAlign;
ffc->extradata = fExtraData;
ffc->extradata_size = fExtraDataSize;
if (avcodec_open(ffc, fCodec) >= 0)
fCodecInitDone = true;
if (ffc->codec_id == CODEC_ID_WMAV1) {
printf("########################### WMA1\n");
}
if (ffc->codec_id == CODEC_ID_WMAV2) {
printf("########################### WMA2\n");
}
if (ffc->codec_id == CODEC_ID_MP2) {
printf("########################### MP3\n");
}
PRINT(("audio: bit_rate = %d, sample_rate = %d, chans = %d\n", ffc->bit_rate, ffc->sample_rate, ffc->channels));
fStartTime = 0;
fOutputFrameCount = fOutputAudioFormat.buffer_size / (2 * fOutputAudioFormat.channel_count);
fOutputFrameRate = fOutputAudioFormat.frame_rate;
fChunkBuffer = 0;
fChunkBufferOffset = 0;
fChunkBufferSize = 0;
fOutputBufferOffset = 0;
fOutputBufferSize = 0;
} else { // no AUDIO_CODEC
fOutputVideoFormat = fInputFormat.u.encoded_video.output;
ffc->width = fOutputVideoFormat.display.line_width;
ffc->height = fOutputVideoFormat.display.line_count;
ffc->frame_rate = (int)(fOutputVideoFormat.field_rate * ffc->frame_rate_base);
// make MediaPlayer happy (if not in rgb32 screen depth and no overlay,
// it will only ask for YCbCr, which DrawBitmap doesn't handle, so the default
// colordepth is RGB32)
if (inout_format->u.raw_video.display.format == B_YCbCr422)
fOutputVideoFormat.display.format = B_YCbCr422;
else
fOutputVideoFormat.display.format = B_RGB32;
// search for a pixel-format the codec handles
while (!fCodecInitDone)
{
// find the proper ff pixel format and the convertion func
conv_func = resolve_colorspace(fOutputVideoFormat.display.format, &ffPixelFmt);
PRINT(("ffc = %08lx, fCodec = %08lx, conv_func = %08lx\n", ffc, fCodec, conv_func));
if (!conv_func)
{
PRINT(("no conv_func (1) !\n"));
// return B_ERROR;
}
// ffc->pix_fmt = ffPixelFmt = 0; // DEBUG !!!
// ffc->pix_fmt =
// ffPixelFmt = PIX_FMT_YUV420P; // DEBUG !!!
// ffc->pix_fmt = ffPixelFmt = PIX_FMT_YUV420P; // DEBUG !!!
if (avcodec_open(ffc, fCodec) >= 0)
fCodecInitDone = true;
else
printf("avCodec: error in avcodec_open()\n");
conv_func = resolve_colorspace(fOutputVideoFormat.display.format, &ffc->pix_fmt);
PRINT(("ffc = %08lx, fCodec = %08lx, conv_func = %08lx, ffcolspace= %s\n", ffc, fCodec, conv_func, pixfmt_to_string(ffc->pix_fmt)));
if (!conv_func)
{
PRINT(("no conv_func (2) !\n"));
return B_ERROR;
}
PRINT(("PIXFMT: %s -> %s\n", pixfmt_to_string(ffPixelFmt), pixfmt_to_string(ffc->pix_fmt)));
}
if (fOutputVideoFormat.display.format == B_YCbCr422)
fOutputVideoFormat.display.bytes_per_row = 2 * fOutputVideoFormat.display.line_width;
else
fOutputVideoFormat.display.bytes_per_row = 4 * fOutputVideoFormat.display.line_width;
inout_format->type = B_MEDIA_RAW_VIDEO;
inout_format->u.raw_video = fOutputVideoFormat;
}
inout_format->require_flags = 0;
inout_format->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
#if DEBUG
string_for_format(*inout_format, buffer, sizeof(buffer));
PRINT(("[%c] out_format=%s\n", isAudio?('a'):('v'), buffer));
#endif
return B_OK;
}
status_t avCodec::Decode(void *out_buffer, int64 *out_frameCount, media_header *mh,
media_decode_info *info)
{
if (out_buffer == NULL || out_frameCount == NULL || mh == NULL || !fCodecInitDone)
return B_BAD_VALUE;
int len = 0;
int got_picture = 0;
#ifdef DO_PROFILING
bigtime_t prof_t1, prof_t2, prof_t3;
static bigtime_t diff1 = 0, diff2 = 0;
static long prof_cnt = 0;
#endif
#ifdef UNREAL
set_thread_priority(find_thread(NULL), B_NORMAL_PRIORITY);
#endif
PRINT(("[%c] avCodec::Decode()\n", isAudio?('a'):('v')));
#if DEBUG
// asm("int $0x0");
#endif
if (isAudio) {
mh->start_time = fStartTime;
printf("audio start_time %.6f\n", mh->start_time / 1000000.0);
char *output_buffer = (char *)out_buffer;
*out_frameCount = 0;
while (*out_frameCount < fOutputFrameCount) {
if (fOutputBufferSize < 0) {
printf("############ fOutputBufferSize %ld\n", fOutputBufferSize);
fOutputBufferSize = 0;
}
if (fChunkBufferSize < 0) {
printf("############ fChunkBufferSize %ld\n", fChunkBufferSize);
fChunkBufferSize = 0;
}
if (fOutputBufferSize > 0) {
int32 frames = min_c(fOutputFrameCount - *out_frameCount, fOutputBufferSize / 4);
memcpy(output_buffer, fOutputBuffer + fOutputBufferOffset, frames * 4);
fOutputBufferOffset += frames * 4;
fOutputBufferSize -= frames * 4;
output_buffer += frames * 4;
*out_frameCount += frames;
fStartTime += (bigtime_t)((1000000LL * frames) / fOutputFrameRate);
continue;
}
if (fChunkBufferSize == 0) {
media_header mh;
status_t err;
err = GetNextChunk((void **)&fChunkBuffer, &fChunkBufferSize, &mh);
if (err != B_OK || fChunkBufferSize < 0) {
printf("GetNextChunk error\n");
fChunkBufferSize = 0;
break;
}
fChunkBufferOffset = 0;
fStartTime = mh.start_time;
continue;
}
if (fOutputBufferSize == 0) {
int len, out_size;
len = avcodec_decode_audio(ffc, (short *)fOutputBuffer, &out_size, (uint8_t *)fChunkBuffer + fChunkBufferOffset, fChunkBufferSize);
if (len < 0) {
printf("########### audio decode error, fChunkBufferSize %ld, fChunkBufferOffset %ld\n", fChunkBufferSize, fChunkBufferOffset);
out_size = 0;
len = 0;
fChunkBufferOffset = 0;
fChunkBufferSize = 0;
} else
printf("audio decode: len %d, out_size %d\n", len, out_size);
fChunkBufferOffset += len;
fChunkBufferSize -= len;
fOutputBufferOffset = 0;
fOutputBufferSize = out_size;
}
}
} else { // no AUDIO_CODEC
// VIDEO
status_t err;
#ifdef DEBUG
//print_media_header(mh);
//print_media_decode_info(info);
#endif
mh->type = B_MEDIA_RAW_VIDEO;
// mh->start_time = (bigtime_t) (1000000.0 * fFrame / fOutputVideoFormat.field_rate);
mh->start_time = fHeader.start_time;
mh->file_pos = mh->orig_size = 0;
mh->u.raw_video.field_gamma = 1.0;
mh->u.raw_video.field_sequence = fFrame;
mh->u.raw_video.field_number = 0;
mh->u.raw_video.pulldown_number = 0;
mh->u.raw_video.first_active_line = 1;
mh->u.raw_video.line_count = fOutputVideoFormat.display.line_count;
/**/
PRINT(("[%c] start_time=%02d:%02d.%02d field_sequence=%u\n",
isAudio?('a'):('v'),
int((mh->start_time / 60000000) % 60),
int((mh->start_time / 1000000) % 60),
int((mh->start_time / 10000) % 100),
mh->u.raw_video.field_sequence));
/**/
fSize = 0L;
err = GetNextChunk(&fData, &fSize, &fHeader);
if (err != B_OK) {
PRINT(("avCodec::Decode(): error 0x%08lx from GetNextChunk()\n", err));
return B_ERROR;
}
PRINT(("avCodec::Decode(): passed GetNextChunk(), fSize=%ld\n", fSize));
#ifdef DEBUG
/*
puts("Chunk:");
for(i=0; i<2;i+=8) {
char *buff = (char *)fData;
printf("%08lX %08lX\t", *(long *)&buff[i], *(long *)&buff[i+4]);
printf("%c%c%c%c%c%c%c%c\n", (buff[i] & 0x7F), (buff[i+1] & 0x7F), (buff[i+2] & 0x7F), (buff[i+3] & 0x7F), (buff[i+4] & 0x7F), (buff[i+5] & 0x7F), (buff[i+6] & 0x7F), (buff[i+7] & 0x7F));
}
*/
#endif
// mmu_man 11/15/2002
//ffc->frame_number = fFrame;
#ifdef DO_PROFILING
prof_t1 = system_time();
#endif
// PRINT(("avCodec::Decode(): before avcodec_decode_video()\n"));
// len = avcodec_decode_video(ffc, &ffpicture, &got_picture, (uint8_t *)fData, fSize);
len = avcodec_decode_video(ffc, ffpicture, &got_picture, (uint8_t *)fData, fSize);
// PRINT(("avCodec::Decode(): after avcodec_decode_video()\n"));
//printf("FFDEC: PTS = %d:%d:%d.%d - ffc->frame_number = %ld ffc->frame_rate = %ld\n", (int)(ffc->pts / (60*60*1000000)), (int)(ffc->pts / (60*1000000)), (int)(ffc->pts / (1000000)), (int)(ffc->pts % 1000000), ffc->frame_number, ffc->frame_rate);
//printf("FFDEC: PTS = %d:%d:%d.%d - ffc->frame_number = %ld ffc->frame_rate = %ld\n", (int)(ffpicture->pts / (60*60*1000000)), (int)(ffpicture->pts / (60*1000000)), (int)(ffpicture->pts / (1000000)), (int)(ffpicture->pts % 1000000), ffc->frame_number, ffc->frame_rate);
if (len < 0)
printf("[%c] avCodec: error in decoding frame %lld\n", isAudio?('a'):('v'), *out_frameCount);
if (got_picture)
{
#ifdef DO_PROFILING
prof_t2 = system_time();
#endif
PRINT(("ONE FRAME OUT !! len=%ld sz=%ld (%s)\n", len, fSize, pixfmt_to_string(ffc->pix_fmt)));
/*
opicture.data[0] = (uint8_t *)out_buffer;
opicture.linesize[0] = fOutputVideoFormat.display.bytes_per_row;
(*conv_func)(&ffpicture, &opicture, fOutputVideoFormat.display.line_width, fOutputVideoFormat.display.line_count);
*/
opicture->data[0] = (uint8_t *)out_buffer;
opicture->linesize[0] = fOutputVideoFormat.display.bytes_per_row;
// PRINT(("avCodec::Decode(): before conv_func()\n"));
(*conv_func)(ffpicture, opicture, fOutputVideoFormat.display.line_width, fOutputVideoFormat.display.line_count);
// PRINT(("avCodec::Decode(): after conv_func()\n"));
#ifdef DEBUG
dump_ffframe(ffpicture, "ffpict");
// dump_ffframe(opicture, "opict");
#endif
*out_frameCount = 1;
fFrame++;
#ifdef DO_PROFILING
prof_t3 = system_time();
diff1 += prof_t2 - prof_t1;
diff2 += prof_t3 - prof_t2;
prof_cnt++;
if (!(fFrame % 10))
printf("[%c] profile: d1 = %lld, d2 = %lld (%ld)\n", isAudio?('a'):('v'), diff1/prof_cnt, diff2/prof_cnt, fFrame);
#endif
}
}
// PRINT(("END of avCodec::Decode()\n"));
return B_OK;
}
status_t
avCodecPlugin::GetSupportedFormats(media_format ** formats, size_t * count)
{
BMediaFormats mediaFormats;
if (B_OK != mediaFormats.InitCheck())
return B_ERROR;
for (int i = 0; i < num_codecs; i++) {
media_format_description description;
description.family = gCodecTable[i].family;
switch(description.family) {
case B_WAV_FORMAT_FAMILY:
description.u.wav.codec = gCodecTable[i].fourcc;
break;
case B_AVI_FORMAT_FAMILY:
description.u.avi.codec = gCodecTable[i].fourcc;
break;
case B_MPEG_FORMAT_FAMILY:
description.u.mpeg.id = gCodecTable[i].fourcc;
break;
case B_QUICKTIME_FORMAT_FAMILY:
description.u.quicktime.codec = gCodecTable[i].fourcc;
break;
default:
break;
}
media_format format;
format.type = gCodecTable[i].type;
format.require_flags = 0;
format.deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
if (B_OK != mediaFormats.MakeFormatFor(&description, 1, &format))
return B_ERROR;
avcodec_formats[i] = format;
}
*formats = avcodec_formats;
*count = num_codecs;
return B_OK;
}
Decoder *
avCodecPlugin::NewDecoder(uint index)
{
return new avCodec();
}
MediaPlugin *instantiate_plugin()
{
return new avCodecPlugin;
}

View File

@ -330,7 +330,7 @@ mp3Decoder::GetFrameLength(void *header)
Decoder *
mp3DecoderPlugin::NewDecoder()
mp3DecoderPlugin::NewDecoder(uint index)
{
static BLocker locker;
static bool initdone = false;
@ -344,8 +344,10 @@ mp3DecoderPlugin::NewDecoder()
}
static media_format mp3_formats[1];
status_t
mp3DecoderPlugin::RegisterDecoder()
mp3DecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count)
{
const mpeg_id ids[] = {
B_MPEG_1_AUDIO_LAYER_1,
@ -374,12 +376,21 @@ mp3DecoderPlugin::RegisterDecoder()
format.type = B_MEDIA_ENCODED_AUDIO;
format.u.encoded_audio = media_encoded_audio_format::wildcard;
BMediaFormats formats;
status_t result = formats.InitCheck();
BMediaFormats mediaFormats;
status_t result = mediaFormats.InitCheck();
if (result != B_OK) {
return result;
}
return formats.MakeFormatFor(descriptions, numIDs, &format);
result = mediaFormats.MakeFormatFor(descriptions, numIDs, &format);
if (result != B_OK) {
return result;
}
mp3_formats[0] = format;
*formats = mp3_formats;
*count = 1;
return result;
}

View File

@ -46,6 +46,6 @@ private:
class mp3DecoderPlugin : public DecoderPlugin
{
public:
Decoder * NewDecoder();
status_t RegisterDecoder();
Decoder * NewDecoder(uint index);
status_t GetSupportedFormats(media_format ** formats, size_t * count);
};

View File

@ -16,13 +16,15 @@ MusePackPlugin::NewReader()
}
Decoder *
MusePackPlugin::NewDecoder()
MusePackPlugin::NewDecoder(uint index)
{
return new MusePackDecoder();
}
static media_format muse_pack_formats[1];
status_t
MusePackPlugin::RegisterDecoder()
MusePackPlugin::GetSupportedFormats(media_format ** formats, size_t * count)
{
media_format_description description;
description.family = B_MISC_FORMAT_FAMILY;
@ -34,7 +36,21 @@ MusePackPlugin::RegisterDecoder()
format.type = B_MEDIA_ENCODED_AUDIO;
format.u.encoded_audio = media_encoded_audio_format::wildcard;
return BMediaFormats().MakeFormatFor(&description, 1, &format);
BMediaFormats mediaFormats;
status_t result = mediaFormats.InitCheck();
if (result != B_OK) {
return result;
}
result = mediaFormats.MakeFormatFor(&description, 1, &format);
if (result != B_OK) {
return result;
}
muse_pack_formats[0] = format;
*formats = muse_pack_formats;
*count = 1;
return B_OK;
}

View File

@ -14,8 +14,8 @@ class MusePackPlugin : public ReaderPlugin, public DecoderPlugin {
public:
Reader *NewReader();
Decoder *NewDecoder();
status_t RegisterDecoder();
Decoder * NewDecoder(uint index);
status_t GetSupportedFormats(media_format ** formats, size_t * count);
};
#endif /* MUSEPACK_PLUGIN_H */

View File

@ -106,8 +106,8 @@ OggTobiasStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
// get the format for the description
media_format_description description = tobias_description();
description.u.avi.codec = header->subtype[0] << 24 | header->subtype[1] << 16
| header->subtype[2] << 8 | header->subtype[3];
description.u.avi.codec = header->subtype[3] << 24 | header->subtype[2] << 16
| header->subtype[1] << 8 | header->subtype[0];
BMediaFormats formats;
result = formats.InitCheck();
if (result == B_OK) {
@ -141,3 +141,13 @@ OggTobiasStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
*frameCount = 60000;
return B_OK;
}
status_t
OggTobiasStream::GetNextChunk(void **chunkBuffer, int32 *chunkSize,
media_header *mediaHeader)
{
OggStream::GetNextChunk(chunkBuffer, chunkSize, mediaHeader);
*chunkSize = ((ogg_packet*)chunkBuffer)->bytes;
*chunkBuffer = ((ogg_packet*)chunkBuffer)->packet;
return B_OK;
}

View File

@ -14,6 +14,11 @@ public:
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
media_format *format);
virtual status_t GetNextChunk(void **chunkBuffer, int32 *chunkSize,
media_header *mediaHeader);
private:
ogg_packet fChunkPacket;
};
} } // namespace BPrivate::media

View File

@ -478,15 +478,18 @@ RawDecoder::Decode(void *buffer, int64 *frameCount,
Decoder *
RawDecoderPlugin::NewDecoder()
RawDecoderPlugin::NewDecoder(uint index)
{
return new RawDecoder;
}
static media_format raw_formats[2];
status_t
RawDecoderPlugin::RegisterDecoder()
RawDecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count)
{
BMediaFormats formats;
BMediaFormats mediaFormats;
media_format_description description;
media_format format;
@ -497,9 +500,10 @@ RawDecoderPlugin::RegisterDecoder()
format.type = B_MEDIA_RAW_AUDIO;
format.u.raw_audio = media_multi_audio_format::wildcard;
status_t status = formats.MakeFormatFor(&description, 1, &format);
status_t status = mediaFormats.MakeFormatFor(&description, 1, &format);
if (status < B_OK)
return status;
raw_formats[0] = format;
// video decoder
@ -507,7 +511,15 @@ RawDecoderPlugin::RegisterDecoder()
format.type = B_MEDIA_RAW_VIDEO;
format.u.raw_video = media_raw_video_format::wildcard;
return formats.MakeFormatFor(&description, 1, &format);
status = mediaFormats.MakeFormatFor(&description, 1, &format);
if (status < B_OK)
return status;
raw_formats[1] = format;
*formats = raw_formats;
*count = 2;
return B_OK;
}
MediaPlugin *instantiate_plugin()

View File

@ -44,6 +44,6 @@ private:
class RawDecoderPlugin : public DecoderPlugin
{
public:
Decoder * NewDecoder();
status_t RegisterDecoder();
Decoder * NewDecoder(uint index);
status_t GetSupportedFormats(media_format ** formats, size_t * count);
};

View File

@ -315,7 +315,7 @@ done:
Decoder *
SpeexDecoderPlugin::NewDecoder()
SpeexDecoderPlugin::NewDecoder(uint index)
{
static BLocker locker;
static bool initdone = false;
@ -327,18 +327,29 @@ SpeexDecoderPlugin::NewDecoder()
}
static media_format speex_formats[1];
status_t
SpeexDecoderPlugin::RegisterDecoder()
SpeexDecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count)
{
media_format_description description = speex_description();
media_format format = speex_encoded_media_format();
BMediaFormats formats;
status_t result = formats.InitCheck();
BMediaFormats mediaFormats;
status_t result = mediaFormats.InitCheck();
if (result != B_OK) {
return result;
}
return formats.MakeFormatFor(&description, 1, &format);
result = mediaFormats.MakeFormatFor(&description, 1, &format);
if (result != B_OK) {
return result;
}
speex_formats[0] = format;
*formats = speex_formats;
*count = 1;
return result;
}

View File

@ -41,6 +41,6 @@ private:
class SpeexDecoderPlugin : public DecoderPlugin
{
public:
Decoder * NewDecoder();
status_t RegisterDecoder();
Decoder * NewDecoder(uint index);
status_t GetSupportedFormats(media_format ** formats, size_t * count);
};

View File

@ -246,7 +246,7 @@ done:
Decoder *
VorbisDecoderPlugin::NewDecoder()
VorbisDecoderPlugin::NewDecoder(uint index)
{
static BLocker locker;
static bool initdone = false;
@ -257,18 +257,29 @@ VorbisDecoderPlugin::NewDecoder()
return new VorbisDecoder;
}
static media_format vorbis_formats[1];
status_t
VorbisDecoderPlugin::RegisterDecoder()
VorbisDecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count)
{
media_format_description description = vorbis_description();
media_format format = vorbis_encoded_media_format();
BMediaFormats formats;
status_t result = formats.InitCheck();
BMediaFormats mediaFormats;
status_t result = mediaFormats.InitCheck();
if (result != B_OK) {
return result;
}
return formats.MakeFormatFor(&description, 1, &format);
result = mediaFormats.MakeFormatFor(&description, 1, &format);
if (result != B_OK) {
return result;
}
vorbis_formats[0] = format;
*formats = vorbis_formats;
*count = 1;
return result;
}

View File

@ -39,8 +39,8 @@ private:
class VorbisDecoderPlugin : public DecoderPlugin
{
public:
Decoder * NewDecoder();
status_t RegisterDecoder();
Decoder * NewDecoder(uint index);
status_t GetSupportedFormats(media_format ** formats, size_t * count);
};
#endif _VORBIS_CODEC_PLUGIN_H_

View File

@ -29,12 +29,17 @@ static port_id MediaAddonServerPort;
void find_media_server_port();
void find_media_addon_server_port();
static BMessenger * GetMediaServerMessenger() {
static BMessenger * messenger = new BMessenger(NEW_MEDIA_SERVER_SIGNATURE);
return MediaServerMessenger = messenger;
}
class initit
{
public:
initit()
{
MediaServerMessenger = new BMessenger(NEW_MEDIA_SERVER_SIGNATURE);
MediaServerMessenger = 0;
find_media_server_port();
find_media_addon_server_port();
@ -82,7 +87,7 @@ request_data::SendReply(status_t result, reply_data *reply, int replysize) const
status_t SendToServer(BMessage *msg)
{
status_t rv;
rv = MediaServerMessenger->SendMessage(msg, static_cast<BHandler *>(NULL), TIMEOUT);
rv = GetMediaServerMessenger()->SendMessage(msg, static_cast<BHandler *>(NULL), TIMEOUT);
if (rv != B_OK) {
ERROR("SendToServer: SendMessage failed, error 0x%08lx (%s)\n", rv, strerror(rv));
DEBUG_ONLY(msg->PrintToStream());
@ -94,7 +99,7 @@ status_t SendToServer(BMessage *msg)
status_t
QueryServer(BMessage &request, BMessage &reply)
{
status_t status = MediaServerMessenger->SendMessage(&request, &reply, TIMEOUT, TIMEOUT);
status_t status = GetMediaServerMessenger()->SendMessage(&request, &reply, TIMEOUT, TIMEOUT);
if (status != B_OK) {
ERROR("QueryServer: SendMessage failed, error 0x%08lx (%s)\n", status, strerror(status));
DEBUG_ONLY(request.PrintToStream());

View File

@ -125,7 +125,7 @@ BMediaDecoder::SetTo(const media_format *in_format,
if (plugin == NULL) {
return fInitStatus = B_ERROR;
}
Decoder * decoder = plugin->NewDecoder();
Decoder * decoder = plugin->NewDecoder(0);
if (decoder == NULL) {
return fInitStatus = B_ERROR;
}
@ -163,7 +163,7 @@ BMediaDecoder::SetTo(const media_codec_info *mci)
if (plugin == NULL) {
return fInitStatus = B_ERROR;
}
Decoder * decoder = plugin->NewDecoder();
Decoder * decoder = plugin->NewDecoder(0);
if (decoder == NULL) {
return fInitStatus = B_ERROR;
}

View File

@ -24,8 +24,6 @@ static BLocker sLock;
static BObjectList<meta_format> sFormats;
static bigtime_t sLastFormatsUpdate;
_MakeFormatHookFunc BPrivate::media::_gMakeFormatHook = NULL;
status_t
get_next_encoder(int32 *cookie, const media_file_format *_fileFormat,
@ -515,14 +513,43 @@ status_t
BMediaFormats::MakeFormatFor(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags, void * _reserved)
{
if (_gMakeFormatHook == NULL)
return B_NOT_ALLOWED;
BMessage request(MEDIA_SERVER_MAKE_FORMAT_FOR);
for (int32 i = 0 ; i < descriptionCount ; i++) {
request.AddData("description", B_RAW_TYPE, &descriptions[i], sizeof(descriptions[i]));
}
request.AddData("format", B_RAW_TYPE, format, sizeof(*format));
request.AddData("flags", B_UINT32_TYPE, &flags, sizeof(flags));
request.AddPointer("_reserved", _reserved);
BMessage reply;
status_t status = QueryServer(request, reply);
if (status != B_OK) {
ERROR("BMediaFormats: Could not make a format: %s\n", strerror(status));
return status;
}
// This function is callable from the server in the
// context of a codec registration only.
// The add-on manager is locked during this call
// check the status
if (reply.FindInt32("result", &status) < B_OK) {
return B_ERROR;
}
if (status != B_OK) {
return status;
}
return _gMakeFormatHook(descriptions, descriptionCount, format, flags);
// get the format
const void * data;
ssize_t size;
if (reply.FindData("format", B_RAW_TYPE, 0, &data, &size) != B_OK) {
return B_ERROR;
}
if (size != sizeof(*format)) {
return B_ERROR;
}
// copy the BMessage's data into our format
*format = *(media_format *)data;
return B_OK;
}
/* --- begin deprecated API --- */

View File

@ -100,7 +100,7 @@ _CreateDecoder(Decoder **_decoder, const media_format *format)
return B_ERROR;
}
*_decoder = decoderPlugin->NewDecoder();
*_decoder = decoderPlugin->NewDecoder(0);
if (*_decoder == NULL) {
printf("_CreateDecoder: NewDecoder() failed\n");
return B_ERROR;

View File

@ -31,6 +31,14 @@ AddOnMonitorHandler::MessageReceived(BMessage * msg)
/* virtual */ status_t
AddOnMonitorHandler::AddDirectory(const node_ref * nref)
{
// ignore directories added twice
std::list<add_on_directory_info>::iterator diter = directories.begin();
for( ; diter != directories.end() ; diter++) {
if (diter->nref == *nref) {
return B_OK;
}
}
BDirectory directory(nref);
status_t status = directory.InitCheck();
if (status != B_OK) {

View File

@ -50,22 +50,6 @@ class ImageLoader {
};
static status_t
register_decoder(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags)
{
return gAddOnManager->MakeDecoderFormats(descriptions, descriptionCount, format, flags);
}
/* not yet used
static status_t
register_encoder(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags)
{
return gAddOnManager->MakeEncoderFormats(descriptions, descriptionCount, format, flags);
}
*/
// #pragma mark -
@ -190,47 +174,62 @@ AddOnManager::RegisterAddOn(BEntry &entry)
RegisterDecoder(decoder, ref);
delete plugin;
}
void
AddOnManager::RegisterAddOnsFor(BPath path)
{
path.Append("media/plugins");
BDirectory directory(path.Path());
if (directory.InitCheck() != B_OK)
return;
BEntry entry;
while (directory.GetNextEntry(&entry) == B_OK)
RegisterAddOn(entry);
return B_OK;
}
void
AddOnManager::RegisterAddOns()
{
BPath path;
// user add-ons come first, so that they can lay over system
// add-ons (add-ons are identified by name for registration)
class CodecHandler : public AddOnMonitorHandler {
private:
AddOnManager * fManager;
public:
CodecHandler(AddOnManager * manager) {
fManager = manager;
}
virtual void AddOnCreated(const add_on_entry_info * entry_info) {
}
virtual void AddOnEnabled(const add_on_entry_info * entry_info) {
entry_ref ref;
make_entry_ref(entry_info->dir_nref.device, entry_info->dir_nref.node,
entry_info->name, &ref);
BEntry entry(&ref, true);
fManager->RegisterAddOn(entry);
}
virtual void AddOnDisabled(const add_on_entry_info * entry_info) {
}
virtual void AddOnRemoved(const add_on_entry_info * entry_info) {
}
};
const directory_which directories[] = {
B_USER_ADDONS_DIRECTORY,
B_COMMON_ADDONS_DIRECTORY,
B_BEOS_ADDONS_DIRECTORY,
};
fHandler = new CodecHandler(this);
fAddOnMonitor = new AddOnMonitor(fHandler);
for (uint32 i = 0; i < sizeof(directories) / sizeof(directory_which); i++) {
if (find_directory(directories[i], &path) == B_OK)
RegisterAddOnsFor(path);
node_ref nref;
BDirectory directory;
BPath path;
for (uint i = 0 ; i < sizeof(directories) / sizeof(directory_which) ; i++) {
if ((find_directory(directories[i], &path) == B_OK)
&& (path.Append("media/plugins") == B_OK)
&& (directory.SetTo(path.Path()) == B_OK)
&& (directory.GetNodeRef(&nref) == B_OK)) {
fHandler->AddDirectory(&nref);
}
}
// ToDo: this is for our own convenience only, and should be removed
// in the final release
path.SetTo("/boot/home/develop/openbeos/current/distro/x86.R1/beos/system/add-ons");
RegisterAddOnsFor(path);
if ((directory.SetTo("/boot/home/develop/openbeos/current/distro/x86.R1/beos/system/add-ons/media/plugins") == B_OK)
&& (directory.GetNodeRef(&nref) == B_OK)) {
fHandler->AddDirectory(&nref);
}
}
@ -257,7 +256,7 @@ AddOnManager::RegisterReader(ReaderPlugin *reader, const entry_ref &ref)
void
AddOnManager::RegisterDecoder(DecoderPlugin *decoder, const entry_ref &ref)
AddOnManager::RegisterDecoder(DecoderPlugin *plugin, const entry_ref &ref)
{
BAutolock locker(fLock);
@ -274,48 +273,16 @@ AddOnManager::RegisterDecoder(DecoderPlugin *decoder, const entry_ref &ref)
decoder_info info;
info.ref = ref;
fCurrentDecoder = &info;
BPrivate::media::_gMakeFormatHook = register_decoder;
if (decoder->RegisterDecoder() != B_OK) {
printf("AddOnManager::RegisterDecoder(): decoder->RegisterDecoder() failed!\n");
media_format * formats = 0;
size_t count = 0;
if (plugin->GetSupportedFormats(&formats,&count) != B_OK) {
printf("AddOnManager::RegisterDecoder(): plugin->GetSupportedFormats(...) failed!\n");
return;
}
for (uint i = 0 ; i < count ; i++) {
info.formats.Insert(formats[i]);
}
fDecoderList.Insert(info);
fCurrentDecoder = NULL;
BPrivate::media::_gMakeFormatHook = NULL;
}
status_t
AddOnManager::MakeEncoderFormats(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags)
{
//ASSERT(fCurrentEncoder != NULL);
status_t status = gFormatManager->RegisterEncoder(descriptions,
descriptionCount, format, flags);
if (status < B_OK)
return status;
//fCurrentEncoder->format = *format;
return B_OK;
}
status_t
AddOnManager::MakeDecoderFormats(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags)
{
ASSERT(fCurrentDecoder != NULL);
status_t status = gFormatManager->RegisterDecoder(descriptions,
descriptionCount, format, flags);
if (status < B_OK)
return status;
fCurrentDecoder->formats.Insert(*format);
return B_OK;
}

View File

@ -15,6 +15,8 @@
#include "DataExchange.h"
#include "TList.h"
#include "AddOnMonitor.h"
#include "AddOnMonitorHandler.h"
class AddOnManager {
public:
@ -30,14 +32,8 @@ class AddOnManager {
status_t GetReaders(xfer_entry_ref *out_res, int32 *out_count,
int32 max_count);
status_t MakeEncoderFormats(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags);
status_t MakeDecoderFormats(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags);
private:
status_t RegisterAddOn(BEntry &entry);
void RegisterAddOnsFor(BPath path);
void RegisterAddOns();
void RegisterReader(ReaderPlugin *reader, const entry_ref &ref);
@ -65,6 +61,9 @@ class AddOnManager {
List<encoder_info> fEncoderList;
decoder_info *fCurrentDecoder;
AddOnMonitorHandler *fHandler;
AddOnMonitor *fAddOnMonitor;
};
#endif // _ADD_ON_MANAGER_H

View File

@ -77,74 +77,82 @@ FormatManager::GetFormats(BMessage &message)
}
status_t
FormatManager::RegisterDecoder(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags)
{
return RegisterDescriptions(descriptions, descriptionCount, format, flags, false);
}
status_t
FormatManager::RegisterEncoder(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags)
{
return RegisterDescriptions(descriptions, descriptionCount, format, flags, true);
}
status_t
FormatManager::RegisterDescriptions(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags, bool encoder)
void
FormatManager::MakeFormatFor(BMessage &message)
{
BAutolock locker(fLock);
int32 codec = fNextCodecID++;
fLastUpdate = system_time();
media_format format;
const void * data;
ssize_t size;
if (message.FindData("format", B_RAW_TYPE, 0, &data, &size) != B_OK
|| size != sizeof(format)) {
// couldn't get the format
BMessage reply;
reply.AddInt32("result", B_ERROR);
message.SendReply(&reply, (BHandler *)NULL, TIMEOUT);
return;
}
// copy the BMessage's data into our format
format = *(media_format *)data;
switch (format->type) {
int codec = fNextCodecID;
switch (format.type) {
case B_MEDIA_RAW_AUDIO:
case B_MEDIA_RAW_VIDEO:
// no marker
break;
case B_MEDIA_ENCODED_AUDIO:
format->u.encoded_audio.encoding = (media_encoded_audio_format::audio_encoding)codec;
if (format.u.encoded_audio.encoding == 0) {
format.u.encoded_audio.encoding = (media_encoded_audio_format::audio_encoding)fNextCodecID++;
} else {
UNIMPLEMENTED();
// TODO: check the encoding and the format passed in for compatibility
// return B_MISMATCHED_VALUES if incompatible - perhaps something else based on flags?
}
break;
case B_MEDIA_ENCODED_VIDEO:
format->u.encoded_video.encoding = (media_encoded_video_format::video_encoding)codec;
if (format.u.encoded_video.encoding == 0) {
format.u.encoded_video.encoding = (media_encoded_video_format::video_encoding)fNextCodecID++;
} else {
UNIMPLEMENTED();
// TODO: check the encoding and the format passed in for compatibility
// return B_MISMATCHED_VALUES if incompatible - perhaps something else based on flags?
}
break;
case B_MEDIA_MULTISTREAM:
format->u.multistream.format = codec;
if (format.u.multistream.format == 0) {
format.u.multistream.format = fNextCodecID++;
} else {
UNIMPLEMENTED();
// TODO: check the encoding and the format passed in for compatibility
// return B_MISMATCHED_VALUES if incompatible - perhaps something else based on flags?
}
break;
default:
// ToDo: what can we do for the raw formats?
break;
// nothing to do
BMessage reply;
reply.AddInt32("result", B_OK);
reply.AddData("format", B_RAW_TYPE, &format, sizeof(format));
message.SendReply(&reply, (BHandler *)NULL, TIMEOUT);
return;
}
fLastUpdate = system_time();
// ToDo: support "flags" (B_SET_DEFAULT, B_EXCLUSIVE, B_NO_MERGE)!
for (int32 i = 0; i < descriptionCount; i++) {
meta_format *metaFormat = new meta_format(descriptions[i], *format, codec);
if (encoder)
fEncoderFormats.BinaryInsert(metaFormat, meta_format::Compare);
else
fDecoderFormats.BinaryInsert(metaFormat, meta_format::Compare);
int32 i = 0;
while (message.FindData("description", B_RAW_TYPE, i++, &data, &size) == B_OK
&& size == sizeof(media_format_description)) {
meta_format *metaFormat = new meta_format(*(media_format_description*)data, format, codec);
fList.BinaryInsert(metaFormat, meta_format::Compare);
}
return B_OK;
}
void
FormatManager::UnregisterDecoder(media_format &format)
{
UNIMPLEMENTED();
}
void
FormatManager::UnregisterEncoder(media_format &format)
{
UNIMPLEMENTED();
BMessage reply;
reply.AddInt32("result", B_OK);
reply.AddData("format", B_RAW_TYPE, &format, sizeof(format));
message.SendReply(&reply, (BHandler *)NULL, TIMEOUT);
return;
}

View File

@ -17,25 +17,11 @@ class FormatManager {
void SaveState();
void GetFormats(BMessage &message);
status_t RegisterDecoder(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags);
status_t RegisterEncoder(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags);
void UnregisterDecoder(media_format &format);
void UnregisterEncoder(media_format &format);
private:
status_t RegisterDescriptions(const media_format_description *descriptions,
int32 descriptionCount, media_format *format, uint32 flags,
bool encoder);
void MakeFormatFor(BMessage &message);
private:
typedef BPrivate::media::meta_format meta_format;
BObjectList<meta_format> fDecoderFormats;
BObjectList<meta_format> fEncoderFormats;
BObjectList<meta_format> fList;
BLocker fLock;
bigtime_t fLastUpdate;

View File

@ -2,6 +2,7 @@ SubDir OBOS_TOP src servers media ;
UsePrivateHeaders media ;
UsePrivateHeaders shared ;
UsePrivateHeaders storage ;
AddResources media_server : media_server.rdef ;
@ -16,5 +17,14 @@ Server media_server :
NodeManager.cpp
NotificationManager.cpp
Queue.cpp
# storage
AddOnMonitor.cpp
AddOnMonitorHandler.cpp
NodeMonitorHandler.cpp
;
LinkSharedOSLibs media_server : be libmedia.so ;
SEARCH on [ FGristFiles AddOnMonitor.cpp
AddOnMonitorHandler.cpp
NodeMonitorHandler.cpp ] += [ FDirName $(SUBDIR) .. .. kits storage ] ;

View File

@ -112,6 +112,7 @@ private:
BLocker *fLocker;
virtual void MessageReceived(BMessage *msg);
virtual void ReadyToRun();
typedef BApplication inherited;
};
@ -134,8 +135,13 @@ ServerApp::ServerApp()
// StartSystemTimeSource();
gNodeManager->LoadState();
gFormatManager->LoadState();
gAddOnManager->LoadState();
gAppManager->StartAddonServer();
}
void ServerApp::ReadyToRun()
{
be_app_messenger.SendMessage(MEDIA_SERVER_READY);
}
ServerApp::~ServerApp()
@ -726,6 +732,11 @@ ServerApp::MessageReceived(BMessage *msg)
{
TRACE("ServerApp::MessageReceived %lx enter\n", msg->what);
switch (msg->what) {
case MEDIA_SERVER_READY:
gAppManager->StartAddonServer();
gAddOnManager->LoadState();
break;
case MEDIA_SERVER_REQUEST_NOTIFICATIONS:
case MEDIA_SERVER_CANCEL_NOTIFICATIONS:
case MEDIA_SERVER_SEND_NOTIFICATIONS:
@ -740,6 +751,10 @@ ServerApp::MessageReceived(BMessage *msg)
gFormatManager->GetFormats(*msg);
break;
case MEDIA_SERVER_MAKE_FORMAT_FOR:
gFormatManager->MakeFormatFor(*msg);
break;
default:
inherited::MessageReceived(msg);
//printf("\nnew media server: unknown message received\n");