@@ -2,26 +2,31 @@ use crate::{ConversionConfig, ConvertError, ConverterBackend, FrameConverter};
22use ffmpeg:: { format:: Pixel , frame} ;
33use parking_lot:: Mutex ;
44use std:: {
5+ mem:: ManuallyDrop ,
56 ptr,
67 sync:: atomic:: { AtomicBool , AtomicU64 , Ordering } ,
78} ;
89use windows:: {
9- Win32 :: Graphics :: {
10- Direct3D :: D3D_DRIVER_TYPE_HARDWARE ,
11- Direct3D11 :: {
12- D3D11_BIND_RENDER_TARGET , D3D11_CPU_ACCESS_READ , D3D11_CPU_ACCESS_WRITE ,
13- D3D11_CREATE_DEVICE_VIDEO_SUPPORT , D3D11_MAP_READ , D3D11_MAP_WRITE , D3D11_SDK_VERSION ,
14- D3D11_TEXTURE2D_DESC , D3D11_USAGE_DEFAULT , D3D11_USAGE_STAGING ,
15- D3D11_VIDEO_PROCESSOR_CONTENT_DESC , D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC ,
16- D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC , D3D11_VIDEO_PROCESSOR_STREAM ,
17- D3D11_VPIV_DIMENSION_TEXTURE2D , D3D11_VPOV_DIMENSION_TEXTURE2D , D3D11CreateDevice ,
18- ID3D11Device , ID3D11DeviceContext , ID3D11Texture2D , ID3D11VideoContext ,
19- ID3D11VideoDevice , ID3D11VideoProcessor , ID3D11VideoProcessorEnumerator ,
20- ID3D11VideoProcessorInputView , ID3D11VideoProcessorOutputView ,
21- } ,
22- Dxgi :: {
23- Common :: { DXGI_FORMAT , DXGI_FORMAT_NV12 , DXGI_FORMAT_YUY2 } ,
24- IDXGIAdapter , IDXGIDevice ,
10+ Win32 :: {
11+ Foundation :: HMODULE ,
12+ Graphics :: {
13+ Direct3D :: D3D_DRIVER_TYPE_HARDWARE ,
14+ Direct3D11 :: {
15+ D3D11_BIND_RENDER_TARGET , D3D11_CPU_ACCESS_READ , D3D11_CPU_ACCESS_WRITE ,
16+ D3D11_CREATE_DEVICE_VIDEO_SUPPORT , D3D11_MAP_READ , D3D11_MAP_WRITE ,
17+ D3D11_MAPPED_SUBRESOURCE , D3D11_SDK_VERSION , D3D11_TEXTURE2D_DESC ,
18+ D3D11_USAGE_DEFAULT , D3D11_USAGE_STAGING , D3D11_VIDEO_PROCESSOR_CONTENT_DESC ,
19+ D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC , D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC ,
20+ D3D11_VIDEO_PROCESSOR_STREAM , D3D11_VPIV_DIMENSION_TEXTURE2D ,
21+ D3D11_VPOV_DIMENSION_TEXTURE2D , D3D11CreateDevice , ID3D11Device ,
22+ ID3D11DeviceContext , ID3D11Texture2D , ID3D11VideoContext , ID3D11VideoDevice ,
23+ ID3D11VideoProcessor , ID3D11VideoProcessorEnumerator ,
24+ ID3D11VideoProcessorInputView , ID3D11VideoProcessorOutputView ,
25+ } ,
26+ Dxgi :: {
27+ Common :: { DXGI_FORMAT , DXGI_FORMAT_NV12 , DXGI_FORMAT_YUY2 } ,
28+ IDXGIAdapter , IDXGIDevice ,
29+ } ,
2530 } ,
2631 } ,
2732 core:: Interface ,
@@ -150,7 +155,7 @@ impl D3D11Converter {
150155 D3D11CreateDevice (
151156 None ,
152157 D3D_DRIVER_TYPE_HARDWARE ,
153- None ,
158+ HMODULE :: default ( ) ,
154159 D3D11_CREATE_DEVICE_VIDEO_SUPPORT ,
155160 None ,
156161 D3D11_SDK_VERSION ,
@@ -243,7 +248,7 @@ impl D3D11Converter {
243248 config. input_height ,
244249 input_dxgi,
245250 D3D11_USAGE_DEFAULT ,
246- D3D11_BIND_RENDER_TARGET . 0 ,
251+ D3D11_BIND_RENDER_TARGET . 0 as u32 ,
247252 0 ,
248253 ) ?;
249254
@@ -253,7 +258,7 @@ impl D3D11Converter {
253258 config. output_height ,
254259 output_dxgi,
255260 D3D11_USAGE_DEFAULT ,
256- D3D11_BIND_RENDER_TARGET . 0 ,
261+ D3D11_BIND_RENDER_TARGET . 0 as u32 ,
257262 0 ,
258263 ) ?;
259264
@@ -264,7 +269,7 @@ impl D3D11Converter {
264269 input_dxgi,
265270 D3D11_USAGE_STAGING ,
266271 0 ,
267- D3D11_CPU_ACCESS_WRITE . 0 ,
272+ D3D11_CPU_ACCESS_WRITE . 0 as u32 ,
268273 ) ?;
269274
270275 let staging_output = create_texture (
@@ -274,7 +279,7 @@ impl D3D11Converter {
274279 output_dxgi,
275280 D3D11_USAGE_STAGING ,
276281 0 ,
277- D3D11_CPU_ACCESS_READ . 0 ,
282+ D3D11_CPU_ACCESS_READ . 0 as u32 ,
278283 ) ?;
279284
280285 let resources = D3D11Resources {
@@ -333,12 +338,19 @@ impl FrameConverter for D3D11Converter {
333338 }
334339
335340 let pts = input. pts ( ) ;
336- let mut resources = self . resources . lock ( ) ;
341+ let resources = self . resources . lock ( ) ;
337342
338343 unsafe {
339- let mapped = resources
344+ let mut mapped = D3D11_MAPPED_SUBRESOURCE :: default ( ) ;
345+ resources
340346 . context
341- . Map ( & resources. staging_input , 0 , D3D11_MAP_WRITE , 0 )
347+ . Map (
348+ & resources. staging_input ,
349+ 0 ,
350+ D3D11_MAP_WRITE ,
351+ 0 ,
352+ Some ( & mut mapped) ,
353+ )
342354 . map_err ( |e| {
343355 ConvertError :: ConversionFailed ( format ! ( "Map input failed: {:?}" , e) )
344356 } ) ?;
@@ -363,16 +375,21 @@ impl FrameConverter for D3D11Converter {
363375 } ,
364376 } ;
365377
366- let input_view: ID3D11VideoProcessorInputView = resources
378+ let mut input_view: Option < ID3D11VideoProcessorInputView > = None ;
379+ resources
367380 . video_device
368381 . CreateVideoProcessorInputView (
369382 & resources. input_texture ,
370383 & resources. enumerator ,
371384 & input_view_desc,
385+ Some ( & mut input_view) ,
372386 )
373387 . map_err ( |e| {
374388 ConvertError :: ConversionFailed ( format ! ( "CreateInputView failed: {:?}" , e) )
375389 } ) ?;
390+ let input_view = input_view. ok_or_else ( || {
391+ ConvertError :: ConversionFailed ( "CreateInputView returned null" . to_string ( ) )
392+ } ) ?;
376393
377394 let output_view_desc = D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC {
378395 ViewDimension : D3D11_VPOV_DIMENSION_TEXTURE2D ,
@@ -384,16 +401,21 @@ impl FrameConverter for D3D11Converter {
384401 } ,
385402 } ;
386403
387- let output_view: ID3D11VideoProcessorOutputView = resources
404+ let mut output_view: Option < ID3D11VideoProcessorOutputView > = None ;
405+ resources
388406 . video_device
389407 . CreateVideoProcessorOutputView (
390408 & resources. output_texture ,
391409 & resources. enumerator ,
392410 & output_view_desc,
411+ Some ( & mut output_view) ,
393412 )
394413 . map_err ( |e| {
395414 ConvertError :: ConversionFailed ( format ! ( "CreateOutputView failed: {:?}" , e) )
396415 } ) ?;
416+ let output_view = output_view. ok_or_else ( || {
417+ ConvertError :: ConversionFailed ( "CreateOutputView returned null" . to_string ( ) )
418+ } ) ?;
397419
398420 let stream = D3D11_VIDEO_PROCESSOR_STREAM {
399421 Enable : true . into ( ) ,
@@ -405,7 +427,7 @@ impl FrameConverter for D3D11Converter {
405427 pInputSurface : std:: mem:: transmute_copy ( & input_view) ,
406428 ppFutureSurfaces : ptr:: null_mut ( ) ,
407429 ppPastSurfacesRight : ptr:: null_mut ( ) ,
408- pInputSurfaceRight : None ,
430+ pInputSurfaceRight : ManuallyDrop :: new ( None ) ,
409431 ppFutureSurfacesRight : ptr:: null_mut ( ) ,
410432 } ;
411433
@@ -427,9 +449,16 @@ impl FrameConverter for D3D11Converter {
427449 . context
428450 . CopyResource ( & resources. staging_output , & resources. output_texture ) ;
429451
430- let mapped = resources
452+ let mut mapped = D3D11_MAPPED_SUBRESOURCE :: default ( ) ;
453+ resources
431454 . context
432- . Map ( & resources. staging_output , 0 , D3D11_MAP_READ , 0 )
455+ . Map (
456+ & resources. staging_output ,
457+ 0 ,
458+ D3D11_MAP_READ ,
459+ 0 ,
460+ Some ( & mut mapped) ,
461+ )
433462 . map_err ( |e| {
434463 ConvertError :: ConversionFailed ( format ! ( "Map output failed: {:?}" , e) )
435464 } ) ?;
@@ -494,16 +523,20 @@ fn create_texture(
494523 Quality : 0 ,
495524 } ,
496525 Usage : usage,
497- BindFlags : windows:: Win32 :: Graphics :: Direct3D11 :: D3D11_BIND_FLAG ( bind_flags as i32 ) ,
498- CPUAccessFlags : windows:: Win32 :: Graphics :: Direct3D11 :: D3D11_CPU_ACCESS_FLAG (
499- cpu_access as i32 ,
500- ) ,
501- MiscFlags : windows:: Win32 :: Graphics :: Direct3D11 :: D3D11_RESOURCE_MISC_FLAG ( 0 ) ,
526+ BindFlags : bind_flags,
527+ CPUAccessFlags : cpu_access,
528+ MiscFlags : 0 ,
502529 } ;
503530
504531 unsafe {
505- device. CreateTexture2D ( & desc, None ) . map_err ( |e| {
506- ConvertError :: HardwareUnavailable ( format ! ( "CreateTexture2D failed: {:?}" , e) )
532+ let mut texture: Option < ID3D11Texture2D > = None ;
533+ device
534+ . CreateTexture2D ( & desc, None , Some ( & mut texture) )
535+ . map_err ( |e| {
536+ ConvertError :: HardwareUnavailable ( format ! ( "CreateTexture2D failed: {:?}" , e) )
537+ } ) ?;
538+ texture. ok_or_else ( || {
539+ ConvertError :: HardwareUnavailable ( "CreateTexture2D returned null" . to_string ( ) )
507540 } )
508541 }
509542}
@@ -515,29 +548,35 @@ unsafe fn copy_frame_to_mapped(frame: &frame::Video, dst: *mut u8, dst_stride: u
515548 match format {
516549 Pixel :: NV12 => {
517550 for y in 0 ..height {
518- ptr:: copy_nonoverlapping (
519- frame. data ( 0 ) . as_ptr ( ) . add ( y * frame. stride ( 0 ) ) ,
520- dst. add ( y * dst_stride) ,
521- frame. width ( ) as usize ,
522- ) ;
551+ unsafe {
552+ ptr:: copy_nonoverlapping (
553+ frame. data ( 0 ) . as_ptr ( ) . add ( y * frame. stride ( 0 ) ) ,
554+ dst. add ( y * dst_stride) ,
555+ frame. width ( ) as usize ,
556+ ) ;
557+ }
523558 }
524559 let uv_offset = height * dst_stride;
525560 for y in 0 ..height / 2 {
526- ptr:: copy_nonoverlapping (
527- frame. data ( 1 ) . as_ptr ( ) . add ( y * frame. stride ( 1 ) ) ,
528- dst. add ( uv_offset + y * dst_stride) ,
529- frame. width ( ) as usize ,
530- ) ;
561+ unsafe {
562+ ptr:: copy_nonoverlapping (
563+ frame. data ( 1 ) . as_ptr ( ) . add ( y * frame. stride ( 1 ) ) ,
564+ dst. add ( uv_offset + y * dst_stride) ,
565+ frame. width ( ) as usize ,
566+ ) ;
567+ }
531568 }
532569 }
533570 Pixel :: YUYV422 | Pixel :: UYVY422 => {
534571 let row_bytes = frame. width ( ) as usize * 2 ;
535572 for y in 0 ..height {
536- ptr:: copy_nonoverlapping (
537- frame. data ( 0 ) . as_ptr ( ) . add ( y * frame. stride ( 0 ) ) ,
538- dst. add ( y * dst_stride) ,
539- row_bytes,
540- ) ;
573+ unsafe {
574+ ptr:: copy_nonoverlapping (
575+ frame. data ( 0 ) . as_ptr ( ) . add ( y * frame. stride ( 0 ) ) ,
576+ dst. add ( y * dst_stride) ,
577+ row_bytes,
578+ ) ;
579+ }
541580 }
542581 }
543582 _ => { }
@@ -551,30 +590,36 @@ unsafe fn copy_mapped_to_frame(src: *const u8, src_stride: usize, frame: &mut fr
551590 match format {
552591 Pixel :: NV12 => {
553592 for y in 0 ..height {
554- ptr:: copy_nonoverlapping (
555- src. add ( y * src_stride) ,
556- frame. data_mut ( 0 ) . as_mut_ptr ( ) . add ( y * frame. stride ( 0 ) ) ,
557- frame. width ( ) as usize ,
558- ) ;
593+ unsafe {
594+ ptr:: copy_nonoverlapping (
595+ src. add ( y * src_stride) ,
596+ frame. data_mut ( 0 ) . as_mut_ptr ( ) . add ( y * frame. stride ( 0 ) ) ,
597+ frame. width ( ) as usize ,
598+ ) ;
599+ }
559600 }
560601 let uv_offset = height * src_stride;
561602 for y in 0 ..height / 2 {
562- ptr:: copy_nonoverlapping (
563- src. add ( uv_offset + y * src_stride) ,
564- frame. data_mut ( 1 ) . as_mut_ptr ( ) . add ( y * frame. stride ( 1 ) ) ,
565- frame. width ( ) as usize ,
566- ) ;
603+ unsafe {
604+ ptr:: copy_nonoverlapping (
605+ src. add ( uv_offset + y * src_stride) ,
606+ frame. data_mut ( 1 ) . as_mut_ptr ( ) . add ( y * frame. stride ( 1 ) ) ,
607+ frame. width ( ) as usize ,
608+ ) ;
609+ }
567610 }
568611 }
569612 Pixel :: YUYV422 => {
570613 let bytes_per_pixel = 2 ;
571614 let row_bytes = frame. width ( ) as usize * bytes_per_pixel;
572615 for y in 0 ..height {
573- ptr:: copy_nonoverlapping (
574- src. add ( y * src_stride) ,
575- frame. data_mut ( 0 ) . as_mut_ptr ( ) . add ( y * frame. stride ( 0 ) ) ,
576- row_bytes,
577- ) ;
616+ unsafe {
617+ ptr:: copy_nonoverlapping (
618+ src. add ( y * src_stride) ,
619+ frame. data_mut ( 0 ) . as_mut_ptr ( ) . add ( y * frame. stride ( 0 ) ) ,
620+ row_bytes,
621+ ) ;
622+ }
578623 }
579624 }
580625 _ => { }
0 commit comments