1 // MediaDemultiplexerNode.cpp
2 //
3 // Andrew Bachmann, 2002
4 //
5 // The MediaDemultiplexerNode class
6 // takes a multistream input and supplies
7 // the individual constituent streams as
8 // the output.
9
10 #include <MediaDefs.h>
11 #include <MediaNode.h>
12 #include <MediaAddOn.h>
13 #include <BufferConsumer.h>
14 #include <BufferProducer.h>
15 #include <MediaEventLooper.h>
16 #include <Errors.h>
17 #include <BufferGroup.h>
18 #include <TimeSource.h>
19 #include <Buffer.h>
20 #include <limits.h>
21
22 #include "MediaDemultiplexerNode.h"
23 #include "misc.h"
24
25 #include <stdio.h>
26 #include <string.h>
27
28 // -------------------------------------------------------- //
29 // ctor/dtor
30 // -------------------------------------------------------- //
31
~MediaDemultiplexerNode(void)32 MediaDemultiplexerNode::~MediaDemultiplexerNode(void)
33 {
34 fprintf(stderr,"MediaDemultiplexerNode::~MediaDemultiplexerNode\n");
35 // Stop the BMediaEventLooper thread
36 Quit();
37 }
38
MediaDemultiplexerNode(const flavor_info * info=0,BMessage * config=0,BMediaAddOn * addOn=0)39 MediaDemultiplexerNode::MediaDemultiplexerNode(
40 const flavor_info * info = 0,
41 BMessage * config = 0,
42 BMediaAddOn * addOn = 0)
43 : BMediaNode("MediaDemultiplexerNode"),
44 BMediaEventLooper(),
45 BBufferConsumer(B_MEDIA_MULTISTREAM),
46 BBufferProducer(B_MEDIA_UNKNOWN_TYPE) // no B_MEDIA_ANY
47 {
48 fprintf(stderr,"MediaDemultiplexerNode::MediaDemultiplexerNode\n");
49 // keep our creator around for AddOn calls later
50 fAddOn = addOn;
51 // null out our latency estimates
52 fDownstreamLatency = 0;
53 fInternalLatency = 0;
54 // don't overwrite available space, and be sure to terminate
55 strncpy(input.name,"Demultiplexer Input",B_MEDIA_NAME_LENGTH-1);
56 input.name[B_MEDIA_NAME_LENGTH-1] = '\0';
57 // initialize the input
58 input.node = media_node::null; // until registration
59 input.source = media_source::null;
60 input.destination = media_destination::null; // until registration
61 GetInputFormat(&input.format);
62
63 outputs.empty();
64 // outputs initialized after we connect,
65 // find a suitable extractor,
66 // and it tells us the ouputs
67
68 fInitCheckStatus = B_OK;
69 }
70
InitCheck(void) const71 status_t MediaDemultiplexerNode::InitCheck(void) const
72 {
73 fprintf(stderr,"MediaDemultiplexerNode::InitCheck\n");
74 return fInitCheckStatus;
75 }
76
GetConfigurationFor(BMessage * into_message)77 status_t MediaDemultiplexerNode::GetConfigurationFor(
78 BMessage * into_message)
79 {
80 fprintf(stderr,"MediaDemultiplexerNode::GetConfigurationFor\n");
81 return B_OK;
82 }
83
84 // -------------------------------------------------------- //
85 // implementation of BMediaNode
86 // -------------------------------------------------------- //
87
AddOn(int32 * internal_id) const88 BMediaAddOn * MediaDemultiplexerNode::AddOn(
89 int32 * internal_id) const
90 {
91 fprintf(stderr,"MediaDemultiplexerNode::AddOn\n");
92 // BeBook says this only gets called if we were in an add-on.
93 if (fAddOn != 0) {
94 // If we get a null pointer then we just won't write.
95 if (internal_id != 0) {
96 internal_id = 0;
97 }
98 }
99 return fAddOn;
100 }
101
Start(bigtime_t performance_time)102 void MediaDemultiplexerNode::Start(
103 bigtime_t performance_time)
104 {
105 fprintf(stderr,"MediaDemultiplexerNode::Start(pt=%lld)\n",performance_time);
106 BMediaEventLooper::Start(performance_time);
107 }
108
Stop(bigtime_t performance_time,bool immediate)109 void MediaDemultiplexerNode::Stop(
110 bigtime_t performance_time,
111 bool immediate)
112 {
113 if (immediate) {
114 fprintf(stderr,"MediaDemultiplexerNode::Stop(pt=%lld,<immediate>)\n",performance_time);
115 } else {
116 fprintf(stderr,"MediaDemultiplexerNode::Stop(pt=%lld,<scheduled>)\n",performance_time);
117 }
118 BMediaEventLooper::Stop(performance_time,immediate);
119 }
120
Seek(bigtime_t media_time,bigtime_t performance_time)121 void MediaDemultiplexerNode::Seek(
122 bigtime_t media_time,
123 bigtime_t performance_time)
124 {
125 fprintf(stderr,"MediaDemultiplexerNode::Seek(mt=%lld,pt=%lld)\n",media_time,performance_time);
126 BMediaEventLooper::Seek(media_time,performance_time);
127 }
128
SetRunMode(run_mode mode)129 void MediaDemultiplexerNode::SetRunMode(
130 run_mode mode)
131 {
132 fprintf(stderr,"MediaDemultiplexerNode::SetRunMode(%i)\n",mode);
133 BMediaEventLooper::SetRunMode(mode);
134 }
135
TimeWarp(bigtime_t at_real_time,bigtime_t to_performance_time)136 void MediaDemultiplexerNode::TimeWarp(
137 bigtime_t at_real_time,
138 bigtime_t to_performance_time)
139 {
140 fprintf(stderr,"MediaDemultiplexerNode::TimeWarp(rt=%lld,pt=%lld)\n",at_real_time,to_performance_time);
141 BMediaEventLooper::TimeWarp(at_real_time,to_performance_time);
142 }
143
Preroll(void)144 void MediaDemultiplexerNode::Preroll(void)
145 {
146 fprintf(stderr,"MediaDemultiplexerNode::Preroll\n");
147 // XXX:Performance opportunity
148 BMediaNode::Preroll();
149 }
150
SetTimeSource(BTimeSource * time_source)151 void MediaDemultiplexerNode::SetTimeSource(
152 BTimeSource * time_source)
153 {
154 fprintf(stderr,"MediaDemultiplexerNode::SetTimeSource\n");
155 BMediaNode::SetTimeSource(time_source);
156 }
157
HandleMessage(int32 message,const void * data,size_t size)158 status_t MediaDemultiplexerNode::HandleMessage(
159 int32 message,
160 const void * data,
161 size_t size)
162 {
163 fprintf(stderr,"MediaDemultiplexerNode::HandleMessage\n");
164 status_t status = B_OK;
165 switch (message) {
166 // no special messages for now
167 default:
168 status = BBufferConsumer::HandleMessage(message,data,size);
169 if (status == B_OK) {
170 break;
171 }
172 status = BBufferProducer::HandleMessage(message,data,size);
173 if (status == B_OK) {
174 break;
175 }
176 status = BMediaNode::HandleMessage(message,data,size);
177 if (status == B_OK) {
178 break;
179 }
180 BMediaNode::HandleBadMessage(message,data,size);
181 status = B_ERROR;
182 break;
183 }
184 return status;
185 }
186
RequestCompleted(const media_request_info & info)187 status_t MediaDemultiplexerNode::RequestCompleted(
188 const media_request_info & info)
189 {
190 fprintf(stderr,"MediaDemultiplexerNode::RequestCompleted\n");
191 return BMediaNode::RequestCompleted(info);
192 }
193
DeleteHook(BMediaNode * node)194 status_t MediaDemultiplexerNode::DeleteHook(
195 BMediaNode * node)
196 {
197 fprintf(stderr,"MediaDemultiplexerNode::DeleteHook\n");
198 return BMediaEventLooper::DeleteHook(node);
199 }
200
NodeRegistered(void)201 void MediaDemultiplexerNode::NodeRegistered(void)
202 {
203 fprintf(stderr,"MediaDemultiplexerNode::NodeRegistered\n");
204
205 // now we can do this
206 input.node = Node();
207 input.destination.id = 0;
208 input.destination.port = input.node.port; // same as ControlPort()
209
210 // outputs initialized after we connect,
211 // find a suitable extractor,
212 // and it tells us the ouputs
213
214 // start the BMediaEventLooper thread
215 SetPriority(B_REAL_TIME_PRIORITY);
216 Run();
217 }
218
GetNodeAttributes(media_node_attribute * outAttributes,size_t inMaxCount)219 status_t MediaDemultiplexerNode::GetNodeAttributes(
220 media_node_attribute * outAttributes,
221 size_t inMaxCount)
222 {
223 fprintf(stderr,"MediaDemultiplexerNode::GetNodeAttributes\n");
224 return BMediaNode::GetNodeAttributes(outAttributes,inMaxCount);
225 }
226
AddTimer(bigtime_t at_performance_time,int32 cookie)227 status_t MediaDemultiplexerNode::AddTimer(
228 bigtime_t at_performance_time,
229 int32 cookie)
230 {
231 fprintf(stderr,"MediaDemultiplexerNode::AddTimer\n");
232 return BMediaEventLooper::AddTimer(at_performance_time,cookie);
233 }
234
235 // -------------------------------------------------------- //
236 // implemention of BBufferConsumer
237 // -------------------------------------------------------- //
238
239 // Check to make sure the format is okay, then remove
240 // any wildcards corresponding to our requirements.
AcceptFormat(const media_destination & dest,media_format * format)241 status_t MediaDemultiplexerNode::AcceptFormat(
242 const media_destination & dest,
243 media_format * format)
244 {
245 fprintf(stderr,"MediaDemultiplexerNode::AcceptFormat\n");
246 if (input.destination != dest) {
247 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION");
248 return B_MEDIA_BAD_DESTINATION; // we only have one input so that better be it
249 }
250 media_format myFormat;
251 GetInputFormat(&myFormat);
252 // Be's format_is_compatible doesn't work,
253 // so use our format_is_acceptible instead
254 if (!format_is_acceptible(*format,myFormat)) {
255 fprintf(stderr,"<- B_MEDIA_BAD_FORMAT\n");
256 return B_MEDIA_BAD_FORMAT;
257 }
258 AddRequirements(format);
259 return B_OK;
260 }
261
GetNextInput(int32 * cookie,media_input * out_input)262 status_t MediaDemultiplexerNode::GetNextInput(
263 int32 * cookie,
264 media_input * out_input)
265 {
266 fprintf(stderr,"MediaDemultiplexerNode::GetNextInput\n");
267 if (*cookie != 0) {
268 fprintf(stderr,"<- B_ERROR (no more inputs)\n");
269 return B_ERROR;
270 }
271
272 // so next time they won't get the same input again
273 *cookie = 1;
274 *out_input = input;
275 return B_OK;
276 }
277
DisposeInputCookie(int32 cookie)278 void MediaDemultiplexerNode::DisposeInputCookie(
279 int32 cookie)
280 {
281 fprintf(stderr,"MediaDemultiplexerNode::DisposeInputCookie\n");
282 // nothing to do since our cookies are just integers
283 return; // B_OK;
284 }
285
BufferReceived(BBuffer * buffer)286 void MediaDemultiplexerNode::BufferReceived(
287 BBuffer * buffer)
288 {
289 fprintf(stderr,"MediaDemultiplexerNode::BufferReceived\n");
290 switch (buffer->Header()->type) {
291 // case B_MEDIA_PARAMETERS:
292 // {
293 // status_t status = ApplyParameterData(buffer->Data(),buffer->SizeUsed());
294 // if (status != B_OK) {
295 // fprintf(stderr,"ApplyParameterData in MediaDemultiplexerNode::BufferReceived failed\n");
296 // }
297 // buffer->Recycle();
298 // }
299 // break;
300 case B_MEDIA_MULTISTREAM:
301 if (buffer->Flags() & BBuffer::B_SMALL_BUFFER) {
302 fprintf(stderr,"NOT IMPLEMENTED: B_SMALL_BUFFER in MediaDemultiplexerNode::BufferReceived\n");
303 // XXX: implement this part
304 buffer->Recycle();
305 } else {
306 media_timed_event event(buffer->Header()->start_time, BTimedEventQueue::B_HANDLE_BUFFER,
307 buffer, BTimedEventQueue::B_RECYCLE_BUFFER);
308 status_t status = EventQueue()->AddEvent(event);
309 if (status != B_OK) {
310 fprintf(stderr,"EventQueue()->AddEvent(event) in MediaDemultiplexerNode::BufferReceived failed\n");
311 buffer->Recycle();
312 }
313 }
314 break;
315 default:
316 fprintf(stderr,"unexpected buffer type in MediaDemultiplexerNode::BufferReceived\n");
317 buffer->Recycle();
318 break;
319 }
320 }
321
ProducerDataStatus(const media_destination & for_whom,int32 status,bigtime_t at_performance_time)322 void MediaDemultiplexerNode::ProducerDataStatus(
323 const media_destination & for_whom,
324 int32 status,
325 bigtime_t at_performance_time)
326 {
327 fprintf(stderr,"MediaDemultiplexerNode::ProducerDataStatus\n");
328 if (input.destination != for_whom) {
329 fprintf(stderr,"invalid destination received in MediaDemultiplexerNode::ProducerDataStatus\n");
330 return;
331 }
332 media_timed_event event(at_performance_time, BTimedEventQueue::B_DATA_STATUS,
333 &input, BTimedEventQueue::B_NO_CLEANUP, status, 0, NULL);
334 EventQueue()->AddEvent(event);
335 }
336
GetLatencyFor(const media_destination & for_whom,bigtime_t * out_latency,media_node_id * out_timesource)337 status_t MediaDemultiplexerNode::GetLatencyFor(
338 const media_destination & for_whom,
339 bigtime_t * out_latency,
340 media_node_id * out_timesource)
341 {
342 fprintf(stderr,"MediaDemultiplexerNode::GetLatencyFor\n");
343 if ((out_latency == 0) || (out_timesource == 0)) {
344 fprintf(stderr,"<- B_BAD_VALUE\n");
345 return B_BAD_VALUE;
346 }
347 if (input.destination != for_whom) {
348 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
349 return B_MEDIA_BAD_DESTINATION;
350 }
351 *out_latency = EventLatency();
352 *out_timesource = TimeSource()->ID();
353 return B_OK;
354 }
355
Connected(const media_source & producer,const media_destination & where,const media_format & with_format,media_input * out_input)356 status_t MediaDemultiplexerNode::Connected(
357 const media_source & producer, /* here's a good place to request buffer group usage */
358 const media_destination & where,
359 const media_format & with_format,
360 media_input * out_input)
361 {
362 fprintf(stderr,"MediaDemultiplexerNode::Connected\n");
363 if (input.destination != where) {
364 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
365 return B_MEDIA_BAD_DESTINATION;
366 }
367
368 // find an appropriate extractor to handle this type
369 fprintf(stderr," XXX: no extractors yet\n");
370
371 // initialize the outputs here
372 // provide all the types that the extractor claims
373 outputs.empty();
374
375 // compute the latency or just guess
376 fInternalLatency = 500; // just guess
377 fprintf(stderr," internal latency guessed = %lld\n",fInternalLatency);
378
379 SetEventLatency(fInternalLatency);
380
381 // record the agreed upon values
382 input.source = producer;
383 input.format = with_format;
384 *out_input = input;
385 return B_OK;
386 }
387
Disconnected(const media_source & producer,const media_destination & where)388 void MediaDemultiplexerNode::Disconnected(
389 const media_source & producer,
390 const media_destination & where)
391 {
392 fprintf(stderr,"MediaDemultiplexerNode::Disconnected\n");
393 if (input.destination != where) {
394 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
395 return;
396 }
397 if (input.source != producer) {
398 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
399 return;
400 }
401 input.source = media_source::null;
402 GetInputFormat(&input.format);
403
404 outputs.empty();
405 }
406
407 /* The notification comes from the upstream producer, so he's already cool with */
408 /* the format; you should not ask him about it in here. */
FormatChanged(const media_source & producer,const media_destination & consumer,int32 change_tag,const media_format & format)409 status_t MediaDemultiplexerNode::FormatChanged(
410 const media_source & producer,
411 const media_destination & consumer,
412 int32 change_tag,
413 const media_format & format)
414 {
415 fprintf(stderr,"MediaDemultiplexerNode::FormatChanged\n");
416 if (input.source != producer) {
417 return B_MEDIA_BAD_SOURCE;
418 }
419 if (input.destination != consumer) {
420 return B_MEDIA_BAD_DESTINATION;
421 }
422 // XXX: implement
423 fprintf(stderr," This is because we asked to have the format changed.\n"
424 " Therefore we must switch to the other extractor that\n"
425 " we presumably have ready.");
426 input.format = format;
427 return B_OK;
428 }
429
430 /* Given a performance time of some previous buffer, retrieve the remembered tag */
431 /* of the closest (previous or exact) performance time. Set *out_flags to 0; the */
432 /* idea being that flags can be added later, and the understood flags returned in */
433 /* *out_flags. */
SeekTagRequested(const media_destination & destination,bigtime_t in_target_time,uint32 in_flags,media_seek_tag * out_seek_tag,bigtime_t * out_tagged_time,uint32 * out_flags)434 status_t MediaDemultiplexerNode::SeekTagRequested(
435 const media_destination & destination,
436 bigtime_t in_target_time,
437 uint32 in_flags,
438 media_seek_tag * out_seek_tag,
439 bigtime_t * out_tagged_time,
440 uint32 * out_flags)
441 {
442 fprintf(stderr,"MediaDemultiplexerNode::SeekTagRequested\n");
443 // XXX: implement this
444 return BBufferConsumer::SeekTagRequested(destination,in_target_time,in_flags,
445 out_seek_tag,out_tagged_time,out_flags);
446 }
447
448 // -------------------------------------------------------- //
449 // implemention of BBufferProducer
450 // -------------------------------------------------------- //
451
452 // They are asking us to make the first offering.
453 // So, we get a fresh format and then add requirements
FormatSuggestionRequested(media_type type,int32 quality,media_format * format)454 status_t MediaDemultiplexerNode::FormatSuggestionRequested(
455 media_type type,
456 int32 quality,
457 media_format * format)
458 {
459 fprintf(stderr,"MediaDemultiplexerNode::FormatSuggestionRequested\n");
460 // XXX: how do I pick which stream to supply here?....
461 // answer?: get the first compatible stream that is available
462 fprintf(stderr," format suggestion requested not implemented\n");
463 // if ((type != B_MEDIA_MULTISTREAM) && (type != B_MEDIA_UNKNOWN_TYPE)) {
464 // fprintf(stderr,"<- B_MEDIA_BAD_FORMAT\n");
465 // return B_MEDIA_BAD_FORMAT;
466 // }
467 GetOutputFormat(format);
468 // AddRequirements(format);
469
470 return B_OK;
471 }
472
473 // They made an offer to us. We should make sure that the offer is
474 // acceptable, and then we can add any requirements we have on top of
475 // that. We leave wildcards for anything that we don't care about.
FormatProposal(const media_source & output_source,media_format * format)476 status_t MediaDemultiplexerNode::FormatProposal(
477 const media_source & output_source,
478 media_format * format)
479 {
480 fprintf(stderr,"MediaDemultiplexerNode::FormatProposal\n");
481 // find the information for this output
482 vector<MediaOutputInfo>::iterator itr;
483 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
484 if (itr->output.source == output_source) {
485 break;
486 }
487 }
488 if (itr == outputs.end()) {
489 // we don't have that output
490 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
491 return B_MEDIA_BAD_SOURCE;
492 }
493 return itr->FormatProposal(format);
494 }
495
496 // Presumably we have already agreed with them that this format is
497 // okay. But just in case, we check the offer. (and complain if it
498 // is invalid) Then as the last thing we do, we get rid of any
499 // remaining wilcards.
FormatChangeRequested(const media_source & source,const media_destination & destination,media_format * io_format,int32 * _deprecated_)500 status_t MediaDemultiplexerNode::FormatChangeRequested(
501 const media_source & source,
502 const media_destination & destination,
503 media_format * io_format,
504 int32 * _deprecated_)
505 {
506 fprintf(stderr,"MediaDemultiplexerNode::FormatChangeRequested\n");
507 // find the information for this output
508 vector<MediaOutputInfo>::iterator itr;
509 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
510 if (itr->output.source == source) {
511 break;
512 }
513 }
514 if (itr == outputs.end()) {
515 // we don't have that output
516 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
517 return B_MEDIA_BAD_SOURCE;
518 }
519 return itr->FormatChangeRequested(destination,io_format);
520 }
521
GetNextOutput(int32 * cookie,media_output * out_output)522 status_t MediaDemultiplexerNode::GetNextOutput( /* cookie starts as 0 */
523 int32 * cookie,
524 media_output * out_output)
525 {
526 fprintf(stderr,"MediaDemultiplexerNode::GetNextOutput\n");
527 // they want a clean start
528 if (*cookie == 0) {
529 *cookie = (int32)outputs.begin();
530 }
531 vector<MediaOutputInfo>::iterator itr
532 = (vector<MediaOutputInfo>::iterator)(*cookie);
533 // XXX: check here if the vector has been modified.
534 // if the iterator is invalid, return an error code??
535
536 // they already got our 1 output
537 if (itr == outputs.end()) {
538 fprintf(stderr,"<- B_ERROR (no more outputs)\n");
539 return B_ERROR;
540 }
541 // return this output
542 *out_output = itr->output;
543 // so next time they won't get the same output again
544 *cookie = (int32)++itr;
545 return B_OK;
546 }
547
DisposeOutputCookie(int32 cookie)548 status_t MediaDemultiplexerNode::DisposeOutputCookie(
549 int32 cookie)
550 {
551 fprintf(stderr,"MediaDemultiplexerNode::DisposeOutputCookie\n");
552 // nothing to do since our cookies are part of the vector iterator
553 return B_OK;
554 }
555
SetBufferGroup(const media_source & for_source,BBufferGroup * group)556 status_t MediaDemultiplexerNode::SetBufferGroup(
557 const media_source & for_source,
558 BBufferGroup * group)
559 {
560 fprintf(stderr,"MediaDemultiplexerNode::SetBufferGroup\n");
561 // find the information for this output
562 vector<MediaOutputInfo>::iterator itr;
563 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
564 if (itr->output.source == for_source) {
565 break;
566 }
567 }
568 if (itr == outputs.end()) {
569 // we don't have that output
570 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
571 return B_MEDIA_BAD_SOURCE;
572 }
573 return itr->SetBufferGroup(group);
574 }
575
576 /* Format of clipping is (as int16-s): <from line> <npairs> <startclip> <endclip>. */
577 /* Repeat for each line where the clipping is different from the previous line. */
578 /* If <npairs> is negative, use the data from line -<npairs> (there are 0 pairs after */
579 /* a negative <npairs>. Yes, we only support 32k*32k frame buffers for clipping. */
580 /* Any non-0 field of 'display' means that that field changed, and if you don't support */
581 /* that change, you should return an error and ignore the request. Note that the buffer */
582 /* offset values do not have wildcards; 0 (or -1, or whatever) are real values and must */
583 /* be adhered to. */
VideoClippingChanged(const media_source & for_source,int16 num_shorts,int16 * clip_data,const media_video_display_info & display,int32 * _deprecated_)584 status_t MediaDemultiplexerNode::VideoClippingChanged(
585 const media_source & for_source,
586 int16 num_shorts,
587 int16 * clip_data,
588 const media_video_display_info & display,
589 int32 * _deprecated_)
590 {
591 return BBufferProducer::VideoClippingChanged(for_source,num_shorts,clip_data,display,_deprecated_);
592 }
593
GetLatency(bigtime_t * out_latency)594 status_t MediaDemultiplexerNode::GetLatency(
595 bigtime_t * out_latency)
596 {
597 fprintf(stderr,"MediaDemultiplexerNode::GetLatency\n");
598 if (out_latency == 0) {
599 fprintf(stderr,"<- B_BAD_VALUE\n");
600 return B_BAD_VALUE;
601 }
602 *out_latency = EventLatency() + SchedulingLatency();
603 return B_OK;
604 }
605
PrepareToConnect(const media_source & what,const media_destination & where,media_format * format,media_source * out_source,char * out_name)606 status_t MediaDemultiplexerNode::PrepareToConnect(
607 const media_source & what,
608 const media_destination & where,
609 media_format * format,
610 media_source * out_source,
611 char * out_name)
612 {
613 fprintf(stderr,"MediaDemultiplexerNode::PrepareToConnect\n");
614 // find the information for this output
615 vector<MediaOutputInfo>::iterator itr;
616 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
617 if (itr->output.source == what) {
618 break;
619 }
620 }
621 if (itr == outputs.end()) {
622 // we don't have that output
623 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
624 return B_MEDIA_BAD_SOURCE;
625 }
626 return itr->PrepareToConnect(where,format,out_source,out_name);
627 }
628
Connect(status_t error,const media_source & source,const media_destination & destination,const media_format & format,char * io_name)629 void MediaDemultiplexerNode::Connect(
630 status_t error,
631 const media_source & source,
632 const media_destination & destination,
633 const media_format & format,
634 char * io_name)
635 {
636 fprintf(stderr,"MediaDemultiplexerNode::Connect\n");
637 // find the information for this output
638 vector<MediaOutputInfo>::iterator itr;
639 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
640 if (itr->output.source == source) {
641 break;
642 }
643 }
644 if (itr == outputs.end()) {
645 // we don't have that output
646 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
647 return;
648 }
649 if (error != B_OK) {
650 fprintf(stderr,"<- error already\n");
651 itr->output.destination = media_destination::null;
652 itr->output.format = itr->generalFormat;
653 return;
654 }
655
656 // calculate the downstream latency
657 // must happen before itr->Connect
658 bigtime_t downstreamLatency;
659 media_node_id id;
660 FindLatencyFor(itr->output.destination, &downstreamLatency, &id);
661
662 // record the agreed upon values
663 status_t status;
664 status = itr->Connect(destination,format,io_name,downstreamLatency);
665 if (status != B_OK) {
666 fprintf(stderr," itr->Connect returned an error\n");
667 return;
668 }
669
670 // compute the internal latency
671 // must happen after itr->Connect
672 if (fInternalLatency == 0) {
673 fInternalLatency = 100; // temporary until we finish computing it
674 ComputeInternalLatency();
675 }
676
677 // If the downstream latency for this output is larger
678 // than our current downstream latency, we have to increase
679 // our current downstream latency to be the larger value.
680 if (downstreamLatency > fDownstreamLatency) {
681 SetEventLatency(fDownstreamLatency + fInternalLatency);
682 }
683
684 // XXX: what do I set the buffer duration to?
685 // it depends on which output is sending!!
686 // SetBufferDuration(bufferPeriod);
687
688 // XXX: do anything else?
689 return;
690 }
691
ComputeInternalLatency()692 void MediaDemultiplexerNode::ComputeInternalLatency() {
693 fprintf(stderr,"MediaDemultiplexerNode::ComputeInternalLatency\n");
694 // if (GetCurrentFile() != 0) {
695 // bigtime_t start, end;
696 // uint8 * data = new uint8[output.format.u.multistream.max_chunk_size]; // <- buffer group buffer size
697 // BBuffer * buffer = 0;
698 // ssize_t bytesRead = 0;
699 // { // timed section
700 // start = TimeSource()->RealTime();
701 // // first we try to use a real BBuffer
702 // buffer = fBufferGroup->RequestBuffer(output.format.u.multistream.max_chunk_size,fBufferPeriod);
703 // if (buffer != 0) {
704 // FillFileBuffer(buffer);
705 // } else {
706 // // didn't get a real BBuffer, try simulation by just a read from the disk
707 // bytesRead = GetCurrentFile()->Read(data,output.format.u.multistream.max_chunk_size);
708 // }
709 // end = TimeSource()->RealTime();
710 // }
711 // bytesRead = buffer->SizeUsed();
712 // delete data;
713 // if (buffer != 0) {
714 // buffer->Recycle();
715 // }
716 // GetCurrentFile()->Seek(-bytesRead,SEEK_CUR); // put it back where we found it
717 //
718 // fInternalLatency = end - start;
719 //
720 // fprintf(stderr," internal latency from disk read = %lld\n",fInternalLatency);
721 // } else {
722 fInternalLatency = 100; // just guess
723 fprintf(stderr," internal latency guessed = %lld\n",fInternalLatency);
724 // }
725 }
726
Disconnect(const media_source & what,const media_destination & where)727 void MediaDemultiplexerNode::Disconnect(
728 const media_source & what,
729 const media_destination & where)
730 {
731 fprintf(stderr,"MediaDemultiplexerNode::Disconnect\n");
732 // find the information for this output
733 vector<MediaOutputInfo>::iterator itr;
734 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
735 if (itr->output.source == what) {
736 break;
737 }
738 }
739 if (itr == outputs.end()) {
740 // we don't have that output
741 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
742 return;
743 }
744 if (itr->output.destination != where) {
745 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
746 return;
747 }
748 // if this output has an equal (or higher!) latency than
749 // our current believed downstream latency, we may have to
750 // update our downstream latency.
751 bool updateDownstreamLatency = (itr->downstreamLatency >= fDownstreamLatency);
752 // disconnect this output
753 itr->Disconnect();
754 // update the downstream latency if necessary
755 if (updateDownstreamLatency) {
756 bigtime_t newDownstreamLatency = 0;
757 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
758 if (itr->downstreamLatency > newDownstreamLatency) {
759 newDownstreamLatency = itr->downstreamLatency;
760 }
761 }
762 fDownstreamLatency = newDownstreamLatency;
763 }
764 }
765
LateNoticeReceived(const media_source & what,bigtime_t how_much,bigtime_t performance_time)766 void MediaDemultiplexerNode::LateNoticeReceived(
767 const media_source & what,
768 bigtime_t how_much,
769 bigtime_t performance_time)
770 {
771 fprintf(stderr,"MediaDemultiplexerNode::LateNoticeReceived\n");
772 vector<MediaOutputInfo>::iterator itr;
773 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
774 if (itr->output.source == what) {
775 break;
776 }
777 }
778 if (itr == outputs.end()) {
779 // we don't have that output
780 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
781 return;
782 }
783 switch (RunMode()) {
784 case B_OFFLINE:
785 // nothing to do
786 break;
787 case B_RECORDING:
788 // nothing to do
789 break;
790 case B_INCREASE_LATENCY:
791 fInternalLatency += how_much;
792 SetEventLatency(fDownstreamLatency + fInternalLatency);
793 break;
794 case B_DECREASE_PRECISION:
795 // XXX: try to catch up by producing buffers faster
796 break;
797 case B_DROP_DATA:
798 // XXX: should we really drop buffers? just for that output?
799 break;
800 default:
801 // huh?? there aren't any more run modes.
802 fprintf(stderr,"MediaDemultiplexerNode::LateNoticeReceived with unexpected run mode.\n");
803 break;
804 }
805 }
806
EnableOutput(const media_source & what,bool enabled,int32 * _deprecated_)807 void MediaDemultiplexerNode::EnableOutput(
808 const media_source & what,
809 bool enabled,
810 int32 * _deprecated_)
811 {
812 fprintf(stderr,"MediaDemultiplexerNode::EnableOutput\n");
813 // find the information for this output
814 vector<MediaOutputInfo>::iterator itr;
815 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
816 if (itr->output.source == what) {
817 break;
818 }
819 }
820 if (itr == outputs.end()) {
821 // we don't have that output
822 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
823 return;
824 }
825 status_t status = itr->EnableOutput(enabled);
826 if (status != B_OK) {
827 fprintf(stderr," error in itr->EnableOutput\n");
828 return;
829 }
830 return;
831 }
832
SetPlayRate(int32 numer,int32 denom)833 status_t MediaDemultiplexerNode::SetPlayRate(
834 int32 numer,
835 int32 denom)
836 {
837 BBufferProducer::SetPlayRate(numer,denom); // XXX: do something intelligent later
838 }
839
AdditionalBufferRequested(const media_source & source,media_buffer_id prev_buffer,bigtime_t prev_time,const media_seek_tag * prev_tag)840 void MediaDemultiplexerNode::AdditionalBufferRequested( // used to be Reserved 0
841 const media_source & source,
842 media_buffer_id prev_buffer,
843 bigtime_t prev_time,
844 const media_seek_tag * prev_tag)
845 {
846 fprintf(stderr,"MediaDemultiplexerNode::AdditionalBufferRequested\n");
847 // find the information for this output
848 vector<MediaOutputInfo>::iterator itr;
849 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
850 if (itr->output.source == source) {
851 break;
852 }
853 }
854 if (itr == outputs.end()) {
855 // we don't have that output
856 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
857 return;
858 }
859 BBuffer * buffer;
860 status_t status = itr->AdditionalBufferRequested(prev_buffer,prev_time,prev_tag);
861 if (status != B_OK) {
862 fprintf(stderr," itr->AdditionalBufferRequested returned an error.\n");
863 return;
864 }
865 return;
866 }
867
LatencyChanged(const media_source & source,const media_destination & destination,bigtime_t new_latency,uint32 flags)868 void MediaDemultiplexerNode::LatencyChanged(
869 const media_source & source,
870 const media_destination & destination,
871 bigtime_t new_latency,
872 uint32 flags)
873 {
874 fprintf(stderr,"MediaDemultiplexerNode::LatencyChanged\n");
875 // find the information for this output
876 vector<MediaOutputInfo>::iterator itr;
877 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
878 if (itr->output.source == source) {
879 break;
880 }
881 }
882 if (itr == outputs.end()) {
883 // we don't have that output
884 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
885 return;
886 }
887 if (itr->output.destination != destination) {
888 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
889 return;
890 }
891 fDownstreamLatency = new_latency;
892 SetEventLatency(fDownstreamLatency + fInternalLatency);
893 // XXX: we may have to recompute the number of buffers that we are using
894 // see SetBufferGroup
895 }
896
897 // -------------------------------------------------------- //
898 // implementation for BMediaEventLooper
899 // -------------------------------------------------------- //
900
HandleEvent(const media_timed_event * event,bigtime_t lateness,bool realTimeEvent=false)901 void MediaDemultiplexerNode::HandleEvent(
902 const media_timed_event *event,
903 bigtime_t lateness,
904 bool realTimeEvent = false)
905 {
906 fprintf(stderr,"MediaDemultiplexerNode::HandleEvent\n");
907 switch (event->type) {
908 case BTimedEventQueue::B_START:
909 HandleStart(event,lateness,realTimeEvent);
910 break;
911 case BTimedEventQueue::B_SEEK:
912 HandleSeek(event,lateness,realTimeEvent);
913 break;
914 case BTimedEventQueue::B_WARP:
915 HandleWarp(event,lateness,realTimeEvent);
916 break;
917 case BTimedEventQueue::B_STOP:
918 HandleStop(event,lateness,realTimeEvent);
919 break;
920 case BTimedEventQueue::B_HANDLE_BUFFER:
921 if (RunState() == BMediaEventLooper::B_STARTED) {
922 HandleBuffer(event,lateness,realTimeEvent);
923 }
924 break;
925 case BTimedEventQueue::B_DATA_STATUS:
926 HandleDataStatus(event,lateness,realTimeEvent);
927 break;
928 case BTimedEventQueue::B_PARAMETER:
929 HandleParameter(event,lateness,realTimeEvent);
930 break;
931 default:
932 fprintf(stderr," unknown event type: %i\n",event->type);
933 break;
934 }
935 }
936
937 /* override to clean up custom events you have added to your queue */
CleanUpEvent(const media_timed_event * event)938 void MediaDemultiplexerNode::CleanUpEvent(
939 const media_timed_event *event)
940 {
941 BMediaEventLooper::CleanUpEvent(event);
942 }
943
944 /* called from Offline mode to determine the current time of the node */
945 /* update your internal information whenever it changes */
OfflineTime()946 bigtime_t MediaDemultiplexerNode::OfflineTime()
947 {
948 fprintf(stderr,"MediaDemultiplexerNode::OfflineTime\n");
949 return BMediaEventLooper::OfflineTime();
950 // XXX: do something else?
951 }
952
953 /* override only if you know what you are doing! */
954 /* otherwise much badness could occur */
955 /* the actual control loop function: */
956 /* waits for messages, Pops events off the queue and calls DispatchEvent */
ControlLoop()957 void MediaDemultiplexerNode::ControlLoop() {
958 BMediaEventLooper::ControlLoop();
959 }
960
961 // protected:
962
HandleStart(const media_timed_event * event,bigtime_t lateness,bool realTimeEvent=false)963 status_t MediaDemultiplexerNode::HandleStart(
964 const media_timed_event *event,
965 bigtime_t lateness,
966 bool realTimeEvent = false)
967 {
968 fprintf(stderr,"MediaDemultiplexerNode::HandleStart()\n");
969 if (RunState() != B_STARTED) {
970 // XXX: Either use the following line or the lines that are not commented.
971 // There doesn't seem to be a practical difference that i can tell.
972 // HandleBuffer(event,lateness,realTimeEvent);
973 media_timed_event firstBufferEvent(event->event_time, BTimedEventQueue::B_HANDLE_BUFFER);
974 HandleEvent(&firstBufferEvent, 0, false);
975 EventQueue()->AddEvent(firstBufferEvent);
976 }
977 return B_OK;
978 }
979
HandleSeek(const media_timed_event * event,bigtime_t lateness,bool realTimeEvent=false)980 status_t MediaDemultiplexerNode::HandleSeek(
981 const media_timed_event *event,
982 bigtime_t lateness,
983 bool realTimeEvent = false)
984 {
985 fprintf(stderr,"MediaDemultiplexerNode::HandleSeek(t=%lld,d=%i,bd=%lld)\n",event->event_time,event->data,event->bigdata);
986 return B_OK;
987 }
988
HandleWarp(const media_timed_event * event,bigtime_t lateness,bool realTimeEvent=false)989 status_t MediaDemultiplexerNode::HandleWarp(
990 const media_timed_event *event,
991 bigtime_t lateness,
992 bool realTimeEvent = false)
993 {
994 fprintf(stderr,"MediaDemultiplexerNode::HandleWarp\n");
995 return B_OK;
996 }
997
HandleStop(const media_timed_event * event,bigtime_t lateness,bool realTimeEvent=false)998 status_t MediaDemultiplexerNode::HandleStop(
999 const media_timed_event *event,
1000 bigtime_t lateness,
1001 bool realTimeEvent = false)
1002 {
1003 fprintf(stderr,"MediaDemultiplexerNode::HandleStop\n");
1004 // flush the queue so downstreamers don't get any more
1005 EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER);
1006 return B_OK;
1007 }
1008
HandleBuffer(const media_timed_event * event,bigtime_t lateness,bool realTimeEvent=false)1009 status_t MediaDemultiplexerNode::HandleBuffer(
1010 const media_timed_event *event,
1011 bigtime_t lateness,
1012 bool realTimeEvent = false)
1013 {
1014 fprintf(stderr,"MediaDemultiplexerNode::HandleBuffer\n");
1015 BBuffer * buffer = const_cast<BBuffer*>((BBuffer*)event->pointer);
1016 if (buffer == 0) {
1017 fprintf(stderr,"<- B_BAD_VALUE\n");
1018 return B_BAD_VALUE;
1019 }
1020 if (buffer->Header()->destination != input.destination.id) {
1021 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
1022 return B_MEDIA_BAD_DESTINATION;
1023 }
1024 if (outputs.begin() == outputs.end()) {
1025 fprintf(stderr,"<- B_MEDIA_NOT_CONNECTED\n");
1026 return B_MEDIA_NOT_CONNECTED;
1027 }
1028 status_t status = B_OK;
1029 fprintf(stderr," XXX: HandleBuffer not yet implemented.\n");
1030 // we have to hand the buffer to the extractor
1031 // and then whenever we get a buffer for an output send it
1032 // to that particular output (assuming it exists and is enabled)
1033 // BBuffer * buffer = fBufferGroup->RequestBuffer(output.format.u.multistream.max_chunk_size,fBufferPeriod);
1034 // if (buffer != 0) {
1035 // status = FillFileBuffer(buffer);
1036 // if (status != B_OK) {
1037 // fprintf(stderr,"MediaDemultiplexerNode::HandleEvent got an error from FillFileBuffer.\n");
1038 // buffer->Recycle();
1039 // } else {
1040 // if (fOutputEnabled) {
1041 // status = SendBuffer(buffer,output.destination);
1042 // if (status != B_OK) {
1043 // fprintf(stderr,"MediaDemultiplexerNode::HandleEvent got an error from SendBuffer.\n");
1044 // buffer->Recycle();
1045 // }
1046 // } else {
1047 buffer->Recycle();
1048 // }
1049 // }
1050 // }
1051 bigtime_t nextEventTime = event->event_time+10000; // fBufferPeriod; // XXX : should multiply
1052 media_timed_event nextBufferEvent(nextEventTime, BTimedEventQueue::B_HANDLE_BUFFER);
1053 EventQueue()->AddEvent(nextBufferEvent);
1054 return status;
1055 }
1056
HandleDataStatus(const media_timed_event * event,bigtime_t lateness,bool realTimeEvent=false)1057 status_t MediaDemultiplexerNode::HandleDataStatus(
1058 const media_timed_event *event,
1059 bigtime_t lateness,
1060 bool realTimeEvent = false)
1061 {
1062 fprintf(stderr,"MediaDemultiplexerNode::HandleDataStatus");
1063 // find the information for this output
1064 vector<MediaOutputInfo>::iterator itr;
1065 for(itr = outputs.begin() ; (itr != outputs.end()) ; itr++) {
1066 SendDataStatus(event->data,itr->output.destination,event->event_time);
1067 }
1068 return B_OK;
1069 }
1070
HandleParameter(const media_timed_event * event,bigtime_t lateness,bool realTimeEvent=false)1071 status_t MediaDemultiplexerNode::HandleParameter(
1072 const media_timed_event *event,
1073 bigtime_t lateness,
1074 bool realTimeEvent = false)
1075 {
1076 fprintf(stderr,"MediaDemultiplexerNode::HandleParameter");
1077 return B_OK;
1078 }
1079
1080 // -------------------------------------------------------- //
1081 // MediaDemultiplexerNode specific functions
1082 // -------------------------------------------------------- //
1083
1084 // public:
1085
GetFlavor(flavor_info * outInfo,int32 id)1086 void MediaDemultiplexerNode::GetFlavor(flavor_info * outInfo, int32 id)
1087 {
1088 fprintf(stderr,"MediaDemultiplexerNode::GetFlavor\n");
1089 if (outInfo == 0) {
1090 return;
1091 }
1092 outInfo->name = "Haiku Demultiplexer";
1093 outInfo->info = "A MediaDemultiplexerNode node demultiplexes a multistream into its constituent streams.";
1094 outInfo->kinds = B_BUFFER_CONSUMER | B_BUFFER_PRODUCER;
1095 outInfo->flavor_flags = B_FLAVOR_IS_LOCAL;
1096 outInfo->possible_count = INT_MAX;
1097 outInfo->in_format_count = 1; // 1 input
1098 media_format * inFormats = new media_format[outInfo->in_format_count];
1099 GetInputFormat(&inFormats[0]);
1100 outInfo->in_formats = inFormats;
1101 outInfo->out_format_count = 1; // 1 output
1102 media_format * outFormats = new media_format[outInfo->out_format_count];
1103 GetOutputFormat(&outFormats[0]);
1104 outInfo->out_formats = outFormats;
1105 outInfo->internal_id = id;
1106 return;
1107 }
1108
GetInputFormat(media_format * outFormat)1109 void MediaDemultiplexerNode::GetInputFormat(media_format * outFormat)
1110 {
1111 fprintf(stderr,"MediaDemultiplexerNode::GetInputFormat\n");
1112 if (outFormat == 0) {
1113 return;
1114 }
1115 outFormat->type = B_MEDIA_MULTISTREAM;
1116 outFormat->require_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
1117 outFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
1118 outFormat->u.multistream = media_multistream_format::wildcard;
1119 }
1120
GetOutputFormat(media_format * outFormat)1121 void MediaDemultiplexerNode::GetOutputFormat(media_format * outFormat)
1122 {
1123 fprintf(stderr,"MediaDemultiplexerNode::GetOutputFormat\n");
1124 if (outFormat == 0) {
1125 return;
1126 }
1127 outFormat->type = B_MEDIA_UNKNOWN_TYPE; // more like ANY_TYPE than unknown
1128 outFormat->require_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
1129 outFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
1130 }
1131
1132 // protected:
1133
AddRequirements(media_format * format)1134 status_t MediaDemultiplexerNode::AddRequirements(media_format * format)
1135 {
1136 fprintf(stderr,"MediaDemultiplexerNode::AddRequirements\n");
1137 return B_OK;
1138 }
1139
1140 // -------------------------------------------------------- //
1141 // stuffing
1142 // -------------------------------------------------------- //
1143
_Reserved_MediaDemultiplexerNode_0(void *)1144 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_0(void *) {}
_Reserved_MediaDemultiplexerNode_1(void *)1145 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_1(void *) {}
_Reserved_MediaDemultiplexerNode_2(void *)1146 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_2(void *) {}
_Reserved_MediaDemultiplexerNode_3(void *)1147 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_3(void *) {}
_Reserved_MediaDemultiplexerNode_4(void *)1148 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_4(void *) {}
_Reserved_MediaDemultiplexerNode_5(void *)1149 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_5(void *) {}
_Reserved_MediaDemultiplexerNode_6(void *)1150 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_6(void *) {}
_Reserved_MediaDemultiplexerNode_7(void *)1151 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_7(void *) {}
_Reserved_MediaDemultiplexerNode_8(void *)1152 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_8(void *) {}
_Reserved_MediaDemultiplexerNode_9(void *)1153 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_9(void *) {}
_Reserved_MediaDemultiplexerNode_10(void *)1154 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_10(void *) {}
_Reserved_MediaDemultiplexerNode_11(void *)1155 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_11(void *) {}
_Reserved_MediaDemultiplexerNode_12(void *)1156 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_12(void *) {}
_Reserved_MediaDemultiplexerNode_13(void *)1157 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_13(void *) {}
_Reserved_MediaDemultiplexerNode_14(void *)1158 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_14(void *) {}
_Reserved_MediaDemultiplexerNode_15(void *)1159 status_t MediaDemultiplexerNode::_Reserved_MediaDemultiplexerNode_15(void *) {}
1160