📄 radeonproducer.cpp
字号:
SetPriority( suggest_thread_priority( B_VIDEO_RECORDING, 60, 8000, 8000 )); /* Start the BMediaEventLooper control loop running */ Run();}voidCRadeonProducer::Start(bigtime_t performance_time){ DPRINT(("CRadeonProducer::Start()\n")); BMediaEventLooper::Start(performance_time);}voidCRadeonProducer::Stop(bigtime_t performance_time, bool immediate){ DPRINT(("CRadeonProducer::Stop()\n")); BMediaEventLooper::Stop(performance_time, immediate);}voidCRadeonProducer::Seek(bigtime_t media_time, bigtime_t performance_time){ DPRINT(("CRadeonProducer::Seek()\n")); BMediaEventLooper::Seek(media_time, performance_time);}voidCRadeonProducer::TimeWarp(bigtime_t at_real_time, bigtime_t to_performance_time){ DPRINT(("CRadeonProducer::TimeWarp()\n")); BMediaEventLooper::TimeWarp(at_real_time, to_performance_time);}status_tCRadeonProducer::AddTimer(bigtime_t at_performance_time, int32 cookie){ DPRINT(("CRadeonProducer::AddTimer()\n")); return BMediaEventLooper::AddTimer(at_performance_time, cookie);}voidCRadeonProducer::SetRunMode(run_mode mode){ DPRINT(("CRadeonProducer::SetRunMode()\n")); BMediaEventLooper::SetRunMode(mode);}void CRadeonProducer::HandleEvent(const media_timed_event *event, bigtime_t lateness, bool realTimeEvent){ //DPRINT(("CRadeonProducer::HandleEvent()\n")); TOUCH(lateness); TOUCH(realTimeEvent); switch(event->type) { case BTimedEventQueue::B_START: HandleStart(event->event_time); break; case BTimedEventQueue::B_STOP: HandleStop(); break; case BTimedEventQueue::B_WARP: HandleTimeWarp(event->bigdata); break; case BTimedEventQueue::B_SEEK: HandleSeek(event->bigdata); break; case BTimedEventQueue::B_HANDLE_BUFFER: case BTimedEventQueue::B_DATA_STATUS: case BTimedEventQueue::B_PARAMETER: default: PRINTF(-1, ("HandleEvent: Unhandled event -- %lx\n", event->type)); break; case BTimedEventQueue::B_HARDWARE: HandleHardware(); break; } //DPRINT(("CRadeonProducer::HandleEvent() done\n"));}void CRadeonProducer::CleanUpEvent(const media_timed_event *event){ DPRINT(("CRadeonProducer::CleanUpEvent()\n")); BMediaEventLooper::CleanUpEvent(event);}bigtime_tCRadeonProducer::OfflineTime(){ return BMediaEventLooper::OfflineTime();}voidCRadeonProducer::ControlLoop(){ BMediaEventLooper::ControlLoop();}status_tCRadeonProducer::DeleteHook(BMediaNode * node){ DPRINT(("CRadeonProducer::DeleteHook()\n")); return BMediaEventLooper::DeleteHook(node);}/* BBufferProducer */// choose capture mode according to format and update format according to thatstatus_tCRadeonProducer::verifySetMode( media_format *format ){ float frame_rate = fVideoIn.getFrameRate( BeToVideoInStandard( fStandard )) / 1000.0f; if( format->u.raw_video.interlace == media_raw_video_format::wildcard.interlace ) { if( format->u.raw_video.field_rate == media_raw_video_format::wildcard.field_rate ) { format->u.raw_video.interlace = fMode == C_VIDEO_IN_BOB ? 2 : 1; format->u.raw_video.field_rate = frame_rate * format->u.raw_video.interlace; } else { if( format->u.raw_video.field_rate == frame_rate ) format->u.raw_video.interlace = 1; else if( format->u.raw_video.field_rate == frame_rate * 2 ) format->u.raw_video.interlace = 2; else { DPRINT(( "Unsupported field rate for active TV standard (%f)\n", format->u.raw_video.field_rate )); return B_MEDIA_BAD_FORMAT; } } } else if( format->u.raw_video.interlace == 1 ) { if( format->u.raw_video.field_rate == media_raw_video_format::wildcard.field_rate ) format->u.raw_video.field_rate = frame_rate; else { // don't compare directly - there are rounding errors if( fabs(format->u.raw_video.field_rate - frame_rate) > 0.001 ) { DPRINT(( "Wrong field rate for active TV standard (%f) in progressive mode (expected %f)\n", format->u.raw_video.field_rate - 29.976, frame_rate - 29.976 )); return B_MEDIA_BAD_FORMAT; } } } else if( format->u.raw_video.interlace == 2 ) { if( format->u.raw_video.field_rate == media_raw_video_format::wildcard.field_rate ) format->u.raw_video.field_rate = frame_rate * 2; else { if( fabs(format->u.raw_video.field_rate - frame_rate * 2) > 0.001 ) { DPRINT(( "Wrong field rate for active TV standard (%f) in interlace mode\n", format->u.raw_video.field_rate )); return B_MEDIA_BAD_FORMAT; } } } else { DPRINT(( "Invalid interlace mode (%d)\n", format->u.raw_video.interlace )); return B_MEDIA_BAD_FORMAT; } return B_OK;}/* Map BeOS capture mode to internal capture mode.*/int32CRadeonProducer::extractCaptureMode( const media_format *format ){ // if application requests interlace, it always gets BOB; // if is requests non-interlace, it may get WEAVE or FIELD - // if the user selected one of them, we are fine; else, // we always choose WEAVE (could choose FIELD as well, make // it dependant on resolution, but the more magic the more problems) if( format->u.raw_video.interlace == 2 ) return C_VIDEO_IN_BOB; else if( fMode == C_VIDEO_IN_BOB ) return C_VIDEO_IN_WEAVE; else return fMode;}// check pixel aspect of format and set it if it's wildcardedstatus_tCRadeonProducer::verifySetPixelAspect( media_format *format ){ // for simplicity, we always assume 1:1 aspect if( format->u.raw_video.pixel_width_aspect != media_raw_video_format::wildcard.pixel_width_aspect || format->u.raw_video.pixel_height_aspect != media_raw_video_format::wildcard.pixel_height_aspect ) { if( format->u.raw_video.pixel_width_aspect != format->u.raw_video.pixel_height_aspect ) { DPRINT(( "Unsupported pixel aspect (%d:%d)\n", format->u.raw_video.pixel_width_aspect, format->u.raw_video.pixel_height_aspect )); return B_MEDIA_BAD_FORMAT; } } else { format->u.raw_video.pixel_width_aspect = 1; format->u.raw_video.pixel_height_aspect = 1; } return B_OK; #if 0 // we assume 1:2 for interlaced and 1:1 for deinterlaced video // (this is not really true as it depends on TV standard and // resolution, but it should be enough for start) if( format->u.raw_video.pixel_width_aspect != media_raw_video_format::wildcard.pixel_width_aspect || format->u.raw_video.pixel_height_aspect != media_raw_video_format::wildcard.pixel_height_aspect ) { double ratio = mode == C_VIDEO_IN_WEAVE ? 1 : 0.5; if( (float)format->u.raw_video.pixel_width_aspect / format->u.raw_video.pixel_height_aspect != ratio ) { DPRINT(( "Unsupported pixel aspect (%d:%d)\n", format->u.raw_video.pixel_width_aspect, format->u.raw_video.pixel_height_aspect )); return B_MEDIA_BAD_FORMAT; } } else { format->u.raw_video.pixel_width_aspect = 1; format->u.raw_video.pixel_height_aspect = mode == C_VIDEO_IN_WEAVE ? 1 : 2; } return B_OK;#endif}// verify active range defined as formatstatus_tCRadeonProducer::verifyActiveRange( media_format *format ){ CRadeonRect active_rect; fVideoIn.getActiveRange( BeToVideoInStandard( fStandard ), active_rect ); if( format->u.raw_video.first_active != media_raw_video_format::wildcard.first_active ) { if( (int32)format->u.raw_video.first_active < 0 ) { DPRINT(( "Unsupported first_active (%d)\n", format->u.raw_video.first_active )); return B_MEDIA_BAD_FORMAT; } } // don't care about last_active much - some programs set it to number of // captured lines, which is really something different // (I have the feeling, noone really knows how to use this value properly) if( format->u.raw_video.last_active != media_raw_video_format::wildcard.last_active ) { if( format->u.raw_video.last_active >= (uint32)active_rect.Height() ) { DPRINT(( "Unsupported last_active (%d)\n", format->u.raw_video.last_active )); return B_MEDIA_BAD_FORMAT; } } return B_OK;}// set active range in format if yet undefinedvoidCRadeonProducer::setActiveRange( media_format *format ){ CRadeonRect active_rect; fVideoIn.getActiveRange( BeToVideoInStandard( fStandard ), active_rect ); if( format->u.raw_video.first_active == media_raw_video_format::wildcard.first_active ) format->u.raw_video.first_active = 0; if( format->u.raw_video.last_active == media_raw_video_format::wildcard.last_active ) format->u.raw_video.last_active = (uint32)active_rect.Height() - 1;}// verify requested orientationstatus_tCRadeonProducer::verifyOrientation( media_format *format ){ if( format->u.raw_video.orientation != media_raw_video_format::wildcard.orientation ) { if( format->u.raw_video.orientation != B_VIDEO_TOP_LEFT_RIGHT ) { DPRINT(( "Unsupported orientation (%d)\n", format->u.raw_video.orientation )); return B_MEDIA_BAD_FORMAT; } } return B_OK;}// set image orientation if yet undefinedvoidCRadeonProducer::setOrientation( media_format *format ){ if( format->u.raw_video.orientation == media_raw_video_format::wildcard.orientation ) format->u.raw_video.orientation = B_VIDEO_TOP_LEFT_RIGHT;}// verify requested pixel formatstatus_tCRadeonProducer::verifyPixelFormat( media_format *format ){ if( format->u.raw_video.display.format != media_raw_video_format::wildcard.display.format ) { switch( format->u.raw_video.display.format ) { case B_RGB32: case B_RGB16: case B_RGB15: case B_YCbCr422: case B_GRAY8: break; default: DPRINT(("Unsupported colour space (%x)\n", format->u.raw_video.display.format )); return B_MEDIA_BAD_FORMAT; } } return B_OK;}// set pixel format to user-defined default if not set yetvoidCRadeonProducer::setPixelFormat( media_format *format ){ if( format->u.raw_video.display.format == media_raw_video_format::wildcard.display.format ) format->u.raw_video.display.format = (color_space)fFormat;}/* Verify video size and set it if undefined.*/status_tCRadeonProducer::verifySetSize( media_format *format, int32 mode, bool set_bytes_per_row ){ CRadeonRect active_rect; fVideoIn.getActiveRange( BeToVideoInStandard( fStandard ), active_rect ); // width and height must both be defined, else we define it ourself, // i.e. if the application leaves one of them wildcarded, we // set both if( format->u.raw_video.display.line_width != media_raw_video_format::wildcard.display.line_width && format->u.raw_video.display.line_count != media_raw_video_format::wildcard.display.line_count ) { uint32 max_height = active_rect.Height(); if( mode != C_VIDEO_IN_WEAVE ) max_height /= 2; if( format->u.raw_video.display.line_width > (uint32)active_rect.Width() || format->u.raw_video.display.line_count > max_height ) { DPRINT(("Requested image size is too high (%dx%d)\n", format->u.raw_video.display.line_width, format->u.raw_video.display.line_count)); return B_MEDIA_BAD_FORMAT; } // our format converters do up to 8 pixels at a time (grey8); // to be absolutely sure we don't get trouble there, refuse // any width that is not a multiple of 8 if( (format->u.raw_video.display.line_width & 7) != 0 ) { DPRINT(( "Request image width is not multiple of 8 (%d)\n", format->u.raw_video.display.line_width )); return B_MEDIA_BAD_FORMAT; } } else { switch (fResolution) { case 0: format->u.raw_video.display.line_width = 640; format->u.raw_video.display.line_count = 480; break; case 3: format->u.raw_video.display.line_width = 480; format->u.raw_video.display.line_count = 360; break; case 4: format->u.raw_video.display.line_width = 720; format->u.raw_video.display.line_count = 480; break; case 5: format->u.raw_video.display.line_width = 720; format->u.raw_video.display.line_count = 576; break; case 6: format->u.raw_video.display.line_width = 768; format->u.raw_video.display.line_count = 576; break; case 1: format->u.raw_video.display.line_width = 320; format->u.raw_video.display.line_count = 240; break; case 2: format->u.raw_video.display.line_width = 160; format->u.raw_video.display.line_count = 120; break; } if( format->u.raw_video.display.line_width > (uint32)active_rect.Width() ) format->u.raw_video.display.line_width = (uint32)active_rect.Width() & ~7; if( format->u.raw_video.display.line_count > (uint32)active_rect.Height() ) format->u.raw_video.display.line_count = (uint32)active_rect.Height(); // BOB and FIELD modes provide only field, which has half height if( mode != C_VIDEO_IN_WEAVE ) { if( format->u.raw_video.display.line_count > (uint32)active_rect.Height() / 2 ) format->u.raw_video.display.line_count = (uint32)active_rect.Height() / 2; } } if( format->u.raw_video.display.format != media_raw_video_format::wildcard.display.format ) { uint32 bytes_per_row; switch( format->u.raw_video.display.format ) { case B_RGB32: bytes_per_row = format->u.raw_video.display.line_width * 4; break; case B_RGB15: case B_RGB16: case B_YCbCr422: bytes_per_row = format->u.raw_video.display.line_width * 2; break; default: bytes_per_row = format->u.raw_video.display.line_width; } if( format->u.raw_video.display.bytes_per_row != media_raw_video_format::wildcard.display.bytes_per_row ) { if( format->u.raw_video.display.bytes_per_row < bytes_per_row ) { DPRINT(( "Requested bytes per row are too small", format->u.raw_video.display.bytes_per_row )); return B_MEDIA_BAD_FORMAT; } } else if( set_bytes_per_row ) format->u.raw_video.display.bytes_per_row = bytes_per_row; } return B_OK;}// verify "offset" parameters of formatstatus_t CRadeonProducer::verifyFormatOffsets( media_format *format ){ if( format->u.raw_video.display.pixel_offset != media_raw_video_format::wildcard.display.pixel_offset && format->u.raw_video.display.pixel_offset != 0 ) { DPRINT(( "Requested pixel offset is not zero" )); return B_MEDIA_BAD_FORMAT; } if( format->u.raw_video.display.line_offset != media_raw_video_format::wildcard.display.line_offset && format->u.raw_video.display.line_offset != 0 ) { DPRINT(( "Requested line offset is not zero" )); return B_MEDIA_BAD_FORMAT; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -