📄 radeonproducer.cpp
字号:
fOutput.destination = destination; fOutput.format = format; fCurMode = extractCaptureMode( &format ); char buffer[256]; string_for_format(format, buffer, sizeof(buffer)); DPRINT(("CRadeonProducer::Connect() - %s\n", buffer)); strcpy(io_name, fOutput.name); startCapturing(); DPRINT(("CRadeonProducer::Connect() done\n"));}void CRadeonProducer::Disconnect(const media_source &source, const media_destination &destination){ DPRINT(("Disconnect()\n")); if( source != fOutput.source || destination != fOutput.destination ) { DPRINT(("Disconnect: Bad source and/or destination\n")); return; } fOutput.destination = media_destination::null; delete fBufferGroup; fBufferGroup = NULL; fVideoIn.Stop(); RealTimeQueue()->FlushEvents( 0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HARDWARE ); // reset format to get rid of any connection left-overs fOutput.format.type = B_MEDIA_RAW_VIDEO; fOutput.format.u.raw_video = media_raw_video_format::wildcard; DPRINT(("Disconnect() done\n"));}void CRadeonProducer::LateNoticeReceived(const media_source &source, bigtime_t how_much, bigtime_t performance_time){ DPRINT(("CRadeonProducer::LateNoticeReceived()\n")); TOUCH(source); TOUCH(how_much); TOUCH(performance_time);}void CRadeonProducer::EnableOutput(const media_source &source, bool enabled, int32 *_deprecated_){ DPRINT(("CRadeonProducer::EnableOutput()\n")); TOUCH(_deprecated_); if (source != fOutput.source) return; fEnabled = enabled;}status_t CRadeonProducer::SetPlayRate(int32 numer, int32 denom){ DPRINT(("CRadeonProducer::SetPlayRate()\n")); TOUCH(numer); TOUCH(denom); return B_ERROR;}void CRadeonProducer::AdditionalBufferRequested(const media_source &source, media_buffer_id prev_buffer, bigtime_t prev_time, const media_seek_tag *prev_tag){ DPRINT(("CRadeonProducer::AdditionalBufferRequested()\n")); TOUCH(source); TOUCH(prev_buffer); TOUCH(prev_time); TOUCH(prev_tag);}void CRadeonProducer::LatencyChanged(const media_source &source, const media_destination &destination, bigtime_t new_latency, uint32 flags){ DPRINT(("CRadeonProducer::LatencyChanged()\n")); BBufferProducer::LatencyChanged( source, destination, new_latency, flags );}/* BControllable */ status_t CRadeonProducer::GetParameterValue( int32 id, bigtime_t *last_change, void *value, size_t *size){ DPRINT(("CRadeonProducer::GetParameterValue(%d)\n", id)); switch (id) { case P_SOURCE: *last_change = fSourceLastChange; *size = sizeof(fSource); *((uint32 *) value) = fSource; break; case P_STANDARD: *last_change = fStandardLastChange; *size = sizeof(fStandard); *((uint32 *) value) = fStandard; break; case P_MODE: *last_change = fModeLastChange; *size = sizeof(fMode); *((uint32 *) value) = fMode; break; case P_FORMAT: *last_change = fFormatLastChange; *size = sizeof(fFormat); *((uint32 *) value) = fFormat; break; case P_RESOLUTION: *last_change = fResolutionLastChange; *size = sizeof(fResolution); *((uint32 *) value) = fResolution; break; case P_TUNER: *last_change = fTunerLastChange; *size = sizeof(fTuner); *((uint32 *) value) = fTuner; break; case P_BRIGHTNESS: *last_change = fBrightnessLastChange; *size = sizeof(fBrightness); *((float *) value) = fBrightness; break; case P_CONTRAST: *last_change = fContrastLastChange; *size = sizeof(fContrast); *((float *) value) = fContrast; break; case P_SATURATION: *last_change = fSaturationLastChange; *size = sizeof(fSaturation); *((float *) value) = fSaturation; break; case P_HUE: *last_change = fHueLastChange; *size = sizeof(fHue); *((float *) value) = fHue; break; case P_SHARPNESS: *last_change = fSharpnessLastChange; *size = sizeof(fSharpness); *((float *) value) = fSharpness; break; default: DPRINT(("Unknown parameter\n")); return B_BAD_VALUE; } return B_OK;}/* * Change video format instantly. * * Used when user changes a settings that affect the video format. * The new format must be the current format with some values * replaced with wildcards. Don't put too many wildcards: * some settings (like video size) are normally chosen by the * application, so don't use this function as a secret override. */voidCRadeonProducer::instantFormatChange( media_format *new_format ){ if( fOutput.destination == media_destination::null ) return; if( finalizeFormat( new_format ) != B_OK ) { DPRINT(("Current format does not allow to change interlace mode on-the-fly\n")); return; } if( ChangeFormat( fOutput.source, fOutput.destination, new_format ) != B_OK ) { DPRINT(("Consumer does not allow to change interlace mode instantly\n")); return; } fOutput.format = *new_format; fCurMode = extractCaptureMode( new_format ); fVideoIn.Stop(); startCapturing();}voidCRadeonProducer::SetParameterValue( int32 id, bigtime_t when, const void *value, size_t size){ DPRINT(("CRadeonProducer::SetParameterValue()\n")); if (!value || size != sizeof(uint32)) return; switch (id) { case P_SOURCE: if (*((const int32 *) value) == fSource) return; fSource = *((const uint32 *) value); fSourceLastChange = when; // if there is no tuner, force composite input // (eXposer sets source manually to tuner, even if there is none) if( (fVideoIn.Capabilities() & C_VIDEO_IN_HAS_TUNER) == 0 ) fSource = C_VIDEO_IN_COMPOSITE; break; case P_STANDARD: { if (*((const int32 *) value) == fStandard) return; fStandard = *((const uint32 *) value); fStandardLastChange = when; media_format new_format = fOutput.format; new_format.u.raw_video.field_rate = media_raw_video_format::wildcard.field_rate; new_format.u.raw_video.interlace = media_raw_video_format::wildcard.interlace; new_format.u.raw_video.pixel_width_aspect = media_raw_video_format::wildcard.pixel_width_aspect; new_format.u.raw_video.pixel_height_aspect = media_raw_video_format::wildcard.pixel_height_aspect; new_format.u.raw_video.first_active = media_raw_video_format::wildcard.first_active; new_format.u.raw_video.last_active = media_raw_video_format::wildcard.last_active; instantFormatChange( &new_format ); break; } case P_MODE: { if (*((const int32 *) value) == fMode) return; fMode = *((const uint32 *) value); fModeLastChange = when; media_format new_format = fOutput.format; new_format.u.raw_video.field_rate = media_raw_video_format::wildcard.field_rate; new_format.u.raw_video.interlace = media_raw_video_format::wildcard.interlace; new_format.u.raw_video.pixel_width_aspect = media_raw_video_format::wildcard.pixel_width_aspect; new_format.u.raw_video.pixel_height_aspect = media_raw_video_format::wildcard.pixel_height_aspect; instantFormatChange( &new_format ); break; } case P_FORMAT: { if (*((const int32 *) value) == fFormat) return; fFormat = *((const uint32 *) value); fFormatLastChange = when; media_format new_format = fOutput.format; new_format.u.raw_video.display.format = media_raw_video_format::wildcard.display.format; new_format.u.raw_video.display.bytes_per_row = media_raw_video_format::wildcard.display.bytes_per_row; instantFormatChange( &new_format ); break; } case P_RESOLUTION: if (*((const int32 *) value) == fResolution) return; fResolution = *((const uint32 *) value); fResolutionLastChange = when; // no live update - see instantFormatChange() break; case P_TUNER: if (*((const int32 *) value) == fTuner) return; fTuner = *((const uint32 *) value); fTunerLastChange = when; fVideoIn.SetChannel(fTuner, C_VIDEO_IN_NTSC); break; case P_BRIGHTNESS: if (*((const float *) value) == fBrightness) return; fBrightness = (int32)*((const float *) value); fBrightnessLastChange = when; fVideoIn.SetBrightness(fBrightness); break; case P_CONTRAST: if (*((const float *) value) == fContrast) return; fContrast = (int32)*((const float *) value); fContrastLastChange = when; fVideoIn.SetContrast(fContrast); break; case P_SATURATION: if (*((const float *) value) == fSaturation) return; fSaturation = (int32)*((const float *) value); fSaturationLastChange = when; fVideoIn.SetSaturation(fSaturation); break; case P_HUE: if (*((const float *) value) == fHue) return; fHue = (int32)*((const float *) value); fHueLastChange = when; fVideoIn.SetHue(fHue); break; case P_SHARPNESS: if (*((const float *) value) == fSharpness) return; fSharpness = (int32)*((const float *) value); fSharpnessLastChange = when; fVideoIn.SetSharpness(fSharpness); break; default: return; } BroadcastNewParameterValue(when, id, const_cast<void *>(value), sizeof(uint32));}status_tCRadeonProducer::StartControlPanel(BMessenger *out_messenger){ return BControllable::StartControlPanel(out_messenger);}status_t CRadeonProducer::AddInt32( BMessage *msg, EOptions option, int32 value ){ char name[5]; *(int32 *)name = option; name[4] = 0; return msg->AddInt32( name, value );}status_tCRadeonProducer::GetConfiguration( BMessage *out ){ status_t res; if( (res = AddInt32( out, P_SOURCE, fSource )) != B_OK || (res = AddInt32( out, P_STANDARD, BeToVideoInStandard( fStandard ))) != B_OK || (res = AddInt32( out, P_MODE, fMode )) != B_OK || (res = AddInt32( out, P_FORMAT, fFormat )) != B_OK || (res = AddInt32( out, P_RESOLUTION, fResolution )) != B_OK || (res = AddInt32( out, P_TUNER, fTuner )) != B_OK || (res = AddInt32( out, P_BRIGHTNESS, fBrightness )) != B_OK || (res = AddInt32( out, P_CONTRAST, fContrast )) != B_OK || (res = AddInt32( out, P_SATURATION, fSaturation )) != B_OK || (res = AddInt32( out, P_HUE, fHue )) != B_OK || (res = AddInt32( out, P_SHARPNESS, fSharpness )) != B_OK ) return res; return B_OK;}/* VideoProducer */voidCRadeonProducer::HandleStart(bigtime_t performance_time){ /* Start producing frames, even if the output hasn't been connected yet. */ DPRINT(("CRadeonProducer::HandleStart()\n")); if( RunState() != BMediaEventLooper::B_STOPPED ) { DPRINT(("already running\n")); return; } SetRunState( BMediaEventLooper::B_STARTED ); startCapturing();}voidCRadeonProducer::HandleStop(void){ DPRINT(("CRadeonProducer::HandleStop()\n")); fVideoIn.Stop(); // discard pending capture event RealTimeQueue()->FlushEvents( 0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HARDWARE );}voidCRadeonProducer::HandleTimeWarp(bigtime_t performance_time){ DPRINT(("CRadeonProducer::HandleTimeWarp()\n"));}voidCRadeonProducer::HandleSeek(bigtime_t performance_time){ DPRINT(("CRadeonProducer::HandleSeek()\n"));}void CRadeonProducer::captureField( bigtime_t *capture_time ){ *capture_time = system_time(); // don't capture if output is disabled if (!fEnabled) return; BBuffer *buffer = fBufferGroup->RequestBuffer( fOutput.format.u.raw_video.display.bytes_per_row * fOutput.format.u.raw_video.display.line_count, 0LL); if (!buffer) { DPRINT(( "No buffer\n" )); return; } media_header *h = buffer->Header(); h->type = B_MEDIA_RAW_VIDEO; h->time_source = TimeSource()->ID(); h->size_used = fOutput.format.u.raw_video.display.bytes_per_row * fOutput.format.u.raw_video.display.line_count; h->file_pos = 0; h->orig_size = 0; h->data_offset = 0; h->u.raw_video.field_gamma = 1.0; h->u.raw_video.pulldown_number = 0; h->u.raw_video.first_active_line = fOutput.format.u.raw_video.first_active; h->u.raw_video.line_count = fOutput.format.u.raw_video.display.line_count; int field_sequence; short field_number; int dropped=fVideoIn.Capture( fOutput.format.u.raw_video.display.format, buffer->Data(), fOutput.format.u.raw_video.display.bytes_per_row * fOutput.format.u.raw_video.display.line_count, fOutput.format.u.raw_video.display.bytes_per_row, &field_sequence, &field_number, capture_time); // HACK: store end instead of start time // obviously, the _start_ time of a frame is always in the past by one // frame; unfortunately, programs like stamptv expect the start time to // be in the present, else they drop the frame; therefore, we write the // _end_ time into the start time field, and everyone is happy (though // the time is wrong) // this leads to many tweaks in the code! h->start_time = TimeSource()->PerformanceTimeFor( *capture_time ); h->u.raw_video.field_sequence = field_sequence - fFieldSequenceBase; h->u.raw_video.field_number = field_number; if (dropped > 1) { PRINT(("%d frames dropped\n", dropped-1)); } if (SendBuffer(buffer, fOutput.destination) < B_OK) { PRINTF(-1, ("FrameGenerator: Error sending buffer\n")); buffer->Recycle(); }}voidCRadeonProducer::HandleHardware(){ bigtime_t capture_time; //DPRINT(("Hi\n")); if( RunState() != BMediaEventLooper::B_STARTED ) return; captureField( &capture_time ); // generate next event after next field media_timed_event event( capture_time + 1000000 / fOutput.format.u.raw_video.field_rate, BTimedEventQueue::B_HARDWARE); RealTimeQueue()->AddEvent(event);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -