initial (non-working) commit

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1096 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty 2002-09-20 05:53:23 +00:00
parent 4cdc6c141b
commit d5525d8c93
7 changed files with 2033 additions and 0 deletions

View File

@ -0,0 +1,11 @@
SubDir OBOS_TOP src add-ons media media-add-ons demultiplexer ;
UsePrivateHeaders demultiplexer ;
Addon demultiplexer.media_addon : media :
MediaDemultiplexerNode.cpp
MediaDemultiplexerAddOn.cpp
misc.cpp
;
LinkSharedOSLibs demultiplexer.media_addon : be media ;

View File

@ -0,0 +1,84 @@
// MediaDemultiplexerAddOn.h
//
// Andrew Bachmann, 2002
//
// MediaDemultiplexerAddOn is an add-on
// that can make instances of MediaDemultiplexerNode
//
// MediaDemultiplexerNode handles a file and a multistream
#if !defined(_MEDIA_DEMULTIPLEXER_ADD_ON_H)
#define _MEDIA_DEMULTIPLEXER_ADD_ON_H
#include <MediaDefs.h>
#include <MediaAddOn.h>
class MediaDemultiplexerAddOn :
public BMediaAddOn
{
public:
virtual ~MediaDemultiplexerAddOn(void);
explicit MediaDemultiplexerAddOn(image_id image);
/**************************/
/* begin from BMediaAddOn */
public:
virtual status_t InitCheck(
const char ** out_failure_text);
virtual int32 CountFlavors(void);
virtual status_t GetFlavorAt(
int32 n,
const flavor_info ** out_info);
virtual BMediaNode * InstantiateNodeFor(
const flavor_info * info,
BMessage * config,
status_t * out_error);
virtual status_t GetConfigurationFor(
BMediaNode * your_node,
BMessage * into_message);
virtual bool WantsAutoStart(void);
virtual status_t AutoStart(
int in_count,
BMediaNode ** out_node,
int32 * out_internal_id,
bool * out_has_more);
/* end from BMediaAddOn */
/************************/
private:
MediaDemultiplexerAddOn( /* private unimplemented */
const MediaDemultiplexerAddOn & clone);
MediaDemultiplexerAddOn & operator=(
const MediaDemultiplexerAddOn & clone);
int32 refCount;
/* Mmmh, stuffing! */
virtual status_t _Reserved_MediaDemultiplexerAddOn_0(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_1(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_2(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_3(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_4(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_5(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_6(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_7(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_8(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_9(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_10(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_11(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_12(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_13(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_14(void *);
virtual status_t _Reserved_MediaDemultiplexerAddOn_15(void *);
uint32 _reserved_media_demultiplexer_add_on_[16];
};
#if BUILDING_MEDIA_DEMULTIPLEXER__ADD_ON
extern "C" _EXPORT BMediaAddOn * make_media_demultiplexer_add_on(image_id you);
#endif
#endif /* _MEDIA_DEMULTIPLEXER_ADD_ON_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,375 @@
// MediaDemultiplexerNode.h
//
// Andrew Bachmann, 2002
//
// The MediaDemultiplexerNode class
// takes a multistream input and supplies
// the individual constituent streams as
// the output.
#if !defined(_MEDIA_DEMULTIPLEXER_NODE_H)
#define _MEDIA_DEMULTIPLEXER_NODE_H
#include <MediaDefs.h>
#include <MediaNode.h>
#include <BufferConsumer.h>
#include <BufferProducer.h>
#include <MediaEventLooper.h>
#include <BufferGroup.h>
#include <vector>
#include "MediaOutputInfo.h"
class MediaDemultiplexerNode :
public BBufferConsumer,
public BBufferProducer,
public BMediaEventLooper
{
protected:
virtual ~MediaDemultiplexerNode(void);
public:
explicit MediaDemultiplexerNode(
const flavor_info * info = 0,
BMessage * config = 0,
BMediaAddOn * addOn = 0);
virtual status_t InitCheck(void) const;
// see BMediaAddOn::GetConfigurationFor
virtual status_t GetConfigurationFor(
BMessage * into_message);
/*************************/
/* begin from BMediaNode */
public:
// /* this port is what a media node listens to for commands */
// virtual port_id ControlPort(void) const;
virtual BMediaAddOn* AddOn(
int32 * internal_id) const; /* Who instantiated you -- or NULL for app class */
protected:
/* These don't return errors; instead, they use the global error condition reporter. */
/* A node is required to have a queue of at least one pending command (plus TimeWarp) */
/* and is recommended to allow for at least one pending command of each type. */
/* Allowing an arbitrary number of outstanding commands might be nice, but apps */
/* cannot depend on that happening. */
virtual void Start(
bigtime_t performance_time);
virtual void Stop(
bigtime_t performance_time,
bool immediate);
virtual void Seek(
bigtime_t media_time,
bigtime_t performance_time);
virtual void SetRunMode(
run_mode mode);
virtual void TimeWarp(
bigtime_t at_real_time,
bigtime_t to_performance_time);
virtual void Preroll(void);
virtual void SetTimeSource(
BTimeSource * time_source);
public:
virtual status_t HandleMessage(
int32 message,
const void * data,
size_t size);
protected:
/* Called when requests have completed, or failed. */
virtual status_t RequestCompleted( /* reserved 0 */
const media_request_info & info);
protected:
virtual status_t DeleteHook(BMediaNode * node); /* reserved 1 */
virtual void NodeRegistered(void); /* reserved 2 */
public:
/* fill out your attributes in the provided array, returning however many you have. */
virtual status_t GetNodeAttributes( /* reserved 3 */
media_node_attribute * outAttributes,
size_t inMaxCount);
virtual status_t AddTimer(
bigtime_t at_performance_time,
int32 cookie);
/* end from BMediaNode */
/***********************/
/******************************/
/* begin from BBufferConsumer */
//included from BMediaAddOn
//virtual status_t HandleMessage(
// int32 message,
// const void * data,
// size_t size);
/* Someone, probably the producer, is asking you about this format. Give */
/* your honest opinion, possibly modifying *format. Do not ask upstream */
/* producer about the format, since he's synchronously waiting for your */
/* reply. */
virtual status_t AcceptFormat(
const media_destination & dest,
media_format * format);
virtual status_t GetNextInput(
int32 * cookie,
media_input * out_input);
virtual void DisposeInputCookie(
int32 cookie);
virtual void BufferReceived(
BBuffer * buffer);
virtual void ProducerDataStatus(
const media_destination & for_whom,
int32 status,
bigtime_t at_performance_time);
virtual status_t GetLatencyFor(
const media_destination & for_whom,
bigtime_t * out_latency,
media_node_id * out_timesource);
virtual status_t Connected(
const media_source & producer, /* here's a good place to request buffer group usage */
const media_destination & where,
const media_format & with_format,
media_input * out_input);
virtual void Disconnected(
const media_source & producer,
const media_destination & where);
/* The notification comes from the upstream producer, so he's already cool with */
/* the format; you should not ask him about it in here. */
virtual status_t FormatChanged(
const media_source & producer,
const media_destination & consumer,
int32 change_tag,
const media_format & format);
/* Given a performance time of some previous buffer, retrieve the remembered tag */
/* of the closest (previous or exact) performance time. Set *out_flags to 0; the */
/* idea being that flags can be added later, and the understood flags returned in */
/* *out_flags. */
virtual status_t SeekTagRequested(
const media_destination & destination,
bigtime_t in_target_time,
uint32 in_flags,
media_seek_tag * out_seek_tag,
bigtime_t * out_tagged_time,
uint32 * out_flags);
/* end from BBufferConsumer */
/****************************/
/******************************/
/* begin from BBufferProducer */
protected:
/* functionality of BBufferProducer */
virtual status_t FormatSuggestionRequested(
media_type type,
int32 quality,
media_format * format);
virtual status_t FormatProposal(
const media_source & output,
media_format * format);
/* If the format isn't good, put a good format into *io_format and return error */
/* If format has wildcard, specialize to what you can do (and change). */
/* If you can change the format, return OK. */
/* The request comes from your destination sychronously, so you cannot ask it */
/* whether it likes it -- you should assume it will since it asked. */
virtual status_t FormatChangeRequested(
const media_source & source,
const media_destination & destination,
media_format * io_format,
int32 * _deprecated_);
virtual status_t GetNextOutput( /* cookie starts as 0 */
int32 * cookie,
media_output * out_output);
virtual status_t DisposeOutputCookie(
int32 cookie);
/* In this function, you should either pass on the group to your upstream guy, */
/* or delete your current group and hang on to this group. Deleting the previous */
/* group (unless you passed it on with the reclaim flag set to false) is very */
/* important, else you will 1) leak memory and 2) block someone who may want */
/* to reclaim the buffers living in that group. */
virtual status_t SetBufferGroup(
const media_source & for_source,
BBufferGroup * group);
/* Format of clipping is (as int16-s): <from line> <npairs> <startclip> <endclip>. */
/* Repeat for each line where the clipping is different from the previous line. */
/* If <npairs> is negative, use the data from line -<npairs> (there are 0 pairs after */
/* a negative <npairs>. Yes, we only support 32k*32k frame buffers for clipping. */
/* Any non-0 field of 'display' means that that field changed, and if you don't support */
/* that change, you should return an error and ignore the request. Note that the buffer */
/* offset values do not have wildcards; 0 (or -1, or whatever) are real values and must */
/* be adhered to. */
virtual status_t VideoClippingChanged(
const media_source & for_source,
int16 num_shorts,
int16 * clip_data,
const media_video_display_info & display,
int32 * _deprecated_);
/* Iterates over all outputs and maxes the latency found */
virtual status_t GetLatency(
bigtime_t * out_latency);
virtual status_t PrepareToConnect(
const media_source & what,
const media_destination & where,
media_format * format,
media_source * out_source,
char * out_name);
virtual void Connect(
status_t error,
const media_source & source,
const media_destination & destination,
const media_format & format,
char * io_name);
virtual void Disconnect(
const media_source & what,
const media_destination & where);
virtual void LateNoticeReceived(
const media_source & what,
bigtime_t how_much,
bigtime_t performance_time);
virtual void EnableOutput(
const media_source & what,
bool enabled,
int32 * _deprecated_);
virtual status_t SetPlayRate(
int32 numer,
int32 denom);
//included from BMediaNode
//virtual status_t HandleMessage( /* call this from the thread that listens to the port */
// int32 message,
// const void * data,
// size_t size);
virtual void AdditionalBufferRequested( // used to be Reserved 0
const media_source & source,
media_buffer_id prev_buffer,
bigtime_t prev_time,
const media_seek_tag * prev_tag); // may be NULL
virtual void LatencyChanged( // used to be Reserved 1
const media_source & source,
const media_destination & destination,
bigtime_t new_latency,
uint32 flags);
/* end from BBufferProducer */
/****************************/
/********************************/
/* start from BMediaEventLooper */
protected:
/* you must override to handle your events! */
/* you should not call HandleEvent directly */
virtual void HandleEvent( const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false);
/* override to clean up custom events you have added to your queue */
virtual void CleanUpEvent(const media_timed_event *event);
/* called from Offline mode to determine the current time of the node */
/* update your internal information whenever it changes */
virtual bigtime_t OfflineTime();
/* override only if you know what you are doing! */
/* otherwise much badness could occur */
/* the actual control loop function: */
/* waits for messages, Pops events off the queue and calls DispatchEvent */
virtual void ControlLoop();
/* end from BMediaEventLooper */
/******************************/
protected:
virtual status_t HandleStart(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false);
virtual status_t HandleSeek(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false);
virtual status_t HandleWarp(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false);
virtual status_t HandleStop(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false);
virtual status_t HandleBuffer(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false);
virtual status_t HandleDataStatus(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false);
virtual status_t HandleParameter(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false);
public:
static void GetFlavor(flavor_info * outInfo, int32 id);
private:
static void GetInputFormat(media_format * outFormat);
static void GetOutputFormat(media_format * outFormat);
protected:
virtual status_t AddRequirements(media_format * format);
private:
MediaDemultiplexerNode( /* private unimplemented */
const MediaDemultiplexerNode & clone);
MediaDemultiplexerNode & operator=(
const MediaDemultiplexerNode & clone);
status_t fInitCheckStatus;
BMediaAddOn * fAddOn;
media_input input;
vector<MediaOutputInfo> outputs;
bigtime_t fDownstreamLatency;
bigtime_t fInternalLatency;
/* Mmmh, stuffing! */
virtual status_t _Reserved_MediaDemultiplexerNode_0(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_1(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_2(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_3(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_4(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_5(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_6(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_7(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_8(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_9(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_10(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_11(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_12(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_13(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_14(void *);
virtual status_t _Reserved_MediaDemultiplexerNode_15(void *);
uint32 _reserved_media_demultiplexer_node_[16];
};
#endif /* _MEDIA_DEMULTIPLEXER_NODE_H */

View File

@ -0,0 +1,226 @@
// MediaOutputInfo.h
//
// Andrew Bachmann, 2002
//
// A class to encapsulate and manipulate
// all the information for a particular
// output of a media node.
#if !defined(_MEDIA_OUTPUT_INFO_H)
#define _MEDIA_OUTPUT_INFO_H
#include <MediaDefs.h>
#include <BufferGroup.h>
class MediaOutputInfo
{
public:
MediaOutputInfo(char * name) {
// null some fields
bufferGroup = 0;
// start enabled
outputEnabled = true;
// don't overwrite available space, and be sure to terminate
strncpy(output.name,name,B_MEDIA_NAME_LENGTH-1);
output.name[B_MEDIA_NAME_LENGTH-1] = '\0';
// initialize the output
output.node = media_node::null;
output.source = media_source::null;
output.destination = media_source::null;
}
~MediaOutputInfo() {
if (bufferGroup != 0) {
BBufferGroup * group = bufferGroup;
bufferGroup = 0;
delete group;
}
}
SetBufferGroup(BBufferGroup * group) {
// if (fBufferGroup != 0) {
// if (fBufferGroup == group) {
// return B_OK; // time saver
// }
// delete fBufferGroup;
// }
// if (group != 0) {
// fBufferGroup = group;
// } else {
// // let's take advantage of this opportunity to recalculate
// // our downstream latency and ensure that it is up to date
// media_node_id id;
// FindLatencyFor(output.destination, &fDownstreamLatency, &id);
// // buffer period gets initialized in Connect() because
// // that is the first time we get the real values for
// // chunk size and bit rate, which are used to compute buffer period
// // note: you can still make a buffer group before connecting (why?)
// // but we don't make it, you make it yourself and pass it here.
// // not sure why anybody would want to do that since they need
// // a connection anyway...
// if (fBufferPeriod <= 0) {
// fprintf(stderr,"<- B_NO_INIT");
// return B_NO_INIT;
// }
// int32 count = int32(fDownstreamLatency/fBufferPeriod)+2;
// fprintf(stderr," downstream latency = %lld, buffer period = %lld, buffer count = %i\n",
// fDownstreamLatency,fBufferPeriod,count);
//
// // allocate the buffers
// fBufferGroup = new BBufferGroup(output.format.u.multistream.max_chunk_size,count);
// if (fBufferGroup == 0) {
// fprintf(stderr,"<- B_NO_MEMORY\n");
// return B_NO_MEMORY;
// }
// status_t status = fBufferGroup->InitCheck();
// if (status != B_OK) {
// fprintf(stderr,"<- fBufferGroup initialization failed\n");
// return status;
// }
// }
}
// They made an offer to us. We should make sure that the offer is
// acceptable, and then we can add any requirements we have on top of
// that. We leave wildcards for anything that we don't care about.
status_t FormatProposal(media_format * format)
{
if (format == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashing
}
// Be's format_is_compatible doesn't work,
// so use our format_is_acceptible instead
if (!format_is_acceptible(*format,generalFormat)) {
fprintf(stderr,"<- B_MEDIA_BAD_FORMAT\n");
return B_MEDIA_BAD_FORMAT;
}
// XXX: test because we don't trust them!
format->SpecializeTo(wildcardedFormat);
return B_OK;
}
// Presumably we have already agreed with them that this format is
// okay. But just in case, we check the offer. (and complain if it
// is invalid) Then as the last thing we do, we get rid of any
// remaining wilcards.
status_t FormatChangeRequested(const media_destination & destination,
media_format * io_format)
{
if (io_format == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashing
}
status_t status = FormatProposal(io_format);
if (status != B_OK) {
fprintf(stderr,"<- MediaOutputInfo::FormatProposal failed\n");
*io_format = generalFormat;
return status;
}
io_format->SpecializeTo(fullySpecifiedFormat);
return B_OK;
}
status_t PrepareToConnect(const media_destination & where,
media_format * format,
media_source * out_source,
char * out_name)
{
if (output.destination != media_destination::null) {
fprintf(stderr,"<- B_MEDIA_ALREADY_CONNECTED\n");
return B_MEDIA_ALREADY_CONNECTED;
}
status_t status = FormatChangeRequested(where,format,out_name);
if (status != B_OK) {
fprintf(stderr,"<- MediaOutputInfo::FormatChangeRequested failed\n");
return status;
}
*out_source = output.source;
output.destination = where;
strncpy(out_name,output.name,B_MEDIA_NAME_LENGTH-1);
out_name[B_MEDIA_NAME_LENGTH] = '\0';
return B_OK;
}
status_t Connect(const media_destination & destination,
const media_format & format,
char * io_name)
{
if (io_name == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE;
}
output.destination = destination;
output.format = format;
strncpy(io_name,output.name,B_MEDIA_NAME_LENGTH-1);
io_name[B_MEDIA_NAME_LENGTH-1] = '\0';
// determine our downstream latency
media_node_id id;
FindLatencyFor(output.destination, &downstreamLatency, &id);
// compute the buffer period (must be done before setbuffergroup)
bufferPeriod = computeBufferPeriod(output.format);
SetBufferDuration(fBufferPeriod);
// setup the buffers if they aren't setup yet
if (bufferGroup == 0) {
status_t status = SetBufferGroup(output.source,0);
if (status != B_OK) {
fprintf(stderr,"<- SetBufferGroup failed\n");
output.destination = media_destination::null;
output.format = generalFormat;
return;
}
}
return B_OK;
}
status_t Disconnect()
{
output.destination = media_destination::null;
output.format = genericFormat;
if (bufferGroup != 0) {
BBufferGroup * group = bufferGroup;
bufferGroup = 0;
delete group;
}
}
status_t EnableOutput(bool enabled)
{
outputEnabled = enabled;
return B_OK;
}
public:
media_output output;
bool outputEnabled;
BBufferGroup * bufferGroup;
size_t bufferSize;
bigtime_t downstreamLatency;
bigtime_t bufferPeriod;
// This format is the least restrictive we can
// support in the general case. (no restrictions
// based on content)
media_format generalFormat;
// This format is the next least restrictive. It
// takes into account the content that we are using.
// It should be the same as above with a few wildcards
// removed. Wildcards for things we are flexible on
// may still be present.
media_format wildcardedFormat;
// This format provides default values for all fields.
// These defaults are used to resolve all wildcards.
media_format fullySpecifiedFormat;
// do we need media_seek_tag in here?
}
#endif // _MEDIA_OUTPUT_INFO_H

View File

@ -0,0 +1,129 @@
// misc.cpp
//
// Andrew Bachmann, 2002
//
// Some functions for general debugging and
// working around be media kit bugs.
#include "misc.h"
#include <stdio.h>
// -------------------------------------------------------- //
// lib functions
// -------------------------------------------------------- //
void print_multistream_format(media_multistream_format * format) {
fprintf(stderr,"[");
switch (format->format) {
case media_multistream_format::B_ANY: fprintf(stderr,"ANY"); break;
case media_multistream_format::B_VID: fprintf(stderr,"VID"); break;
case media_multistream_format::B_AVI: fprintf(stderr,"AVI"); break;
case media_multistream_format::B_MPEG1: fprintf(stderr,"MPEG1"); break;
case media_multistream_format::B_MPEG2: fprintf(stderr,"MPEG2"); break;
case media_multistream_format::B_QUICKTIME: fprintf(stderr,"QUICKTIME"); break;
default: fprintf(stderr,"????"); break;
}
fprintf(stderr," avg_bit_rate(%f) max_bit_rate(%f)",
format->avg_bit_rate,format->max_bit_rate);
fprintf(stderr," avg_chunk_size(%i) max_chunk_size(%i)",
format->avg_chunk_size,format->max_chunk_size);
}
void print_media_format(media_format * format) {
fprintf(stderr,"{");
switch (format->type) {
case B_MEDIA_NO_TYPE: fprintf(stderr,"NO_TYPE"); break;
case B_MEDIA_UNKNOWN_TYPE: fprintf(stderr,"UNKNOWN_TYPE"); break;
case B_MEDIA_RAW_AUDIO: fprintf(stderr,"RAW_AUDIO"); break;
case B_MEDIA_RAW_VIDEO: fprintf(stderr,"RAW_VIDEO"); break;
case B_MEDIA_VBL: fprintf(stderr,"VBL"); break;
case B_MEDIA_TIMECODE: fprintf(stderr,"TIMECODE"); break;
case B_MEDIA_MIDI: fprintf(stderr,"MIDI"); break;
case B_MEDIA_TEXT: fprintf(stderr,"TEXT"); break;
case B_MEDIA_HTML: fprintf(stderr,"HTML"); break;
case B_MEDIA_MULTISTREAM: fprintf(stderr,"MULTISTREAM"); break;
case B_MEDIA_PARAMETERS: fprintf(stderr,"PARAMETERS"); break;
case B_MEDIA_ENCODED_AUDIO: fprintf(stderr,"ENCODED_AUDIO"); break;
case B_MEDIA_ENCODED_VIDEO: fprintf(stderr,"ENCODED_VIDEO"); break;
default: fprintf(stderr,"????"); break;
}
fprintf(stderr,":");
switch (format->type) {
case B_MEDIA_RAW_AUDIO: fprintf(stderr,"RAW_AUDIO"); break;
case B_MEDIA_RAW_VIDEO: fprintf(stderr,"RAW_VIDEO"); break;
case B_MEDIA_MULTISTREAM: print_multistream_format(&format->u.multistream); break;
case B_MEDIA_ENCODED_AUDIO: fprintf(stderr,"ENCODED_AUDIO"); break;
case B_MEDIA_ENCODED_VIDEO: fprintf(stderr,"ENCODED_VIDEO"); break;
default: fprintf(stderr,"????"); break;
}
fprintf(stderr,"}");
}
bool multistream_format_is_acceptible(
const media_multistream_format & producer_format,
const media_multistream_format & consumer_format)
{
// first check the format, if necessary
if (consumer_format.format != media_multistream_format::B_ANY) {
if (consumer_format.format != producer_format.format) {
return false;
}
}
// then check the average bit rate
if (consumer_format.avg_bit_rate != media_multistream_format::wildcard.avg_bit_rate) {
if (consumer_format.avg_bit_rate != producer_format.avg_bit_rate) {
// do they have to match exactly? I don't know. assume yes.
return false;
}
}
// then check the maximum bit rate
if (consumer_format.max_bit_rate != media_multistream_format::wildcard.max_bit_rate) {
if (consumer_format.max_bit_rate != producer_format.max_bit_rate) {
// do they have to match exactly? I don't know. assume yes.
return false;
}
}
// then check the average chunk size
if (consumer_format.avg_chunk_size != media_multistream_format::wildcard.avg_chunk_size) {
if (consumer_format.avg_chunk_size != producer_format.avg_chunk_size) {
// do they have to match exactly? I don't know. assume yes.
return false;
}
}
// then check the maximum bit rate
if (consumer_format.max_chunk_size != media_multistream_format::wildcard.max_chunk_size) {
if (consumer_format.max_chunk_size != producer_format.max_chunk_size) {
// do they have to match exactly? I don't know. assume yes.
return false;
}
}
// should also check format specific fields, and others?
return true;
}
bool format_is_acceptible(
const media_format & producer_format,
const media_format & consumer_format)
{
// first check the type, if necessary
if (consumer_format.type != B_MEDIA_UNKNOWN_TYPE) {
if (consumer_format.type != producer_format.type) {
return false;
}
switch (consumer_format.type) {
case B_MEDIA_MULTISTREAM:
if (!multistream_format_is_acceptible(producer_format.u.multistream,
consumer_format.u.multistream)) {
return false;
}
break;
default:
fprintf(stderr,"format_is_acceptible : unimplemented type.\n");
return format_is_compatible(producer_format,consumer_format);
break;
}
}
// should also check non-type fields?
return true;
}

View File

@ -0,0 +1,30 @@
// misc.h
//
// Andrew Bachmann, 2002
//
// Some functions for general debugging and
// working around be media kit bugs.
#if !defined(_MISC_H)
#define _MISC_H
#include <MediaDefs.h>
// -------------------------------------------------------- //
// lib functions
// -------------------------------------------------------- //
void print_multistream_format(media_multistream_format * format);
void print_media_format(media_format * format);
bool multistream_format_is_acceptible(
const media_multistream_format & producer_format,
const media_multistream_format & consumer_format);
bool format_is_acceptible(
const media_format & producer_format,
const media_format & consumer_format);
#endif // _MISC_H