Skip to content

Commit e6a5a6e

Browse files
committed
Patch some of the FFmpeg specific error process macros
1 parent 624db4b commit e6a5a6e

File tree

7 files changed

+99
-66
lines changed

7 files changed

+99
-66
lines changed

Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,10 @@ doctest = false
2929

3030
[dependencies]
3131
once_cell = "1.4.0"
32+
libc = "0.2.71"
3233

3334
[build-dependencies]
3435
bindgen = "0.54.0"
3536
once_cell = "1.4.0"
3637
pkg-config = "0.3.17"
3738
num_cpus = "1.13.0"
38-
39-
[dev-dependencies]
40-
libc = "0.2.71"

examples/slice/main.rs

Lines changed: 31 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
//! Port from Original code: https://github.com/leandromoreira/ffmpeg-libav-tutorial/blob/master/0_hello_world.c
22
//! Since this is a ported code, many warnings will emits.
33
#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
4-
use rusty_ffmpeg::ffi::*;
4+
use rusty_ffmpeg::{
5+
avutil::error::{AVERROR, AVERROR_EOF},
6+
ffi
7+
};
58

6-
use libc::c_int;
79
use std::{
810
ffi::{CStr, CString},
911
fs::File,
@@ -13,46 +15,12 @@ use std::{
1315
slice,
1416
};
1517

16-
#[inline(always)]
17-
pub fn AVERROR(e: c_int) -> c_int {
18-
-e
19-
}
20-
21-
#[macro_export]
22-
macro_rules! MKTAG {
23-
($a:expr, $b:expr, $c:expr, $d:expr) => {
24-
($a as isize) | (($b as isize) << 8) | (($c as isize) << 16) | (($d as isize) << 24)
25-
};
26-
}
27-
28-
macro_rules! FFERRTAG {
29-
($a:expr, $b:expr, $c:expr, $d:expr) => {
30-
-MKTAG!($a, $b, $c, $d) as c_int
31-
};
32-
}
33-
34-
pub const AVERROR_BSF_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'B', b'S', b'F');
35-
pub const AVERROR_BUG: c_int = FFERRTAG!(b'B', b'U', b'G', b'!');
36-
pub const AVERROR_BUFFER_TOO_SMALL: c_int = FFERRTAG!(b'B', b'U', b'F', b'S');
37-
pub const AVERROR_DECODER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'D', b'E', b'C');
38-
pub const AVERROR_DEMUXER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'D', b'E', b'M');
39-
pub const AVERROR_ENCODER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'E', b'N', b'C');
40-
pub const AVERROR_EOF: c_int = FFERRTAG!(b'E', b'O', b'F', b' ');
41-
pub const AVERROR_EXIT: c_int = FFERRTAG!(b'E', b'X', b'I', b'T');
42-
pub const AVERROR_EXTERNAL: c_int = FFERRTAG!(b'E', b'X', b'T', b' ');
43-
pub const AVERROR_FILTER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'F', b'I', b'L');
44-
pub const AVERROR_INVALIDDATA: c_int = FFERRTAG!(b'I', b'N', b'D', b'A');
45-
pub const AVERROR_MUXER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'M', b'U', b'X');
46-
pub const AVERROR_OPTION_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'O', b'P', b'T');
47-
pub const AVERROR_PATCHWELCOME: c_int = FFERRTAG!(b'P', b'A', b'W', b'E');
48-
pub const AVERROR_PROTOCOL_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'P', b'R', b'O');
49-
5018
fn main() {
5119
let filepath: CString = CString::new("./examples/slice/bear.mp4").unwrap();
5220

5321
println!("initializing all the containers, codecs and protocols.");
5422

55-
let pFormatContext = unsafe { avformat_alloc_context().as_mut() }
23+
let pFormatContext = unsafe { ffi::avformat_alloc_context().as_mut() }
5624
.expect("ERROR could not allocate memory for Format Context");
5725

5826
println!(
@@ -61,7 +29,7 @@ fn main() {
6129
);
6230

6331
let result = unsafe {
64-
avformat_open_input(
32+
ffi::avformat_open_input(
6533
&mut (pFormatContext as *mut _),
6634
filepath.as_ptr(),
6735
null_mut(),
@@ -83,18 +51,18 @@ fn main() {
8351

8452
println!("finding stream info from format");
8553

86-
let result = unsafe { avformat_find_stream_info(pFormatContext, null_mut()) };
54+
let result = unsafe { ffi::avformat_find_stream_info(pFormatContext, null_mut()) };
8755
if result < 0 {
8856
panic!("ERROR could not get the stream info");
8957
}
9058

91-
let mut pCodec: *const AVCodec = null_mut();
92-
let mut pCodecParameters: *const AVCodecParameters = null_mut();
59+
let mut pCodec: *const ffi::AVCodec = null_mut();
60+
let mut pCodecParameters: *const ffi::AVCodecParameters = null_mut();
9361
let mut video_stream_index = None;
9462

9563
for i in 0..pFormatContext.nb_streams as i32 {
9664
let stream = unsafe {
97-
slice::from_raw_parts(pFormatContext.streams, size_of::<AVStream>())[i as usize]
65+
slice::from_raw_parts(pFormatContext.streams, size_of::<ffi::AVStream>())[i as usize]
9866
.as_ref()
9967
}
10068
.unwrap();
@@ -111,10 +79,10 @@ fn main() {
11179
println!("AVStream->duration {}", stream.duration);
11280
println!("finding the proper decoder (CODEC)");
11381

114-
let pLocalCodec = unsafe { avcodec_find_decoder(pLocalCodecParameters.codec_id).as_ref() }
82+
let pLocalCodec = unsafe { ffi::avcodec_find_decoder(pLocalCodecParameters.codec_id).as_ref() }
11583
.expect("ERROR unsupported codec!");
11684

117-
if pLocalCodecParameters.codec_type == AVMediaType_AVMEDIA_TYPE_VIDEO {
85+
if pLocalCodecParameters.codec_type == ffi::AVMediaType_AVMEDIA_TYPE_VIDEO {
11886
if video_stream_index.is_none() {
11987
video_stream_index = Some(i);
12088
pCodec = pLocalCodec;
@@ -125,7 +93,7 @@ fn main() {
12593
"Video Codec: resolution {} x {}",
12694
pLocalCodecParameters.width, pLocalCodecParameters.height
12795
);
128-
} else if pLocalCodecParameters.codec_type == AVMediaType_AVMEDIA_TYPE_AUDIO {
96+
} else if pLocalCodecParameters.codec_type == ffi::AVMediaType_AVMEDIA_TYPE_AUDIO {
12997
println!(
13098
"Audio Codec: {} channels, sample rate {}",
13199
pLocalCodecParameters.channels, pLocalCodecParameters.sample_rate
@@ -141,27 +109,27 @@ fn main() {
141109
codec_name, pLocalCodec.id, pLocalCodecParameters.bit_rate
142110
);
143111
}
144-
let pCodecContext = unsafe { avcodec_alloc_context3(pCodec).as_mut() }
112+
let pCodecContext = unsafe { ffi::avcodec_alloc_context3(pCodec).as_mut() }
145113
.expect("failed to allocated memory for AVCodecContext");
146114

147-
let result = unsafe { avcodec_parameters_to_context(pCodecContext, pCodecParameters) };
115+
let result = unsafe { ffi::avcodec_parameters_to_context(pCodecContext, pCodecParameters) };
148116
if result < 0 {
149117
panic!("failed to copy codec params to codec context");
150118
}
151119

152-
let result = unsafe { avcodec_open2(pCodecContext, pCodec, null_mut()) };
120+
let result = unsafe { ffi::avcodec_open2(pCodecContext, pCodec, null_mut()) };
153121
if result < 0 {
154122
panic!("failed to open codec through avcodec_open2");
155123
}
156124

157125
let pFrame =
158-
unsafe { av_frame_alloc().as_mut() }.expect("failed to allocated memory for AVFrame");
126+
unsafe { ffi::av_frame_alloc().as_mut() }.expect("failed to allocated memory for AVFrame");
159127
let pPacket =
160-
unsafe { av_packet_alloc().as_mut() }.expect("failed to allocated memory for AVPacket");
128+
unsafe { ffi::av_packet_alloc().as_mut() }.expect("failed to allocated memory for AVPacket");
161129

162130
let mut how_many_packets_to_process = 8;
163131

164-
while unsafe { av_read_frame(pFormatContext, pPacket) } >= 0 {
132+
while unsafe { ffi::av_read_frame(pFormatContext, pPacket) } >= 0 {
165133
if Some(pPacket.stream_index) == video_stream_index {
166134
println!("AVPacket->pts {}", pPacket.pts);
167135
if let Err(s) = decode_packet(pPacket, pCodecContext, pFrame) {
@@ -172,33 +140,33 @@ fn main() {
172140
break;
173141
}
174142
}
175-
unsafe { av_packet_unref(pPacket) };
143+
unsafe { ffi::av_packet_unref(pPacket) };
176144
}
177145

178146
println!("releasing all the resources");
179147

180148
unsafe {
181-
avformat_close_input(&mut (pFormatContext as *mut _));
182-
av_packet_free(&mut (pPacket as *mut _));
183-
av_frame_free(&mut (pFrame as *mut _));
184-
avcodec_free_context(&mut (pCodecContext as *mut _));
149+
ffi::avformat_close_input(&mut (pFormatContext as *mut _));
150+
ffi::av_packet_free(&mut (pPacket as *mut _));
151+
ffi::av_frame_free(&mut (pFrame as *mut _));
152+
ffi::avcodec_free_context(&mut (pCodecContext as *mut _));
185153
}
186154
}
187155

188156
fn decode_packet(
189-
pPacket: &AVPacket,
190-
pCodecContext: &mut AVCodecContext,
191-
pFrame: &mut AVFrame,
157+
pPacket: &ffi::AVPacket,
158+
pCodecContext: &mut ffi::AVCodecContext,
159+
pFrame: &mut ffi::AVFrame,
192160
) -> Result<(), String> {
193-
let response = unsafe { avcodec_send_packet(pCodecContext, pPacket) };
161+
let response = unsafe { ffi::avcodec_send_packet(pCodecContext, pPacket) };
194162

195163
if response < 0 {
196164
return Err(String::from("Error while sending a packet to the decoder."));
197165
}
198166

199167
while response >= 0 {
200-
let response = unsafe { avcodec_receive_frame(pCodecContext, pFrame) };
201-
if response == AVERROR(EAGAIN as i32) || response == AVERROR_EOF {
168+
let response = unsafe { ffi::avcodec_receive_frame(pCodecContext, pFrame) };
169+
if response == AVERROR(ffi::EAGAIN as i32) || response == AVERROR_EOF {
202170
break;
203171
} else if response < 0 {
204172
return Err(String::from(
@@ -210,7 +178,7 @@ fn decode_packet(
210178
println!(
211179
"Frame {} (type={}, size={} bytes) pts {} key_frame {} [DTS {}]",
212180
pCodecContext.frame_number,
213-
unsafe { av_get_picture_type_char(pFrame.pict_type) },
181+
unsafe { ffi::av_get_picture_type_char(pFrame.pict_type) },
214182
pFrame.pkt_size,
215183
pFrame.pts,
216184
pFrame.key_frame,

src/avutil/avutil.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub const AV_NOPTS_VALUE: i64 = 0x8000000000000000u64 as i64;

src/avutil/common.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[allow(non_snake_case)]
2+
pub const fn MKBETAG(a: u8, b: u8, c: u8, d: u8) -> u32 {
3+
(d as u32) | ((c as u32) << 8) | ((b as u32) << 16) | ((a as u32) << 24)
4+
}
5+
6+
#[allow(non_snake_case)]
7+
pub const fn MKTAG(a: u8, b: u8, c: u8, d: u8) -> u32 {
8+
(a as u32) | ((b as u32) << 8) | ((c as u32) << 16) | ((d as u32) << 24)
9+
}

src/avutil/error.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use libc::c_int;
2+
use super::common::MKTAG;
3+
4+
#[allow(non_snake_case)]
5+
pub const fn AVERROR(e: c_int) -> c_int {
6+
-e
7+
}
8+
9+
#[allow(non_snake_case)]
10+
pub const fn AVUNERROR(e: c_int) -> c_int {
11+
-e
12+
}
13+
14+
macro_rules! FFERRTAG {
15+
($a:expr, $b:expr, $c:expr, $d:expr) =>
16+
(-(MKTAG($a, $b, $c, $d) as c_int))
17+
}
18+
19+
pub const AVERROR_BSF_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'B', b'S', b'F');
20+
pub const AVERROR_BUG: c_int = FFERRTAG!(b'B', b'U', b'G', b'!');
21+
pub const AVERROR_BUFFER_TOO_SMALL: c_int = FFERRTAG!(b'B', b'U', b'F', b'S');
22+
pub const AVERROR_DECODER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'D', b'E', b'C');
23+
pub const AVERROR_DEMUXER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'D', b'E', b'M');
24+
pub const AVERROR_ENCODER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'E', b'N', b'C');
25+
pub const AVERROR_EOF: c_int = FFERRTAG!(b'E', b'O', b'F', b' ');
26+
pub const AVERROR_EXIT: c_int = FFERRTAG!(b'E', b'X', b'I', b'T');
27+
pub const AVERROR_EXTERNAL: c_int = FFERRTAG!(b'E', b'X', b'T', b' ');
28+
pub const AVERROR_FILTER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'F', b'I', b'L');
29+
pub const AVERROR_INVALIDDATA: c_int = FFERRTAG!(b'I', b'N', b'D', b'A');
30+
pub const AVERROR_MUXER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'M', b'U', b'X');
31+
pub const AVERROR_OPTION_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'O', b'P', b'T');
32+
pub const AVERROR_PATCHWELCOME: c_int = FFERRTAG!(b'P', b'A', b'W', b'E');
33+
pub const AVERROR_PROTOCOL_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'P', b'R', b'O');
34+
35+
pub const AVERROR_STREAM_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'S', b'T', b'R');
36+
37+
pub const AVERROR_BUG2: c_int = FFERRTAG!(b'B', b'U', b'G', b' ');
38+
pub const AVERROR_UNKNOWN: c_int = FFERRTAG!(b'U', b'N', b'K', b'N');
39+
pub const AVERROR_EXPERIMENTAL: c_int = -0x2bb2afa8; ///< Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it.
40+
pub const AVERROR_INPUT_CHANGED: c_int = -0x636e6701; ///< Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED)
41+
pub const AVERROR_OUTPUT_CHANGED: c_int = -0x636e6702; ///< Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED)
42+
43+
44+
pub const AVERROR_HTTP_BAD_REQUEST: c_int = FFERRTAG!(0xF8, b'4', b'0', b'0');
45+
pub const AVERROR_HTTP_UNAUTHORIZED: c_int = FFERRTAG!(0xF8, b'4', b'0', b'1');
46+
pub const AVERROR_HTTP_FORBIDDEN: c_int = FFERRTAG!(0xF8, b'4', b'0', b'3');
47+
pub const AVERROR_HTTP_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'4', b'0', b'4');
48+
pub const AVERROR_HTTP_OTHER_4XX: c_int = FFERRTAG!(0xF8, b'4', b'X', b'X');
49+
pub const AVERROR_HTTP_SERVER_ERROR: c_int = FFERRTAG!(0xF8, b'5', b'X', b'X');
50+
51+
pub const AV_ERROR_MAX_STRING_SIZE: c_int = 64;

src/avutil/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod common;
2+
pub mod error;
3+
pub mod avutil;

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@
88
pub mod ffi {
99
include!(concat!(env!("OUT_DIR"), "/binding.rs"));
1010
}
11+
12+
#[rustfmt::skip]
13+
pub mod avutil;

0 commit comments

Comments
 (0)