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 56 enum { 57 PARAM_ENABLED, 58 PARAM_HOST, 59 PARAM_PORT 60 }; 61 62 class ESDSinkNode : 63 public BBufferConsumer, 64 #if ENABLE_INPUT 65 public BBufferProducer, 66 #endif 67 #ifdef ENABLE_TS 68 public BTimeSource, 69 #endif 70 public BMediaEventLooper, 71 public BControllable 72 { 73 protected: 74 virtual ~ESDSinkNode(void); 75 76 public: 77 78 explicit ESDSinkNode(BMediaAddOn *addon, char* name, BMessage * config); 79 80 virtual status_t InitCheck(void) const; 81 82 /*************************/ 83 /* begin from BMediaNode */ 84 public: 85 virtual BMediaAddOn* AddOn( 86 int32 * internal_id) const; /* Who instantiated you -- or NULL for app class */ 87 88 protected: 89 /* These don't return errors; instead, they use the global error condition reporter. */ 90 /* A node is required to have a queue of at least one pending command (plus TimeWarp) */ 91 /* and is recommended to allow for at least one pending command of each type. */ 92 /* Allowing an arbitrary number of outstanding commands might be nice, but apps */ 93 /* cannot depend on that happening. */ 94 virtual void Preroll(void); 95 96 public: 97 virtual status_t HandleMessage( 98 int32 message, 99 const void * data, 100 size_t size); 101 102 protected: 103 virtual void NodeRegistered(void); /* reserved 2 */ 104 virtual status_t RequestCompleted(const media_request_info &info); 105 virtual void SetTimeSource(BTimeSource *timeSource); 106 107 /* end from BMediaNode */ 108 /***********************/ 109 110 /******************************/ 111 /* begin from BBufferConsumer */ 112 113 //included from BMediaAddOn 114 //virtual status_t HandleMessage( 115 // int32 message, 116 // const void * data, 117 // size_t size); 118 119 /* Someone, probably the producer, is asking you about this format. Give */ 120 /* your honest opinion, possibly modifying *format. Do not ask upstream */ 121 /* producer about the format, since he's synchronously waiting for your */ 122 /* reply. */ 123 virtual status_t AcceptFormat( 124 const media_destination & dest, 125 media_format * format); 126 virtual status_t GetNextInput( 127 int32 * cookie, 128 media_input * out_input); 129 virtual void DisposeInputCookie( 130 int32 cookie); 131 virtual void BufferReceived( 132 BBuffer * buffer); 133 virtual void ProducerDataStatus( 134 const media_destination & for_whom, 135 int32 status, 136 bigtime_t at_performance_time); 137 virtual status_t GetLatencyFor( 138 const media_destination & for_whom, 139 bigtime_t * out_latency, 140 media_node_id * out_timesource); 141 virtual status_t Connected( 142 const media_source & producer, /* here's a good place to request buffer group usage */ 143 const media_destination & where, 144 const media_format & with_format, 145 media_input * out_input); 146 virtual void Disconnected( 147 const media_source & producer, 148 const media_destination & where); 149 /* The notification comes from the upstream producer, so he's already cool with */ 150 /* the format; you should not ask him about it in here. */ 151 virtual status_t FormatChanged( 152 const media_source & producer, 153 const media_destination & consumer, 154 int32 change_tag, 155 const media_format & format); 156 157 /* Given a performance time of some previous buffer, retrieve the remembered tag */ 158 /* of the closest (previous or exact) performance time. Set *out_flags to 0; the */ 159 /* idea being that flags can be added later, and the understood flags returned in */ 160 /* *out_flags. */ 161 virtual status_t SeekTagRequested( 162 const media_destination & destination, 163 bigtime_t in_target_time, 164 uint32 in_flags, 165 media_seek_tag * out_seek_tag, 166 bigtime_t * out_tagged_time, 167 uint32 * out_flags); 168 169 /* end from BBufferConsumer */ 170 /****************************/ 171 172 /******************************/ 173 /* begin from BBufferProducer */ 174 #if 0 175 virtual status_t FormatSuggestionRequested( media_type type, 176 int32 quality, 177 media_format* format); 178 179 virtual status_t FormatProposal( const media_source& output, 180 media_format* format); 181 182 virtual status_t FormatChangeRequested( const media_source& source, 183 const media_destination& destination, 184 media_format* io_format, 185 int32* _deprecated_); 186 virtual status_t GetNextOutput( int32* cookie, 187 media_output* out_output); 188 virtual status_t DisposeOutputCookie( int32 cookie); 189 190 virtual status_t SetBufferGroup( const media_source& for_source, 191 BBufferGroup* group); 192 193 virtual status_t PrepareToConnect( const media_source& what, 194 const media_destination& where, 195 media_format* format, 196 media_source* out_source, 197 char* out_name); 198 199 virtual void Connect( status_t error, 200 const media_source& source, 201 const media_destination& destination, 202 const media_format& format, 203 char* io_name); 204 205 virtual void Disconnect( const media_source& what, 206 const media_destination& where); 207 208 virtual void LateNoticeReceived( const media_source& what, 209 bigtime_t how_much, 210 bigtime_t performance_time); 211 212 virtual void EnableOutput( const media_source & what, 213 bool enabled, 214 int32* _deprecated_); 215 virtual void AdditionalBufferRequested( const media_source& source, 216 media_buffer_id prev_buffer, 217 bigtime_t prev_time, 218 const media_seek_tag* prev_tag); 219 #endif 220 /* end from BBufferProducer */ 221 /****************************/ 222 223 /*****************/ 224 /* BControllable */ 225 /*****************/ 226 227 /********************************/ 228 /* start from BMediaEventLooper */ 229 230 protected: 231 /* you must override to handle your events! */ 232 /* you should not call HandleEvent directly */ 233 virtual void HandleEvent( const media_timed_event *event, 234 bigtime_t lateness, 235 bool realTimeEvent = false); 236 237 /* end from BMediaEventLooper */ 238 /******************************/ 239 240 /********************************/ 241 /* start from BTimeSource */ 242 #ifdef ENABLE_TS 243 protected: 244 virtual void SetRunMode( run_mode mode); 245 virtual status_t TimeSourceOp( const time_source_op_info &op, 246 void *_reserved); 247 #endif 248 /* end from BTimeSource */ 249 /******************************/ 250 251 /********************************/ 252 /* start from BControllable */ 253 protected: 254 virtual status_t GetParameterValue( int32 id, 255 bigtime_t* last_change, 256 void* value, 257 size_t* ioSize); 258 virtual void SetParameterValue( int32 id, 259 bigtime_t when, 260 const void* value, 261 size_t size); 262 virtual BParameterWeb* MakeParameterWeb(); 263 264 /* end from BControllable */ 265 /******************************/ 266 267 protected: 268 269 virtual status_t HandleStart( 270 const media_timed_event *event, 271 bigtime_t lateness, 272 bool realTimeEvent = false); 273 virtual status_t HandleSeek( 274 const media_timed_event *event, 275 bigtime_t lateness, 276 bool realTimeEvent = false); 277 virtual status_t HandleWarp( 278 const media_timed_event *event, 279 bigtime_t lateness, 280 bool realTimeEvent = false); 281 virtual status_t HandleStop( 282 const media_timed_event *event, 283 bigtime_t lateness, 284 bool realTimeEvent = false); 285 virtual status_t HandleBuffer( 286 const media_timed_event *event, 287 bigtime_t lateness, 288 bool realTimeEvent = false); 289 virtual status_t HandleDataStatus( 290 const media_timed_event *event, 291 bigtime_t lateness, 292 bool realTimeEvent = false); 293 virtual status_t HandleParameter( 294 const media_timed_event *event, 295 bigtime_t lateness, 296 bool realTimeEvent = false); 297 298 public: 299 300 static void GetFlavor(flavor_info * outInfo, int32 id); 301 static void GetFormat(media_format * outFormat); 302 303 status_t GetConfigurationFor(BMessage * into_message); 304 305 306 private: 307 308 ESDSinkNode( /* private unimplemented */ 309 const ESDSinkNode & clone); 310 ESDSinkNode & operator=( 311 const ESDSinkNode & clone); 312 313 #if 0 314 315 void AllocateBuffers(node_output &channel); 316 BBuffer* FillNextBuffer( multi_buffer_info &MBI, 317 node_output &channel); 318 void UpdateTimeSource(multi_buffer_info &MBI, 319 multi_buffer_info &oldMBI, 320 node_input &input); 321 #endif 322 // node_output* FindOutput(media_source source); 323 // node_input* FindInput(media_destination dest); 324 // node_input* FindInput(int32 destinationId); 325 326 // void ProcessGroup(BParameterGroup *group, int32 index, int32 &nbParameters); 327 // void ProcessMux(BDiscreteParameter *parameter, int32 index); 328 329 status_t fInitCheckStatus; 330 331 BMediaAddOn *fAddOn; 332 int32 fId; 333 334 BList fInputs; 335 media_input fInput; 336 337 bigtime_t fLatency; 338 BList fOutputs; 339 media_output fOutput; 340 media_format fPreferredFormat; 341 342 bigtime_t fInternalLatency; 343 // this is computed from the real (negotiated) chunk size and bit rate, 344 // not the defaults that are in the parameters 345 bigtime_t fBufferPeriod; 346 347 348 //volatile uint32 fBufferCycle; 349 sem_id fBuffer_free; 350 351 352 thread_id fThread; 353 354 BString fHostname; 355 uint16 fPort; 356 bool fEnabled; 357 ESDEndpoint *fDevice; 358 359 //multi_description MD; 360 //multi_format_info MFI; 361 //multi_buffer_list MBL; 362 363 //multi_mix_control_info MMCI; 364 //multi_mix_control MMC[MAX_CONTROLS]; 365 366 bool fTimeSourceStarted; 367 368 BParameterWeb *fWeb; 369 370 BMessage fConfig; 371 }; 372 373 #endif /* _ESDSINK_NODE_H */ 374