Skip to main content

VideoDecoder

Struct VideoDecoder 

Source
pub struct VideoDecoder { /* private fields */ }

Implementations§

Source§

impl VideoDecoder

Source

pub fn open(input: &InputContext, config: VideoDecoderConfig) -> Result<Self>

Examples found in repository?
examples/transcode_file.rs (lines 24-30)
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9    let mut args = env::args().skip(1);
10    let input_path = args
11        .next()
12        .map(PathBuf::from)
13        .ok_or("usage: transcode_file <input> <output> [max_frames] [encoder]")?;
14    let output_path = args
15        .next()
16        .map(PathBuf::from)
17        .ok_or("missing output path")?;
18    let max_frames = args.next().and_then(|value| value.parse::<usize>().ok());
19    let encoder_name = args.next();
20
21    let started = Instant::now();
22    let mut input = InputContext::open(input_path.to_string_lossy().to_string())?;
23    let stream = input.best_video_stream()?;
24    let mut decoder = VideoDecoder::open(
25        &input,
26        VideoDecoderConfig {
27            stream_index: stream.stream_index,
28            mode: DecodeMode::Cpu,
29        },
30    )?;
31    let fps = stream
32        .avg_frame_rate
33        .as_f64()
34        .filter(|fps| *fps > 0.0)
35        .unwrap_or(60.0)
36        .round()
37        .clamp(1.0, u32::MAX as f64) as u32;
38    let mut config =
39        VideoEncoderConfig::cpu_rgba(stream.width, stream.height, fps, VideoCodec::H264);
40    if let Some(encoder_name) = encoder_name {
41        config.encoder_name = Some(encoder_name);
42    }
43    let mut encoder = MuxedEncoder::create(output_path.to_string_lossy().to_string(), config)?;
44
45    let mut frames = 0_usize;
46    'decode: while let Some(packet) = input.read_packet()? {
47        decoder.send_packet(&packet)?;
48        while let Some(frame) = decoder.receive_cpu_frame()? {
49            encoder.write_video_frame(&frame)?;
50            frames = frames.saturating_add(1);
51            if max_frames.is_some_and(|limit| frames >= limit) {
52                break 'decode;
53            }
54        }
55    }
56
57    if max_frames.is_none_or(|limit| frames < limit) {
58        decoder.send_eof()?;
59        while let Some(frame) = decoder.receive_cpu_frame()? {
60            encoder.write_video_frame(&frame)?;
61            frames = frames.saturating_add(1);
62            if max_frames.is_some_and(|limit| frames >= limit) {
63                break;
64            }
65        }
66    }
67
68    encoder.finish()?;
69    println!("input={}", input_path.display());
70    println!("output={}", output_path.display());
71    println!("frames={frames}");
72    println!("elapsed_ms={}", started.elapsed().as_millis());
73    println!(
74        "fps={:.2}",
75        frames as f64 / started.elapsed().as_secs_f64().max(1e-9)
76    );
77    Ok(())
78}
More examples
Hide additional examples
examples/decode_file.rs (lines 44-50)
13fn main() -> Result<(), Box<dyn std::error::Error>> {
14    let mut args = env::args().skip(1);
15    let path = args.next().map(PathBuf::from).ok_or(
16        "usage: decode_file <path> [max_frames] [cpu|cuda|metal|vulkan] [gpu|rgba|cuda-rgba]",
17    )?;
18    let next = args.next();
19    let (max_frames, mode_arg) = match next {
20        Some(value) => match value.parse::<usize>() {
21            Ok(max_frames) => (Some(max_frames), args.next()),
22            Err(_) => (None, Some(value)),
23        },
24        None => (None, None),
25    };
26    let mode = match mode_arg.as_deref() {
27        Some("cuda") => DecodeMode::Gpu(GpuBackend::Cuda),
28        Some("metal") => DecodeMode::Gpu(GpuBackend::Metal),
29        Some("vulkan") => DecodeMode::Gpu(GpuBackend::Vulkan),
30        Some("cpu") | None => DecodeMode::Cpu,
31        Some(other) => return Err(format!("unknown decode mode `{other}`").into()),
32    };
33    let receive = match args.next().as_deref() {
34        Some("gpu") => ReceiveMode::Gpu,
35        Some("cuda-rgba") => ReceiveMode::CudaRgba,
36        Some("rgba") | None => ReceiveMode::Rgba,
37        Some(other) => return Err(format!("unknown receive mode `{other}`").into()),
38    };
39
40    let started = Instant::now();
41    let mut input = InputContext::open(path.to_string_lossy().to_string())?;
42    let stream = input.best_video_stream()?;
43    let open_elapsed = started.elapsed();
44    let mut decoder = VideoDecoder::open(
45        &input,
46        VideoDecoderConfig {
47            stream_index: stream.stream_index,
48            mode,
49        },
50    )?;
51
52    let decode_started = Instant::now();
53    let mut cuda = CudaRgbaState::new(receive, stream.width, stream.height)?;
54    let mut frames = 0_usize;
55    let mut bytes = 0_usize;
56
57    'decode: while let Some(packet) = input.read_packet()? {
58        decoder.send_packet(&packet)?;
59        while let Some(frame_bytes) = receive_frame(&mut decoder, mode, receive, cuda.as_mut())? {
60            frames = frames.saturating_add(1);
61            bytes = bytes.saturating_add(frame_bytes);
62            if max_frames.is_some_and(|limit| frames >= limit) {
63                break 'decode;
64            }
65        }
66    }
67
68    if max_frames.is_none_or(|limit| frames < limit) {
69        decoder.send_eof()?;
70        while let Some(frame_bytes) = receive_frame(&mut decoder, mode, receive, cuda.as_mut())? {
71            frames = frames.saturating_add(1);
72            bytes = bytes.saturating_add(frame_bytes);
73            if max_frames.is_some_and(|limit| frames >= limit) {
74                break;
75            }
76        }
77    }
78
79    let decode_elapsed = decode_started.elapsed();
80    let total_elapsed = started.elapsed();
81    let usage = usage();
82    println!("path={}", path.display());
83    println!("codec={:?}", stream.codec);
84    println!("dimensions={}x{}", stream.width, stream.height);
85    println!("frames={frames}");
86    println!("mode={mode:?}");
87    println!("receive={receive:?}");
88    println!("decoded_frame_bytes={bytes}");
89    println!("open_ms={}", millis(open_elapsed));
90    println!("decode_ms={}", millis(decode_elapsed));
91    println!("total_ms={}", millis(total_elapsed));
92    println!(
93        "fps={:.2}",
94        frames as f64 / decode_elapsed.as_secs_f64().max(1e-9)
95    );
96    println!("user_cpu_ms={}", millis(usage.user));
97    println!("system_cpu_ms={}", millis(usage.system));
98    println!("max_rss_platform_units={}", usage.max_rss);
99    Ok(())
100}
Source

pub fn codec(&self) -> VideoCodec

Source

pub fn stream_index(&self) -> usize

Source

pub fn time_base(&self) -> Rational

Source

pub fn send_packet(&mut self, packet: &Packet) -> Result<()>

Examples found in repository?
examples/transcode_file.rs (line 47)
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9    let mut args = env::args().skip(1);
10    let input_path = args
11        .next()
12        .map(PathBuf::from)
13        .ok_or("usage: transcode_file <input> <output> [max_frames] [encoder]")?;
14    let output_path = args
15        .next()
16        .map(PathBuf::from)
17        .ok_or("missing output path")?;
18    let max_frames = args.next().and_then(|value| value.parse::<usize>().ok());
19    let encoder_name = args.next();
20
21    let started = Instant::now();
22    let mut input = InputContext::open(input_path.to_string_lossy().to_string())?;
23    let stream = input.best_video_stream()?;
24    let mut decoder = VideoDecoder::open(
25        &input,
26        VideoDecoderConfig {
27            stream_index: stream.stream_index,
28            mode: DecodeMode::Cpu,
29        },
30    )?;
31    let fps = stream
32        .avg_frame_rate
33        .as_f64()
34        .filter(|fps| *fps > 0.0)
35        .unwrap_or(60.0)
36        .round()
37        .clamp(1.0, u32::MAX as f64) as u32;
38    let mut config =
39        VideoEncoderConfig::cpu_rgba(stream.width, stream.height, fps, VideoCodec::H264);
40    if let Some(encoder_name) = encoder_name {
41        config.encoder_name = Some(encoder_name);
42    }
43    let mut encoder = MuxedEncoder::create(output_path.to_string_lossy().to_string(), config)?;
44
45    let mut frames = 0_usize;
46    'decode: while let Some(packet) = input.read_packet()? {
47        decoder.send_packet(&packet)?;
48        while let Some(frame) = decoder.receive_cpu_frame()? {
49            encoder.write_video_frame(&frame)?;
50            frames = frames.saturating_add(1);
51            if max_frames.is_some_and(|limit| frames >= limit) {
52                break 'decode;
53            }
54        }
55    }
56
57    if max_frames.is_none_or(|limit| frames < limit) {
58        decoder.send_eof()?;
59        while let Some(frame) = decoder.receive_cpu_frame()? {
60            encoder.write_video_frame(&frame)?;
61            frames = frames.saturating_add(1);
62            if max_frames.is_some_and(|limit| frames >= limit) {
63                break;
64            }
65        }
66    }
67
68    encoder.finish()?;
69    println!("input={}", input_path.display());
70    println!("output={}", output_path.display());
71    println!("frames={frames}");
72    println!("elapsed_ms={}", started.elapsed().as_millis());
73    println!(
74        "fps={:.2}",
75        frames as f64 / started.elapsed().as_secs_f64().max(1e-9)
76    );
77    Ok(())
78}
More examples
Hide additional examples
examples/decode_file.rs (line 58)
13fn main() -> Result<(), Box<dyn std::error::Error>> {
14    let mut args = env::args().skip(1);
15    let path = args.next().map(PathBuf::from).ok_or(
16        "usage: decode_file <path> [max_frames] [cpu|cuda|metal|vulkan] [gpu|rgba|cuda-rgba]",
17    )?;
18    let next = args.next();
19    let (max_frames, mode_arg) = match next {
20        Some(value) => match value.parse::<usize>() {
21            Ok(max_frames) => (Some(max_frames), args.next()),
22            Err(_) => (None, Some(value)),
23        },
24        None => (None, None),
25    };
26    let mode = match mode_arg.as_deref() {
27        Some("cuda") => DecodeMode::Gpu(GpuBackend::Cuda),
28        Some("metal") => DecodeMode::Gpu(GpuBackend::Metal),
29        Some("vulkan") => DecodeMode::Gpu(GpuBackend::Vulkan),
30        Some("cpu") | None => DecodeMode::Cpu,
31        Some(other) => return Err(format!("unknown decode mode `{other}`").into()),
32    };
33    let receive = match args.next().as_deref() {
34        Some("gpu") => ReceiveMode::Gpu,
35        Some("cuda-rgba") => ReceiveMode::CudaRgba,
36        Some("rgba") | None => ReceiveMode::Rgba,
37        Some(other) => return Err(format!("unknown receive mode `{other}`").into()),
38    };
39
40    let started = Instant::now();
41    let mut input = InputContext::open(path.to_string_lossy().to_string())?;
42    let stream = input.best_video_stream()?;
43    let open_elapsed = started.elapsed();
44    let mut decoder = VideoDecoder::open(
45        &input,
46        VideoDecoderConfig {
47            stream_index: stream.stream_index,
48            mode,
49        },
50    )?;
51
52    let decode_started = Instant::now();
53    let mut cuda = CudaRgbaState::new(receive, stream.width, stream.height)?;
54    let mut frames = 0_usize;
55    let mut bytes = 0_usize;
56
57    'decode: while let Some(packet) = input.read_packet()? {
58        decoder.send_packet(&packet)?;
59        while let Some(frame_bytes) = receive_frame(&mut decoder, mode, receive, cuda.as_mut())? {
60            frames = frames.saturating_add(1);
61            bytes = bytes.saturating_add(frame_bytes);
62            if max_frames.is_some_and(|limit| frames >= limit) {
63                break 'decode;
64            }
65        }
66    }
67
68    if max_frames.is_none_or(|limit| frames < limit) {
69        decoder.send_eof()?;
70        while let Some(frame_bytes) = receive_frame(&mut decoder, mode, receive, cuda.as_mut())? {
71            frames = frames.saturating_add(1);
72            bytes = bytes.saturating_add(frame_bytes);
73            if max_frames.is_some_and(|limit| frames >= limit) {
74                break;
75            }
76        }
77    }
78
79    let decode_elapsed = decode_started.elapsed();
80    let total_elapsed = started.elapsed();
81    let usage = usage();
82    println!("path={}", path.display());
83    println!("codec={:?}", stream.codec);
84    println!("dimensions={}x{}", stream.width, stream.height);
85    println!("frames={frames}");
86    println!("mode={mode:?}");
87    println!("receive={receive:?}");
88    println!("decoded_frame_bytes={bytes}");
89    println!("open_ms={}", millis(open_elapsed));
90    println!("decode_ms={}", millis(decode_elapsed));
91    println!("total_ms={}", millis(total_elapsed));
92    println!(
93        "fps={:.2}",
94        frames as f64 / decode_elapsed.as_secs_f64().max(1e-9)
95    );
96    println!("user_cpu_ms={}", millis(usage.user));
97    println!("system_cpu_ms={}", millis(usage.system));
98    println!("max_rss_platform_units={}", usage.max_rss);
99    Ok(())
100}
Source

pub fn send_eof(&mut self) -> Result<()>

Examples found in repository?
examples/transcode_file.rs (line 58)
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9    let mut args = env::args().skip(1);
10    let input_path = args
11        .next()
12        .map(PathBuf::from)
13        .ok_or("usage: transcode_file <input> <output> [max_frames] [encoder]")?;
14    let output_path = args
15        .next()
16        .map(PathBuf::from)
17        .ok_or("missing output path")?;
18    let max_frames = args.next().and_then(|value| value.parse::<usize>().ok());
19    let encoder_name = args.next();
20
21    let started = Instant::now();
22    let mut input = InputContext::open(input_path.to_string_lossy().to_string())?;
23    let stream = input.best_video_stream()?;
24    let mut decoder = VideoDecoder::open(
25        &input,
26        VideoDecoderConfig {
27            stream_index: stream.stream_index,
28            mode: DecodeMode::Cpu,
29        },
30    )?;
31    let fps = stream
32        .avg_frame_rate
33        .as_f64()
34        .filter(|fps| *fps > 0.0)
35        .unwrap_or(60.0)
36        .round()
37        .clamp(1.0, u32::MAX as f64) as u32;
38    let mut config =
39        VideoEncoderConfig::cpu_rgba(stream.width, stream.height, fps, VideoCodec::H264);
40    if let Some(encoder_name) = encoder_name {
41        config.encoder_name = Some(encoder_name);
42    }
43    let mut encoder = MuxedEncoder::create(output_path.to_string_lossy().to_string(), config)?;
44
45    let mut frames = 0_usize;
46    'decode: while let Some(packet) = input.read_packet()? {
47        decoder.send_packet(&packet)?;
48        while let Some(frame) = decoder.receive_cpu_frame()? {
49            encoder.write_video_frame(&frame)?;
50            frames = frames.saturating_add(1);
51            if max_frames.is_some_and(|limit| frames >= limit) {
52                break 'decode;
53            }
54        }
55    }
56
57    if max_frames.is_none_or(|limit| frames < limit) {
58        decoder.send_eof()?;
59        while let Some(frame) = decoder.receive_cpu_frame()? {
60            encoder.write_video_frame(&frame)?;
61            frames = frames.saturating_add(1);
62            if max_frames.is_some_and(|limit| frames >= limit) {
63                break;
64            }
65        }
66    }
67
68    encoder.finish()?;
69    println!("input={}", input_path.display());
70    println!("output={}", output_path.display());
71    println!("frames={frames}");
72    println!("elapsed_ms={}", started.elapsed().as_millis());
73    println!(
74        "fps={:.2}",
75        frames as f64 / started.elapsed().as_secs_f64().max(1e-9)
76    );
77    Ok(())
78}
More examples
Hide additional examples
examples/decode_file.rs (line 69)
13fn main() -> Result<(), Box<dyn std::error::Error>> {
14    let mut args = env::args().skip(1);
15    let path = args.next().map(PathBuf::from).ok_or(
16        "usage: decode_file <path> [max_frames] [cpu|cuda|metal|vulkan] [gpu|rgba|cuda-rgba]",
17    )?;
18    let next = args.next();
19    let (max_frames, mode_arg) = match next {
20        Some(value) => match value.parse::<usize>() {
21            Ok(max_frames) => (Some(max_frames), args.next()),
22            Err(_) => (None, Some(value)),
23        },
24        None => (None, None),
25    };
26    let mode = match mode_arg.as_deref() {
27        Some("cuda") => DecodeMode::Gpu(GpuBackend::Cuda),
28        Some("metal") => DecodeMode::Gpu(GpuBackend::Metal),
29        Some("vulkan") => DecodeMode::Gpu(GpuBackend::Vulkan),
30        Some("cpu") | None => DecodeMode::Cpu,
31        Some(other) => return Err(format!("unknown decode mode `{other}`").into()),
32    };
33    let receive = match args.next().as_deref() {
34        Some("gpu") => ReceiveMode::Gpu,
35        Some("cuda-rgba") => ReceiveMode::CudaRgba,
36        Some("rgba") | None => ReceiveMode::Rgba,
37        Some(other) => return Err(format!("unknown receive mode `{other}`").into()),
38    };
39
40    let started = Instant::now();
41    let mut input = InputContext::open(path.to_string_lossy().to_string())?;
42    let stream = input.best_video_stream()?;
43    let open_elapsed = started.elapsed();
44    let mut decoder = VideoDecoder::open(
45        &input,
46        VideoDecoderConfig {
47            stream_index: stream.stream_index,
48            mode,
49        },
50    )?;
51
52    let decode_started = Instant::now();
53    let mut cuda = CudaRgbaState::new(receive, stream.width, stream.height)?;
54    let mut frames = 0_usize;
55    let mut bytes = 0_usize;
56
57    'decode: while let Some(packet) = input.read_packet()? {
58        decoder.send_packet(&packet)?;
59        while let Some(frame_bytes) = receive_frame(&mut decoder, mode, receive, cuda.as_mut())? {
60            frames = frames.saturating_add(1);
61            bytes = bytes.saturating_add(frame_bytes);
62            if max_frames.is_some_and(|limit| frames >= limit) {
63                break 'decode;
64            }
65        }
66    }
67
68    if max_frames.is_none_or(|limit| frames < limit) {
69        decoder.send_eof()?;
70        while let Some(frame_bytes) = receive_frame(&mut decoder, mode, receive, cuda.as_mut())? {
71            frames = frames.saturating_add(1);
72            bytes = bytes.saturating_add(frame_bytes);
73            if max_frames.is_some_and(|limit| frames >= limit) {
74                break;
75            }
76        }
77    }
78
79    let decode_elapsed = decode_started.elapsed();
80    let total_elapsed = started.elapsed();
81    let usage = usage();
82    println!("path={}", path.display());
83    println!("codec={:?}", stream.codec);
84    println!("dimensions={}x{}", stream.width, stream.height);
85    println!("frames={frames}");
86    println!("mode={mode:?}");
87    println!("receive={receive:?}");
88    println!("decoded_frame_bytes={bytes}");
89    println!("open_ms={}", millis(open_elapsed));
90    println!("decode_ms={}", millis(decode_elapsed));
91    println!("total_ms={}", millis(total_elapsed));
92    println!(
93        "fps={:.2}",
94        frames as f64 / decode_elapsed.as_secs_f64().max(1e-9)
95    );
96    println!("user_cpu_ms={}", millis(usage.user));
97    println!("system_cpu_ms={}", millis(usage.system));
98    println!("max_rss_platform_units={}", usage.max_rss);
99    Ok(())
100}
Source

pub fn flush(&mut self)

Source

pub fn receive_cpu_frame(&mut self) -> Result<Option<CpuVideoFrame>>

Examples found in repository?
examples/decode_file.rs (line 124)
102fn receive_frame(
103    decoder: &mut VideoDecoder,
104    mode: DecodeMode,
105    receive: ReceiveMode,
106    cuda: Option<&mut CudaRgbaState>,
107) -> lumen_ffmpeg::Result<Option<usize>> {
108    match receive {
109        ReceiveMode::Rgba => Ok(decoder.receive_rgba_frame()?.map(|frame| frame.data.len())),
110        ReceiveMode::CudaRgba => match decoder.receive_gpu_frame()? {
111            Some(frame) => {
112                let Some(cuda) = cuda else {
113                    return Err(lumen_ffmpeg::FfmpegError::new(
114                        "decode_file",
115                        "cuda-rgba receive mode requires a CUDA conversion state",
116                    ));
117                };
118                cuda.convert(&frame)?;
119                Ok(Some(frame.estimated_rgba_bytes() as usize))
120            }
121            None => Ok(None),
122        },
123        ReceiveMode::Gpu => match mode {
124            DecodeMode::Cpu => Ok(decoder.receive_cpu_frame()?.map(|frame| frame.data.len())),
125            DecodeMode::Gpu(_) => Ok(decoder.receive_gpu_frame()?.map(|_| 0)),
126        },
127    }
128}
More examples
Hide additional examples
examples/transcode_file.rs (line 48)
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9    let mut args = env::args().skip(1);
10    let input_path = args
11        .next()
12        .map(PathBuf::from)
13        .ok_or("usage: transcode_file <input> <output> [max_frames] [encoder]")?;
14    let output_path = args
15        .next()
16        .map(PathBuf::from)
17        .ok_or("missing output path")?;
18    let max_frames = args.next().and_then(|value| value.parse::<usize>().ok());
19    let encoder_name = args.next();
20
21    let started = Instant::now();
22    let mut input = InputContext::open(input_path.to_string_lossy().to_string())?;
23    let stream = input.best_video_stream()?;
24    let mut decoder = VideoDecoder::open(
25        &input,
26        VideoDecoderConfig {
27            stream_index: stream.stream_index,
28            mode: DecodeMode::Cpu,
29        },
30    )?;
31    let fps = stream
32        .avg_frame_rate
33        .as_f64()
34        .filter(|fps| *fps > 0.0)
35        .unwrap_or(60.0)
36        .round()
37        .clamp(1.0, u32::MAX as f64) as u32;
38    let mut config =
39        VideoEncoderConfig::cpu_rgba(stream.width, stream.height, fps, VideoCodec::H264);
40    if let Some(encoder_name) = encoder_name {
41        config.encoder_name = Some(encoder_name);
42    }
43    let mut encoder = MuxedEncoder::create(output_path.to_string_lossy().to_string(), config)?;
44
45    let mut frames = 0_usize;
46    'decode: while let Some(packet) = input.read_packet()? {
47        decoder.send_packet(&packet)?;
48        while let Some(frame) = decoder.receive_cpu_frame()? {
49            encoder.write_video_frame(&frame)?;
50            frames = frames.saturating_add(1);
51            if max_frames.is_some_and(|limit| frames >= limit) {
52                break 'decode;
53            }
54        }
55    }
56
57    if max_frames.is_none_or(|limit| frames < limit) {
58        decoder.send_eof()?;
59        while let Some(frame) = decoder.receive_cpu_frame()? {
60            encoder.write_video_frame(&frame)?;
61            frames = frames.saturating_add(1);
62            if max_frames.is_some_and(|limit| frames >= limit) {
63                break;
64            }
65        }
66    }
67
68    encoder.finish()?;
69    println!("input={}", input_path.display());
70    println!("output={}", output_path.display());
71    println!("frames={frames}");
72    println!("elapsed_ms={}", started.elapsed().as_millis());
73    println!(
74        "fps={:.2}",
75        frames as f64 / started.elapsed().as_secs_f64().max(1e-9)
76    );
77    Ok(())
78}
Source

pub fn receive_rgba_frame(&mut self) -> Result<Option<CpuVideoFrame>>

Receives the next decoded frame as RGBA8.

CPU decoders convert their native software frame with swscale. Hardware decoders first transfer the decoded frame into software memory, then use the same RGBA8 conversion path. This keeps callers independent from FFmpeg’s platform-specific GPU frame handles while still allowing decode itself to use VideoToolbox/NVDEC/Vulkan when available.

Examples found in repository?
examples/decode_file.rs (line 109)
102fn receive_frame(
103    decoder: &mut VideoDecoder,
104    mode: DecodeMode,
105    receive: ReceiveMode,
106    cuda: Option<&mut CudaRgbaState>,
107) -> lumen_ffmpeg::Result<Option<usize>> {
108    match receive {
109        ReceiveMode::Rgba => Ok(decoder.receive_rgba_frame()?.map(|frame| frame.data.len())),
110        ReceiveMode::CudaRgba => match decoder.receive_gpu_frame()? {
111            Some(frame) => {
112                let Some(cuda) = cuda else {
113                    return Err(lumen_ffmpeg::FfmpegError::new(
114                        "decode_file",
115                        "cuda-rgba receive mode requires a CUDA conversion state",
116                    ));
117                };
118                cuda.convert(&frame)?;
119                Ok(Some(frame.estimated_rgba_bytes() as usize))
120            }
121            None => Ok(None),
122        },
123        ReceiveMode::Gpu => match mode {
124            DecodeMode::Cpu => Ok(decoder.receive_cpu_frame()?.map(|frame| frame.data.len())),
125            DecodeMode::Gpu(_) => Ok(decoder.receive_gpu_frame()?.map(|_| 0)),
126        },
127    }
128}
Source

pub fn receive_gpu_frame(&mut self) -> Result<Option<GpuVideoFrame>>

Examples found in repository?
examples/decode_file.rs (line 110)
102fn receive_frame(
103    decoder: &mut VideoDecoder,
104    mode: DecodeMode,
105    receive: ReceiveMode,
106    cuda: Option<&mut CudaRgbaState>,
107) -> lumen_ffmpeg::Result<Option<usize>> {
108    match receive {
109        ReceiveMode::Rgba => Ok(decoder.receive_rgba_frame()?.map(|frame| frame.data.len())),
110        ReceiveMode::CudaRgba => match decoder.receive_gpu_frame()? {
111            Some(frame) => {
112                let Some(cuda) = cuda else {
113                    return Err(lumen_ffmpeg::FfmpegError::new(
114                        "decode_file",
115                        "cuda-rgba receive mode requires a CUDA conversion state",
116                    ));
117                };
118                cuda.convert(&frame)?;
119                Ok(Some(frame.estimated_rgba_bytes() as usize))
120            }
121            None => Ok(None),
122        },
123        ReceiveMode::Gpu => match mode {
124            DecodeMode::Cpu => Ok(decoder.receive_cpu_frame()?.map(|frame| frame.data.len())),
125            DecodeMode::Gpu(_) => Ok(decoder.receive_gpu_frame()?.map(|_| 0)),
126        },
127    }
128}

Trait Implementations§

Source§

impl Drop for VideoDecoder

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Send for VideoDecoder

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.