* get reader.media_addon compiling (both gcc2 and 4)(used for testing BFileInterface node kind)

* warning/style fixes
* removed some dubious comments :)
* no behaviour changes so far...



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24714 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Maurice Kalinowski
2008-03-31 21:23:38 +00:00
parent 01533b17a2
commit fb16552f1d
7 changed files with 623 additions and 474 deletions
@@ -8,55 +8,49 @@
// AbstractFileInterfaceNode handles a file and a multistream
#include <MediaDefs.h>
#include <MediaAddOn.h>
#include <Errors.h>
#include <Node.h>
#include <Mime.h>
#include <StorageDefs.h>
#include "AbstractFileInterfaceNode.h"
#include "AbstractFileInterfaceAddOn.h"
#include "debug.h"
#include <Errors.h>
#include <MediaDefs.h>
#include <MediaAddOn.h>
#include <Mime.h>
#include <Node.h>
#include <StorageDefs.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
// instantiation function
extern "C" _EXPORT BMediaAddOn * make_media_addon(image_id image);
// {
// return new AbstractFileInterfaceAddOn(image);
// }
// -------------------------------------------------------- //
// ctor/dtor
// -------------------------------------------------------- //
AbstractFileInterfaceAddOn::~AbstractFileInterfaceAddOn()
{
}
AbstractFileInterfaceAddOn::AbstractFileInterfaceAddOn(image_id image) :
BMediaAddOn(image)
{
fprintf(stderr,"AbstractFileInterfaceAddOn::AbstractFileInterfaceAddOn\n");
CALLED();
refCount = 0;
}
// -------------------------------------------------------- //
// BMediaAddOn impl
// -------------------------------------------------------- //
status_t AbstractFileInterfaceAddOn::InitCheck(
const char ** out_failure_text)
{
fprintf(stderr,"AbstractFileInterfaceAddOn::InitCheck\n");
CALLED();
return B_OK;
}
int32 AbstractFileInterfaceAddOn::CountFlavors()
{
fprintf(stderr,"AbstractFileInterfaceAddOn::CountFlavors\n");
CALLED();
return 1;
}
@@ -64,70 +58,77 @@ status_t AbstractFileInterfaceAddOn::GetFlavorAt(
int32 n,
const flavor_info ** out_info)
{
fprintf(stderr,"AbstractFileInterfaceAddOn::GetFlavorAt\n");
CALLED();
if (out_info == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // we refuse to crash because you were stupid
}
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // avoid crash
}
if (n != 0) {
fprintf(stderr,"<- B_BAD_INDEX\n");
PRINT("\t<- B_BAD_INDEX\n");
return B_BAD_INDEX;
}
flavor_info * infos = new flavor_info[1];
AbstractFileInterfaceNode::GetFlavor(&infos[0],n);
(*out_info) = infos;
return B_OK;
}
status_t AbstractFileInterfaceAddOn::GetConfigurationFor(
BMediaNode * your_node,
BMessage * into_message)
{
fprintf(stderr,"AbstractFileInterfaceAddOn::GetConfigurationFor\n");
CALLED();
if (into_message == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // we refuse to crash because you were stupid
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // avoid crash
}
AbstractFileInterfaceNode * node
= dynamic_cast<AbstractFileInterfaceNode*>(your_node);
if (node == 0) {
fprintf(stderr,"<- B_BAD_TYPE\n");
PRINT("\t<- B_BAD_TYPE\n");
return B_BAD_TYPE;
}
return node->GetConfigurationFor(into_message);
}
bool AbstractFileInterfaceAddOn::WantsAutoStart()
{
fprintf(stderr,"AbstractFileInterfaceAddOn::WantsAutoStart\n");
CALLED();
return false;
}
status_t AbstractFileInterfaceAddOn::AutoStart(
int in_count,
BMediaNode ** out_node,
int32 * out_internal_id,
bool * out_has_more)
{
fprintf(stderr,"AbstractFileInterfaceAddOn::AutoStart\n");
CALLED();
return B_OK;
}
// -------------------------------------------------------- //
// BMediaAddOn impl for B_FILE_INTERFACE nodes
// -------------------------------------------------------- //
status_t AbstractFileInterfaceAddOn::SniffRef(
const entry_ref & file,
BMimeType * io_mime_type,
float * out_quality,
int32 * out_internal_id)
{
fprintf(stderr,"AbstractFileInterfaceAddOn::SniffRef\n");
CALLED();
if ((io_mime_type == 0) || (out_quality == 0) || (out_internal_id == 0)) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // we refuse to crash because you were stupid
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // avoid crash
}
*out_internal_id = 0; // only one flavor
char mime_string[B_MIME_TYPE_LENGTH+1];
status_t status = AbstractFileInterfaceNode::StaticSniffRef(file,mime_string,out_quality);
@@ -135,6 +136,7 @@ status_t AbstractFileInterfaceAddOn::SniffRef(
return status;
}
// even though I implemented SniffTypeKind below and this shouldn't get called,
// I am going to implement it anyway. I'll use it later anyhow.
status_t AbstractFileInterfaceAddOn::SniffType(
@@ -142,16 +144,19 @@ status_t AbstractFileInterfaceAddOn::SniffType(
float * out_quality,
int32 * out_internal_id)
{
fprintf(stderr,"AbstractFileInterfaceAddOn::SniffType\n");
CALLED();
if ((out_quality == 0) || (out_internal_id == 0)) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // we refuse to crash because you were stupid
}
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // avoid crash
}
*out_quality = 1.0;
*out_internal_id = 0;
return B_OK;
}
// This function treats null pointers slightly differently than the others.
// This is because a program could reasonably call this function with just
// about any junk, get the out_read_items or out_write_items and then use
@@ -168,23 +173,25 @@ status_t AbstractFileInterfaceAddOn::GetFileFormatList(
int32 * out_read_items,
void * _reserved)
{
fprintf(stderr,"AbstractFileInterfaceAddOn::GetFileFormatList\n");
CALLED();
if (flavor_id != 0) {
// this is a sanity check for now
fprintf(stderr,"<- B_BAD_INDEX\n");
PRINT("\t<- B_BAD_INDEX\n");
return B_BAD_INDEX;
}
// see null check comment above
if (out_write_items != 0) {
if (out_write_items != 0)
*out_write_items = 0;
}
// see null check comment above
if (out_read_items != 0) {
if (out_read_items != 0)
*out_read_items = 0;
}
return B_OK;
}
status_t AbstractFileInterfaceAddOn::SniffTypeKind(
const BMimeType & type,
uint64 in_kinds,
@@ -193,10 +200,11 @@ status_t AbstractFileInterfaceAddOn::SniffTypeKind(
int32 * out_internal_id,
void * _reserved)
{
fprintf(stderr,"AbstractFileInterfaceAddOn::SniffTypeKind\n");
CALLED();
if ((out_quality == 0) || (out_internal_id == 0)) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // we refuse to crash because you were stupid
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // avoid crash
}
if (in_kinds & (io_kind | B_FILE_INTERFACE | B_CONTROLLABLE)) {
return SniffType(type,out_quality,out_internal_id);
@@ -205,11 +213,12 @@ status_t AbstractFileInterfaceAddOn::SniffTypeKind(
// just in case they try to do something with it anyway (!)
*out_quality = 0;
*out_internal_id = -1;
fprintf(stderr,"<- B_BAD_TYPE\n");
PRINT("\t<- B_BAD_TYPE\n");
return B_BAD_TYPE;
}
}
// -------------------------------------------------------- //
// main
// -------------------------------------------------------- //
@@ -222,19 +231,19 @@ status_t AbstractFileInterfaceAddOn::SniffTypeKind(
// stuffing
// -------------------------------------------------------- //
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_0(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_1(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_2(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_3(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_4(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_5(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_6(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_7(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_8(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_9(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_10(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_11(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_12(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_13(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_14(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_15(void *) {};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_0(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_1(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_2(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_3(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_4(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_5(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_6(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_7(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_8(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_9(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_10(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_11(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_12(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_13(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_14(void *) {return B_ERROR;};
status_t AbstractFileInterfaceAddOn::_Reserved_AbstractFileInterfaceAddOn_15(void *) {return B_ERROR;};
@@ -5,69 +5,68 @@
// The AbstractFileInterfaceNode class implements
// the common functionality between MediaReader
// and MediaWriter.
#include "AbstractFileInterfaceNode.h"
#include "debug.h"
#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 <Controllable.h>
#include <Entry.h>
#include <Errors.h>
#include <File.h>
#include <FileInterface.h>
#include <MediaDefs.h>
#include <MediaEventLooper.h>
#include <MediaNode.h>
#include <TimeSource.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");
CALLED();
// Stop the BMediaEventLooper thread
Quit();
if (fCurrentFile != 0) {
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)
size_t defaultChunkSize,
float defaultBitRate,
const flavor_info * info,
BMessage * config,
BMediaAddOn * addOn)
: BMediaNode("AbstractFileInterfaceNode"),
BFileInterface(),
BControllable(),
BMediaEventLooper()
{
fprintf(stderr,"AbstractFileInterfaceNode::AbstractFileInterfaceNode\n");
CALLED();
// 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
@@ -85,99 +84,108 @@ AbstractFileInterfaceNode::AbstractFileInterfaceNode(
fInitCheckStatus = B_OK;
}
status_t AbstractFileInterfaceNode::InitCheck(void) const
{
fprintf(stderr,"AbstractFileInterfaceNode::InitCheck\n");
CALLED();
return fInitCheckStatus;
}
status_t AbstractFileInterfaceNode::GetConfigurationFor(
BMessage * into_message)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetConfigurationFor\n");
CALLED();
return B_OK;
}
// -------------------------------------------------------- //
// implementation of BMediaNode
// -------------------------------------------------------- //
BMediaAddOn * AbstractFileInterfaceNode::AddOn(
int32 * internal_id) const
{
fprintf(stderr,"AbstractFileInterfaceNode::AddOn\n");
CALLED();
// 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) {
if (internal_id != 0)
internal_id = 0;
}
}
return fAddOn;
}
void AbstractFileInterfaceNode::Start(
bigtime_t performance_time)
{
fprintf(stderr,"AbstractFileInterfaceNode::Start(pt=%lld)\n",performance_time);
PRINT("AbstractFileInterfaceNode::Start(pt=%lld)\n",performance_time);
BMediaEventLooper::Start(performance_time);
}
void AbstractFileInterfaceNode::Stop(
bigtime_t performance_time,
bool immediate)
{
if (immediate) {
fprintf(stderr,"AbstractFileInterfaceNode::Stop(pt=%lld,<immediate>)\n",performance_time);
} else {
fprintf(stderr,"AbstractFileInterfaceNode::Stop(pt=%lld,<scheduled>)\n",performance_time);
}
PRINT("AbstractFileInterfaceNode::Stop(pt=%lld, im=%d)\n",
performance_time, immediate);
BMediaEventLooper::Stop(performance_time,immediate);
}
void AbstractFileInterfaceNode::Seek(
bigtime_t media_time,
bigtime_t performance_time)
{
fprintf(stderr,"AbstractFileInterfaceNode::Seek(mt=%lld,pt=%lld)\n",media_time,performance_time);
PRINT("AbstractFileInterfaceNode::Seek(mt=%lld,pt=%lld)\n",
media_time,performance_time);
BMediaEventLooper::Seek(media_time,performance_time);
}
void AbstractFileInterfaceNode::SetRunMode(
run_mode mode)
{
fprintf(stderr,"AbstractFileInterfaceNode::SetRunMode(%i)\n",mode);
PRINT("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=%lld,pt=%lld)\n",at_real_time,to_performance_time);
PRINT("AbstractFileInterfaceNode::TimeWarp(rt=%lld,pt=%lld)\n",
at_real_time,to_performance_time);
BMediaEventLooper::TimeWarp(at_real_time,to_performance_time);
}
void AbstractFileInterfaceNode::Preroll(void)
{
fprintf(stderr,"AbstractFileInterfaceNode::Preroll\n");
CALLED();
// XXX:Performance opportunity
BMediaNode::Preroll();
}
void AbstractFileInterfaceNode::SetTimeSource(
BTimeSource * time_source)
{
fprintf(stderr,"AbstractFileInterfaceNode::SetTimeSource\n");
CALLED();
BMediaNode::SetTimeSource(time_source);
}
status_t AbstractFileInterfaceNode::HandleMessage(
int32 message,
const void * data,
size_t size)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleMessage\n");
CALLED();
status_t status = B_OK;
switch (message) {
// no special messages for now
@@ -186,6 +194,9 @@ status_t AbstractFileInterfaceNode::HandleMessage(
if (status == B_OK) {
break;
}
status = BControllable::HandleMessage(message, data, size);
if (status == B_OK)
break;
status = BMediaNode::HandleMessage(message,data,size);
if (status == B_OK) {
break;
@@ -197,23 +208,26 @@ status_t AbstractFileInterfaceNode::HandleMessage(
return status;
}
status_t AbstractFileInterfaceNode::RequestCompleted(
const media_request_info & info)
{
fprintf(stderr,"AbstractFileInterfaceNode::RequestCompleted\n");
CALLED();
return BMediaNode::RequestCompleted(info);
}
status_t AbstractFileInterfaceNode::DeleteHook(
BMediaNode * node)
{
fprintf(stderr,"AbstractFileInterfaceNode::DeleteHook\n");
CALLED();
return BMediaEventLooper::DeleteHook(node);
}
void AbstractFileInterfaceNode::NodeRegistered(void)
{
fprintf(stderr,"AbstractFileInterfaceNode::NodeRegistered\n");
CALLED();
// set up our parameter web
SetParameterWeb(MakeParameterWeb());
@@ -223,33 +237,36 @@ void AbstractFileInterfaceNode::NodeRegistered(void)
Run();
}
status_t AbstractFileInterfaceNode::GetNodeAttributes(
media_node_attribute * outAttributes,
size_t inMaxCount)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetNodeAttributes\n");
CALLED();
return BMediaNode::GetNodeAttributes(outAttributes,inMaxCount);
}
status_t AbstractFileInterfaceNode::AddTimer(
bigtime_t at_performance_time,
int32 cookie)
{
fprintf(stderr,"AbstractFileInterfaceNode::AddTimer\n");
CALLED();
return BMediaEventLooper::AddTimer(at_performance_time,cookie);
}
// protected:
// protected:
BParameterWeb * AbstractFileInterfaceNode::MakeParameterWeb(void)
{
fprintf(stderr,"AbstractFileInterfaceNode::MakeParameterWeb\n");
CALLED();
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
// 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(
@@ -277,76 +294,87 @@ BParameterWeb * AbstractFileInterfaceNode::MakeParameterWeb(void)
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
CALLED();
// avoid crashes
if (out_format == 0) {
// no place to write!
fprintf(stderr,"<- B_BAD_VALUE\n");
PRINT("\t<- 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");
PRINT("\t<- B_ERROR\n");
return B_ERROR;
}
// so next time they won't get the same format again
*cookie = 1;
}
GetFileFormat(out_format);
return B_OK;
}
void AbstractFileInterfaceNode::DisposeFileFormatCookie(
int32 cookie)
{
fprintf(stderr,"AbstractFileInterfaceNode::DisposeFileFormatCookie\n");
CALLED();
// nothing to do since our cookies are just integers
}
status_t AbstractFileInterfaceNode::GetDuration(
bigtime_t * out_time)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetDuration\n");
CALLED();
if (out_time == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE;
}
if (fCurrentFile == 0) {
fprintf(stderr,"<- B_NO_INIT\n");
PRINT("\t<- 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");
CALLED();
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");
CALLED();
if (out_time == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashes today thanks
}
status_t status;
f_current_ref = file;
if (fCurrentFile == 0) {
@@ -355,77 +383,88 @@ status_t AbstractFileInterfaceNode::SetRef(
} else {
status = fCurrentFile->SetTo(&f_current_ref,(openMode|(create?B_CREATE_FILE:0)));
}
if (status != B_OK) {
fprintf(stderr,"<- failed BFile initialization\n");
PRINT("\t<- 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");
CALLED();
if ((out_ref == 0) || (out_mime_type == 0)) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashes today thanks
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // avoid crash
}
if (fCurrentFile == 0) {
fprintf(stderr,"<- B_NO_INIT\n");
PRINT("\t<- 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
// 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");
CALLED();
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
}
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // avoid crash
}
BNode node(&file);
status_t initCheck = node.InitCheck();
if (initCheck != B_OK) {
fprintf(stderr,"<- failed BNode::InitCheck()\n");
PRINT("\t<- 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)) {
CALLED();
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)) {
@@ -455,19 +494,22 @@ status_t AbstractFileInterfaceNode::GetParameterValue(
break;
default:
fprintf(stderr,"AbstractFileInterfaceNode::GetParameterValue unknown id (%i)\n",id);
PRINT("AbstractFileInterfaceNode::GetParameterValue unknown id (%ld)\n",id);
return B_ERROR;
}
return B_OK;
return B_OK;
}
void AbstractFileInterfaceNode::SetParameterValue(
int32 id,
bigtime_t when,
const void * value,
size_t size)
{
fprintf(stderr,"AbstractFileInterfaceNode::SetParameterValue(id=%i,when=%lld,size=%i)\n",id,when,int32(size));
PRINT("AbstractFileInterfaceNode::SetParameterValue(id=%ld,when=%lld,size=%ld)\n",id,when,int32(size));
switch (id) {
case DEFAULT_CHUNK_SIZE_PARAM:
case DEFAULT_BIT_RATE_PARAM:
@@ -481,28 +523,30 @@ void AbstractFileInterfaceNode::SetParameterValue(
break;
default:
fprintf(stderr,"AbstractFileInterfaceNode::SetParameterValue unknown id (%i)\n",id);
PRINT("AbstractFileInterfaceNode::SetParameterValue unknown id (%ld)\n",id);
break;
}
}
// the default implementation should call the add-on main()
status_t AbstractFileInterfaceNode::StartControlPanel(
BMessenger * out_messenger)
{
BControllable::StartControlPanel(out_messenger);
CALLED();
return BControllable::StartControlPanel(out_messenger);
}
// -------------------------------------------------------- //
// implementation for BMediaEventLooper
// -------------------------------------------------------- //
void AbstractFileInterfaceNode::HandleEvent(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
bool realTimeEvent)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleEvent\n");
CALLED();
switch (event->type) {
case BTimedEventQueue::B_START:
HandleStart(event,lateness,realTimeEvent);
@@ -528,32 +572,35 @@ void AbstractFileInterfaceNode::HandleEvent(
HandleParameter(event,lateness,realTimeEvent);
break;
default:
fprintf(stderr," unknown event type: %i\n",event->type);
PRINT(" unknown event type: %ld\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");
CALLED();
return BMediaEventLooper::OfflineTime();
// XXX: do something else?
// if (inputFile == 0) {
// return 0;
// } else {
// return inputFile->Position();
// }
// XXX: do something else?
// 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: */
@@ -562,80 +609,91 @@ void AbstractFileInterfaceNode::ControlLoop() {
BMediaEventLooper::ControlLoop();
}
// protected:
// protected:
status_t AbstractFileInterfaceNode::HandleStart(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
bool realTimeEvent)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleStart()\n");
CALLED();
if (RunState() != B_STARTED) {
// XXX: Either use the following line or the lines that are not commented.
// There doesn't seem to be a practical difference that i can tell.
// HandleBuffer(event,lateness,realTimeEvent);
// XXX: Either use the following line or the lines that are not commented.
// There doesn't seem to be a practical difference that i can tell.
// HandleBuffer(event,lateness,realTimeEvent);
media_timed_event firstBufferEvent(event->event_time, BTimedEventQueue::B_HANDLE_BUFFER);
HandleEvent(&firstBufferEvent, 0, false);
EventQueue()->AddEvent(firstBufferEvent);
}
return B_OK;
}
status_t AbstractFileInterfaceNode::HandleSeek(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
bool realTimeEvent)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleSeek(t=%lld,d=%i,bd=%lld)\n",event->event_time,event->data,event->bigdata);
if (fCurrentFile != 0) {
fCurrentFile->Seek(event->bigdata,SEEK_SET);
}
PRINT("AbstractFileInterfaceNode::HandleSeek(t=%lld,d=%ld,bd=%lld)\n",event->event_time,event->data,event->bigdata);
if (fCurrentFile != 0)
return fCurrentFile->Seek(event->bigdata,SEEK_SET);
else
return B_ERROR;
}
status_t AbstractFileInterfaceNode::HandleWarp(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
bool realTimeEvent)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleWarp\n");
CALLED();
return B_OK;
}
status_t AbstractFileInterfaceNode::HandleStop(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
bool realTimeEvent)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleStop\n");
CALLED();
// flush the queue so downstreamers don't get any more
EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER);
return B_OK;
}
status_t AbstractFileInterfaceNode::HandleParameter(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
bool realTimeEvent)
{
fprintf(stderr,"AbstractFileInterfaceNode::HandleParameter");
CALLED();
status_t status = B_OK;
bool chunkSizeUpdated = false, bitRateUpdated = false, bufferPeriodUpdated = false;
size_t dataSize = size_t(event->data);
int64 param = int64(event->bigdata);
switch (param) {
case DEFAULT_CHUNK_SIZE_PARAM:
fprintf(stderr,"(DEFAULT_CHUNK_SIZE_PARAM,size=%i",dataSize);
PRINT("(DEFAULT_CHUNK_SIZE_PARAM,size=%ld",dataSize);
if (dataSize < sizeof(size_t)) {
fprintf(stderr,")\n");
fprintf(stderr,"<- B_BAD_VALUE\n",param);
PRINT("\ŧ<- B_BAD_VALUE: %lld\n",param);
status = B_BAD_VALUE;
} else {
size_t newDefaultChunkSize = *((size_t*)event->user_data);
fprintf(stderr,",%i)\n",newDefaultChunkSize);
PRINT(",%ld)\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);
PRINT("\tgot a new chunk size, old chunk size was %ld\n",fDefaultChunkSizeParam);
fDefaultChunkSizeParam = newDefaultChunkSize;
fDefaultChunkSizeParamChangeTime = TimeSource()->Now();
chunkSizeUpdated = true;
@@ -648,11 +706,10 @@ status_t AbstractFileInterfaceNode::HandleParameter(
// 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) {
if (fLastUpdatedParameter == DEFAULT_BIT_RATE_PARAM)
fLeastRecentlyUpdatedParameter = DEFAULT_BUFFER_PERIOD_PARAM;
} else {
else
fLeastRecentlyUpdatedParameter = DEFAULT_BIT_RATE_PARAM;
}
}
// we just got an update, so we are the new lastUpdatedParameter
fLastUpdatedParameter = DEFAULT_CHUNK_SIZE_PARAM;
@@ -679,17 +736,16 @@ status_t AbstractFileInterfaceNode::HandleParameter(
}
break;
case DEFAULT_BIT_RATE_PARAM:
fprintf(stderr,"(DEFAULT_BIT_RATE_PARAM,size=%i",dataSize);
PRINT("(DEFAULT_BIT_RATE_PARAM,size=%ld",dataSize);
if (dataSize < sizeof(float)) {
fprintf(stderr,")\n");
fprintf(stderr,"<- B_BAD_VALUE\n",param);
PRINT("\t<- B_BAD_VALUE:lld\n",param);
status = B_BAD_VALUE;
} else {
float newDefaultBitRate = *((float*)event->user_data);
fprintf(stderr,",%f)\n",newDefaultBitRate);
PRINT(",%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);
PRINT("\tgot a new bit rate, old bit rate was %ld\n",fDefaultBitRateParam);
fDefaultBitRateParam = newDefaultBitRate;
fDefaultBitRateParamChangeTime = TimeSource()->Now();
bitRateUpdated = true;
@@ -713,24 +769,28 @@ status_t AbstractFileInterfaceNode::HandleParameter(
// 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);
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);
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);
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);
fDefaultBitRateParam =
MAX(0.001,8000000/1024*fDefaultChunkSizeParam/fDefaultBufferPeriodParam);
} else {
fDefaultChunkSizeParam = MAX(1,int32(value));
}
@@ -741,17 +801,17 @@ status_t AbstractFileInterfaceNode::HandleParameter(
}
break;
case DEFAULT_BUFFER_PERIOD_PARAM:
fprintf(stderr,"(DEFAULT_BUFFER_PERIOD_PARAM,size=%i",dataSize);
PRINT("(DEFAULT_BUFFER_PERIOD_PARAM,size=%ld",dataSize);
if (dataSize < sizeof(int32)) {
fprintf(stderr,")\n");
fprintf(stderr,"<- B_BAD_VALUE\n",param);
PRINT("\t<- B_BAD_VALUE:%ld\n",param);
status = B_BAD_VALUE;
} else {
int32 newBufferPeriod = *((int32*)event->user_data);
fprintf(stderr,",%i)\n",newBufferPeriod);
PRINT(",%ld)\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);
PRINT("\tgot a new buffer period, old buffer period was %ld\n",
fDefaultBufferPeriodParam);
fDefaultBufferPeriodParam = newBufferPeriod;
fDefaultBufferPeriodParamChangeTime = TimeSource()->Now();
bufferPeriodUpdated = true;
@@ -768,7 +828,8 @@ status_t AbstractFileInterfaceNode::HandleParameter(
// 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);
fDefaultBitRateParam =
MAX(0.001,8000000/1024*fDefaultChunkSizeParam/fDefaultBufferPeriodParam);
fDefaultBitRateParamChangeTime = fDefaultBufferPeriodParamChangeTime;
bitRateUpdated = true;
} else { // must have been chunk size
@@ -777,7 +838,8 @@ status_t AbstractFileInterfaceNode::HandleParameter(
// clamp to INT_MAX
fDefaultChunkSizeParam = INT_MAX;
// recompute buffer period
fDefaultBufferPeriodParam = size_t(8000000/1024*fDefaultChunkSizeParam/fDefaultBitRateParam);
fDefaultBufferPeriodParam =
size_t(8000000/1024*fDefaultChunkSizeParam/fDefaultBitRateParam);
} else {
fDefaultChunkSizeParam = MAX(1,int32(value));
}
@@ -788,27 +850,27 @@ status_t AbstractFileInterfaceNode::HandleParameter(
}
break;
default:
fprintf(stderr,"AbstractFileInterfaceNode::HandleParameter called with unknown param id (%i)\n",param);
PRINT("AbstractFileInterfaceNode::HandleParameter called with unknown param id (%ld)\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");
PRINT("\tchunk size parameter updated\n");
BroadcastNewParameterValue(fDefaultChunkSizeParamChangeTime,
DEFAULT_CHUNK_SIZE_PARAM,
&fDefaultChunkSizeParam,
sizeof(fDefaultChunkSizeParam));
}
if (bitRateUpdated) {
fprintf(stderr," bit rate parameter updated\n");
PRINT("\tbit rate parameter updated\n");
BroadcastNewParameterValue(fDefaultBitRateParamChangeTime,
DEFAULT_BIT_RATE_PARAM,
&fDefaultBitRateParam,
sizeof(fDefaultBitRateParam));
}
if (bufferPeriodUpdated) {
fprintf(stderr," buffer period parameter updated\n");
PRINT("\tbuffer period parameter updated\n");
BroadcastNewParameterValue(fDefaultBufferPeriodParamChangeTime,
DEFAULT_BUFFER_PERIOD_PARAM,
&fDefaultBufferPeriodParam,
@@ -817,20 +879,19 @@ status_t AbstractFileInterfaceNode::HandleParameter(
return status;
}
// -------------------------------------------------------- //
// AbstractFileInterfaceNode specific functions
// -------------------------------------------------------- //
// public:
void AbstractFileInterfaceNode::GetFlavor(flavor_info * info, int32 id)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetFlavor\n");
if (info == 0) {
CALLED();
if (info == 0)
return;
}
info->name = "AbstractFileInterfaceNode";
info->info = "A AbstractFileInterfaceNode node handles a file.";
info->name = strdup("AbstractFileInterfaceNode");
info->info = strdup("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;
@@ -842,24 +903,28 @@ void AbstractFileInterfaceNode::GetFlavor(flavor_info * info, int32 id)
return;
}
void AbstractFileInterfaceNode::GetFormat(media_format * outFormat)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetFormat\n");
if (outFormat == 0) {
CALLED();
if (outFormat == 0)
return;
}
outFormat->type = B_MEDIA_MULTISTREAM;
outFormat->require_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
outFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
outFormat->u.multistream = media_multistream_format::wildcard;
}
void AbstractFileInterfaceNode::GetFileFormat(media_file_format * outFileFormat)
{
fprintf(stderr,"AbstractFileInterfaceNode::GetFileFormat\n");
if (outFileFormat == 0) {
CALLED();
if (outFileFormat == 0)
return;
}
outFileFormat->capabilities =
media_file_format::B_PERFECTLY_SEEKABLE
| media_file_format::B_IMPERFECTLY_SEEKABLE
@@ -879,8 +944,8 @@ void AbstractFileInterfaceNode::GetFileFormat(media_file_format * outFileFormat)
outFileFormat->file_extension[7]='\0';
}
// protected:
// 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
@@ -912,15 +977,16 @@ status_t AbstractFileInterfaceNode::AddRequirements(media_format * format)
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;
// }
CALLED();
// 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;
}
@@ -936,23 +1002,23 @@ status_t AbstractFileInterfaceNode::ResolveWildcards(media_format * format)
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 *) {}
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_0(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_1(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_2(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_3(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_4(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_5(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_6(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_7(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_8(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_9(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_10(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_11(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_12(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_13(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_14(void *) { return B_ERROR; }
status_t AbstractFileInterfaceNode::_Reserved_AbstractFileInterfaceNode_15(void *) { return B_ERROR; }
@@ -9,14 +9,15 @@
#if !defined(_ABSTRACT_FILE_INTERFACE_NODE_H)
#define _ABSTRACT_FILE_INTERFACE_NODE_H
#include <BufferGroup.h>
#include <Controllable.h>
#include <Entry.h>
#include <File.h>
#include <FileInterface.h>
#include <MediaAddOn.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,
+1 -1
View File
@@ -1,7 +1,6 @@
SubDir HAIKU_TOP src add-ons media media-add-ons ;
# SubInclude HAIKU_TOP src add-ons media media-add-ons demultiplexer ;
# SubInclude HAIKU_TOP src add-ons media media-add-ons reader ;
# SubInclude HAIKU_TOP src add-ons media media-add-ons writer ;
SubInclude HAIKU_TOP src add-ons media media-add-ons dvb ;
SubInclude HAIKU_TOP src add-ons media media-add-ons esound_sink ;
@@ -10,6 +9,7 @@ SubInclude HAIKU_TOP src add-ons media media-add-ons mixer ;
SubInclude HAIKU_TOP src add-ons media media-add-ons multi_audio ;
SubInclude HAIKU_TOP src add-ons media media-add-ons opensound ;
SubInclude HAIKU_TOP src add-ons media media-add-ons radeon ;
SubInclude HAIKU_TOP src add-ons media media-add-ons reader ;
SubInclude HAIKU_TOP src add-ons media media-add-ons tone_producer_demo ;
SubInclude HAIKU_TOP src add-ons media media-add-ons usb_vision ;
SubInclude HAIKU_TOP src add-ons media media-add-ons usb_webcam ;
@@ -2,12 +2,13 @@ SubDir HAIKU_TOP src add-ons media media-add-ons reader ;
UsePrivateHeaders media ;
Addon reader.media_addon :
../AbstractFileInterfaceNode.cpp
../AbstractFileInterfaceAddOn.cpp
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons media media-add-ons ] ;
Application reader.media_addon :
AbstractFileInterfaceNode.cpp
AbstractFileInterfaceAddOn.cpp
MediaReader.cpp
MediaReaderAddOn.cpp
misc.cpp
: be media
: true
;
@@ -8,34 +8,32 @@
// which is a multistream.
//
// see also MediaReaderAddOn.cpp
#include <MediaDefs.h>
#include <MediaNode.h>
#include <MediaAddOn.h>
#include <BufferProducer.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 <MediaRoster.h>
#include <limits.h>
#include "../AbstractFileInterfaceNode.h"
#include "MediaReader.h"
#include "misc.h"
#include "debug.h"
#include <Buffer.h>
#include <BufferGroup.h>
#include <BufferProducer.h>
#include <Controllable.h>
#include <Entry.h>
#include <Errors.h>
#include <File.h>
#include <FileInterface.h>
#include <MediaAddOn.h>
#include <MediaDefs.h>
#include <MediaEventLooper.h>
#include <MediaNode.h>
#include <MediaRoster.h>
#include <ParameterWeb.h>
#include <TimeSource.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
// -------------------------------------------------------- //
// ctor/dtor
// -------------------------------------------------------- //
MediaReader::~MediaReader(void)
{
@@ -47,17 +45,19 @@ MediaReader::~MediaReader(void)
}
}
MediaReader::MediaReader(
size_t defaultChunkSize = 8192,
float defaultBitRate = 800000,
const flavor_info * info = 0,
BMessage * config = 0,
BMediaAddOn * addOn = 0)
size_t defaultChunkSize,
float defaultBitRate,
const flavor_info * info,
BMessage * config,
BMediaAddOn * addOn)
: BMediaNode("MediaReader"),
AbstractFileInterfaceNode(defaultChunkSize,defaultBitRate,info,config,addOn),
BBufferProducer(B_MEDIA_MULTISTREAM)
BBufferProducer(B_MEDIA_MULTISTREAM),
AbstractFileInterfaceNode(defaultChunkSize, defaultBitRate, info, config, addOn)
{
fprintf(stderr,"MediaReader::MediaReader\n");
CALLED();
// null some fields
fBufferGroup = 0;
// start enabled
@@ -72,24 +72,27 @@ MediaReader::MediaReader(
GetFormat(&output.format);
}
// -------------------------------------------------------- //
// implementation of BMediaNode
// -------------------------------------------------------- //
void MediaReader::Preroll(void)
{
fprintf(stderr,"MediaReader::Preroll\n");
CALLED();
// XXX:Performance opportunity
BMediaNode::Preroll();
}
status_t MediaReader::HandleMessage(
int32 message,
const void * data,
size_t size)
{
fprintf(stderr,"MediaReader::HandleMessage\n");
CALLED();
status_t status = B_OK;
switch (message) {
// no special messages for now
default:
@@ -100,12 +103,14 @@ status_t MediaReader::HandleMessage(
status = AbstractFileInterfaceNode::HandleMessage(message,data,size);
break;
}
return status;
}
void MediaReader::NodeRegistered(void)
{
fprintf(stderr,"MediaReader::NodeRegistered\n");
CALLED();
// now we can do this
output.node = Node();
@@ -116,27 +121,30 @@ void MediaReader::NodeRegistered(void)
AbstractFileInterfaceNode::NodeRegistered();
}
// -------------------------------------------------------- //
// implementation of BFileInterface
// -------------------------------------------------------- //
status_t MediaReader::SetRef(
const entry_ref & file,
bool create,
bigtime_t * out_time)
{
fprintf(stderr,"MediaReader::SetRef\n");
CALLED();
status_t status = AbstractFileInterfaceNode::SetRef(file,B_READ_ONLY,create,out_time);
if (status != B_OK) {
fprintf(stderr,"AbstractFileInterfaceNode::SetRef returned an error\n");
PRINT("AbstractFileInterfaceNode::SetRef returned an error\n");
return status;
}
if (output.destination == media_destination::null) {
// reset the format, and set the requirements imposed by this file
GetFormat(&output.format);
AddRequirements(&output.format);
return B_OK;
}
// if we are connected we may have to re-negotiate the connection
media_format format;
GetFormat(&format);
@@ -147,29 +155,30 @@ status_t MediaReader::SetRef(
}
// first try the easy way : SORRY DEPRECATED into private :-(
// this code from MediaWriter would be different for MediaReader even if it worked...
// int32 change_tag = NewChangeTag();
// status = this->BBufferConsumer::RequestFormatChange(output.source,output.destination,&format,&change_tag);
// if (status == B_OK) {
// fprintf(stderr," format change successful\n");
// return B_OK;
// }
// int32 change_tag = NewChangeTag();
// status = this->BBufferConsumer::RequestFormatChange(output.source,output.destination,&format,&change_tag);
// if (status == B_OK) {
// fprintf(stderr," format change successful\n");
// return B_OK;
// }
// okay, the hard way requires we get the MediaRoster
BMediaRoster * roster = BMediaRoster::Roster(&status);
if (roster == 0) {
if (roster == 0)
return B_MEDIA_SYSTEM_FAILURE;
}
if (status != B_OK) {
if (status != B_OK)
return status;
}
// before disconnect one should always stop the nodes (bebook says)
// requires run_state cast since the return type on RunState() is
// wrong [int32]
run_state destinationRunState = run_state(RunState());
if (destinationRunState == BMediaEventLooper::B_STARTED) {
if (destinationRunState == BMediaEventLooper::B_STARTED)
Stop(0,true); // stop us right now
}
// should also stop the destination if it is running, but how?
/* BMediaNode destinationNode = ??
/* BMediaNode destinationNode = ??
run_state destinationRunState = destinationNode->??;
status = destinationNode->StopNode(??,0,true);
if (status != B_OK) {
@@ -179,17 +188,17 @@ status_t MediaReader::SetRef(
media_destination outputDestination = output.destination;
status = roster->Disconnect(output.source.id,output.source,
output.destination.id,output.destination);
if (status != B_OK) {
if (status != B_OK)
return status;
}
// if that went okay, we'll try reconnecting
media_output connectOutput;
media_input connectInput;
status = roster->Connect(output.source,outputDestination,
&format,&connectOutput,&connectInput);
if (status != B_OK) {
if (status != B_OK)
return status;
}
// now restart if necessary
if (destinationRunState == BMediaEventLooper::B_STARTED) {
Start(0);
@@ -197,6 +206,7 @@ status_t MediaReader::SetRef(
return status;
}
// -------------------------------------------------------- //
// implemention of BBufferProducer
// -------------------------------------------------------- //
@@ -209,20 +219,24 @@ status_t MediaReader::FormatSuggestionRequested(
int32 quality,
media_format * format)
{
fprintf(stderr,"MediaReader::FormatSuggestionRequested\n");
CALLED();
if (format == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashing
}
if ((type != B_MEDIA_MULTISTREAM) && (type != B_MEDIA_UNKNOWN_TYPE)) {
fprintf(stderr,"<- B_MEDIA_BAD_FORMAT\n");
PRINT("\t<- B_MEDIA_BAD_FORMAT\n");
return B_MEDIA_BAD_FORMAT;
}
GetFormat(format);
AddRequirements(format);
return B_OK;
}
// 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.
@@ -230,16 +244,17 @@ status_t MediaReader::FormatProposal(
const media_source & output_source,
media_format * format)
{
fprintf(stderr,"MediaReader::FormatProposal\n");
CALLED();
if (format == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashing
}
if (output.source != output_source) {
fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
PRINT("\t<- B_MEDIA_BAD_SOURCE\n");
return B_MEDIA_BAD_SOURCE; // we only have one output so that better be it
}
/* media_format * myFormat = GetFormat();
/* media_format * myFormat = GetFormat();
fprintf(stderr,"proposed format: ");
print_media_format(format);
fprintf(stderr,"\n");
@@ -247,17 +262,18 @@ status_t MediaReader::FormatProposal(
print_media_format(myFormat);
fprintf(stderr,"\n"); */
// Be's format_is_compatible doesn't work.
// if (!format_is_compatible(*format,*myFormat)) {
// if (!format_is_compatible(*format,*myFormat)) {
media_format myFormat;
GetFormat(&myFormat);
if (!format_is_acceptible(*format,myFormat)) {
fprintf(stderr,"<- B_MEDIA_BAD_FORMAT\n");
PRINT("\t<- B_MEDIA_BAD_FORMAT\n");
return B_MEDIA_BAD_FORMAT;
}
AddRequirements(format);
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
@@ -268,39 +284,43 @@ status_t MediaReader::FormatChangeRequested(
media_format * io_format,
int32 * _deprecated_)
{
fprintf(stderr,"MediaReader::FormatChangeRequested\n");
CALLED();
if (io_format == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashing
}
if (output.source != source) {
fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
PRINT("\t<- B_MEDIA_BAD_SOURCE\n");
return B_MEDIA_BAD_SOURCE;
}
status_t status = FormatProposal(source,io_format);
if (status != B_OK) {
fprintf(stderr," error returned by FormatProposal\n");
PRINT("\terror returned by FormatProposal\n");
GetFormat(io_format);
return status;
}
return ResolveWildcards(io_format);
}
status_t MediaReader::GetNextOutput( /* cookie starts as 0 */
int32 * cookie,
media_output * out_output)
{
fprintf(stderr,"MediaReader::GetNextOutput\n");
CALLED();
// let's not crash even if they are stupid
if (out_output == 0) {
// no place to write!
fprintf(stderr,"<- B_BAD_VALUE\n");
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE;
}
if (cookie != 0) {
// it's valid but they already got our 1 output
if (*cookie != 0) {
fprintf(stderr,"<- B_ERROR (no more outputs)\n");
PRINT("\t<- B_ERROR (no more outputs)\n");
return B_ERROR;
}
// so next time they won't get the same output again
@@ -310,27 +330,29 @@ status_t MediaReader::GetNextOutput( /* cookie starts as 0 */
return B_OK;
}
status_t MediaReader::DisposeOutputCookie(
int32 cookie)
{
fprintf(stderr,"MediaReader::DisposeOutputCookie\n");
CALLED();
// nothing to do since our cookies are just integers
return B_OK;
}
status_t MediaReader::SetBufferGroup(
const media_source & for_source,
BBufferGroup * group)
{
fprintf(stderr,"MediaReader::SetBufferGroup\n");
CALLED();
if (output.source != for_source) {
fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
PRINT("\t<- B_MEDIA_BAD_SOURCE\n");
return B_MEDIA_BAD_SOURCE; // we only have one output so that better be it
}
if (fBufferGroup != 0) {
if (fBufferGroup == group) {
if (fBufferGroup == group)
return B_OK; // time saver
}
delete fBufferGroup;
}
if (group != 0) {
@@ -352,32 +374,33 @@ status_t MediaReader::SetBufferGroup(
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);
PRINT("\tdownstream latency = %lld, buffer period = %lld, buffer count = %ld\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");
PRINT("\t<- B_NO_MEMORY\n");
return B_NO_MEMORY;
}
status_t status = fBufferGroup->InitCheck();
if (status != B_OK) {
fprintf(stderr,"<- fBufferGroup initialization failed\n");
PRINT("\t<- fBufferGroup initialization failed\n");
return status;
}
}
return B_OK;
}
/* 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. */
/* 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. */
status_t MediaReader::VideoClippingChanged(
const media_source & for_source,
int16 num_shorts,
@@ -388,18 +411,21 @@ status_t MediaReader::VideoClippingChanged(
return BBufferProducer::VideoClippingChanged(for_source,num_shorts,clip_data,display,_deprecated_);
}
status_t MediaReader::GetLatency(
bigtime_t * out_latency)
{
fprintf(stderr,"MediaReader::GetLatency\n");
CALLED();
if (out_latency == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE;
}
*out_latency = EventLatency() + SchedulingLatency();
return B_OK;
}
status_t MediaReader::PrepareToConnect(
const media_source & what,
const media_destination & where,
@@ -407,29 +433,34 @@ status_t MediaReader::PrepareToConnect(
media_source * out_source,
char * out_name)
{
fprintf(stderr,"MediaReader::PrepareToConnect\n");
CALLED();
if ((format == 0) || (out_source == 0) || (out_name == 0)) {
fprintf(stderr,"<- B_BAD_VALUE\n");
PRINT("\ŧ<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashes...
}
if (output.source != what) {
fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
PRINT("\t<- B_MEDIA_BAD_SOURCE\n");
return B_MEDIA_BAD_SOURCE;
}
if (output.destination != media_destination::null) {
fprintf(stderr,"<- B_MEDIA_ALREADY_CONNECTED\n");
PRINT("\t<- B_MEDIA_ALREADY_CONNECTED\n");
return B_MEDIA_ALREADY_CONNECTED;
}
}
status_t status = FormatChangeRequested(output.source,where,format,0);
if (status != B_OK) {
fprintf(stderr,"<- MediaReader::FormatChangeRequested failed\n");
PRINT("\t<- MediaReader::FormatChangeRequested failed\n");
return status;
}
// last check for wildcards and general validity
if (format->type != B_MEDIA_MULTISTREAM) {
fprintf(stderr,"<- B_MEDIA_BAD_FORMAT\n");
PRINT("\t<- B_MEDIA_BAD_FORMAT\n");
return B_MEDIA_BAD_FORMAT;
}
*out_source = output.source;
output.destination = where;
strncpy(out_name,output.name,B_MEDIA_NAME_LENGTH-1);
@@ -437,6 +468,7 @@ status_t MediaReader::PrepareToConnect(
return ResolveWildcards(format);
}
void MediaReader::Connect(
status_t error,
const media_source & source,
@@ -444,15 +476,16 @@ void MediaReader::Connect(
const media_format & format,
char * io_name)
{
fprintf(stderr,"MediaReader::Connect\n");
CALLED();
if (error != B_OK) {
fprintf(stderr,"<- error already\n");
PRINT("\t<- error already\n");
output.destination = media_destination::null;
GetFormat(&output.format);
return;
}
if (output.source != source) {
fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
PRINT("\t<- B_MEDIA_BAD_SOURCE\n");
output.destination = media_destination::null;
GetFormat(&output.format);
return;
@@ -473,7 +506,7 @@ void MediaReader::Connect(
* output.format.u.multistream.max_chunk_size
/ output.format.u.multistream.max_bit_rate);
fprintf(stderr," max chunk size = %i, max bit rate = %f, buffer period = %lld\n",
PRINT("\tmax chunk size = %ld, max bit rate = %f, buffer period = %lld\n",
output.format.u.multistream.max_chunk_size,
output.format.u.multistream.max_bit_rate,fBufferPeriod);
@@ -481,28 +514,32 @@ void MediaReader::Connect(
if (fBufferGroup == 0) {
status_t status = SetBufferGroup(output.source,0);
if (status != B_OK) {
fprintf(stderr,"<- SetBufferGroup failed\n");
PRINT("\t<- SetBufferGroup failed\n");
output.destination = media_destination::null;
GetFormat(&output.format);
return;
}
}
SetBufferDuration(fBufferPeriod);
if (GetCurrentFile() != 0) {
bigtime_t start, end;
uint8 * data = new uint8[output.format.u.multistream.max_chunk_size]; // <- buffer group buffer size
// buffer group buffer size
uint8 * data = new uint8[output.format.u.multistream.max_chunk_size];
BBuffer * buffer = 0;
ssize_t bytesRead = 0;
{ // timed section
start = TimeSource()->RealTime();
// first we try to use a real BBuffer
buffer = fBufferGroup->RequestBuffer(output.format.u.multistream.max_chunk_size,fBufferPeriod);
buffer = fBufferGroup->RequestBuffer(
output.format.u.multistream.max_chunk_size,fBufferPeriod);
if (buffer != 0) {
FillFileBuffer(buffer);
} else {
// didn't get a real BBuffer, try simulation by just a read from the disk
bytesRead = GetCurrentFile()->Read(data,output.format.u.multistream.max_chunk_size);
bytesRead = GetCurrentFile()->Read(
data, output.format.u.multistream.max_chunk_size);
}
end = TimeSource()->RealTime();
}
@@ -515,10 +552,10 @@ void MediaReader::Connect(
fInternalLatency = end - start;
fprintf(stderr," internal latency from disk read = %lld\n",fInternalLatency);
PRINT("\tinternal latency from disk read = %lld\n", fInternalLatency);
} else {
fInternalLatency = 100; // just guess
fprintf(stderr," internal latency guessed = %lld\n",fInternalLatency);
PRINT("\tinternal latency guessed = %lld\n", fInternalLatency);
}
SetEventLatency(fDownstreamLatency + fInternalLatency);
@@ -526,19 +563,22 @@ void MediaReader::Connect(
// XXX: do anything else?
}
void MediaReader::Disconnect(
const media_source & what,
const media_destination & where)
{
fprintf(stderr,"MediaReader::Disconnect\n");
CALLED();
if (output.destination != where) {
fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
PRINT("\t<- B_MEDIA_BAD_DESTINATION\n");
return;
}
if (output.source != what) {
fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
PRINT("\t<- B_MEDIA_BAD_SOURCE\n");
return;
}
output.destination = media_destination::null;
GetFormat(&output.format);
if (fBufferGroup != 0) {
@@ -548,12 +588,14 @@ void MediaReader::Disconnect(
}
}
void MediaReader::LateNoticeReceived(
const media_source & what,
bigtime_t how_much,
bigtime_t performance_time)
{
fprintf(stderr,"MediaReader::LateNoticeReceived\n");
CALLED();
if (what == output.source) {
switch (RunMode()) {
case B_OFFLINE:
@@ -579,64 +621,72 @@ void MediaReader::LateNoticeReceived(
// Okay you asked for it, we'll skip ahead in the file!
// We'll drop 1 buffer's worth
if (GetCurrentFile() == 0) {
fprintf(stderr,"MediaReader::LateNoticeReceived called without an GetCurrentFile() (!)\n");
PRINT("MediaReader::LateNoticeReceived called without"
"an GetCurrentFile() (!)\n");
} else {
GetCurrentFile()->Seek(output.format.u.multistream.max_chunk_size,SEEK_CUR);
}
break;
default:
// huh?? there aren't any more run modes.
fprintf(stderr,"MediaReader::LateNoticeReceived with unexpected run mode.\n");
PRINT("MediaReader::LateNoticeReceived with unexpected run mode.\n");
break;
}
}
}
void MediaReader::EnableOutput(
const media_source & what,
bool enabled,
int32 * _deprecated_)
{
fprintf(stderr,"MediaReader::EnableOutput\n");
CALLED();
if (output.source != what) {
fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
PRINT("\t<- B_MEDIA_BAD_SOURCE\n");
return;
}
fOutputEnabled = enabled;
}
status_t MediaReader::SetPlayRate(
int32 numer,
int32 denom)
{
BBufferProducer::SetPlayRate(numer,denom); // XXX: do something intelligent later
return BBufferProducer::SetPlayRate(numer,denom); // XXX: do something intelligent later
}
void MediaReader::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)
{
fprintf(stderr,"MediaReader::AdditionalBufferRequested\n");
CALLED();
if (output.source == source) {
BBuffer * buffer;
status_t status = GetFilledBuffer(&buffer);
if (status != B_OK) {
fprintf(stderr,"MediaReader::AdditionalBufferRequested got an error from GetFilledBuffer.\n");
PRINT("MediaReader::AdditionalBufferRequested got an error from GetFilledBuffer.\n");
return; // don't send the buffer
}
SendBuffer(buffer,output.destination);
}
}
void MediaReader::LatencyChanged(
const media_source & source,
const media_destination & destination,
bigtime_t new_latency,
uint32 flags)
{
fprintf(stderr,"MediaReader::LatencyChanged\n");
CALLED();
if ((output.source == source) && (output.destination == destination)) {
fDownstreamLatency = new_latency;
SetEventLatency(fDownstreamLatency + fInternalLatency);
@@ -645,33 +695,33 @@ void MediaReader::LatencyChanged(
// see SetBufferGroup
}
// -------------------------------------------------------- //
// implementation for BMediaEventLooper
// -------------------------------------------------------- //
// protected:
status_t MediaReader::HandleBuffer(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
bool realTimeEvent)
{
fprintf(stderr,"MediaReader::HandleBuffer\n");
if (output.destination == media_destination::null) {
CALLED();
if (output.destination == media_destination::null)
return B_MEDIA_NOT_CONNECTED;
}
status_t status = B_OK;
BBuffer * buffer = fBufferGroup->RequestBuffer(output.format.u.multistream.max_chunk_size,fBufferPeriod);
if (buffer != 0) {
status = FillFileBuffer(buffer);
if (status != B_OK) {
fprintf(stderr,"MediaReader::HandleEvent got an error from FillFileBuffer.\n");
PRINT("MediaReader::HandleEvent got an error from FillFileBuffer.\n");
buffer->Recycle();
} else {
if (fOutputEnabled) {
status = SendBuffer(buffer,output.destination);
if (status != B_OK) {
fprintf(stderr,"MediaReader::HandleEvent got an error from SendBuffer.\n");
PRINT("MediaReader::HandleEvent got an error from SendBuffer.\n");
buffer->Recycle();
}
} else {
@@ -685,30 +735,31 @@ status_t MediaReader::HandleBuffer(
return status;
}
status_t MediaReader::HandleDataStatus(
const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false)
bool realTimeEvent)
{
fprintf(stderr,"MediaReader::HandleDataStatus");
CALLED();
return SendDataStatus(event->data,output.destination,event->event_time);
}
// -------------------------------------------------------- //
// MediaReader specific functions
// -------------------------------------------------------- //
// static:
void MediaReader::GetFlavor(flavor_info * outInfo, int32 id)
{
fprintf(stderr,"MediaReader::GetFlavor\n");
if (outInfo == 0) {
CALLED();
if (outInfo == 0)
return;
}
AbstractFileInterfaceNode::GetFlavor(outInfo,id);
outInfo->name = "OpenBeOS Media Reader";
outInfo->info = "The OpenBeOS Media Reader reads a file and produces a multistream.";
outInfo->name = strdup("OpenBeOS Media Reader");
outInfo->info = strdup("The OpenBeOS Media Reader reads a file and produces a multistream.");
outInfo->kinds |= B_BUFFER_PRODUCER;
outInfo->out_format_count = 1; // 1 output
media_format * formats = new media_format[outInfo->out_format_count];
@@ -717,62 +768,71 @@ void MediaReader::GetFlavor(flavor_info * outInfo, int32 id)
return;
}
void MediaReader::GetFormat(media_format * outFormat)
{
fprintf(stderr,"MediaReader::GetFormat\n");
if (outFormat == 0) {
CALLED();
if (outFormat == 0)
return;
}
AbstractFileInterfaceNode::GetFormat(outFormat);
return;
}
void MediaReader::GetFileFormat(media_file_format * outFileFormat)
{
fprintf(stderr,"MediaReader::GetFileFormat\n");
if (outFileFormat == 0) {
CALLED();
if (outFileFormat == 0)
return;
}
AbstractFileInterfaceNode::GetFileFormat(outFileFormat);
outFileFormat->capabilities |= media_file_format::B_READABLE;
return;
}
// protected:
// protected:
status_t MediaReader::GetFilledBuffer(
BBuffer ** outBuffer)
{
fprintf(stderr,"MediaReader::GetFilledBuffer\n");
CALLED();
BBuffer * buffer = fBufferGroup->RequestBuffer(output.format.u.multistream.max_chunk_size,-1);
if (buffer == 0) {
// XXX: add a new buffer and get it
fprintf(stderr,"MediaReader::GetFilledBuffer needs a new buffer.\n");
PRINT("MediaReader::GetFilledBuffer needs a new buffer.\n");
return B_ERROR; // don't send the buffer
}
status_t status = FillFileBuffer(buffer);
*outBuffer = buffer;
return status;
}
status_t MediaReader::FillFileBuffer(
BBuffer * buffer)
{
fprintf(stderr,"MediaReader::FillFileBuffer\n");
CALLED();
if (GetCurrentFile() == 0) {
fprintf(stderr,"<- B_NO_INIT\n");
PRINT("\t<- B_NO_INIT\n");
return B_NO_INIT;
}
fprintf(stderr," %i buffer bytes used, %i buffer bytes available\n",
buffer->SizeUsed(),buffer->SizeAvailable());
PRINT("\t%ld buffer bytes used, %ld buffer bytes available\n",
buffer->SizeUsed(), buffer->SizeAvailable());
off_t position = GetCurrentFile()->Position();
ssize_t bytesRead = GetCurrentFile()->Read(buffer->Data(),buffer->SizeAvailable());
if (bytesRead < 0) {
fprintf(stderr,"<- B_FILE_ERROR\n");
PRINT("\t<- B_FILE_ERROR\n");
return B_FILE_ERROR; // some sort of file related error
}
fprintf(stderr," %i file bytes read at position %i.\n",
bytesRead,position);
PRINT("\t%ld file bytes read at position %ld.\n",
bytesRead, position);
buffer->SetSizeUsed(bytesRead);
media_header * header = buffer->Header();
header->type = B_MEDIA_MULTISTREAM;
@@ -785,23 +845,23 @@ status_t MediaReader::FillFileBuffer(
return B_OK;
}
// -------------------------------------------------------- //
// stuffing
// -------------------------------------------------------- //
status_t MediaReader::_Reserved_MediaReader_0(void *) {}
status_t MediaReader::_Reserved_MediaReader_1(void *) {}
status_t MediaReader::_Reserved_MediaReader_2(void *) {}
status_t MediaReader::_Reserved_MediaReader_3(void *) {}
status_t MediaReader::_Reserved_MediaReader_4(void *) {}
status_t MediaReader::_Reserved_MediaReader_5(void *) {}
status_t MediaReader::_Reserved_MediaReader_6(void *) {}
status_t MediaReader::_Reserved_MediaReader_7(void *) {}
status_t MediaReader::_Reserved_MediaReader_8(void *) {}
status_t MediaReader::_Reserved_MediaReader_9(void *) {}
status_t MediaReader::_Reserved_MediaReader_10(void *) {}
status_t MediaReader::_Reserved_MediaReader_11(void *) {}
status_t MediaReader::_Reserved_MediaReader_12(void *) {}
status_t MediaReader::_Reserved_MediaReader_13(void *) {}
status_t MediaReader::_Reserved_MediaReader_14(void *) {}
status_t MediaReader::_Reserved_MediaReader_15(void *) {}
status_t MediaReader::_Reserved_MediaReader_0(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_1(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_2(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_3(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_4(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_5(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_6(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_7(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_8(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_9(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_10(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_11(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_12(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_13(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_14(void *) { return B_ERROR; }
status_t MediaReader::_Reserved_MediaReader_15(void *) { return B_ERROR; }
@@ -6,99 +6,108 @@
// that can make MediaReader nodes
//
// MediaReader nodes read a file into a multistream
#include <MediaDefs.h>
#include <MediaAddOn.h>
#include <Errors.h>
#include <Node.h>
#include <Mime.h>
#include <StorageDefs.h>
#include "MediaReader.h"
#include "MediaReaderAddOn.h"
#include "debug.h"
#include <Errors.h>
#include <MediaAddOn.h>
#include <MediaDefs.h>
#include <MediaRoster.h>
#include <Mime.h>
#include <Node.h>
#include <StorageDefs.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
// instantiation function
extern "C" _EXPORT BMediaAddOn * make_media_addon(image_id image) {
return new MediaReaderAddOn(image);
}
// -------------------------------------------------------- //
// ctor/dtor
// -------------------------------------------------------- //
MediaReaderAddOn::~MediaReaderAddOn()
{
}
MediaReaderAddOn::MediaReaderAddOn(image_id image) :
AbstractFileInterfaceAddOn(image)
{
fprintf(stderr,"MediaReaderAddOn::MediaReaderAddOn\n");
CALLED();
}
// -------------------------------------------------------- //
// BMediaAddOn impl
// -------------------------------------------------------- //
status_t MediaReaderAddOn::GetFlavorAt(
int32 n,
const flavor_info ** out_info)
{
fprintf(stderr,"MediaReaderAddOn::GetFlavorAt\n");
CALLED();
if (out_info == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // we refuse to crash because you were stupid
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // avoid crash
}
if (n != 0) {
fprintf(stderr,"<- B_BAD_INDEX\n");
PRINT("\t<- B_BAD_INDEX\n");
return B_BAD_INDEX;
}
flavor_info * infos = new flavor_info[1];
MediaReader::GetFlavor(&infos[0],n);
(*out_info) = infos;
return B_OK;
}
BMediaNode * MediaReaderAddOn::InstantiateNodeFor(
const flavor_info * info,
BMessage * config,
status_t * out_error)
{
fprintf(stderr,"MediaReaderAddOn::InstantiateNodeFor\n");
CALLED();
if (out_error == 0) {
fprintf(stderr,"<- NULL\n");
return 0; // we refuse to crash because you were stupid
PRINT("\t<- NULL\n");
return 0; // avoid crash
}
// XXX: read from add-on's attributes
size_t defaultChunkSize = size_t(8192); // 8192 bytes = 8 Kilobytes
float defaultBitRate = 2048; // = 2048 kilobits/millisec = 256000 Kilobytes/sec
// = 2048 kilobits/millisec = 256000 Kilobytes/sec
float defaultBitRate = 2048;
MediaReader * node
= new MediaReader(defaultChunkSize,
defaultBitRate,
info,config,this);
if (node == 0) {
*out_error = B_NO_MEMORY;
fprintf(stderr,"<- B_NO_MEMORY\n");
PRINT("\t<- B_NO_MEMORY\n");
} else {
*out_error = node->InitCheck();
}
return node;
}
status_t MediaReaderAddOn::GetConfigurationFor(
BMediaNode * your_node,
BMessage * into_message)
{
fprintf(stderr,"MediaReaderAddOn::GetConfigurationFor\n");
CALLED();
if (into_message == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n");
return B_BAD_VALUE; // we refuse to crash because you were stupid
}
PRINT("\t<- B_BAD_VALUE\n");
return B_BAD_VALUE; // avoid crash
}
MediaReader * node
= dynamic_cast<MediaReader*>(your_node);
if (node == 0) {
@@ -108,6 +117,7 @@ status_t MediaReaderAddOn::GetConfigurationFor(
return node->GetConfigurationFor(into_message);
}
// -------------------------------------------------------- //
// BMediaAddOn impl for B_FILE_INTERFACE nodes
// -------------------------------------------------------- //
@@ -133,10 +143,11 @@ status_t MediaReaderAddOn::GetFileFormatList(
int32 * out_read_items,
void * _reserved)
{
fprintf(stderr,"MediaReaderAddOn::GetFileFormatList\n");
CALLED();
if (flavor_id != 0) {
// this is a sanity check for now
fprintf(stderr,"<- B_BAD_INDEX\n");
PRINT("\t<- B_BAD_INDEX\n");
return B_BAD_INDEX;
}
// see null check comment above
@@ -156,6 +167,7 @@ status_t MediaReaderAddOn::GetFileFormatList(
return B_OK;
}
status_t MediaReaderAddOn::SniffTypeKind(
const BMimeType & type,
uint64 in_kinds,
@@ -163,7 +175,7 @@ status_t MediaReaderAddOn::SniffTypeKind(
int32 * out_internal_id,
void * _reserved)
{
fprintf(stderr,"MediaReaderAddOn::SniffTypeKind\n");
CALLED();
return AbstractFileInterfaceAddOn::SniffTypeKind(type,in_kinds,
B_BUFFER_PRODUCER,
out_quality,out_internal_id,
@@ -173,29 +185,29 @@ status_t MediaReaderAddOn::SniffTypeKind(
// -------------------------------------------------------- //
// main
// -------------------------------------------------------- //
int main(int argc, char *argv[])
{
fprintf(stderr,"main called for MediaReaderAddOn\n");
return 0;
}
// -------------------------------------------------------- //
// stuffing
// -------------------------------------------------------- //
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_0(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_1(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_2(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_3(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_4(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_5(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_6(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_7(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_8(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_9(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_10(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_11(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_12(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_13(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_14(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_15(void *) {};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_0(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_1(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_2(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_3(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_4(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_5(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_6(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_7(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_8(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_9(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_10(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_11(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_12(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_13(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_14(void *) {return B_ERROR;};
status_t MediaReaderAddOn::_Reserved_MediaReaderAddOn_15(void *) {return B_ERROR;};