abstract file interface node used for reader and writer

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1049 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty
2002-09-16 03:29:54 +00:00
parent 8aabdd2043
commit 242094db6d
3 changed files with 1388 additions and 0 deletions
@@ -0,0 +1,118 @@
// AbstractFileInterfaceAddOn.h
//
// Andrew Bachmann, 2002
//
// AbstractFileInterfaceAddOn is an add-on
// that can make instances of AbstractFileInterfaceNode
//
// AbstractFileInterfaceNode handles a file and a multistream
#if !defined(_ABSTRACT_FILE_INTERFACE_ADD_ON_H)
#define _ABSTRACT_FILE_INTERFACE_ADD_ON_H
#include <MediaDefs.h>
#include <MediaAddOn.h>
class AbstractFileInterfaceAddOn :
public BMediaAddOn
{
public:
virtual ~AbstractFileInterfaceAddOn(void);
explicit AbstractFileInterfaceAddOn(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) = 0;
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);
/* only implement if you have a B_FILE_INTERFACE node */
virtual status_t SniffRef(
const entry_ref & file,
BMimeType * io_mime_type,
float * out_quality,
int32 * out_internal_id);
virtual status_t SniffType( // This is broken if you deal with producers
const BMimeType & type, // and consumers both. Use SniffTypeKind instead.
float * out_quality, // If you implement SniffTypeKind, this doesn't
int32 * out_internal_id); // get called.
virtual status_t GetFileFormatList(
int32 flavor_id, // for this node flavor (if it matters)
media_file_format * out_writable_formats, // don't write here if NULL
int32 in_write_items, // this many slots in out_writable_formats
int32 * out_write_items, // set this to actual # available, even if bigger than in count
media_file_format * out_readable_formats, // don't write here if NULL
int32 in_read_items, // this many slots in out_readable_formats
int32 * out_read_items, // set this to actual # available, even if bigger than in count
void * _reserved); // ignore until further notice
virtual status_t SniffTypeKind( // Like SniffType, but for the specific kind(s)
const BMimeType & type,
uint64 in_kinds,
float * out_quality,
int32 * out_internal_id,
void * _reserved) = 0;
virtual status_t SniffTypeKind( // Like SniffType, but for the specific kind(s)
const BMimeType & type,
uint64 in_kinds,
uint64 io_kind,
float * out_quality,
int32 * out_internal_id,
void * _reserved);
/* end from BMediaAddOn */
/************************/
private:
AbstractFileInterfaceAddOn( /* private unimplemented */
const AbstractFileInterfaceAddOn & clone);
AbstractFileInterfaceAddOn & operator=(
const AbstractFileInterfaceAddOn & clone);
int32 refCount;
/* Mmmh, stuffing! */
virtual status_t _Reserved_AbstractFileInterfaceAddOn_0(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_1(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_2(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_3(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_4(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_5(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_6(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_7(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_8(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_9(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_10(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_11(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_12(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_13(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_14(void *);
virtual status_t _Reserved_AbstractFileInterfaceAddOn_15(void *);
uint32 _reserved_media_reader_add_on_[16];
};
#if BUILDING_ABSTRACT_FILE_INTERFACE__ADD_ON
extern "C" _EXPORT BMediaAddOn * make_abstract_file_interface_add_on(image_id you);
#endif
#endif /* _ABSTRACT_FILE_INTERFACE_ADD_ON_H */
@@ -0,0 +1,957 @@
// AbstractFileInterfaceNode.cpp
//
// Andrew Bachmann, 2002
//
// The AbstractFileInterfaceNode class implements
// the common functionality between MediaReader
// and MediaWriter.
#include <MediaDefs.h>
#include <MediaNode.h>
#include <MediaAddOn.h>
#include <FileInterface.h>
#include <Controllable.h>
#include <MediaEventLooper.h>
#include <File.h>
#include <Errors.h>
#include <Entry.h>
#include <BufferGroup.h>
#include <TimeSource.h>
#include <Buffer.h>
#include <ParameterWeb.h>
#include <limits.h>
#include "AbstractFileInterfaceNode.h"
#include <stdio.h>
#include <string.h>
// -------------------------------------------------------- //
// ctor/dtor
// -------------------------------------------------------- //
AbstractFileInterfaceNode::~AbstractFileInterfaceNode(void)
{
fprintf(stderr,"AbstractFileInterfaceNode::~AbstractFileInterfaceNode\n");
// Stop the BMediaEventLooper thread
Quit();
if (fCurrentFile != 0) {
delete fCurrentFile;
}
}
AbstractFileInterfaceNode::AbstractFileInterfaceNode(
size_t defaultChunkSize = 8192,
float defaultBitRate = 800000,
const flavor_info * info = 0,
BMessage * config = 0,
BMediaAddOn * addOn = 0)
: BMediaNode("AbstractFileInterfaceNode"),
BFileInterface(),
BControllable(),
BMediaEventLooper()
{
fprintf(stderr,"AbstractFileInterfaceNode::AbstractFileInterfaceNode\n");
// keep our creator around for AddOn calls later
fAddOn = addOn;
// null some fields
fCurrentFile = 0;
f_current_mime_type[0] = '\0';
// initialize the parameters
if (defaultChunkSize <= 0) {
fInitCheckStatus = B_BAD_VALUE;
return;
}
fDefaultChunkSizeParam = defaultChunkSize;
fDefaultChunkSizeParamChangeTime = 0;
if (defaultBitRate <= 0) {
fInitCheckStatus = B_BAD_VALUE;
return;
}
fDefaultBitRateParam = defaultBitRate;
fDefaultBitRateParamChangeTime = 0;
// initialize parameter compute fields
fLeastRecentlyUpdatedParameter = DEFAULT_BIT_RATE_PARAM;
fLastUpdatedParameter = DEFAULT_BUFFER_PERIOD_PARAM;
// From the chunk size and bit rate we compute the buffer period.
int64 value = int64(8000000/1024*fDefaultChunkSizeParam/fDefaultBitRateParam);
if ((value <= 0) || (value > INT_MAX)) {
fInitCheckStatus = B_BAD_VALUE;
return;
}
fDefaultBufferPeriodParam = int32(value);
fDefaultBufferPeriodParamChangeTime = 0;
fInitCheckStatus = B_OK;
}
status_t AbstractFileInterfaceNode::InitCheck(void) const
{
fprintf(stderr,"AbstractFileInterfaceNode::InitCheck\n");
return fInitCheckStatus;
}
status_t AbstractFileInterfaceNode::GetConfigurationFor(
BMessage * into_message)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetConfigurationFor\n");
return B_OK;
}
// -------------------------------------------------------- //
// implementation of BMediaNode
// -------------------------------------------------------- //
BMediaAddOn * AbstractFileInterfaceNode::AddOn(
int32 * internal_id) const
{
fprintf(stderr,"AbstractFileInterfaceNode::AddOn\n");
// BeBook says this only gets called if we were in an add-on.
if (fAddOn != 0) {
// If we get a null pointer then we just won't write.
if (internal_id != 0) {
internal_id = 0;
}
}
return fAddOn;
}
void AbstractFileInterfaceNode::Start(
bigtime_t performance_time)
{
fprintf(stderr,"AbstractFileInterfaceNode::Start(pt=%i)\n",performance_time);
BMediaEventLooper::Start(performance_time);
}
void AbstractFileInterfaceNode::Stop(
bigtime_t performance_time,
bool immediate)
{
fprintf(stderr,"AbstractFileInterfaceNode::Stop(pt=%i,%s)\n",performance_time,(immediate?"now":"then"));
BMediaEventLooper::Stop(performance_time,immediate);
}
void AbstractFileInterfaceNode::Seek(
bigtime_t media_time,
bigtime_t performance_time)
{
fprintf(stderr,"AbstractFileInterfaceNode::Seek(mt=%i,pt=%i)\n",media_time,performance_time);
BMediaEventLooper::Seek(media_time,performance_time);
}
void AbstractFileInterfaceNode::SetRunMode(
run_mode mode)
{
fprintf(stderr,"AbstractFileInterfaceNode::SetRunMode(%i)\n",mode);
BMediaEventLooper::SetRunMode(mode);
}
void AbstractFileInterfaceNode::TimeWarp(
bigtime_t at_real_time,
bigtime_t to_performance_time)
{
fprintf(stderr,"AbstractFileInterfaceNode::TimeWarp(rt=%i,pt=%i)\n",at_real_time,to_performance_time);
BMediaEventLooper::TimeWarp(at_real_time,to_performance_time);
}
void AbstractFileInterfaceNode::Preroll(void)
{
fprintf(stderr,"AbstractFileInterfaceNode::Preroll\n");
// XXX:Performance opportunity
BMediaNode::Preroll();
}
void AbstractFileInterfaceNode::SetTimeSource(
BTimeSource * time_source)
{
fprintf(stderr,"AbstractFileInterfaceNode::SetTimeSource\n");
BMediaNode::SetTimeSource(time_source);
}
status_t AbstractFileInterfaceNode::HandleMessage(
int32 message,
const void * data,
size_t size)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleMessage\n");
status_t status = B_OK;
switch (message) {
// no special messages for now
default:
status = BFileInterface::HandleMessage(message,data,size);
if (status == B_OK) {
break;
}
status = BMediaNode::HandleMessage(message,data,size);
if (status == B_OK) {
break;
}
BMediaNode::HandleBadMessage(message,data,size);
status = B_ERROR;
break;
}
return status;
}
status_t AbstractFileInterfaceNode::RequestCompleted(
const media_request_info & info)
{
fprintf(stderr,"AbstractFileInterfaceNode::RequestCompleted\n");
return BMediaNode::RequestCompleted(info);
}
status_t AbstractFileInterfaceNode::DeleteHook(
BMediaNode * node)
{
fprintf(stderr,"AbstractFileInterfaceNode::DeleteHook\n");
return BMediaEventLooper::DeleteHook(node);
}
void AbstractFileInterfaceNode::NodeRegistered(void)
{
fprintf(stderr,"AbstractFileInterfaceNode::NodeRegistered\n");
// set up our parameter web
SetParameterWeb(MakeParameterWeb());
// start the BMediaEventLooper thread
SetPriority(B_REAL_TIME_PRIORITY);
Run();
}
status_t AbstractFileInterfaceNode::GetNodeAttributes(
media_node_attribute * outAttributes,
size_t inMaxCount)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetNodeAttributes\n");
return BMediaNode::GetNodeAttributes(outAttributes,inMaxCount);
}
status_t AbstractFileInterfaceNode::AddTimer(
bigtime_t at_performance_time,
int32 cookie)
{
fprintf(stderr,"AbstractFileInterfaceNode::AddTimer\n");
return BMediaEventLooper::AddTimer(at_performance_time,cookie);
}
// protected:
BParameterWeb * AbstractFileInterfaceNode::MakeParameterWeb(void)
{
fprintf(stderr,"AbstractFileInterfaceNode::MakeParameterWeb\n");
BParameterWeb * web = new BParameterWeb();
BParameterGroup * mainGroup = web->MakeGroup("AbstractFileInterfaceNode Parameters");
// these three are related:
// DEFAULT_CHUNK_SIZE_PARAM = DEFAULT_BIT_RATE_PARAM / 1024 * DEFAULT_BUFFER_PERIOD_PARAM * 1000
BParameterGroup * chunkSizeGroup = mainGroup->MakeGroup("Chunk Size Group");
BContinuousParameter * chunkSizeParameter
= chunkSizeGroup->MakeContinuousParameter(
DEFAULT_CHUNK_SIZE_PARAM, B_MEDIA_MULTISTREAM,
"Chunk Size", B_GAIN, "bytes", 1024, 32*1024, 512);
chunkSizeParameter->SetResponse(BContinuousParameter::B_LINEAR,1,0);
chunkSizeParameter->SetValue(&fDefaultChunkSizeParam,sizeof(fDefaultChunkSizeParam),0);
BParameterGroup * bitRateGroup = mainGroup->MakeGroup("Bit Rate Group");
BContinuousParameter * bitRateParameter
= bitRateGroup->MakeContinuousParameter(
DEFAULT_BIT_RATE_PARAM, B_MEDIA_MULTISTREAM,
"Bit Rate", B_GAIN, "kbits/sec", 1, 320000, 1);
bitRateParameter->SetResponse(BContinuousParameter::B_LINEAR,.001,0);
bitRateParameter->SetValue(&fDefaultBitRateParam,sizeof(fDefaultBitRateParam),0);
BParameterGroup * bufferPeriodGroup = mainGroup->MakeGroup("Buffer Period Group");
BContinuousParameter * bufferPeriodParameter
= bufferPeriodGroup->MakeContinuousParameter(
DEFAULT_BUFFER_PERIOD_PARAM, B_MEDIA_MULTISTREAM,
"Buffer Period", B_GAIN, "ms", 1, 10000, 1);
bufferPeriodParameter->SetResponse(BContinuousParameter::B_LINEAR,1,0);
bufferPeriodParameter->SetValue(&fDefaultBufferPeriodParam,sizeof(fDefaultBufferPeriodParam),0);
return web;
}
// -------------------------------------------------------- //
// implementation of BFileInterface
// -------------------------------------------------------- //
status_t AbstractFileInterfaceNode::GetNextFileFormat(
int32 * cookie,
media_file_format * out_format)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetNextFileFormat\n");
// let's not crash even if they are stupid
if (out_format == 0) {
// no place to write!
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE;
}
if (cookie != 0) {
// it's valid but they already got our 1 file format
if (*cookie != 0) {
fprintf(stderr,"<- B_ERROR\n");
return B_ERROR;
}
// so next time they won't get the same format again
*cookie = 1;
}
*out_format = *GetFileFormat();
return B_OK;
}
void AbstractFileInterfaceNode::DisposeFileFormatCookie(
int32 cookie)
{
fprintf(stderr,"AbstractFileInterfaceNode::DisposeFileFormatCookie\n");
// nothing to do since our cookies are just integers
}
status_t AbstractFileInterfaceNode::GetDuration(
bigtime_t * out_time)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetDuration\n");
if (out_time == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE;
}
if (fCurrentFile == 0) {
fprintf(stderr,"<- B_NO_INIT\n");
return B_NO_INIT;
}
return fCurrentFile->GetSize(out_time);
}
status_t AbstractFileInterfaceNode::SniffRef(
const entry_ref & file,
char * out_mime_type, /* 256 bytes */
float * out_quality)
{
fprintf(stderr,"AbstractFileInterfaceNode::SniffRef\n");
return StaticSniffRef(file,out_mime_type,out_quality);
}
status_t AbstractFileInterfaceNode::SetRef(
const entry_ref & file,
uint32 openMode,
bool create,
bigtime_t * out_time)
{
fprintf(stderr,"AbstractFileInterfaceNode::SetRef\n");
if (out_time == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashes today thanks
}
status_t status;
f_current_ref = file;
if (fCurrentFile == 0) {
fCurrentFile = new BFile(&f_current_ref,(openMode|(create?B_CREATE_FILE:0)));
status = fCurrentFile->InitCheck();
} else {
status = fCurrentFile->SetTo(&f_current_ref,(openMode|(create?B_CREATE_FILE:0)));
}
if (status != B_OK) {
fprintf(stderr,"<- failed BFile initialization\n");
return status;
}
// cache the mime type for later
fCurrentFile->ReadAttr("BEOS:TYPE",0,0,f_current_mime_type,B_MIME_TYPE_LENGTH);
// compute the duration and return any error
return GetDuration(out_time);
}
status_t AbstractFileInterfaceNode::GetRef(
entry_ref * out_ref,
char * out_mime_type)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetRef\n");
if ((out_ref == 0) || (out_mime_type == 0)) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashes today thanks
}
if (fCurrentFile == 0) {
fprintf(stderr,"<- B_NO_INIT\n");
return B_NO_INIT; // the input_ref isn't valid yet either
}
*out_ref = f_current_ref;
// they hopefully allocated enough space (no way to check :-/ )
strcpy(out_mime_type,f_current_mime_type);
return B_OK;
}
// provided for BAbstractFileInterfaceNodeAddOn
status_t AbstractFileInterfaceNode::StaticSniffRef(
const entry_ref & file,
char * out_mime_type, /* 256 bytes */
float * out_quality)
{
fprintf(stderr,"AbstractFileInterfaceNode::StaticSniffRef\n");
if ((out_mime_type == 0) || (out_quality == 0)) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // we refuse to crash because you were stupid
}
BNode node(&file);
status_t initCheck = node.InitCheck();
if (initCheck != B_OK) {
fprintf(stderr,"<- failed BNode::InitCheck()\n");
return initCheck;
}
// they hopefully allocated enough room
node.ReadAttr("BEOS:TYPE",0,0,out_mime_type,B_MIME_TYPE_LENGTH);
*out_quality = 1.0; // we handle all files perfectly! we are so amazing!
return B_OK;
}
// -------------------------------------------------------- //
// implementation for BControllable
// -------------------------------------------------------- //
const int32 AbstractFileInterfaceNode::DEFAULT_CHUNK_SIZE_PARAM = 1;
const int32 AbstractFileInterfaceNode::DEFAULT_BIT_RATE_PARAM = 2;
const int32 AbstractFileInterfaceNode::DEFAULT_BUFFER_PERIOD_PARAM = 3;
status_t AbstractFileInterfaceNode::GetParameterValue(
int32 id,
bigtime_t * last_change,
void * value,
size_t * ioSize)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetParameterValue\n");
if ((last_change == 0) || (value == 0) || (ioSize == 0)) {
return B_BAD_VALUE; // no crashing
}
switch (id) {
case DEFAULT_CHUNK_SIZE_PARAM:
if (*ioSize < sizeof(size_t)) {
return B_ERROR; // not enough room
}
*last_change = fDefaultChunkSizeParamChangeTime;
*((size_t*)value) = fDefaultChunkSizeParam;
*ioSize = sizeof(size_t);
break;
case DEFAULT_BIT_RATE_PARAM:
if (*ioSize < sizeof(float)) {
return B_ERROR; // not enough room
}
*last_change = fDefaultBitRateParamChangeTime;
*((float*)value) = fDefaultBitRateParam;
*ioSize = sizeof(float);
break;
case DEFAULT_BUFFER_PERIOD_PARAM:
if (*ioSize < sizeof(int32)) {
return B_ERROR; // not enough room
}
*last_change = fDefaultBufferPeriodParamChangeTime;
*((int32*)value) = fDefaultBufferPeriodParam;
*ioSize = sizeof(int32);
break;
default:
fprintf(stderr,"AbstractFileInterfaceNode::GetParameterValue unknown id (%i)\n",id);
return B_ERROR;
}
return B_OK;
}
void AbstractFileInterfaceNode::SetParameterValue(
int32 id,
bigtime_t when,
const void * value,
size_t size)
{
fprintf(stderr,"AbstractFileInterfaceNode::SetParameterValue(id=%i,when=%ld,size=%i)\n",id,int32(when),int32(size));
switch (id) {
case DEFAULT_CHUNK_SIZE_PARAM:
case DEFAULT_BIT_RATE_PARAM:
case DEFAULT_BUFFER_PERIOD_PARAM:
{
media_timed_event event(when, BTimedEventQueue::B_PARAMETER,
NULL, BTimedEventQueue::B_NO_CLEANUP,
size, id, (char*) value, size);
EventQueue()->AddEvent(event);
}
break;
default:
fprintf(stderr,"AbstractFileInterfaceNode::SetParameterValue unknown id (%i)\n",id);
break;
}
}
// the default implementation should call the add-on main()
status_t AbstractFileInterfaceNode::StartControlPanel(
BMessenger * out_messenger)
{
BControllable::StartControlPanel(out_messenger);
}
// -------------------------------------------------------- //
// implementation for BMediaEventLooper
// -------------------------------------------------------- //
void AbstractFileInterfaceNode::HandleEvent(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleEvent\n");
switch (event->type) {
case BTimedEventQueue::B_START:
HandleStart(event,lateness,realTimeEvent);
break;
case BTimedEventQueue::B_SEEK:
HandleSeek(event,lateness,realTimeEvent);
break;
case BTimedEventQueue::B_WARP:
HandleWarp(event,lateness,realTimeEvent);
break;
case BTimedEventQueue::B_STOP:
HandleStop(event,lateness,realTimeEvent);
break;
case BTimedEventQueue::B_HANDLE_BUFFER:
if (RunState() == BMediaEventLooper::B_STARTED) {
HandleBuffer(event,lateness,realTimeEvent);
}
break;
case BTimedEventQueue::B_DATA_STATUS:
HandleDataStatus(event,lateness,realTimeEvent);
break;
case BTimedEventQueue::B_PARAMETER:
HandleParameter(event,lateness,realTimeEvent);
break;
default:
fprintf(stderr," unknown event type: %i\n",event->type);
break;
}
}
/* override to clean up custom events you have added to your queue */
void AbstractFileInterfaceNode::CleanUpEvent(
const media_timed_event *event)
{
BMediaEventLooper::CleanUpEvent(event);
}
/* called from Offline mode to determine the current time of the node */
/* update your internal information whenever it changes */
bigtime_t AbstractFileInterfaceNode::OfflineTime()
{
fprintf(stderr,"AbstractFileInterfaceNode::OfflineTime\n");
return BMediaEventLooper::OfflineTime();
// if (inputFile == 0) {
// return 0;
// } else {
// return inputFile->Position();
// }
}
/* 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 */
void AbstractFileInterfaceNode::ControlLoop() {
BMediaEventLooper::ControlLoop();
}
// protected:
status_t AbstractFileInterfaceNode::HandleStart(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
{
fprintf(stderr,"MediaReader::HandleStart()\n");
if (RunState() != B_STARTED) {
HandleBuffer(event,lateness,realTimeEvent);
// media_timed_event firstBufferEvent(event->event_time, BTimedEventQueue::B_HANDLE_BUFFER);
// //this->HandleEvent(&firstBufferEvent, 0, false);
// EventQueue()->AddEvent(firstBufferEvent);
}
}
status_t AbstractFileInterfaceNode::HandleSeek(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
{
// XXX: argghh.. seek events seem broken when received from
// the usual BMediaEventLooper::Seek() dispatcher :-(
// They lost where we are supposed to seek to!?!
fprintf(stderr,"AbstractFileInterfaceNode::HandleSeek(t=%i,d=%i,bd=%ld)\n",event->event_time,event->data,event->bigdata);
if (fCurrentFile != 0) {
fCurrentFile->Seek(event->bigdata,SEEK_SET);
}
}
status_t AbstractFileInterfaceNode::HandleWarp(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleWarp\n");
}
status_t AbstractFileInterfaceNode::HandleStop(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleStop\n");
// flush the queue so downstreamers don't get any more
EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER);
}
status_t AbstractFileInterfaceNode::HandleParameter(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleParameter");
status_t status = B_OK;
bool chunkSizeUpdated = false, bitRateUpdated = false, bufferPeriodUpdated = false;
size_t dataSize = size_t(event->data);
int32 param = int32(event->bigdata);
switch (param) {
case DEFAULT_CHUNK_SIZE_PARAM:
fprintf(stderr,"(DEFAULT_CHUNK_SIZE_PARAM,size=%i",dataSize);
if (dataSize < sizeof(size_t)) {
fprintf(stderr,")\n");
fprintf(stderr,"<- B_BAD_VALUE\n",param);
status = B_BAD_VALUE;
} else {
size_t newDefaultChunkSize = *((size_t*)event->user_data);
fprintf(stderr,",%i)\n",newDefaultChunkSize);
// ignore non positive chunk sizes
// XXX: we may decide later that a 0 chunk size means ship the whole file in one chunk (!)
if ((newDefaultChunkSize > 0) && (newDefaultChunkSize != fDefaultChunkSizeParam)) {
fprintf(stderr," got a new chunk size, old chunk size was %i\n",fDefaultChunkSizeParam);
fDefaultChunkSizeParam = newDefaultChunkSize;
fDefaultChunkSizeParamChangeTime = TimeSource()->Now();
chunkSizeUpdated = true;
if (fLeastRecentlyUpdatedParameter == DEFAULT_CHUNK_SIZE_PARAM) {
// Okay we were the least recently updated parameter,
// but we just got an update so we are no longer that.
// Let's figure out who the new least recently updated
// parameter is. We are going to prefer to compute the
// bit rate since you usually don't want to muck with
// the buffer period. However, if you just set the bitrate
// then we are stuck with making the buffer period the new
// parameter to be computed.
if (fLastUpdatedParameter == DEFAULT_BIT_RATE_PARAM) {
fLeastRecentlyUpdatedParameter = DEFAULT_BUFFER_PERIOD_PARAM;
} else {
fLeastRecentlyUpdatedParameter = DEFAULT_BIT_RATE_PARAM;
}
}
// we just got an update, so we are the new lastUpdatedParameter
fLastUpdatedParameter = DEFAULT_CHUNK_SIZE_PARAM;
// now we have to compute the new value for the leastRecentlyUpdatedParameter
// we use the chunk size change time to preserve "simultaneity" information
if (fLeastRecentlyUpdatedParameter == DEFAULT_BUFFER_PERIOD_PARAM) {
int64 value = int64(8000000/1024*fDefaultChunkSizeParam/fDefaultBitRateParam);
if (value > INT_MAX) {
// clamp to INT_MAX
fDefaultBufferPeriodParam = INT_MAX;
// recompute chunk size
fDefaultChunkSizeParam = size_t(1024/8000000*fDefaultBitRateParam*fDefaultBufferPeriodParam);
} else {
fDefaultBufferPeriodParam = MAX(1,value);
}
fDefaultBufferPeriodParamChangeTime = fDefaultChunkSizeParamChangeTime;
bufferPeriodUpdated = true;
} else { // must have been bit rate
fDefaultBitRateParam = MAX(0.001,8000000/1024*fDefaultChunkSizeParam/fDefaultBufferPeriodParam);
fDefaultBitRateParamChangeTime = fDefaultChunkSizeParamChangeTime;
bitRateUpdated = true;
}
}
}
break;
case DEFAULT_BIT_RATE_PARAM:
fprintf(stderr,"(DEFAULT_BIT_RATE_PARAM,size=%i",dataSize);
if (dataSize < sizeof(float)) {
fprintf(stderr,")\n");
fprintf(stderr,"<- B_BAD_VALUE\n",param);
status = B_BAD_VALUE;
} else {
float newDefaultBitRate = *((float*)event->user_data);
fprintf(stderr,",%f)\n",newDefaultBitRate);
// ignore non positive bitrates
if ((newDefaultBitRate > 0) && (newDefaultBitRate != fDefaultBitRateParam)) {
fprintf(stderr," got a new bit rate, old bit rate was %i\n",fDefaultBitRateParam);
fDefaultBitRateParam = newDefaultBitRate;
fDefaultBitRateParamChangeTime = TimeSource()->Now();
bitRateUpdated = true;
if (fLeastRecentlyUpdatedParameter == DEFAULT_BIT_RATE_PARAM) {
// Okay we were the least recently updated parameter,
// but we just got an update so we are no longer that.
// Let's figure out who the new least recently updated
// parameter is. We are going to prefer to compute the
// chunk size since you usually don't want to muck with
// the buffer period. However, if you just set the chunk size
// then we are stuck with making the buffer period the new
// parameter to be computed.
if (fLastUpdatedParameter == DEFAULT_CHUNK_SIZE_PARAM) {
fLeastRecentlyUpdatedParameter = DEFAULT_BUFFER_PERIOD_PARAM;
} else {
fLeastRecentlyUpdatedParameter = DEFAULT_CHUNK_SIZE_PARAM;
}
}
// we just got an update, so we are the new lastUpdatedParameter
fLastUpdatedParameter = DEFAULT_BIT_RATE_PARAM;
// now we have to compute the new value for the leastRecentlyUpdatedParameter
// we use the bit rate change time to preserve "simultaneity" information
if (fLeastRecentlyUpdatedParameter == DEFAULT_BUFFER_PERIOD_PARAM) {
int64 value = int64(8000000/1024*fDefaultChunkSizeParam/fDefaultBitRateParam);
if (value > INT_MAX) {
// clamp to INT_MAX
fDefaultBufferPeriodParam = INT_MAX;
// recompute bit rate
fDefaultBitRateParam = MAX(0.001,8000000/1024*fDefaultChunkSizeParam/fDefaultBufferPeriodParam);
} else {
fDefaultBufferPeriodParam = MAX(1,int32(value));
}
fDefaultBufferPeriodParamChangeTime = fDefaultBitRateParamChangeTime;
bufferPeriodUpdated = true;
} else { // must have been chunk size
int64 value = int64(1024/8000000*fDefaultBitRateParam*fDefaultBufferPeriodParam);
if (value > INT_MAX) {
// clamp to INT_MAX
fDefaultChunkSizeParam = INT_MAX;
// recompute bit rate
fDefaultBitRateParam = MAX(0.001,8000000/1024*fDefaultChunkSizeParam/fDefaultBufferPeriodParam);
} else {
fDefaultChunkSizeParam = MAX(1,int32(value));
}
fDefaultChunkSizeParamChangeTime = fDefaultBitRateParamChangeTime;
chunkSizeUpdated = true;
}
}
}
break;
case DEFAULT_BUFFER_PERIOD_PARAM:
fprintf(stderr,"(DEFAULT_BUFFER_PERIOD_PARAM,size=%i",dataSize);
if (dataSize < sizeof(int32)) {
fprintf(stderr,")\n");
fprintf(stderr,"<- B_BAD_VALUE\n",param);
status = B_BAD_VALUE;
} else {
int32 newBufferPeriod = *((int32*)event->user_data);
fprintf(stderr,",%i)\n",newBufferPeriod);
// ignore non positive buffer period
if ((newBufferPeriod > 0) && (newBufferPeriod != fDefaultBufferPeriodParam)) {
fprintf(stderr," got a new buffer period, old buffer period was %i\n",fDefaultBufferPeriodParam);
fDefaultBufferPeriodParam = newBufferPeriod;
fDefaultBufferPeriodParamChangeTime = TimeSource()->Now();
bufferPeriodUpdated = true;
if (fLastUpdatedParameter == DEFAULT_BUFFER_PERIOD_PARAM) {
// prefer to update bit rate, unless you just set it
if (fLastUpdatedParameter == DEFAULT_BIT_RATE_PARAM) {
fLeastRecentlyUpdatedParameter = DEFAULT_CHUNK_SIZE_PARAM;
} else {
fLeastRecentlyUpdatedParameter = DEFAULT_BIT_RATE_PARAM;
}
}
// we just got an update, so we are the new lastUpdatedParameter
fLastUpdatedParameter = DEFAULT_BUFFER_PERIOD_PARAM;
// now we have to compute the new value for the leastRecentlyUpdatedParameter
// we use the buffer period change time to preserve "simultaneity" information
if (fLeastRecentlyUpdatedParameter == DEFAULT_BIT_RATE_PARAM) {
fDefaultBitRateParam = MAX(0.001,8000000/1024*fDefaultChunkSizeParam/fDefaultBufferPeriodParam);
fDefaultBitRateParamChangeTime = fDefaultBufferPeriodParamChangeTime;
bitRateUpdated = true;
} else { // must have been chunk size
int64 value = int64(1024/8000000*fDefaultBitRateParam*fDefaultBufferPeriodParam);
if (value > INT_MAX) {
// clamp to INT_MAX
fDefaultChunkSizeParam = INT_MAX;
// recompute buffer period
fDefaultBufferPeriodParam = size_t(8000000/1024*fDefaultChunkSizeParam/fDefaultBitRateParam);
} else {
fDefaultChunkSizeParam = MAX(1,int32(value));
}
fDefaultChunkSizeParamChangeTime = fDefaultBufferPeriodParamChangeTime;
chunkSizeUpdated = true;
}
}
}
break;
default:
fprintf(stderr,"AbstractFileInterfaceNode::HandleParameter called with unknown param id (%i)\n",param);
status = B_ERROR;
}
// send updates out for all the parameters that changed
// in every case this should be two updates. (if I have not made an error :-) )
if (chunkSizeUpdated) {
fprintf(stderr," chunk size parameter updated\n");
BroadcastNewParameterValue(fDefaultChunkSizeParamChangeTime,
DEFAULT_CHUNK_SIZE_PARAM,
&fDefaultChunkSizeParam,
sizeof(fDefaultChunkSizeParam));
}
if (bitRateUpdated) {
fprintf(stderr," bit rate parameter updated\n");
BroadcastNewParameterValue(fDefaultBitRateParamChangeTime,
DEFAULT_BIT_RATE_PARAM,
&fDefaultBitRateParam,
sizeof(fDefaultBitRateParam));
}
if (bufferPeriodUpdated) {
fprintf(stderr," buffer period parameter updated\n");
BroadcastNewParameterValue(fDefaultBufferPeriodParamChangeTime,
DEFAULT_BUFFER_PERIOD_PARAM,
&fDefaultBufferPeriodParam,
sizeof(fDefaultBufferPeriodParam));
}
return status;
}
// -------------------------------------------------------- //
// AbstractFileInterfaceNode specific functions
// -------------------------------------------------------- //
// public:
flavor_info * AbstractFileInterfaceNode::GetFlavor(int32 id)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetFlavor\n");
static bool initialized = false;
static flavor_info info;
if (initialized == false) {
info.name = "AbstractFileInterfaceNode";
info.info = "A AbstractFileInterfaceNode node handles a file.";
info.kinds = B_FILE_INTERFACE | B_CONTROLLABLE;
info.flavor_flags = B_FLAVOR_IS_LOCAL;
info.possible_count = INT_MAX;
info.in_format_count = 0; // no inputs
info.in_formats = 0;
info.out_format_count = 0; // no outputs
info.out_formats = 0;
info.internal_id = id;
initialized = true;
}
return &info;
}
media_format * AbstractFileInterfaceNode::GetFormat()
{
fprintf(stderr,"AbstractFileInterfaceNode::GetFormat\n");
static bool initialized = false;
static media_format format;
if (initialized == false) {
format.type = B_MEDIA_MULTISTREAM;
format.require_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
format.deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
format.u.multistream = media_multistream_format::wildcard;
initialized = true;
}
return &format;
}
media_file_format * AbstractFileInterfaceNode::GetFileFormat()
{
fprintf(stderr,"AbstractFileInterfaceNode::GetFileFormat\n");
static bool initialized = false;
static media_file_format file_format;
if (initialized == false) {
file_format.capabilities =
media_file_format::B_PERFECTLY_SEEKABLE
| media_file_format::B_IMPERFECTLY_SEEKABLE
| media_file_format::B_KNOWS_ANYTHING;
/* I don't know what to initialize this to. (or if I should) */
// format.id =
file_format.family = B_ANY_FORMAT_FAMILY;
file_format.version = 100;
strcpy(file_format.mime_type,"");
strcpy(file_format.pretty_name,"any media file format");
strcpy(file_format.short_name,"any");
strcpy(file_format.file_extension,"");
initialized = true;
}
return &file_format;
}
// protected:
// Here we make some guesses based on the file's mime type.
// We don't have enough information to add any other requirements.
// This function doesn't complain if you have already decided you want
// the stream to be considered a different one. (so you can say that you
// want to read that mpeg file as avi if you are so nutty.)
//
status_t AbstractFileInterfaceNode::AddRequirements(media_format * format)
{
if (strcmp("video/x-msvideo",f_current_mime_type) == 0) {
if (format->u.multistream.format == media_multistream_format::wildcard.format) {
format->u.multistream.format = media_multistream_format::B_AVI;
}
} else
if (strcmp("video/mpeg",f_current_mime_type) == 0) {
if (format->u.multistream.format == media_multistream_format::wildcard.format) {
format->u.multistream.format = media_multistream_format::B_MPEG1;
}
} else
if (strcmp("video/quicktime",f_current_mime_type) == 0) {
if (format->u.multistream.format == media_multistream_format::wildcard.format) {
format->u.multistream.format = media_multistream_format::B_QUICKTIME;
}
} else
if (strcmp("audio/x-mpeg",f_current_mime_type) == 0) {
if (format->u.multistream.format == media_multistream_format::wildcard.format) {
format->u.multistream.format = media_multistream_format::B_MPEG1;
}
}
return B_OK;
}
// We need some sort of bit rate and chunk size, so if the other guy
// didn't care, we'll use our own defaults.
status_t AbstractFileInterfaceNode::ResolveWildcards(media_format * format)
{
fprintf(stderr,"AbstractFileInterfaceNode::ResolveWildcards\n");
// There isn't an unknown format. hmph.
// if (format->u.multistream.format == media_multistream_format::wildcard.format) {
// format->u.multistream.format = media_multistream_format::B_UNKNOWN;
// }
if (format->u.multistream.max_bit_rate == media_multistream_format::wildcard.max_bit_rate) {
format->u.multistream.max_bit_rate = fDefaultBitRateParam;
}
if (format->u.multistream.max_chunk_size == media_multistream_format::wildcard.max_chunk_size) {
format->u.multistream.max_chunk_size = fDefaultChunkSizeParam;
}
if (format->u.multistream.avg_bit_rate == media_multistream_format::wildcard.avg_bit_rate) {
format->u.multistream.avg_bit_rate = fDefaultBitRateParam;
}
if (format->u.multistream.avg_chunk_size == media_multistream_format::wildcard.avg_chunk_size) {
format->u.multistream.avg_chunk_size = fDefaultChunkSizeParam;
}
return B_OK;
}
// -------------------------------------------------------- //
// stuffing
// -------------------------------------------------------- //
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_0(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_1(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_2(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_3(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_4(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_5(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_6(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_7(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_8(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_9(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_10(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_11(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_12(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_13(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_14(void *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_15(void *) {}
@@ -0,0 +1,313 @@
// AbstractFileInterfaceNode.h
//
// Andrew Bachmann, 2002
//
// The AbstractFileInterfaceNode class implements
// the common functionality between MediaReader
// and MediaWriter.
#if !defined(_ABSTRACT_FILE_INTERFACE_NODE_H)
#define _ABSTRACT_FILE_INTERFACE_NODE_H
#include <MediaDefs.h>
#include <MediaNode.h>
#include <FileInterface.h>
#include <Controllable.h>
#include <MediaEventLooper.h>
#include <File.h>
#include <Entry.h>
#include <BufferGroup.h>
class AbstractFileInterfaceNode :
public BFileInterface,
public BControllable,
public BMediaEventLooper
{
protected:
virtual ~AbstractFileInterfaceNode(void);
public:
explicit AbstractFileInterfaceNode(
size_t defaultChunkSize = 8192, // chunk size = 8 KB
float defaultBitRate = 800000, // bit rate = 100.000 KB/sec = 5.85 MB/minute
const flavor_info * info = 0, // buffer period = 80 milliseconds
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 */
/***********************/
protected:
virtual BParameterWeb * MakeParameterWeb(void);
/*****************************/
/* begin from BFileInterface */
protected:
//included from BMediaNode
//virtual status_t HandleMessage(
// int32 message,
// const void * data,
// size_t size);
virtual status_t GetNextFileFormat(
int32 * cookie,
media_file_format * out_format);
virtual void DisposeFileFormatCookie(
int32 cookie);
virtual status_t GetDuration(
bigtime_t * out_time);
virtual status_t SniffRef(
const entry_ref & file,
char * out_mime_type, /* 256 bytes */
float * out_quality);
virtual status_t SetRef(
const entry_ref & file,
bool create,
bigtime_t * out_time) = 0;
virtual status_t SetRef(
const entry_ref & file,
uint32 openMode,
bool create,
bigtime_t * out_time);
virtual status_t GetRef(
entry_ref * out_ref,
char * out_mime_type);
/* end from BFileInterface */
/***************************/
// provided for BAbstractFileInterfaceNodeAddOn
public:
static status_t StaticSniffRef(
const entry_ref & file,
char * out_mime_type, /* 256 bytes */
float * out_quality);
/****************************/
/* begin from BControllable */
//included from BMediaNode
//virtual status_t HandleMessage(
// int32 message,
// const void * data,
// size_t size);
public:
/* These are alternate methods of accomplishing the same thing as */
/* connecting to control information source/destinations would. */
virtual status_t GetParameterValue(
int32 id,
bigtime_t * last_change,
void * value,
size_t * ioSize);
virtual void SetParameterValue(
int32 id,
bigtime_t when,
const void * value,
size_t size);
virtual status_t StartControlPanel(
BMessenger * out_messenger);
/* end from BControllable */
/**************************/
public:
// these three are related:
// DEFAULT_CHUNK_SIZE = (DEFAULT_BIT_RATE * 1024) * (DEFAULT_BUFFER_PERIOD / 8000000)
static const int32 DEFAULT_CHUNK_SIZE_PARAM; // in bytes
static const int32 DEFAULT_BIT_RATE_PARAM; // in 1000*kilobits/sec
static const int32 DEFAULT_BUFFER_PERIOD_PARAM; // milliseconds
private:
size_t fDefaultChunkSizeParam;
bigtime_t fDefaultChunkSizeParamChangeTime;
float fDefaultBitRateParam;
bigtime_t fDefaultBitRateParamChangeTime;
int32 fDefaultBufferPeriodParam;
bigtime_t fDefaultBufferPeriodParamChangeTime;
// This is used to figure out which parameter to compute
// when enforcing the above constraint relating the three params
int32 fLastUpdatedParameter;
int32 fLeastRecentlyUpdatedParameter;
/********************************/
/* 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) = 0;
virtual status_t HandleDataStatus(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false) = 0;
virtual status_t HandleParameter(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false);
public:
static flavor_info * GetFlavor(int32 id);
static media_format * GetFormat();
static media_file_format * GetFileFormat();
protected:
virtual status_t AddRequirements(media_format * format);
virtual status_t ResolveWildcards(media_format * format);
// accessors
inline BFile * GetCurrentFile() { return fCurrentFile; }
private:
AbstractFileInterfaceNode( /* private unimplemented */
const AbstractFileInterfaceNode & clone);
AbstractFileInterfaceNode & operator=(
const AbstractFileInterfaceNode & clone);
status_t fInitCheckStatus;
BMediaAddOn * fAddOn;
BFile * fCurrentFile;
entry_ref f_current_ref;
char f_current_mime_type[B_MIME_TYPE_LENGTH+1];
/* Mmmh, stuffing! */
virtual status_t _Reserved_AbstractFileInterfaceNode_0(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_1(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_2(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_3(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_4(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_5(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_6(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_7(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_8(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_9(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_10(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_11(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_12(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_13(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_14(void *);
virtual status_t _Reserved_AbstractFileInterfaceNode_15(void *);
uint32 _reserved_abstract_file_interface_node_[16];
};
#endif /* _ABSTRACT_FILE_INTERFACE_NODE_H */