📄 xaosproducer.cpp
字号:
status_t XaoSProducer::VideoClippingChanged( const media_source & /* for_source */, int16 /* num_shorts */, int16 * /* clip_data */, const media_video_display_info & /* display */, int32 * /* out_from_change_count */){ NODE(stderr, "XaoSProducer: ClippingChanged (not implemented)\n"); /* FIXME handle XaoS resize here and send the clipping info to the * handler */ return B_ERROR;}status_t XaoSProducer::GetLatency( bigtime_t * out_latency){ NODE(stderr, "XaoSProducer: GetLatency\n"); status_t err = BBufferProducer::GetLatency(out_latency); if (err >= B_OK) { *out_latency = TotalLatency(); } return err;}status_t XaoSProducer::PrepareToConnect( const media_source & what, const media_destination & where, media_format * format, media_source * out_source, char * out_name){ NODE(stderr, "XaoSProducer::PrepareToConnect()\n"); // We only accept connections to our single output, and only // when that output isn't already connected to something. if (what != m_output.source) { NODE(stderr, "XaoSProducer::PrepareToConnect(): bad source\n"); return B_MEDIA_BAD_SOURCE; } if (m_output.destination != media_destination::null) { NODE(stderr, "XaoSProducer::PrepareToConnect(): already connected\n"); return B_MEDIA_BAD_DESTINATION; } #if DEBUG char fmt[100]; string_for_format(m_output.format, fmt, 100); FORMAT(stderr, "we're suggesting %s\n", fmt); string_for_format(*format, fmt, 100); FORMAT(stderr, "he's expecting %s\n", fmt);#endif if (!format_is_compatible(*format, m_output.format)) { NODE(stderr, "XaoSProducer::PrepareToConnect(): bad format\n"); return B_MEDIA_BAD_FORMAT; } /* We require non interlaced TOP_LEFT_RIGHT oriented mode */ fprintf(stderr,"XaoSProducer::interlace %i!\n", format->u.raw_video.interlace); if (format->u.raw_video.interlace <= media_raw_video_format::wildcard.interlace) { format->u.raw_video.interlace = 1; } fprintf(stderr,"XaoSProducer::orientation %i!\n", format->u.raw_video.orientation); if (format->u.raw_video.orientation <= media_raw_video_format::wildcard.orientation) { format->u.raw_video.orientation = B_VIDEO_TOP_LEFT_RIGHT; } fprintf(stderr,"XaoSProducer::field rate %f!\n", format->u.raw_video.field_rate); if (format->u.raw_video.field_rate <= media_raw_video_format::wildcard.field_rate) { format->u.raw_video.field_rate = PREFFERED_FIELD_RATE; } fprintf(stderr,"XaoSProducer::first_active %i!\n", format->u.raw_video.first_active); if (format->u.raw_video.first_active <= media_raw_video_format::wildcard.first_active) { format->u.raw_video.first_active = 0; } fprintf(stderr,"XaoSProducer::last_active %i!\n", format->u.raw_video.last_active); if (format->u.raw_video.last_active <= media_raw_video_format::wildcard.last_active) { format->u.raw_video.last_active = PREFFERED_HEIGHT-1; } fprintf(stderr,"XaoSProducer::width_aspect %i!\n", format->u.raw_video.pixel_width_aspect); if (format->u.raw_video.pixel_width_aspect <= media_raw_video_format::wildcard.pixel_width_aspect) { format->u.raw_video.pixel_width_aspect = 1; } fprintf(stderr,"XaoSProducer::height_aspect %i!\n", format->u.raw_video.pixel_height_aspect); if (format->u.raw_video.pixel_height_aspect <= media_raw_video_format::wildcard.pixel_height_aspect) { format->u.raw_video.pixel_height_aspect = 1; } fprintf(stderr,"XaoSProducer::display.format %i!\n", format->u.raw_video.display.format); if (format->u.raw_video.display.format <= media_raw_video_format::wildcard.display.format) { format->u.raw_video.display.format = PREFFERED_COLOR_SPACE; } fprintf(stderr,"XaoSProducer::display.line_width %i!\n", format->u.raw_video.display.line_width); if (format->u.raw_video.display.line_width <= media_raw_video_format::wildcard.display.line_width) { format->u.raw_video.display.line_width = PREFFERED_WIDTH; } fprintf(stderr,"XaoSProducer::display.line_count %i!\n", format->u.raw_video.display.line_count); if (format->u.raw_video.display.line_count <= media_raw_video_format::wildcard.display.line_width) { format->u.raw_video.display.line_count = PREFFERED_HEIGHT; } fprintf(stderr,"XaoSProducer::display.bytes_per_row %i!\n", format->u.raw_video.display.bytes_per_row); if (format->u.raw_video.display.bytes_per_row <= media_raw_video_format::wildcard.display.bytes_per_row) { int mult; switch (format->u.raw_video.display.format) { /*The 24-bit versions are not compiled in, because BeOS don't support them in most cases. Use 32 instead. */ case B_RGB24: case B_RGB24_BIG: mult=3*8; break; case B_RGB32: case B_RGB32_BIG: case B_RGBA32: case B_RGBA32_BIG: mult=4*8; break; case B_RGB16: case B_RGB16_BIG: case B_RGBA15: case B_RGBA15_BIG: case B_RGB15: case B_RGB15_BIG: mult=2*8; break; case B_CMAP8: case B_GRAY8: mult=8; case B_GRAY1: mult=1; break; default: abort(); } format->u.raw_video.display.bytes_per_row = (mult*m_raw_format.display.line_width+7)/8; } fprintf(stderr,"XaoSProducer::display.bytes_per_row %i!\n", format->u.raw_video.display.bytes_per_row); string_for_format(*format, fmt, 100); FORMAT(stderr, "We've decided to use %s\n", fmt); m_output.destination = where; m_output.format = *format; *out_source = m_output.source; strncpy(out_name, Name(), B_MEDIA_NAME_LENGTH); /*alloc_buffers();*/ return B_OK;}void XaoSProducer::Connect( status_t error, const media_source & source, const media_destination & destination, const media_format & format, char * io_name){ ASSERT(source == m_output.source); NODE(stderr, "XaoSProducer: Connect\n"); if (error < B_OK) { NODE(stderr, "XaoSProducer::Connect(): we were told about an error\n"); m_output.destination = media_destination::null; return; }#if !NDEBUG char fmt[100]; string_for_format(format, fmt, 100); FORMAT(stderr, "Connect(): format %s\n", fmt);#endif m_output.destination = destination; m_output.format = format; NODE(stderr, "XaoSProducer::Connect(): source = %ld, dest = %ld\n", source.id, destination.id); alloc_buffers(); BBufferProducer::GetLatency(&m_downstream_latency); strncpy(io_name, Name(), B_MEDIA_NAME_LENGTH);#if 0 // Tell whomever is interested that there's now a connection. if (m_notifyHook) { (*m_notifyHook)(m_cookie, B_CONNECTED, m_output.name); } else { Notify(B_CONNECTED, m_output.name); }#endif}void XaoSProducer::Disconnect( const media_source & what, const media_destination & consumer){ NODE(stderr, "XaoSProducer::Disconnect()\n"); // We can't disconnect something which isn't us. if (what != m_output.source) { NODE(stderr, "XaoSProducer::Disconnect(): source is incorrect\t"); return; } // We can't disconnect from someone who isn't connected to us. if (consumer != m_output.destination) { NODE(stderr, "XaoSProducer::Disconnect(): destination is incorrect\n"); return; }#if 0 // Tell the interested party that it's time to leave. if (m_notifyHook) { (*m_notifyHook)(m_cookie, B_DISCONNECTED); } else { Notify(B_DISCONNECTED); }#endif // Mark ourselves as not-connected. We also clean up // the buffer group that we were using. m_output.destination = media_destination::null; //m_output.format.u.raw_audio.buffer_size = 0; delete m_buffers; m_buffers = 0;}void XaoSProducer::LateNoticeReceived( const media_source & /* what */, bigtime_t how_much, bigtime_t performance_time){ LATE(stderr, "XaoSProducer::LateNoticeReceived(%.4f @ %.4f)\n", us_to_s(how_much), us_to_s(performance_time)); switch (RunMode()) { case B_OFFLINE: // If we're not running in real time, we should never receive // late notices! break; case B_DECREASE_PRECISION: // We can't really do much here. Maybe our hook functions // will be able to do something about this?... break; case B_INCREASE_LATENCY: // Adjust our latencies so that we start sending buffers // earlier. if (how_much > 3000) { how_much = 3000; } m_downstream_latency += how_much; m_private_latency += how_much/2; break; default: // As a simple producer, we can't be recording, so // we must be in B_DROP_DATA. Just drop a buffer and // hope that catches us up. m_frames_played++; break; }#if 0 // Tell whoever's interested that we're running behind. if (m_notifyHook) { (*m_notifyHook)(m_cookie, B_LATE_NOTICE, how_much, performance_time); } else { Notify(B_LATE_NOTICE, how_much, performance_time); }#endif}void XaoSProducer::EnableOutput( const media_source & what, bool enabled, int32 * change_tag){ NODE(stderr, "XaoSProducer: EnableOutput\n"); if (what != m_output.source) { NODE(stderr, "XaoSProducer::EnableOutput(): bad source\n"); return; } //m_muted = !enabled; // We increment our node's private change tag and pass it back to // the caller. The current change tag is always attached to the // header of each buffer we send. By setting the change tag pointer // we are given, downstream consumers know the tag corresponding // to this state, and can match that tag against buffers that they // receive from us, should they have a reason to know. *change_tag = IncrementChangeTag(); if (m_output.destination != media_destination::null) { // It's important to tell the consumer that we will or // won't be sending it data, so it's ready for the data // or won't get stuck waiting for data that never comes. //SendDataStatus(m_muted ? B_DATA_NOT_AVAILABLE : B_DATA_AVAILABLE, SendDataStatus(B_DATA_AVAILABLE, m_output.destination, TimeSource()->Now()); }}//////////////////////////////////////////////////////////////////////////////////// Service thread methods//////////////////////////////////////////////////////////////////////////////////#if 0voidXaoSProducer::DoHookChange( void * msg){ // Tell the old guy we're changing the hooks ... if (m_notifyHook) { (*m_notifyHook)(m_cookie, B_HOOKS_CHANGED); } else { Notify(B_HOOKS_CHANGED); } // ... and then do it. set_hooks_q * ptr = (set_hooks_q *)msg; m_playHook = ptr->process; m_notifyHook = ptr->notify; m_cookie = ptr->cookie;}#endifstatus_tXaoSProducer::ThreadEntry( void * obj){ ((XaoSProducer *)obj)->ServiceThread(); return B_OK;}void XaoSProducer::ServiceThread(){ NODE(stderr, "XaoSProducer::ServiceThread() is alive!\n"); // A media kit message will never be bigger than B_MEDIA_MESSAGE_SIZE. // Avoid wasing stack space by dynamically allocating at start. //char msg = new char[B_MEDIA_MESSAGE_SIZE]; char msg[B_MEDIA_MESSAGE_SIZE]; //array_delete<char> msg_delete(msg); int bad = 0; m_private_latency = estimate_max_scheduling_latency(find_thread(0)); while (true) { // buffer_perf is the next performance time at which a buffer // needs to be performed. // // perf_target is the next performance time at which some event // has to occur. If we're running & connected, and don't have any // pending performance events (such as start or stop), our // perf_target will be buffer_perf. bigtime_t buffer_perf = (bigtime_t)(1000000/m_output.format.u.raw_video.field_rate * m_frames_played+m_delta); bigtime_t perf_target; bool ts_running = TimeSource()->IsRunning(); bool connected = (m_output.destination != media_destination::null); bigtime_t timeout = 1000000000000LL; if (m_running && connected) { perf_target = buffer_perf; } else { // If we're not running or connected, we might as well // relax for a while (unless there are pending events // coming up sooner). perf_target = TimeSource()->Now() + HUGE_TIMEOUT; } fprintf(stderr,"Thread loop! %i %i %i\n",ts_running, m_starting, m_running);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -