1+ use std:: collections:: HashMap ;
2+ use std:: path:: Path ;
3+ use std:: sync:: Arc ;
4+ use std:: thread:: { spawn, JoinHandle } ;
5+ use std:: time:: SystemTime ;
6+
17use crossbeam:: channel:: { Receiver , Sender } ;
28use ffmpeg:: util:: frame:: video:: Video ;
39use ffmpeg_next as ffmpeg;
@@ -10,13 +16,8 @@ use parking_lot::Mutex;
1016use pyo3:: exceptions:: PyBrokenPipeError ;
1117use pyo3:: prelude:: * ;
1218use pyo3:: types:: PyBytes ;
13- use std:: collections:: HashMap ;
14- use std:: path:: Path ;
15- use std:: sync:: Arc ;
16- use std:: thread:: { spawn, JoinHandle } ;
17- use std:: time:: SystemTime ;
1819
19- const DECODING_FORMAT : Pixel = Pixel :: BGR24 ;
20+ const DECODING_FORMAT : Pixel = Pixel :: RGB24 ;
2021const DECODED_PIX_BYTES : u32 = 3 ;
2122
2223fn is_stream_key_framed ( id : Id ) -> Result < bool , String > {
@@ -108,8 +109,12 @@ impl VideoFrameEnvelope {
108109 self . __repr__ ( )
109110 }
110111
111- fn payload_as_bytes ( & self , py : Python ) -> PyObject {
112- PyBytes :: new ( py, & self . payload ) . into ( )
112+ fn payload_as_bytes ( & self , py : Python ) -> PyResult < PyObject > {
113+ let res = PyBytes :: new_with ( py, self . payload . len ( ) , |b : & mut [ u8 ] | {
114+ b. copy_from_slice ( & self . payload ) ;
115+ Ok ( ( ) )
116+ } ) ?;
117+ Ok ( res. into ( ) )
113118 }
114119}
115120
@@ -139,6 +144,7 @@ fn handle(
139144 tx : Sender < VideoFrameEnvelope > ,
140145 signal : Arc < Mutex < bool > > ,
141146 decode : bool ,
147+ autoconvert_raw_formats_to_rgb24 : bool ,
142148 log_level : Arc < Mutex < Option < Level > > > ,
143149) {
144150 let mut queue_full_skipped_count = 0 ;
@@ -181,7 +187,7 @@ fn handle(
181187 // video_decoder.format(),
182188 // video_decoder.width(),
183189 // video_decoder.height(),
184- // Pixel::BGR24 ,
190+ // Pixel::rgb24 ,
185191 // video_decoder.width(),
186192 // video_decoder.height(),
187193 // Flags::FAST_BILINEAR,
@@ -256,6 +262,10 @@ fn handle(
256262 continue ;
257263 }
258264
265+ let decode = decode
266+ || ( autoconvert_raw_formats_to_rgb24
267+ && video_decoder. codec ( ) . map ( |c| c. id ( ) ) == Some ( Id :: RAWVIDEO ) ) ;
268+
259269 let raw_frames = if decode {
260270 let mut raw_frames = Vec :: new ( ) ;
261271 video_decoder
@@ -364,12 +374,18 @@ fn assign_log_level(ffmpeg_log_level: FFmpegLogLevel) -> Level {
364374#[ pymethods]
365375impl FFMpegSource {
366376 #[ new]
367- #[ pyo3( signature = ( uri, params, queue_len = 32 , decode = false , ffmpeg_log_level = FFmpegLogLevel :: Info ) ) ]
377+ #[ pyo3( signature = ( uri, params,
378+ queue_len = 32 ,
379+ decode = false ,
380+ autoconvert_raw_formats_to_rgb24 = false ,
381+ ffmpeg_log_level = FFmpegLogLevel :: Info )
382+ ) ]
368383 pub fn new (
369384 uri : String ,
370385 params : HashMap < String , String > ,
371386 queue_len : i64 ,
372387 decode : bool ,
388+ autoconvert_raw_formats_to_rgb24 : bool ,
373389 ffmpeg_log_level : FFmpegLogLevel ,
374390 ) -> Self {
375391 assert ! ( queue_len > 0 , "Queue length must be a positive number" ) ;
@@ -383,7 +399,15 @@ impl FFMpegSource {
383399 let thread_exit_signal = exit_signal. clone ( ) ;
384400 let thread_ll = log_level. clone ( ) ;
385401 let thread = Some ( spawn ( move || {
386- handle ( uri, params, tx, thread_exit_signal, decode, thread_ll)
402+ handle (
403+ uri,
404+ params,
405+ tx,
406+ thread_exit_signal,
407+ decode,
408+ autoconvert_raw_formats_to_rgb24,
409+ thread_ll,
410+ )
387411 } ) ) ;
388412
389413 Self {
0 commit comments