1
1
//! Port from Original code: https://github.com/leandromoreira/ffmpeg-libav-tutorial/blob/master/0_hello_world.c
2
2
//! Since this is a ported code, many warnings will emits.
3
3
#![ 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
+ } ;
5
8
6
- use libc:: c_int;
7
9
use std:: {
8
10
ffi:: { CStr , CString } ,
9
11
fs:: File ,
@@ -13,46 +15,12 @@ use std::{
13
15
slice,
14
16
} ;
15
17
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
-
50
18
fn main ( ) {
51
19
let filepath: CString = CString :: new ( "./examples/slice/bear.mp4" ) . unwrap ( ) ;
52
20
53
21
println ! ( "initializing all the containers, codecs and protocols." ) ;
54
22
55
- let pFormatContext = unsafe { avformat_alloc_context ( ) . as_mut ( ) }
23
+ let pFormatContext = unsafe { ffi :: avformat_alloc_context ( ) . as_mut ( ) }
56
24
. expect ( "ERROR could not allocate memory for Format Context" ) ;
57
25
58
26
println ! (
@@ -61,7 +29,7 @@ fn main() {
61
29
) ;
62
30
63
31
let result = unsafe {
64
- avformat_open_input (
32
+ ffi :: avformat_open_input (
65
33
& mut ( pFormatContext as * mut _ ) ,
66
34
filepath. as_ptr ( ) ,
67
35
null_mut ( ) ,
@@ -83,18 +51,18 @@ fn main() {
83
51
84
52
println ! ( "finding stream info from format" ) ;
85
53
86
- let result = unsafe { avformat_find_stream_info ( pFormatContext, null_mut ( ) ) } ;
54
+ let result = unsafe { ffi :: avformat_find_stream_info ( pFormatContext, null_mut ( ) ) } ;
87
55
if result < 0 {
88
56
panic ! ( "ERROR could not get the stream info" ) ;
89
57
}
90
58
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 ( ) ;
93
61
let mut video_stream_index = None ;
94
62
95
63
for i in 0 ..pFormatContext. nb_streams as i32 {
96
64
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 ]
98
66
. as_ref ( )
99
67
}
100
68
. unwrap ( ) ;
@@ -111,10 +79,11 @@ fn main() {
111
79
println ! ( "AVStream->duration {}" , stream. duration) ;
112
80
println ! ( "finding the proper decoder (CODEC)" ) ;
113
81
114
- let pLocalCodec = unsafe { avcodec_find_decoder ( pLocalCodecParameters. codec_id ) . as_ref ( ) }
115
- . expect ( "ERROR unsupported codec!" ) ;
82
+ let pLocalCodec =
83
+ unsafe { ffi:: avcodec_find_decoder ( pLocalCodecParameters. codec_id ) . as_ref ( ) }
84
+ . expect ( "ERROR unsupported codec!" ) ;
116
85
117
- if pLocalCodecParameters. codec_type == AVMediaType_AVMEDIA_TYPE_VIDEO {
86
+ if pLocalCodecParameters. codec_type == ffi :: AVMediaType_AVMEDIA_TYPE_VIDEO {
118
87
if video_stream_index. is_none ( ) {
119
88
video_stream_index = Some ( i) ;
120
89
pCodec = pLocalCodec;
@@ -125,7 +94,7 @@ fn main() {
125
94
"Video Codec: resolution {} x {}" ,
126
95
pLocalCodecParameters. width, pLocalCodecParameters. height
127
96
) ;
128
- } else if pLocalCodecParameters. codec_type == AVMediaType_AVMEDIA_TYPE_AUDIO {
97
+ } else if pLocalCodecParameters. codec_type == ffi :: AVMediaType_AVMEDIA_TYPE_AUDIO {
129
98
println ! (
130
99
"Audio Codec: {} channels, sample rate {}" ,
131
100
pLocalCodecParameters. channels, pLocalCodecParameters. sample_rate
@@ -141,27 +110,27 @@ fn main() {
141
110
codec_name, pLocalCodec. id, pLocalCodecParameters. bit_rate
142
111
) ;
143
112
}
144
- let pCodecContext = unsafe { avcodec_alloc_context3 ( pCodec) . as_mut ( ) }
113
+ let pCodecContext = unsafe { ffi :: avcodec_alloc_context3 ( pCodec) . as_mut ( ) }
145
114
. expect ( "failed to allocated memory for AVCodecContext" ) ;
146
115
147
- let result = unsafe { avcodec_parameters_to_context ( pCodecContext, pCodecParameters) } ;
116
+ let result = unsafe { ffi :: avcodec_parameters_to_context ( pCodecContext, pCodecParameters) } ;
148
117
if result < 0 {
149
118
panic ! ( "failed to copy codec params to codec context" ) ;
150
119
}
151
120
152
- let result = unsafe { avcodec_open2 ( pCodecContext, pCodec, null_mut ( ) ) } ;
121
+ let result = unsafe { ffi :: avcodec_open2 ( pCodecContext, pCodec, null_mut ( ) ) } ;
153
122
if result < 0 {
154
123
panic ! ( "failed to open codec through avcodec_open2" ) ;
155
124
}
156
125
157
126
let pFrame =
158
- unsafe { av_frame_alloc ( ) . as_mut ( ) } . expect ( "failed to allocated memory for AVFrame" ) ;
159
- let pPacket =
160
- unsafe { av_packet_alloc ( ) . as_mut ( ) } . expect ( "failed to allocated memory for AVPacket" ) ;
127
+ unsafe { ffi :: av_frame_alloc ( ) . as_mut ( ) } . expect ( "failed to allocated memory for AVFrame" ) ;
128
+ let pPacket = unsafe { ffi :: av_packet_alloc ( ) . as_mut ( ) }
129
+ . expect ( "failed to allocated memory for AVPacket" ) ;
161
130
162
131
let mut how_many_packets_to_process = 8 ;
163
132
164
- while unsafe { av_read_frame ( pFormatContext, pPacket) } >= 0 {
133
+ while unsafe { ffi :: av_read_frame ( pFormatContext, pPacket) } >= 0 {
165
134
if Some ( pPacket. stream_index ) == video_stream_index {
166
135
println ! ( "AVPacket->pts {}" , pPacket. pts) ;
167
136
if let Err ( s) = decode_packet ( pPacket, pCodecContext, pFrame) {
@@ -172,33 +141,33 @@ fn main() {
172
141
break ;
173
142
}
174
143
}
175
- unsafe { av_packet_unref ( pPacket) } ;
144
+ unsafe { ffi :: av_packet_unref ( pPacket) } ;
176
145
}
177
146
178
147
println ! ( "releasing all the resources" ) ;
179
148
180
149
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 _ ) ) ;
150
+ ffi :: avformat_close_input ( & mut ( pFormatContext as * mut _ ) ) ;
151
+ ffi :: av_packet_free ( & mut ( pPacket as * mut _ ) ) ;
152
+ ffi :: av_frame_free ( & mut ( pFrame as * mut _ ) ) ;
153
+ ffi :: avcodec_free_context ( & mut ( pCodecContext as * mut _ ) ) ;
185
154
}
186
155
}
187
156
188
157
fn decode_packet (
189
- pPacket : & AVPacket ,
190
- pCodecContext : & mut AVCodecContext ,
191
- pFrame : & mut AVFrame ,
158
+ pPacket : & ffi :: AVPacket ,
159
+ pCodecContext : & mut ffi :: AVCodecContext ,
160
+ pFrame : & mut ffi :: AVFrame ,
192
161
) -> Result < ( ) , String > {
193
- let response = unsafe { avcodec_send_packet ( pCodecContext, pPacket) } ;
162
+ let response = unsafe { ffi :: avcodec_send_packet ( pCodecContext, pPacket) } ;
194
163
195
164
if response < 0 {
196
165
return Err ( String :: from ( "Error while sending a packet to the decoder." ) ) ;
197
166
}
198
167
199
168
while response >= 0 {
200
- let response = unsafe { avcodec_receive_frame ( pCodecContext, pFrame) } ;
201
- if response == AVERROR ( EAGAIN as i32 ) || response == AVERROR_EOF {
169
+ let response = unsafe { ffi :: avcodec_receive_frame ( pCodecContext, pFrame) } ;
170
+ if response == AVERROR ( ffi :: EAGAIN as i32 ) || response == AVERROR_EOF {
202
171
break ;
203
172
} else if response < 0 {
204
173
return Err ( String :: from (
@@ -210,7 +179,7 @@ fn decode_packet(
210
179
println ! (
211
180
"Frame {} (type={}, size={} bytes) pts {} key_frame {} [DTS {}]" ,
212
181
pCodecContext. frame_number,
213
- unsafe { av_get_picture_type_char( pFrame. pict_type) } ,
182
+ unsafe { ffi :: av_get_picture_type_char( pFrame. pict_type) } ,
214
183
pFrame. pkt_size,
215
184
pFrame. pts,
216
185
pFrame. key_frame,
0 commit comments