Ticket #7285: media_mixer.diff
File media_mixer.diff, 7.3 KB (added by , 14 years ago) |
---|
-
src/kits/media/MediaEventLooper.cpp
222 222 // only the scheduling latency). 223 223 224 224 latency = fEventLatency + fSchedulingLatency; 225 if (fEventQueue.HasEvents() && (TimeSource()->Now() - latency) >= fEventQueue.FirstEventTime()) { 226 // printf("node %02d waiting for %12Ld that has already happened, now %12Ld\n", ID(), fEventQueue.FirstEventTime(), system_time()); 225 if (fEventQueue.HasEvents() 226 && (TimeSource()->Now() + latency) >= fEventQueue.FirstEventTime()) { 227 // printf("node %02ld waiting for %12Ld that already happened, now %12Ld(%Ld)\n", 228 // ID(), fEventQueue.FirstEventTime(), TimeSource()->Now(), system_time()); 227 229 is_realtime = false; 228 230 break; 229 231 } 230 if (fRealTimeQueue.HasEvents() && (TimeSource()->RealTime() - fSchedulingLatency) >= fRealTimeQueue.FirstEventTime()) { 232 if (fRealTimeQueue.HasEvents() 233 && (TimeSource()->RealTime() + fSchedulingLatency) >= fRealTimeQueue.FirstEventTime()) { 231 234 latency = fSchedulingLatency; 232 235 is_realtime = true; 233 236 break; … … 235 238 waituntil = B_INFINITE_TIMEOUT; 236 239 if (fEventQueue.HasEvents()) { 237 240 waituntil = TimeSource()->RealTimeFor(fEventQueue.FirstEventTime(), latency); 238 // printf("node %02d waiting for %12Ld that will happen at %12Ld\n", ID(), fEventQueue.FirstEventTime(), waituntil); 241 // printf("node %02ld waiting for %12Ld that will happen at %12Ld\n", 242 // ID(), fEventQueue.FirstEventTime(), waituntil); 239 243 is_realtime = false; 240 244 } 241 245 if (fRealTimeQueue.HasEvents()) { … … 265 269 if (is_realtime) 266 270 lateness = TimeSource()->RealTime() - event.event_time; 267 271 else 268 lateness = TimeSource()->RealTime() - TimeSource()->RealTimeFor(event.event_time, 0) + fEventLatency; 272 lateness = 273 TimeSource()->RealTime() - TimeSource()->RealTimeFor(event.event_time, 0) + fEventLatency; 269 274 DispatchEvent(&event, lateness, is_realtime); 270 275 } 271 276 } -
src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp
86 86 #define FORMAT_USER_DATA_MAGIC_1 0xc84173bd 87 87 #define FORMAT_USER_DATA_MAGIC_2 0x4af62b7d 88 88 89 90 89 const static bigtime_t kMaxLatency = 150000; 91 90 // 150 ms is the maximum latency we publish 92 91 … … 109 108 fInternalLatency(1), 110 109 fDisableStop(false), 111 110 fLastLateNotification(0) 111 // fBlockRepeatNotify(0) 112 112 { 113 113 BMediaNode::AddNodeKind(B_SYSTEM_MIXER); 114 114 … … 302 302 303 303 //PRINT(4, "buffer received at %12Ld, should arrive at %12Ld, delta %12Ld\n", TimeSource()->Now(), buffer->Header()->start_time, TimeSource()->Now() - buffer->Header()->start_time); 304 304 305 bigtime_t lateness = 306 TimeSource()->RealTime() + EventLatency() 307 - TimeSource()->RealTimeFor(buffer->Header()->start_time, 0); 308 if (lateness > kMaxJitter) { 309 printf("Buffer start=%Ld: received %Ld usec late at %Ld EventLatency=%Ld\n", 310 buffer->Header()->start_time, lateness, TimeSource()->Now(), 311 EventLatency()); 312 // I believe this is pointless here, because the relevant run mode is the source, mot the mixer! 313 // if (RunMode() == B_DROP_DATA || RunMode() == B_DECREASE_PRECISION 314 // || RunMode() == B_INCREASE_LATENCY) { 315 // Increase latency only if we didn't do it recently: 316 if (TimeSource()->Now() >= fLastLateNotification) { 317 debug_printf("mixer sending notify\n"); 318 319 // Build a media_source out of the header data 320 media_source source = media_source::null; 321 source.port = buffer->Header()->source_port; 322 source.id = buffer->Header()->source; 323 324 NotifyLateProducer(source, lateness, TimeSource()->Now()); 325 // Don't send another before this: 326 fLastLateNotification = buffer->Header()->start_time; 327 } 328 329 if (RunMode() == B_DROP_DATA || lateness > EventLatency()) { // Experimental limit 330 debug_printf("Mixer dropping buffer\n"); 331 return; 332 } 333 } 305 334 // to receive the buffer at the right time, 306 335 // push it through the event looper 307 336 media_timed_event event(buffer->Header()->start_time, 308 337 BTimedEventQueue::B_HANDLE_BUFFER, buffer, 309 338 BTimedEventQueue::B_RECYCLE_BUFFER); 310 339 EventQueue()->AddEvent(event); 340 311 341 } 312 342 313 343 314 344 void 315 345 AudioMixer::HandleInputBuffer(BBuffer* buffer, bigtime_t lateness) 316 346 { 317 if (lateness > kMaxJitter) { 318 debug_printf("Received buffer %Ld usec late\n", lateness); 319 if (RunMode() == B_DROP_DATA || RunMode() == B_DECREASE_PRECISION 320 || RunMode() == B_INCREASE_LATENCY) { 321 debug_printf("sending notify\n"); 322 323 // Build a media_source out of the header data 324 media_source source = media_source::null; 325 source.port = buffer->Header()->source_port; 326 source.id = buffer->Header()->source; 327 328 NotifyLateProducer(source, lateness, TimeSource()->Now()); 329 330 if (RunMode() == B_DROP_DATA) { 331 debug_printf("dropping buffer\n"); 332 return; 333 } 334 } 347 // Handle possible 'blackouts' in MediaEventLooper timing: 348 bigtime_t real_lateness = TimeSource()->RealTime() + fDownstreamLatency 349 - TimeSource()->RealTimeFor(buffer->Header()->start_time, 0); 350 // Increase latency only if we didn't do it recently 351 // -- because we don't want to respond to multiple reports from buffers in the queue 352 if (real_lateness > kMaxJitter && TimeSource()->Now() >= fLastLateNotification) { 353 fInternalLatency += real_lateness; 354 SetEventLatency(fDownstreamLatency + fInternalLatency); 355 printf("Mixer: perftime %Ld actual lateness = %Ld reset event latency=%Ld\n", 356 buffer->Header()->start_time, real_lateness, EventLatency()); 357 PublishEventLatencyChange(); 358 fLastLateNotification = buffer->Header()->start_time; 335 359 } 336 360 337 361 // printf("Received buffer with lateness %Ld\n", lateness); … … 998 1022 999 1023 ERROR("AudioMixer::LateNoticeReceived, %Ld too late at %Ld\n", howMuch, 1000 1024 performanceTime); 1025 printf("AudioMixer::LateNoticeReceived, %Ld too late at %Ld\n", howMuch, 1026 performanceTime); 1001 1027 1002 1028 if (what == fCore->Output()->MediaOutput().source 1003 1029 && RunMode() == B_INCREASE_LATENCY) { 1004 // We need to ignore subsequent notices whose performance time1005 // lies before the performance time of the last notification1030 // We need to ignore subsequent notices whose arrival time here 1031 // lies within the latency, because queued-up buffers will all be 'late' 1006 1032 if (performanceTime < fLastLateNotification) 1007 1033 return; 1008 1034 1009 1035 fInternalLatency += howMuch; 1010 1036 1011 1037 // At some point a too large latency can get annoying 1038 // (actually more than annoying, as there won't be enough buffers long before this!) 1012 1039 if (fInternalLatency > kMaxLatency) 1013 1040 fInternalLatency = kMaxLatency; 1014 1041 1015 fLastLateNotification = TimeSource()->Now() ;1042 fLastLateNotification = TimeSource()->Now() + EventLatency(); 1016 1043 1017 1044 debug_printf("AudioMixer: increasing internal latency to %Ld usec\n", fInternalLatency); 1045 printf("AudioMixer: increasing internal latency to %Ld usec\n", fInternalLatency); 1018 1046 SetEventLatency(fDownstreamLatency + fInternalLatency); 1019 1047 1020 1048 PublishEventLatencyChange(); … … 1066 1094 switch (event->type) { 1067 1095 case BTimedEventQueue::B_HANDLE_BUFFER: 1068 1096 { 1097 // printf("Mixer HandleInputBuffer at %Ld\n", system_time()); 1069 1098 HandleInputBuffer((BBuffer *)event->pointer, lateness); 1070 1099 ((BBuffer *)event->pointer)->Recycle(); 1071 1100 break;