1*0fe9fd36SDavid McPaul /* 2*0fe9fd36SDavid McPaul * Copyright (C) 2009-2010 David McPaul 3*0fe9fd36SDavid McPaul * 4*0fe9fd36SDavid McPaul * All rights reserved. Distributed under the terms of the MIT License. 5*0fe9fd36SDavid McPaul * VideoMixerNode.cpp 6*0fe9fd36SDavid McPaul * 7*0fe9fd36SDavid McPaul * The VideoMixerNode class takes in multiple video streams and supplies 8*0fe9fd36SDavid McPaul * a single stream as the output. 9*0fe9fd36SDavid McPaul * each stream is converted to the same colourspace and should match 10*0fe9fd36SDavid McPaul * either the primary input OR the requested colourspace from the output 11*0fe9fd36SDavid McPaul * destination. 12*0fe9fd36SDavid McPaul * 13*0fe9fd36SDavid McPaul * The first input is considered the primary input 14*0fe9fd36SDavid McPaul * subsequent input framesize should match the primary input framesize 15*0fe9fd36SDavid McPaul * The output framerate will be the same as the primary input 16*0fe9fd36SDavid McPaul * 17*0fe9fd36SDavid McPaul */ 18*0fe9fd36SDavid McPaul 19*0fe9fd36SDavid McPaul #include <stdio.h> 20*0fe9fd36SDavid McPaul #include <string.h> 21*0fe9fd36SDavid McPaul 22*0fe9fd36SDavid McPaul #include "VideoMixerNode.h" 23*0fe9fd36SDavid McPaul 24*0fe9fd36SDavid McPaul VideoMixerNode::~VideoMixerNode(void) 25*0fe9fd36SDavid McPaul { 26*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::~VideoMixerNode\n"); 27*0fe9fd36SDavid McPaul // Stop the BMediaEventLooper thread 28*0fe9fd36SDavid McPaul Quit(); 29*0fe9fd36SDavid McPaul } 30*0fe9fd36SDavid McPaul 31*0fe9fd36SDavid McPaul VideoMixerNode::VideoMixerNode( 32*0fe9fd36SDavid McPaul const flavor_info *info = 0, 33*0fe9fd36SDavid McPaul BMessage *config = 0, 34*0fe9fd36SDavid McPaul BMediaAddOn *addOn = 0) 35*0fe9fd36SDavid McPaul : BMediaNode("VideoMixerNode"), 36*0fe9fd36SDavid McPaul BBufferConsumer(B_MEDIA_RAW_VIDEO), // Raw video buffers in 37*0fe9fd36SDavid McPaul BBufferProducer(B_MEDIA_RAW_VIDEO), // Raw video buffers out 38*0fe9fd36SDavid McPaul BMediaEventLooper() 39*0fe9fd36SDavid McPaul { 40*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::VideoMixerNode\n"); 41*0fe9fd36SDavid McPaul // keep our creator around for AddOn calls later 42*0fe9fd36SDavid McPaul fAddOn = addOn; 43*0fe9fd36SDavid McPaul // NULL out our latency estimates 44*0fe9fd36SDavid McPaul fDownstreamLatency = 0; 45*0fe9fd36SDavid McPaul fInternalLatency = 0; 46*0fe9fd36SDavid McPaul 47*0fe9fd36SDavid McPaul // Start with 1 input and 1 output 48*0fe9fd36SDavid McPaul ClearInput(&fInitialInput); 49*0fe9fd36SDavid McPaul 50*0fe9fd36SDavid McPaul strncpy(fOutput.name,"VideoMixer Output", B_MEDIA_NAME_LENGTH-1); 51*0fe9fd36SDavid McPaul fOutput.name[B_MEDIA_NAME_LENGTH-1] = '\0'; 52*0fe9fd36SDavid McPaul 53*0fe9fd36SDavid McPaul // initialize the output 54*0fe9fd36SDavid McPaul fOutput.node = media_node::null; // until registration 55*0fe9fd36SDavid McPaul fOutput.destination = media_destination::null; 56*0fe9fd36SDavid McPaul fOutput.source.port = ControlPort(); 57*0fe9fd36SDavid McPaul fOutput.source.id = 0; 58*0fe9fd36SDavid McPaul 59*0fe9fd36SDavid McPaul GetOutputFormat(&fOutput.format); 60*0fe9fd36SDavid McPaul 61*0fe9fd36SDavid McPaul fInitCheckStatus = B_OK; 62*0fe9fd36SDavid McPaul } 63*0fe9fd36SDavid McPaul 64*0fe9fd36SDavid McPaul void VideoMixerNode::NodeRegistered(void) 65*0fe9fd36SDavid McPaul { 66*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::NodeRegistered\n"); 67*0fe9fd36SDavid McPaul 68*0fe9fd36SDavid McPaul // for every node created so far set to this Node; 69*0fe9fd36SDavid McPaul for (uint32 i=0;i<fConnectedInputs.size();i++) { 70*0fe9fd36SDavid McPaul fConnectedInputs[i]->node = Node(); 71*0fe9fd36SDavid McPaul fConnectedInputs[i]->destination.id = i; 72*0fe9fd36SDavid McPaul fConnectedInputs[i]->destination.port = ControlPort(); 73*0fe9fd36SDavid McPaul } 74*0fe9fd36SDavid McPaul 75*0fe9fd36SDavid McPaul fInitialInput.node = Node(); 76*0fe9fd36SDavid McPaul fInitialInput.destination.id = fConnectedInputs.size(); 77*0fe9fd36SDavid McPaul fInitialInput.destination.port = ControlPort(); 78*0fe9fd36SDavid McPaul 79*0fe9fd36SDavid McPaul GetOutputFormat(&fOutput.format); 80*0fe9fd36SDavid McPaul fOutput.node = Node(); 81*0fe9fd36SDavid McPaul 82*0fe9fd36SDavid McPaul // start the BMediaEventLooper thread 83*0fe9fd36SDavid McPaul SetPriority(B_REAL_TIME_PRIORITY); 84*0fe9fd36SDavid McPaul Run(); 85*0fe9fd36SDavid McPaul } 86*0fe9fd36SDavid McPaul 87*0fe9fd36SDavid McPaul media_input * 88*0fe9fd36SDavid McPaul VideoMixerNode::CreateInput(uint32 inputID) { 89*0fe9fd36SDavid McPaul media_input *input = new media_input(); 90*0fe9fd36SDavid McPaul 91*0fe9fd36SDavid McPaul ClearInput(input); 92*0fe9fd36SDavid McPaul 93*0fe9fd36SDavid McPaul // don't overwrite available space, and be sure to terminate 94*0fe9fd36SDavid McPaul sprintf(input->name, "VideoMixer Input %ld", inputID); 95*0fe9fd36SDavid McPaul 96*0fe9fd36SDavid McPaul return input; 97*0fe9fd36SDavid McPaul } 98*0fe9fd36SDavid McPaul 99*0fe9fd36SDavid McPaul void 100*0fe9fd36SDavid McPaul VideoMixerNode::ClearInput(media_input *input) { 101*0fe9fd36SDavid McPaul 102*0fe9fd36SDavid McPaul // initialize the input 103*0fe9fd36SDavid McPaul sprintf(input->name, "VideoMixer Input"); 104*0fe9fd36SDavid McPaul input->node = Node(); 105*0fe9fd36SDavid McPaul input->source = media_source::null; 106*0fe9fd36SDavid McPaul input->destination = media_destination::null; 107*0fe9fd36SDavid McPaul 108*0fe9fd36SDavid McPaul GetInputFormat(&input->format); 109*0fe9fd36SDavid McPaul } 110*0fe9fd36SDavid McPaul 111*0fe9fd36SDavid McPaul media_input * 112*0fe9fd36SDavid McPaul VideoMixerNode::GetInput(const media_source &source) { 113*0fe9fd36SDavid McPaul 114*0fe9fd36SDavid McPaul vector<media_input *>::iterator each; 115*0fe9fd36SDavid McPaul 116*0fe9fd36SDavid McPaul for (each=fConnectedInputs.begin(); each<fConnectedInputs.end(); each++) { 117*0fe9fd36SDavid McPaul if ((*each)->source == source) { 118*0fe9fd36SDavid McPaul return *each; 119*0fe9fd36SDavid McPaul } 120*0fe9fd36SDavid McPaul } 121*0fe9fd36SDavid McPaul 122*0fe9fd36SDavid McPaul return NULL; 123*0fe9fd36SDavid McPaul } 124*0fe9fd36SDavid McPaul 125*0fe9fd36SDavid McPaul media_input * 126*0fe9fd36SDavid McPaul VideoMixerNode::GetInput(const media_destination &destination) { 127*0fe9fd36SDavid McPaul 128*0fe9fd36SDavid McPaul vector<media_input *>::iterator each; 129*0fe9fd36SDavid McPaul 130*0fe9fd36SDavid McPaul for (each=fConnectedInputs.begin(); each<fConnectedInputs.end(); each++) { 131*0fe9fd36SDavid McPaul if ((*each)->destination == destination) { 132*0fe9fd36SDavid McPaul return *each; 133*0fe9fd36SDavid McPaul } 134*0fe9fd36SDavid McPaul } 135*0fe9fd36SDavid McPaul 136*0fe9fd36SDavid McPaul return NULL; 137*0fe9fd36SDavid McPaul } 138*0fe9fd36SDavid McPaul 139*0fe9fd36SDavid McPaul media_input * 140*0fe9fd36SDavid McPaul VideoMixerNode::GetInput(const int32 id) { 141*0fe9fd36SDavid McPaul 142*0fe9fd36SDavid McPaul vector<media_input *>::iterator each; 143*0fe9fd36SDavid McPaul 144*0fe9fd36SDavid McPaul for (each=fConnectedInputs.begin(); each<fConnectedInputs.end(); each++) { 145*0fe9fd36SDavid McPaul if ((*each)->destination.id == id) { 146*0fe9fd36SDavid McPaul return *each; 147*0fe9fd36SDavid McPaul } 148*0fe9fd36SDavid McPaul } 149*0fe9fd36SDavid McPaul 150*0fe9fd36SDavid McPaul return NULL; 151*0fe9fd36SDavid McPaul } 152*0fe9fd36SDavid McPaul 153*0fe9fd36SDavid McPaul status_t VideoMixerNode::InitCheck(void) const 154*0fe9fd36SDavid McPaul { 155*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::InitCheck\n"); 156*0fe9fd36SDavid McPaul return fInitCheckStatus; 157*0fe9fd36SDavid McPaul } 158*0fe9fd36SDavid McPaul 159*0fe9fd36SDavid McPaul status_t VideoMixerNode::GetConfigurationFor( 160*0fe9fd36SDavid McPaul BMessage *into_message) 161*0fe9fd36SDavid McPaul { 162*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::GetConfigurationFor\n"); 163*0fe9fd36SDavid McPaul return B_OK; 164*0fe9fd36SDavid McPaul } 165*0fe9fd36SDavid McPaul 166*0fe9fd36SDavid McPaul // -------------------------------------------------------- // 167*0fe9fd36SDavid McPaul // implementation of BMediaNode 168*0fe9fd36SDavid McPaul // -------------------------------------------------------- // 169*0fe9fd36SDavid McPaul 170*0fe9fd36SDavid McPaul BMediaAddOn *VideoMixerNode::AddOn( 171*0fe9fd36SDavid McPaul int32 *internal_id) const 172*0fe9fd36SDavid McPaul { 173*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::AddOn\n"); 174*0fe9fd36SDavid McPaul // BeBook says this only gets called if we were in an add-on. 175*0fe9fd36SDavid McPaul if (fAddOn != NULL) { 176*0fe9fd36SDavid McPaul // If we get a null pointer then we just won't write. 177*0fe9fd36SDavid McPaul if (internal_id != NULL) { 178*0fe9fd36SDavid McPaul internal_id = 0; 179*0fe9fd36SDavid McPaul } 180*0fe9fd36SDavid McPaul } 181*0fe9fd36SDavid McPaul return fAddOn; 182*0fe9fd36SDavid McPaul } 183*0fe9fd36SDavid McPaul 184*0fe9fd36SDavid McPaul void VideoMixerNode::Start(bigtime_t performance_time) 185*0fe9fd36SDavid McPaul { 186*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::Start(pt=%lld)\n", performance_time); 187*0fe9fd36SDavid McPaul BMediaEventLooper::Start(performance_time); 188*0fe9fd36SDavid McPaul } 189*0fe9fd36SDavid McPaul 190*0fe9fd36SDavid McPaul void VideoMixerNode::Stop( 191*0fe9fd36SDavid McPaul bigtime_t performance_time, 192*0fe9fd36SDavid McPaul bool immediate) 193*0fe9fd36SDavid McPaul { 194*0fe9fd36SDavid McPaul if (immediate) { 195*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::Stop(pt=%lld,<immediate>)\n", performance_time); 196*0fe9fd36SDavid McPaul } else { 197*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::Stop(pt=%lld,<scheduled>)\n", performance_time); 198*0fe9fd36SDavid McPaul } 199*0fe9fd36SDavid McPaul BMediaEventLooper::Stop(performance_time, immediate); 200*0fe9fd36SDavid McPaul } 201*0fe9fd36SDavid McPaul 202*0fe9fd36SDavid McPaul void VideoMixerNode::Seek( 203*0fe9fd36SDavid McPaul bigtime_t media_time, 204*0fe9fd36SDavid McPaul bigtime_t performance_time) 205*0fe9fd36SDavid McPaul { 206*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::Seek(mt=%lld,pt=%lld)\n", media_time,performance_time); 207*0fe9fd36SDavid McPaul BMediaEventLooper::Seek(media_time, performance_time); 208*0fe9fd36SDavid McPaul } 209*0fe9fd36SDavid McPaul 210*0fe9fd36SDavid McPaul void VideoMixerNode::SetRunMode(run_mode mode) 211*0fe9fd36SDavid McPaul { 212*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::SetRunMode(%i)\n", mode); 213*0fe9fd36SDavid McPaul BMediaEventLooper::SetRunMode(mode); 214*0fe9fd36SDavid McPaul } 215*0fe9fd36SDavid McPaul 216*0fe9fd36SDavid McPaul void VideoMixerNode::TimeWarp( 217*0fe9fd36SDavid McPaul bigtime_t at_real_time, 218*0fe9fd36SDavid McPaul bigtime_t to_performance_time) 219*0fe9fd36SDavid McPaul { 220*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::TimeWarp(rt=%lld,pt=%lld)\n", at_real_time, to_performance_time); 221*0fe9fd36SDavid McPaul BMediaEventLooper::TimeWarp(at_real_time, to_performance_time); 222*0fe9fd36SDavid McPaul } 223*0fe9fd36SDavid McPaul 224*0fe9fd36SDavid McPaul void VideoMixerNode::Preroll(void) 225*0fe9fd36SDavid McPaul { 226*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::Preroll\n"); 227*0fe9fd36SDavid McPaul // XXX:Performance opportunity 228*0fe9fd36SDavid McPaul BMediaNode::Preroll(); 229*0fe9fd36SDavid McPaul } 230*0fe9fd36SDavid McPaul 231*0fe9fd36SDavid McPaul void VideoMixerNode::SetTimeSource(BTimeSource *time_source) 232*0fe9fd36SDavid McPaul { 233*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::SetTimeSource\n"); 234*0fe9fd36SDavid McPaul BMediaNode::SetTimeSource(time_source); 235*0fe9fd36SDavid McPaul } 236*0fe9fd36SDavid McPaul 237*0fe9fd36SDavid McPaul status_t VideoMixerNode::HandleMessage( 238*0fe9fd36SDavid McPaul int32 message, 239*0fe9fd36SDavid McPaul const void *data, 240*0fe9fd36SDavid McPaul size_t size) 241*0fe9fd36SDavid McPaul { 242*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::HandleMessage\n"); 243*0fe9fd36SDavid McPaul status_t status = B_OK; 244*0fe9fd36SDavid McPaul switch (message) { 245*0fe9fd36SDavid McPaul // no special messages for now 246*0fe9fd36SDavid McPaul default: 247*0fe9fd36SDavid McPaul status = BBufferConsumer::HandleMessage(message, data, size); 248*0fe9fd36SDavid McPaul if (status == B_OK) { 249*0fe9fd36SDavid McPaul break; 250*0fe9fd36SDavid McPaul } 251*0fe9fd36SDavid McPaul status = BBufferProducer::HandleMessage(message, data, size); 252*0fe9fd36SDavid McPaul if (status == B_OK) { 253*0fe9fd36SDavid McPaul break; 254*0fe9fd36SDavid McPaul } 255*0fe9fd36SDavid McPaul status = BMediaNode::HandleMessage(message, data, size); 256*0fe9fd36SDavid McPaul if (status == B_OK) { 257*0fe9fd36SDavid McPaul break; 258*0fe9fd36SDavid McPaul } 259*0fe9fd36SDavid McPaul BMediaNode::HandleBadMessage(message, data, size); 260*0fe9fd36SDavid McPaul status = B_ERROR; 261*0fe9fd36SDavid McPaul break; 262*0fe9fd36SDavid McPaul } 263*0fe9fd36SDavid McPaul return status; 264*0fe9fd36SDavid McPaul } 265*0fe9fd36SDavid McPaul 266*0fe9fd36SDavid McPaul status_t VideoMixerNode::RequestCompleted(const media_request_info &info) 267*0fe9fd36SDavid McPaul { 268*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::RequestCompleted\n"); 269*0fe9fd36SDavid McPaul return BMediaNode::RequestCompleted(info); 270*0fe9fd36SDavid McPaul } 271*0fe9fd36SDavid McPaul 272*0fe9fd36SDavid McPaul status_t VideoMixerNode::DeleteHook(BMediaNode *node) 273*0fe9fd36SDavid McPaul { 274*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::DeleteHook\n"); 275*0fe9fd36SDavid McPaul return BMediaEventLooper::DeleteHook(node); 276*0fe9fd36SDavid McPaul } 277*0fe9fd36SDavid McPaul 278*0fe9fd36SDavid McPaul status_t VideoMixerNode::GetNodeAttributes( 279*0fe9fd36SDavid McPaul media_node_attribute *outAttributes, 280*0fe9fd36SDavid McPaul size_t inMaxCount) 281*0fe9fd36SDavid McPaul { 282*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::GetNodeAttributes\n"); 283*0fe9fd36SDavid McPaul return BMediaNode::GetNodeAttributes(outAttributes, inMaxCount); 284*0fe9fd36SDavid McPaul } 285*0fe9fd36SDavid McPaul 286*0fe9fd36SDavid McPaul status_t VideoMixerNode::AddTimer( 287*0fe9fd36SDavid McPaul bigtime_t at_performance_time, 288*0fe9fd36SDavid McPaul int32 cookie) 289*0fe9fd36SDavid McPaul { 290*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::AddTimer\n"); 291*0fe9fd36SDavid McPaul return BMediaEventLooper::AddTimer(at_performance_time, cookie); 292*0fe9fd36SDavid McPaul } 293*0fe9fd36SDavid McPaul 294*0fe9fd36SDavid McPaul // -------------------------------------------------------- // 295*0fe9fd36SDavid McPaul // VideoMixerNode specific functions 296*0fe9fd36SDavid McPaul // -------------------------------------------------------- // 297*0fe9fd36SDavid McPaul 298*0fe9fd36SDavid McPaul // public: 299*0fe9fd36SDavid McPaul 300*0fe9fd36SDavid McPaul void VideoMixerNode::GetFlavor(flavor_info *outInfo, int32 id) 301*0fe9fd36SDavid McPaul { 302*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::GetFlavor\n"); 303*0fe9fd36SDavid McPaul 304*0fe9fd36SDavid McPaul if (outInfo != NULL) { 305*0fe9fd36SDavid McPaul outInfo->internal_id = id; 306*0fe9fd36SDavid McPaul outInfo->name = "Haiku VideoMixer"; 307*0fe9fd36SDavid McPaul outInfo->info = "A VideoMixerNode node mixes multiple video streams into a single stream."; 308*0fe9fd36SDavid McPaul outInfo->kinds = B_BUFFER_CONSUMER | B_BUFFER_PRODUCER; 309*0fe9fd36SDavid McPaul outInfo->flavor_flags = B_FLAVOR_IS_LOCAL; 310*0fe9fd36SDavid McPaul outInfo->possible_count = INT_MAX; // no limit 311*0fe9fd36SDavid McPaul outInfo->in_format_count = 1; 312*0fe9fd36SDavid McPaul media_format *inFormats = new media_format[outInfo->in_format_count]; 313*0fe9fd36SDavid McPaul GetInputFormat(&inFormats[0]); 314*0fe9fd36SDavid McPaul outInfo->in_formats = inFormats; 315*0fe9fd36SDavid McPaul outInfo->out_format_count = 1; // single output 316*0fe9fd36SDavid McPaul media_format *outFormats = new media_format[outInfo->out_format_count]; 317*0fe9fd36SDavid McPaul GetOutputFormat(&outFormats[0]); 318*0fe9fd36SDavid McPaul outInfo->out_formats = outFormats; 319*0fe9fd36SDavid McPaul } 320*0fe9fd36SDavid McPaul } 321*0fe9fd36SDavid McPaul 322*0fe9fd36SDavid McPaul void VideoMixerNode::GetInputFormat(media_format *outFormat) 323*0fe9fd36SDavid McPaul { 324*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::GetInputFormat\n"); 325*0fe9fd36SDavid McPaul 326*0fe9fd36SDavid McPaul if (outFormat != NULL) { 327*0fe9fd36SDavid McPaul outFormat->type = B_MEDIA_RAW_VIDEO; 328*0fe9fd36SDavid McPaul outFormat->require_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 329*0fe9fd36SDavid McPaul outFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 330*0fe9fd36SDavid McPaul outFormat->u.raw_video = media_raw_video_format::wildcard; 331*0fe9fd36SDavid McPaul } 332*0fe9fd36SDavid McPaul } 333*0fe9fd36SDavid McPaul 334*0fe9fd36SDavid McPaul void VideoMixerNode::GetOutputFormat(media_format *outFormat) 335*0fe9fd36SDavid McPaul { 336*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::GetOutputFormat\n"); 337*0fe9fd36SDavid McPaul if (outFormat != NULL) { 338*0fe9fd36SDavid McPaul outFormat->type = B_MEDIA_RAW_VIDEO; 339*0fe9fd36SDavid McPaul outFormat->require_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 340*0fe9fd36SDavid McPaul outFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 341*0fe9fd36SDavid McPaul outFormat->u.raw_video = media_raw_video_format::wildcard; 342*0fe9fd36SDavid McPaul } 343*0fe9fd36SDavid McPaul } 344*0fe9fd36SDavid McPaul 345*0fe9fd36SDavid McPaul // protected: 346*0fe9fd36SDavid McPaul 347*0fe9fd36SDavid McPaul status_t VideoMixerNode::AddRequirements(media_format *format) 348*0fe9fd36SDavid McPaul { 349*0fe9fd36SDavid McPaul fprintf(stderr,"VideoMixerNode::AddRequirements\n"); 350*0fe9fd36SDavid McPaul return B_OK; 351*0fe9fd36SDavid McPaul } 352