Skip to content

Commit 4b81f55

Browse files
committed
implemented automatic color conversion
1 parent 0ba1769 commit 4b81f55

File tree

5 files changed

+67
-14
lines changed

5 files changed

+67
-14
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ repository = "https://github.com/insight-platform/FFmpeg-Input"
77
readme = "README.md"
88
keywords = ["FFmpeg", "Video"]
99
categories = ["computer-vision"]
10-
version = "0.1.22"
10+
version = "0.1.23"
1111
edition = "2021"
1212
license="Apache-2.0"
1313
rust-version = "1.62"

src/lib.rs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
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+
17
use crossbeam::channel::{Receiver, Sender};
28
use ffmpeg::util::frame::video::Video;
39
use ffmpeg_next as ffmpeg;
@@ -10,13 +16,8 @@ use parking_lot::Mutex;
1016
use pyo3::exceptions::PyBrokenPipeError;
1117
use pyo3::prelude::*;
1218
use 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;
2021
const DECODED_PIX_BYTES: u32 = 3;
2122

2223
fn 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]
365375
impl 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 {

test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
if __name__ == '__main__':
44
s = FFMpegSource("/home/ivan/road-traffic-processed.mp4", params={"fflags": "+genpts"},
5-
queue_len=100, decode=True,
5+
queue_len=100, decode=False,
66
ffmpeg_log_level=FFmpegLogLevel.Debug)
77
s.log_level = FFmpegLogLevel.Trace
88
while True:

test_autoconvert.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from ffmpeg_input import FFMpegSource, FFmpegLogLevel
2+
import numpy as np
3+
import cv2
4+
import time
5+
6+
if __name__ == '__main__':
7+
s = FFMpegSource("/dev/video0",
8+
params={"video_size": "1920x1080", "c:v": "v4l2m2m", "input_format": "yuyv422"},
9+
queue_len=100,
10+
autoconvert_raw_formats_to_rgb24=True,
11+
ffmpeg_log_level=FFmpegLogLevel.Info)
12+
s.log_level = FFmpegLogLevel.Panic
13+
while True:
14+
try:
15+
p = s.video_frame()
16+
res = p.payload_as_bytes()
17+
# 1944 2592
18+
#print(p.frame_height, p.frame_width)
19+
#res = np.frombuffer(res, dtype=np.uint8)
20+
#res = np.reshape(res, (p.frame_height, p.frame_width, 3))
21+
end = time.time()
22+
print(p.codec, p.pixel_format, p.queue_len, "all_time={}".format(int(end * 1000 - p.frame_received_ts)),
23+
"python_time={}".format(int(end * 1000 - p.frame_processed_ts)))
24+
# cv2.imshow('Image', res)
25+
#if cv2.waitKey(1) & 0xFF == ord('q'):
26+
# break
27+
except BrokenPipeError:
28+
print("EOS")
29+
break

test_decode.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
s = FFMpegSource("/dev/video0",
88
params={"video_size": "1920x1080", "c:v": "v4l2m2m", "input_format": "mjpeg"},
99
queue_len=100,
10-
decode=False,
10+
decode=True,
1111
ffmpeg_log_level=FFmpegLogLevel.Info)
1212
s.log_level = FFmpegLogLevel.Panic
1313
while True:

0 commit comments

Comments
 (0)