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:
parent
4cdc6c141b
commit
d5525d8c93
11
src/add-ons/media/media-add-ons/demultiplexer/Jamfile
Normal file
11
src/add-ons/media/media-add-ons/demultiplexer/Jamfile
Normal 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 ;
|
@ -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
@ -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 */
|
226
src/add-ons/media/media-add-ons/demultiplexer/MediaOutputInfo.h
Normal file
226
src/add-ons/media/media-add-ons/demultiplexer/MediaOutputInfo.h
Normal 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
|
||||
|
129
src/add-ons/media/media-add-ons/demultiplexer/misc.cpp
Normal file
129
src/add-ons/media/media-add-ons/demultiplexer/misc.cpp
Normal 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;
|
||||
}
|
||||
|
30
src/add-ons/media/media-add-ons/demultiplexer/misc.h
Normal file
30
src/add-ons/media/media-add-ons/demultiplexer/misc.h
Normal 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
|
||||
|
Loading…
Reference in New Issue
Block a user