/** * It returns the format (closest to chroma) that can be converted to target */ static const d3d_format_t *Direct3DFindFormat(vout_display_t *vd, vlc_fourcc_t chroma, D3DFORMAT target) { vout_display_sys_t *sys = vd->sys; for (unsigned pass = 0; pass < 2; pass++) { const vlc_fourcc_t *list; if (pass == 0 && sys->allow_hw_yuv && vlc_fourcc_IsYUV(chroma)) list = vlc_fourcc_GetYUVFallback(chroma); else if (pass == 1) list = vlc_fourcc_GetRGBFallback(chroma); else continue; for (unsigned i = 0; list[i] != 0; i++) { for (unsigned j = 0; d3d_formats[j].name; j++) { const d3d_format_t *format = &d3d_formats[j]; if (format->fourcc != list[i]) continue; msg_Warn(vd, "trying surface pixel format: %s", format->name); if (!Direct3DCheckConversion(vd, format->format, target)) { msg_Dbg(vd, "selected surface pixel format is %s", format->name); return format; } } } } return NULL; }
static int DirectXCreatePictureResource(vout_display_t *vd, bool *use_overlay, video_format_t *fmt) { vout_display_sys_t *sys = vd->sys; /* */ picture_sys_t *picsys = calloc(1, sizeof(*picsys)); if (unlikely(picsys == NULL)) return VLC_ENOMEM; sys->picsys = picsys; /* */ bool allow_hw_yuv = sys->can_blit_fourcc && vlc_fourcc_IsYUV(fmt->i_chroma) && var_InheritBool(vd, "directx-hw-yuv"); bool allow_overlay = var_InheritBool(vd, "directx-overlay"); /* Try to use an yuv surface */ if (allow_hw_yuv) { const vlc_fourcc_t *list = vlc_fourcc_GetYUVFallback(fmt->i_chroma); /* Try with overlay first */ for (unsigned pass = allow_overlay ? 0 : 1; pass < 2; pass++) { for (unsigned i = 0; list[i] != 0; i++) { const DWORD fourcc = DirectXGetFourcc(list[i]); if (!fourcc) continue; if (pass == 0) { if (DirectXCreatePictureResourceYuvOverlay(vd, fmt, fourcc)) { #ifndef NDEBUG msg_Dbg(vd, "Failed to create YUV overlay surface %4.4s", (const char*)&fourcc); #endif continue; } } else { if (DirectXCreatePictureResourceYuv(vd, fmt, fourcc)) { #ifndef NDEBUG msg_Dbg(vd, "Failed to create YUV surface %4.4s", (const char*)&fourcc); #endif continue; } } /* */ *use_overlay = pass == 0; fmt->i_chroma = list[i]; return VLC_SUCCESS; } } } /* Try plain RGB */ return DirectXCreatePictureResourceRgb(vd, fmt); }
static int DirectXCreatePictureResource(vout_display_t *vd, bool *use_overlay, video_format_t *fmt) { vout_display_sys_t *sys = vd->sys; /* */ picture_resource_t *rsc = &sys->resource; rsc->p_sys = calloc(1, sizeof(*rsc->p_sys)); if (!rsc->p_sys) return VLC_ENOMEM; /* */ bool allow_hw_yuv = sys->can_blit_fourcc && vlc_fourcc_IsYUV(fmt->i_chroma) && var_InheritBool(vd, "directx-hw-yuv"); bool allow_overlay = var_InheritBool(vd, "overlay"); /* Try to use an yuv surface */ if (allow_hw_yuv) { const vlc_fourcc_t *list = vlc_fourcc_GetYUVFallback(fmt->i_chroma); /* Try with overlay first */ for (unsigned pass = allow_overlay ? 0 : 1; pass < 2; pass++) { for (unsigned i = 0; list[i] != 0; i++) { const DWORD fourcc = DirectXGetFourcc(list[i]); if (!fourcc) continue; if (pass == 0) { if (DirectXCreatePictureResourceYuvOverlay(vd, fmt, fourcc)) continue; } else { if (DirectXCreatePictureResourceYuv(vd, fmt, fourcc)) continue; } /* */ *use_overlay = pass == 0; fmt->i_chroma = list[i]; return VLC_SUCCESS; } } } /* Try plain RGB */ return DirectXCreatePictureResourceRgb(vd, fmt); }
static int DirectXOpen(vout_display_t *vd, video_format_t *fmt) { vout_display_sys_t *sys = vd->sys; assert(!sys->ddobject); assert(!sys->display); assert(!sys->clipper); /* Initialise DirectDraw */ if (DirectXOpenDDraw(vd)) { msg_Err(vd, "cannot initialize DirectX DirectDraw"); return VLC_EGENERIC; } /* Create the directx display */ if (DirectXOpenDisplay(vd)) { msg_Err(vd, "cannot initialize DirectX DirectDraw"); return VLC_EGENERIC; } UpdateRects(vd, NULL, NULL, true); /* Create the picture pool */ if (DirectXCreatePool(vd, &sys->use_overlay, fmt)) { msg_Err(vd, "cannot create any DirectX surface"); return VLC_EGENERIC; } /* */ if (sys->use_overlay) DirectXUpdateOverlay(vd, NULL); EventThreadUseOverlay(sys->event, sys->use_overlay); /* Change the window title bar text */ const char *fallback; if (sys->use_overlay) fallback = VOUT_TITLE " (hardware YUV overlay DirectX output)"; else if (vlc_fourcc_IsYUV(fmt->i_chroma)) fallback = VOUT_TITLE " (hardware YUV DirectX output)"; else fallback = VOUT_TITLE " (software RGB DirectX output)"; EventThreadUpdateTitle(sys->event, fallback); return VLC_SUCCESS; }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; if (p_demux->out == NULL) return VLC_EGENERIC; p_sys = vlc_obj_calloc( p_this, 1, sizeof(demux_sys_t) ); if( !p_sys ) return VLC_ENOMEM; p_sys->f_fps = var_InheritFloat( p_demux, CFG_PREFIX "fps" ); if ( p_sys->f_fps <= 0 ) p_sys->f_fps = 1.0; p_sys->i_frame_interval = vlc_tick_rate_duration( p_sys->f_fps ); char *psz_chroma = var_InheritString( p_demux, CFG_PREFIX "chroma" ); vlc_fourcc_t i_chroma = vlc_fourcc_GetCodecFromString( VIDEO_ES, psz_chroma ); free( psz_chroma ); if ( !i_chroma || vlc_fourcc_IsYUV( i_chroma ) ) { msg_Err( p_demux, "Only RGB chroma are supported" ); return VLC_EGENERIC; } const vlc_chroma_description_t *p_chroma_desc = vlc_fourcc_GetChromaDescription( i_chroma ); if ( !p_chroma_desc ) { msg_Err( p_demux, "Unable to get RGB chroma description" ); return VLC_EGENERIC; } #ifdef NDEBUG rfbEnableClientLogging = FALSE; #endif p_sys->p_client = rfbGetClient( p_chroma_desc->pixel_bits / 3, // bitsPerSample 3, // samplesPerPixel p_chroma_desc->pixel_size ); // bytesPerPixel if ( ! p_sys->p_client ) { msg_Dbg( p_demux, "Unable to set up client for %s", vlc_fourcc_GetDescription( VIDEO_ES, i_chroma ) ); return VLC_EGENERIC; } msg_Dbg( p_demux, "set up client for %s %d %d %d", vlc_fourcc_GetDescription( VIDEO_ES, i_chroma ), p_chroma_desc->pixel_bits / 3, 3, p_chroma_desc->pixel_size ); p_sys->p_client->MallocFrameBuffer = mallocFrameBufferHandler; p_sys->p_client->canHandleNewFBSize = TRUE; p_sys->p_client->GetCredential = getCredentialHandler; p_sys->p_client->GetPassword = getPasswordHandler; /* VNC simple auth */ /* Set compression and quality levels */ p_sys->p_client->appData.compressLevel = var_InheritInteger( p_demux, CFG_PREFIX "compress-level" ); p_sys->p_client->appData.qualityLevel = var_InheritInteger( p_demux, CFG_PREFIX "quality-level" ); /* Parse uri params */ vlc_url_t url; vlc_UrlParse( &url, p_demux->psz_location ); if ( !EMPTY_STR(url.psz_host) ) p_sys->p_client->serverHost = strdup( url.psz_host ); else p_sys->p_client->serverHost = strdup( "localhost" ); p_sys->p_client->appData.viewOnly = TRUE; p_sys->p_client->serverPort = ( url.i_port > 0 ) ? url.i_port : 5900; msg_Dbg( p_demux, "VNC init %s host=%s port=%d", p_demux->psz_location, p_sys->p_client->serverHost, p_sys->p_client->serverPort ); vlc_UrlClean( &url ); /* make demux available for callback handlers */ rfbClientSetClientData( p_sys->p_client, DemuxThread, p_demux ); p_demux->p_sys = p_sys; if( !rfbInitClient( p_sys->p_client, NULL, NULL ) ) { msg_Err( p_demux, "can't connect to RFB server" ); return VLC_EGENERIC; } p_sys->i_starttime = vlc_tick_now(); if ( vlc_clone( &p_sys->thread, DemuxThread, p_demux, VLC_THREAD_PRIORITY_INPUT ) != VLC_SUCCESS ) { msg_Err( p_demux, "can't spawn thread" ); return VLC_EGENERIC; } p_demux->pf_demux = NULL; p_demux->pf_control = Control; return VLC_SUCCESS; }
int Open( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t*)p_this; filter_sys_t *p_sys; const vlc_fourcc_t fourcc = p_filter->fmt_in.video.i_chroma; const vlc_chroma_description_t *chroma = vlc_fourcc_GetChromaDescription( fourcc ); if( !vlc_fourcc_IsYUV( fourcc ) || !chroma || chroma->plane_count != 3 || chroma->pixel_size > 2 ) { msg_Err( p_filter, "Unsupported chroma (%4.4s)", (char*)&fourcc ); return VLC_EGENERIC; } /* */ p_sys = p_filter->p_sys = malloc( sizeof( *p_sys ) ); if( !p_sys ) return VLC_ENOMEM; p_sys->chroma = chroma; p_sys->i_mode = DEINTERLACE_BLEND; p_sys->b_double_rate = false; p_sys->b_half_height = true; p_sys->b_use_frame_history = false; for( int i = 0; i < METADATA_SIZE; i++ ) { p_sys->meta.pi_date[i] = VLC_TS_INVALID; p_sys->meta.pi_nb_fields[i] = 2; p_sys->meta.pb_top_field_first[i] = true; } p_sys->i_frame_offset = 0; /* start with default value (first-ever frame cannot have offset) */ for( int i = 0; i < HISTORY_SIZE; i++ ) p_sys->pp_history[i] = NULL; IVTCClearState( p_filter ); #if defined(CAN_COMPILE_C_ALTIVEC) if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_ALTIVEC) ) { p_sys->pf_merge = MergeAltivec; p_sys->pf_end_merge = NULL; } else #endif #if defined(CAN_COMPILE_SSE) if( (vlc_CPU() & CPU_CAPABILITY_SSE2) ) { p_sys->pf_merge = chroma->pixel_size == 1 ? Merge8BitSSE2 : Merge16BitSSE2; p_sys->pf_end_merge = EndMMX; } else #endif #if defined(CAN_COMPILE_MMXEXT) if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_MMXEXT) ) { p_sys->pf_merge = MergeMMXEXT; p_sys->pf_end_merge = EndMMX; } else #endif #if defined(CAN_COMPILE_3DNOW) if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_3DNOW) ) { p_sys->pf_merge = Merge3DNow; p_sys->pf_end_merge = End3DNow; } else #endif #if defined __ARM_NEON__ // FIXME: runtime detect support if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_NEON) ) { p_sys->pf_merge = MergeNEON; p_sys->pf_end_merge = NULL; } else #endif { p_sys->pf_merge = chroma->pixel_size == 1 ? Merge8BitGeneric : Merge16BitGeneric; p_sys->pf_end_merge = NULL; } /* */ config_ChainParse( p_filter, FILTER_CFG_PREFIX, ppsz_filter_options, p_filter->p_cfg ); char *psz_mode = var_GetNonEmptyString( p_filter, FILTER_CFG_PREFIX "mode" ); SetFilterMethod( p_filter, psz_mode ); free( psz_mode ); if( p_sys->i_mode == DEINTERLACE_PHOSPHOR ) { int i_c420 = var_GetInteger( p_filter, FILTER_CFG_PREFIX "phosphor-chroma" ); if( i_c420 != PC_LATEST && i_c420 != PC_ALTLINE && i_c420 != PC_BLEND && i_c420 != PC_UPCONVERT ) { msg_Dbg( p_filter, "Phosphor 4:2:0 input chroma mode not set"\ "or out of range (valid: 1, 2, 3 or 4), "\ "using default" ); i_c420 = PC_ALTLINE; } msg_Dbg( p_filter, "using Phosphor 4:2:0 input chroma mode %d", i_c420 ); /* This maps directly to the phosphor_chroma_t enum. */ p_sys->phosphor.i_chroma_for_420 = i_c420; int i_dimmer = var_GetInteger( p_filter, FILTER_CFG_PREFIX "phosphor-dimmer" ); if( i_dimmer < 1 || i_dimmer > 4 ) { msg_Dbg( p_filter, "Phosphor dimmer strength not set "\ "or out of range (valid: 1, 2, 3 or 4), "\ "using default" ); i_dimmer = 2; /* low */ } msg_Dbg( p_filter, "using Phosphor dimmer strength %d", i_dimmer ); /* The internal value ranges from 0 to 3. */ p_sys->phosphor.i_dimmer_strength = i_dimmer - 1; } else { p_sys->phosphor.i_chroma_for_420 = PC_ALTLINE; p_sys->phosphor.i_dimmer_strength = 1; } /* */ video_format_t fmt; GetOutputFormat( p_filter, &fmt, &p_filter->fmt_in.video ); if( !p_filter->b_allow_fmt_out_change && ( fmt.i_chroma != p_filter->fmt_in.video.i_chroma || fmt.i_height != p_filter->fmt_in.video.i_height ) ) { Close( VLC_OBJECT(p_filter) ); return VLC_EGENERIC; } p_filter->fmt_out.video = fmt; p_filter->fmt_out.i_codec = fmt.i_chroma; p_filter->pf_video_filter = Deinterlace; p_filter->pf_video_flush = Flush; p_filter->pf_video_mouse = Mouse; msg_Dbg( p_filter, "deinterlacing" ); return VLC_SUCCESS; }
int Open( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t*)p_this; filter_sys_t *p_sys; const vlc_fourcc_t fourcc = p_filter->fmt_in.video.i_chroma; const vlc_chroma_description_t *chroma = vlc_fourcc_GetChromaDescription( fourcc ); if( chroma == NULL || chroma->pixel_size > 2 ) { notsupp: msg_Err( p_filter, "unsupported chroma %4.4s", (char*)&fourcc ); return VLC_EGENERIC; } unsigned pixel_size = chroma->pixel_size; bool packed = false; if( chroma->plane_count != 3 ) { packed = true; switch( fourcc ) { case VLC_CODEC_YUYV: case VLC_CODEC_UYVY: case VLC_CODEC_YVYU: case VLC_CODEC_VYUY: case VLC_CODEC_NV12: case VLC_CODEC_NV21: pixel_size = 1; break; default: goto notsupp; } } assert( vlc_fourcc_IsYUV( fourcc ) ); /* */ p_sys = p_filter->p_sys = malloc( sizeof( *p_sys ) ); if( !p_sys ) return VLC_ENOMEM; p_sys->chroma = chroma; config_ChainParse( p_filter, FILTER_CFG_PREFIX, ppsz_filter_options, p_filter->p_cfg ); char *psz_mode = var_InheritString( p_filter, FILTER_CFG_PREFIX "mode" ); SetFilterMethod( p_filter, psz_mode, packed ); free( psz_mode ); for( int i = 0; i < METADATA_SIZE; i++ ) { p_sys->meta.pi_date[i] = VLC_TS_INVALID; p_sys->meta.pi_nb_fields[i] = 2; p_sys->meta.pb_top_field_first[i] = true; } p_sys->i_frame_offset = 0; /* start with default value (first-ever frame cannot have offset) */ for( int i = 0; i < HISTORY_SIZE; i++ ) p_sys->pp_history[i] = NULL; IVTCClearState( p_filter ); #if defined(CAN_COMPILE_C_ALTIVEC) if( pixel_size == 1 && vlc_CPU_ALTIVEC() ) p_sys->pf_merge = MergeAltivec; else #endif #if defined(CAN_COMPILE_SSE2) if( vlc_CPU_SSE2() ) { p_sys->pf_merge = pixel_size == 1 ? Merge8BitSSE2 : Merge16BitSSE2; p_sys->pf_end_merge = EndMMX; } else #endif #if defined(CAN_COMPILE_MMXEXT) if( pixel_size == 1 && vlc_CPU_MMXEXT() ) { p_sys->pf_merge = MergeMMXEXT; p_sys->pf_end_merge = EndMMX; } else #endif #if defined(CAN_COMPILE_3DNOW) if( pixel_size == 1 && vlc_CPU_3dNOW() ) { p_sys->pf_merge = Merge3DNow; p_sys->pf_end_merge = End3DNow; } else #endif #if defined(CAN_COMPILE_ARM) if( vlc_CPU_ARM_NEON() ) p_sys->pf_merge = pixel_size == 1 ? merge8_arm_neon : merge16_arm_neon; else if( vlc_CPU_ARMv6() ) p_sys->pf_merge = pixel_size == 1 ? merge8_armv6 : merge16_armv6; else #endif { p_sys->pf_merge = pixel_size == 1 ? Merge8BitGeneric : Merge16BitGeneric; #if defined(__i386__) || defined(__x86_64__) p_sys->pf_end_merge = NULL; #endif } /* */ if( p_sys->i_mode == DEINTERLACE_PHOSPHOR ) { int i_c420 = var_GetInteger( p_filter, FILTER_CFG_PREFIX "phosphor-chroma" ); if( i_c420 != PC_LATEST && i_c420 != PC_ALTLINE && i_c420 != PC_BLEND && i_c420 != PC_UPCONVERT ) { msg_Dbg( p_filter, "Phosphor 4:2:0 input chroma mode not set"\ "or out of range (valid: 1, 2, 3 or 4), "\ "using default" ); i_c420 = PC_ALTLINE; } msg_Dbg( p_filter, "using Phosphor 4:2:0 input chroma mode %d", i_c420 ); /* This maps directly to the phosphor_chroma_t enum. */ p_sys->phosphor.i_chroma_for_420 = i_c420; int i_dimmer = var_GetInteger( p_filter, FILTER_CFG_PREFIX "phosphor-dimmer" ); if( i_dimmer < 1 || i_dimmer > 4 ) { msg_Dbg( p_filter, "Phosphor dimmer strength not set "\ "or out of range (valid: 1, 2, 3 or 4), "\ "using default" ); i_dimmer = 2; /* low */ } msg_Dbg( p_filter, "using Phosphor dimmer strength %d", i_dimmer ); /* The internal value ranges from 0 to 3. */ p_sys->phosphor.i_dimmer_strength = i_dimmer - 1; } else { p_sys->phosphor.i_chroma_for_420 = PC_ALTLINE; p_sys->phosphor.i_dimmer_strength = 1; } /* */ video_format_t fmt; GetOutputFormat( p_filter, &fmt, &p_filter->fmt_in.video ); if( !p_filter->b_allow_fmt_out_change && ( fmt.i_chroma != p_filter->fmt_in.video.i_chroma || fmt.i_height != p_filter->fmt_in.video.i_height ) ) { Close( VLC_OBJECT(p_filter) ); return VLC_EGENERIC; } p_filter->fmt_out.video = fmt; p_filter->fmt_out.i_codec = fmt.i_chroma; p_filter->pf_video_filter = Deinterlace; p_filter->pf_video_flush = Flush; p_filter->pf_video_mouse = Mouse; msg_Dbg( p_filter, "deinterlacing" ); return VLC_SUCCESS; }