1 /* 2 * ESounD media addon for BeOS 3 * 4 * Copyright (c) 2006 François Revol (revol@free.fr) 5 * 6 * Based on Multi Audio addon for Haiku, 7 * Copyright (c) 2002, 2003 Jerome Duval (jerome.duval@free.fr) 8 * 9 * All rights reserved. 10 * Redistribution and use in source and binary forms, with or without modification, 11 * are permitted provided that the following conditions are met: 12 * 13 * - Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * - Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 25 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31 #ifndef _ESDSINK_NODE_H 32 #define _ESDSINK_NODE_H 33 34 #include <MediaDefs.h> 35 #include <MediaNode.h> 36 #include <FileInterface.h> 37 #include <BufferConsumer.h> 38 #include <BufferProducer.h> 39 #include <Controllable.h> 40 #include <MediaEventLooper.h> 41 #include <ParameterWeb.h> 42 #include <TimeSource.h> 43 #include <Controllable.h> 44 #include <File.h> 45 #include <Entry.h> 46 #include "ESDEndpoint.h" 47 48 //#define ENABLE_INPUT 1 49 //#define ENABLE_TS 1 50 51 /*bool format_is_acceptible( 52 const media_format & producer_format, 53 const media_format & consumer_format);*/ 54 55 class ESDSinkNode : 56 public BBufferConsumer, 57 #if ENABLE_INPUT 58 public BBufferProducer, 59 #endif 60 #ifdef ENABLE_TS 61 public BTimeSource, 62 #endif 63 public BMediaEventLooper, 64 public BControllable 65 { 66 protected: 67 virtual ~ESDSinkNode(void); 68 69 public: 70 71 explicit ESDSinkNode(BMediaAddOn *addon, char* name, BMessage * config); 72 73 virtual status_t InitCheck(void) const; 74 75 /*************************/ 76 /* begin from BMediaNode */ 77 public: 78 virtual BMediaAddOn* AddOn( 79 int32 * internal_id) const; /* Who instantiated you -- or NULL for app class */ 80 81 protected: 82 /* These don't return errors; instead, they use the global error condition reporter. */ 83 /* A node is required to have a queue of at least one pending command (plus TimeWarp) */ 84 /* and is recommended to allow for at least one pending command of each type. */ 85 /* Allowing an arbitrary number of outstanding commands might be nice, but apps */ 86 /* cannot depend on that happening. */ 87 virtual void Preroll(void); 88 89 public: 90 virtual status_t HandleMessage( 91 int32 message, 92 const void * data, 93 size_t size); 94 95 protected: 96 virtual void NodeRegistered(void); /* reserved 2 */ 97 virtual status_t RequestCompleted(const media_request_info &info); 98 virtual void SetTimeSource(BTimeSource *timeSource); 99 100 /* end from BMediaNode */ 101 /***********************/ 102 103 /******************************/ 104 /* begin from BBufferConsumer */ 105 106 //included from BMediaAddOn 107 //virtual status_t HandleMessage( 108 // int32 message, 109 // const void * data, 110 // size_t size); 111 112 /* Someone, probably the producer, is asking you about this format. Give */ 113 /* your honest opinion, possibly modifying *format. Do not ask upstream */ 114 /* producer about the format, since he's synchronously waiting for your */ 115 /* reply. */ 116 virtual status_t AcceptFormat( 117 const media_destination & dest, 118 media_format * format); 119 virtual status_t GetNextInput( 120 int32 * cookie, 121 media_input * out_input); 122 virtual void DisposeInputCookie( 123 int32 cookie); 124 virtual void BufferReceived( 125 BBuffer * buffer); 126 virtual void ProducerDataStatus( 127 const media_destination & for_whom, 128 int32 status, 129 bigtime_t at_performance_time); 130 virtual status_t GetLatencyFor( 131 const media_destination & for_whom, 132 bigtime_t * out_latency, 133 media_node_id * out_timesource); 134 virtual status_t Connected( 135 const media_source & producer, /* here's a good place to request buffer group usage */ 136 const media_destination & where, 137 const media_format & with_format, 138 media_input * out_input); 139 virtual void Disconnected( 140 const media_source & producer, 141 const media_destination & where); 142 /* The notification comes from the upstream producer, so he's already cool with */ 143 /* the format; you should not ask him about it in here. */ 144 virtual status_t FormatChanged( 145 const media_source & producer, 146 const media_destination & consumer, 147 int32 change_tag, 148 const media_format & format); 149 150 /* Given a performance time of some previous buffer, retrieve the remembered tag */ 151 /* of the closest (previous or exact) performance time. Set *out_flags to 0; the */ 152 /* idea being that flags can be added later, and the understood flags returned in */ 153 /* *out_flags. */ 154 virtual status_t SeekTagRequested( 155 const media_destination & destination, 156 bigtime_t in_target_time, 157 uint32 in_flags, 158 media_seek_tag * out_seek_tag, 159 bigtime_t * out_tagged_time, 160 uint32 * out_flags); 161 162 /* end from BBufferConsumer */ 163 /****************************/ 164 165 /******************************/ 166 /* begin from BBufferProducer */ 167 #if 0 168 virtual status_t FormatSuggestionRequested( media_type type, 169 int32 quality, 170 media_format* format); 171 172 virtual status_t FormatProposal( const media_source& output, 173 media_format* format); 174 175 virtual status_t FormatChangeRequested( const media_source& source, 176 const media_destination& destination, 177 media_format* io_format, 178 int32* _deprecated_); 179 virtual status_t GetNextOutput( int32* cookie, 180 media_output* out_output); 181 virtual status_t DisposeOutputCookie( int32 cookie); 182 183 virtual status_t SetBufferGroup( const media_source& for_source, 184 BBufferGroup* group); 185 186 virtual status_t PrepareToConnect( const media_source& what, 187 const media_destination& where, 188 media_format* format, 189 media_source* out_source, 190 char* out_name); 191 192 virtual void Connect( status_t error, 193 const media_source& source, 194 const media_destination& destination, 195 const media_format& format, 196 char* io_name); 197 198 virtual void Disconnect( const media_source& what, 199 const media_destination& where); 200 201 virtual void LateNoticeReceived( const media_source& what, 202 bigtime_t how_much, 203 bigtime_t performance_time); 204 205 virtual void EnableOutput( const media_source & what, 206 bool enabled, 207 int32* _deprecated_); 208 virtual void AdditionalBufferRequested( const media_source& source, 209 media_buffer_id prev_buffer, 210 bigtime_t prev_time, 211 const media_seek_tag* prev_tag); 212 #endif 213 /* end from BBufferProducer */ 214 /****************************/ 215 216 /*****************/ 217 /* BControllable */ 218 /*****************/ 219 220 /********************************/ 221 /* start from BMediaEventLooper */ 222 223 protected: 224 /* you must override to handle your events! */ 225 /* you should not call HandleEvent directly */ 226 virtual void HandleEvent( const media_timed_event *event, 227 bigtime_t lateness, 228 bool realTimeEvent = false); 229 230 /* end from BMediaEventLooper */ 231 /******************************/ 232 233 /********************************/ 234 /* start from BTimeSource */ 235 #ifdef ENABLE_TS 236 protected: 237 virtual void SetRunMode( run_mode mode); 238 virtual status_t TimeSourceOp( const time_source_op_info &op, 239 void *_reserved); 240 #endif 241 /* end from BTimeSource */ 242 /******************************/ 243 244 /********************************/ 245 /* start from BControllable */ 246 protected: 247 virtual status_t GetParameterValue( int32 id, 248 bigtime_t* last_change, 249 void* value, 250 size_t* ioSize); 251 virtual void SetParameterValue( int32 id, 252 bigtime_t when, 253 const void* value, 254 size_t size); 255 virtual BParameterWeb* MakeParameterWeb(); 256 257 /* end from BControllable */ 258 /******************************/ 259 260 protected: 261 262 virtual status_t HandleStart( 263 const media_timed_event *event, 264 bigtime_t lateness, 265 bool realTimeEvent = false); 266 virtual status_t HandleSeek( 267 const media_timed_event *event, 268 bigtime_t lateness, 269 bool realTimeEvent = false); 270 virtual status_t HandleWarp( 271 const media_timed_event *event, 272 bigtime_t lateness, 273 bool realTimeEvent = false); 274 virtual status_t HandleStop( 275 const media_timed_event *event, 276 bigtime_t lateness, 277 bool realTimeEvent = false); 278 virtual status_t HandleBuffer( 279 const media_timed_event *event, 280 bigtime_t lateness, 281 bool realTimeEvent = false); 282 virtual status_t HandleDataStatus( 283 const media_timed_event *event, 284 bigtime_t lateness, 285 bool realTimeEvent = false); 286 virtual status_t HandleParameter( 287 const media_timed_event *event, 288 bigtime_t lateness, 289 bool realTimeEvent = false); 290 291 public: 292 293 static void GetFlavor(flavor_info * outInfo, int32 id); 294 static void GetFormat(media_format * outFormat); 295 296 status_t GetConfigurationFor(BMessage * into_message); 297 298 299 private: 300 301 ESDSinkNode( /* private unimplemented */ 302 const ESDSinkNode & clone); 303 ESDSinkNode & operator=( 304 const ESDSinkNode & clone); 305 306 #if 0 307 308 void AllocateBuffers(node_output &channel); 309 BBuffer* FillNextBuffer( multi_buffer_info &MBI, 310 node_output &channel); 311 void UpdateTimeSource(multi_buffer_info &MBI, 312 multi_buffer_info &oldMBI, 313 node_input &input); 314 #endif 315 // node_output* FindOutput(media_source source); 316 // node_input* FindInput(media_destination dest); 317 // node_input* FindInput(int32 destinationId); 318 319 // void ProcessGroup(BParameterGroup *group, int32 index, int32 &nbParameters); 320 // void ProcessMux(BDiscreteParameter *parameter, int32 index); 321 322 status_t fInitCheckStatus; 323 324 BMediaAddOn *fAddOn; 325 int32 fId; 326 327 BList fInputs; 328 media_input fInput; 329 330 bigtime_t fLatency; 331 BList fOutputs; 332 media_output fOutput; 333 media_format fPreferredFormat; 334 335 bigtime_t fInternalLatency; 336 // this is computed from the real (negotiated) chunk size and bit rate, 337 // not the defaults that are in the parameters 338 bigtime_t fBufferPeriod; 339 340 341 //volatile uint32 fBufferCycle; 342 sem_id fBuffer_free; 343 344 345 thread_id fThread; 346 347 BString fHostname; 348 ESDEndpoint *fDevice; 349 350 //multi_description MD; 351 //multi_format_info MFI; 352 //multi_buffer_list MBL; 353 354 //multi_mix_control_info MMCI; 355 //multi_mix_control MMC[MAX_CONTROLS]; 356 357 bool fTimeSourceStarted; 358 359 BParameterWeb *fWeb; 360 int32 fWebHostId; 361 int32 fWebPortId; 362 363 BMessage fConfig; 364 }; 365 366 #endif /* _ESDSINK_NODE_H */ 367