@@ -31,7 +31,7 @@ defmodule ExWebRTC.Media.IVFHeader do
3131 width: non_neg_integer ( ) ,
3232 height: non_neg_integer ( ) ,
3333 timebase_denum: non_neg_integer ( ) ,
34- timebase_num: non_neg_integer ( ) ,
34+ timebase_num: pos_integer ( ) ,
3535 num_frames: non_neg_integer ( ) ,
3636 unused: non_neg_integer ( )
3737 }
7373
7474defmodule ExWebRTC.Media.IVFReader do
7575 @ moduledoc """
76- Defines IVF reader .
76+ Reads video frames from an IVF file .
7777
7878 Based on:
7979 * https://formats.kaitai.io/vp8_ivf/
@@ -84,37 +84,34 @@ defmodule ExWebRTC.Media.IVFReader do
8484
8585 @ opaque t ( ) :: File . io_device ( )
8686
87- @ spec open ( Path . t ( ) ) :: { :ok , t ( ) } | { :error , File . posix ( ) }
88- def open ( path ) , do: File . open ( path )
89-
90- @ spec read_header ( t ( ) ) :: { :ok , IVFHeader . t ( ) } | { :error , :invalid_file } | :eof
91- def read_header ( reader ) do
92- case IO . binread ( reader , 32 ) do
93- << "DKIF" , 0 :: little - integer - size ( 16 ) , 32 :: little - integer - size ( 16 ) ,
94- fourcc :: little - integer - size ( 32 ) , width :: little - integer - size ( 16 ) ,
95- height :: little - integer - size ( 16 ) , timebase_denum :: little - integer - size ( 32 ) ,
96- timebase_num :: little - integer - size ( 32 ) , num_frames :: little - integer - size ( 32 ) ,
97- unused :: little - integer - size ( 32 ) >> ->
98- { :ok ,
99- % IVFHeader {
100- signature: "DKIF" ,
101- version: 0 ,
102- header_size: 32 ,
103- fourcc: fourcc ,
104- width: width ,
105- height: height ,
106- timebase_denum: timebase_denum ,
107- timebase_num: timebase_num ,
108- num_frames: num_frames ,
109- unused: unused
110- } }
111-
112- _other ->
113- { :error , :invalid_file }
87+ @ spec open ( Path . t ( ) ) :: { :ok , IVFHeader . t ( ) , t ( ) } | { :error , term ( ) }
88+ def open ( path ) do
89+ with { :ok , file } <- File . open ( path ) ,
90+ << "DKIF" , 0 :: little - 16 , 32 :: little - 16 , fourcc :: little - 32 , width :: little - 16 ,
91+ height :: little - 16 , timebase_denum :: little - 32 , timebase_num :: little - 32 ,
92+ num_frames :: little - 32 , unused :: little - 32 >> <- IO . binread ( file , 32 ) do
93+ header = % IVFHeader {
94+ signature: "DKIF" ,
95+ version: 0 ,
96+ header_size: 32 ,
97+ fourcc: fourcc ,
98+ width: width ,
99+ height: height ,
100+ timebase_denum: timebase_denum ,
101+ timebase_num: timebase_num ,
102+ num_frames: num_frames ,
103+ unused: unused
104+ }
105+
106+ { :ok , header , file }
107+ else
108+ { :error , _reason } = error -> error
109+ # eof or invalid pattern matching
110+ _other -> { :error , :invalid_file }
114111 end
115112 end
116113
117- @ spec next_frame ( t ( ) ) :: { :ok , IVFFrame . t ( ) } | { :error , :invalid_file } | :eof
114+ @ spec next_frame ( t ( ) ) :: { :ok , IVFFrame . t ( ) } | { :error , term ( ) } | :eof
118115 def next_frame ( reader ) do
119116 with << len_frame :: little - integer - size ( 32 ) , timestamp :: little - integer - size ( 64 ) >> <-
120117 IO . binread ( reader , 12 ) ,
@@ -123,6 +120,7 @@ defmodule ExWebRTC.Media.IVFReader do
123120 { :ok , % IVFFrame { timestamp: timestamp , data: data } }
124121 else
125122 :eof -> :eof
123+ { :error , _reason } = error -> error
126124 _other -> { :error , :invalid_file }
127125 end
128126 end
0 commit comments