Codebase list ocaml-faad / f3cfaa3
New upstream version 0.5.1 Kyle Robbertze 1 year, 10 months ago
17 changed file(s) with 162 addition(s) and 178 deletion(s). Raw diff Collapse all Expand all
0 version=0.19.0
1 profile = conventional
2 break-separators = after
3 space-around-lists = false
4 doc-comments = before
5 match-indent = 2
6 match-indent-nested = always
7 parens-ite
8 exp-grouping = preserve
9 module-item-spacing = compact
+0
-10
.travis.yml less more
0 language: c
1 sudo: false
2 addons:
3 apt:
4 packages:
5 - ocaml-nox
6 - ocaml-findlib
7 - libfaad-dev
8
9 script: ./bootstrap && ./configure && make
0 0.5.1 (20-05-2022)
1 =====
2 * Switch to `pkg-config` for library detection.
3 * Cleanup warnings
4
05 0.5.0 (07-10-2020)
16 =====
27 * Convert to Unix.read style API.
0 (lang dune 2.0)
1 (version 0.5.0)
0 (lang dune 2.8)
1 (version 0.5.1)
22 (name faad)
33 (source (github savonet/ocaml-faad))
44 (license GPL-2.0)
66 (maintainers "Romain Beauxis <toots@rastageeks.org>")
77
88 (generate_opam_files true)
9 (use_standard_c_and_cxx_flags false)
910
1011 (package
1112 (name faad)
1213 (synopsis "Bindings for the faad library which provides functions for decoding AAC audio files")
1314 (depends
14 (dune (> 2.0))
15 conf-faad
16 conf-pkg-config
17 dune
1518 dune-configurator)
1619 )
2424 *)
2525
2626 let bufsize = 16 * 1024
27
2827 let src = ref ""
2928 let dst = ref ""
3029
4140 let usage = "usage: aac2wav [options] source destination"
4241
4342 let () =
44 Arg.parse
45 []
46 (
47 let pnum = ref (-1) in
48 (fun s -> incr pnum; match !pnum with
49 | 0 -> src := s
50 | 1 -> dst := s
51 | _ -> Printf.eprintf "Error: too many arguments\n"; exit 1
52 )
53 ) usage;
54 if !src = "" || !dst = "" then
55 (
56 Printf.printf "%s\n" usage;
57 exit 1
58 );
43 Arg.parse []
44 (let pnum = ref (-1) in
45 fun s ->
46 incr pnum;
47 match !pnum with
48 | 0 -> src := s
49 | 1 -> dst := s
50 | _ ->
51 Printf.eprintf "Error: too many arguments\n";
52 exit 1)
53 usage;
54 if !src = "" || !dst = "" then (
55 Printf.printf "%s\n" usage;
56 exit 1);
5957
6058 let buflen = 1024 in
6159 let buf = Bytes.create buflen in
7068 for c = 0 to channels - 1 do
7169 let n = a.(c).(i) *. 32767. in
7270 let n = int_of_float n in
73 Bytes.set tmp (2 * (i * channels + c)) (char_of_int (n land 0xff));
74 Bytes.set tmp (2 * (i * channels + c) + 1) (char_of_int ((n lsr 8) land 0xff));
71 Bytes.set tmp (2 * ((i * channels) + c)) (char_of_int (n land 0xff));
72 Bytes.set tmp
73 ((2 * ((i * channels) + c)) + 1)
74 (char_of_int ((n lsr 8) land 0xff))
7575 done
7676 done;
77 outbuf := !outbuf ^ (Bytes.to_string tmp)
77 outbuf := !outbuf ^ Bytes.to_string tmp
7878 in
7979
8080 let decode_mp4 () =
8484 let fill_out = fill_out channels in
8585 let samples = Faad.Mp4.samples mp4 track in
8686 Printf.printf "Input file: %d channels at %d Hz.\n%!" channels samplerate;
87 Array.iter (fun (i,t) -> Printf.printf "%s: %s\n%!" i t) (Faad.Mp4.metadata mp4);
87 Array.iter
88 (fun (i, t) -> Printf.printf "%s: %s\n%!" i t)
89 (Faad.Mp4.metadata mp4);
8890 Printf.printf "%d tracks (AAC track: %d).\n%!" (Faad.Mp4.tracks mp4) track;
8991 Printf.printf "%d samples.\n" samples;
9092 for i = 0 to samples - 1 do
91 Printf.printf "Decoding sample: %d / %d (%d bytes).\r%!" i samples (String.length !outbuf);
93 Printf.printf "Decoding sample: %d / %d (%d bytes).\r%!" i samples
94 (String.length !outbuf);
9295 let a = Faad.Mp4.decode mp4 track i dec in
9396 fill_out a
9497 done;
9598 Printf.printf "\n%!";
96 channels, samplerate, !outbuf
99 (channels, samplerate, !outbuf)
97100 in
98101
99102 let decode_aac () =
100103 let len = Unix.read f buf 0 buflen in
101104 let offset, samplerate, channels = Faad.init dec buf 0 len in
102 let buflen = Faad.min_bytes_per_channel * channels in
105 let buflen = Faad.min_bytes_per_channel * channels in
103106 let consumed = ref buflen in
104107 let aacbuf = Bytes.create buflen in
105108
108111 while !consumed <> 0 do
109112 let n = Unix.read f aacbuf (buflen - !consumed) !consumed in
110113 if n = 0 then raise End_of_file;
111 consumed := !consumed - n;
114 consumed := !consumed - n
112115 done
113116 in
114117
125128 consumed := c;
126129 fill_out a
127130 done;
128 channels, samplerate, !outbuf
131 (channels, samplerate, !outbuf)
129132 with
130 | End_of_file
131 | Faad.Failed ->
132 channels, samplerate, !outbuf
133 | Faad.Error n as e ->
134 Printf.printf "Faad error %d: %s\n%!" n (Faad.error_message n);
135 raise e
133 | End_of_file | Faad.Failed -> (channels, samplerate, !outbuf)
134 | Faad.Error n as e ->
135 Printf.printf "Faad error %d: %s\n%!" n (Faad.error_message n);
136 raise e
136137 in
137138
138139 let channels, samplerate, outbuf =
139 if Filename.check_suffix !src ".aac" || Filename.check_suffix !src ".AAC" then
140 decode_aac ()
141 else
142 decode_mp4 ()
140 if Filename.check_suffix !src ".aac" || Filename.check_suffix !src ".AAC"
141 then decode_aac ()
142 else decode_mp4 ()
143143 in
144144
145145 (* Do the wav stuff. *)
150150 output_string oc "WAVE";
151151 output_string oc "fmt ";
152152 output_int oc 16;
153 output_short oc 1; (* WAVE_FORMAT_PCM *)
154 output_short oc channels; (* channels *)
155 output_int oc samplerate; (* freq *)
156 output_int oc (samplerate * channels * 2); (* bytes / s *)
157 output_short oc (channels * 2); (* block alignment *)
158 output_short oc 16; (* bits per sample *)
153 output_short oc 1;
154 (* WAVE_FORMAT_PCM *)
155 output_short oc channels;
156 (* channels *)
157 output_int oc samplerate;
158 (* freq *)
159 output_int oc (samplerate * channels * 2);
160 (* bytes / s *)
161 output_short oc (channels * 2);
162 (* block alignment *)
163 output_short oc 16;
164 (* bits per sample *)
159165 output_string oc "data";
160166 output_int oc datalen;
161167 output_string oc outbuf;
00 # This file is generated by dune, edit dune-project instead
11 opam-version: "2.0"
2 version: "0.5.0"
2 version: "0.5.1"
33 synopsis:
44 "Bindings for the faad library which provides functions for decoding AAC audio files"
55 maintainer: ["Romain Beauxis <toots@rastageeks.org>"]
88 homepage: "https://github.com/savonet/ocaml-faad"
99 bug-reports: "https://github.com/savonet/ocaml-faad/issues"
1010 depends: [
11 "dune" {> "2.0"}
11 "conf-faad"
12 "conf-pkg-config"
13 "dune" {>= "2.8"}
1214 "dune-configurator"
15 "odoc" {with-doc}
1316 ]
1417 build: [
15 ["dune" "subst"] {pinned}
18 ["dune" "subst"] {dev}
1619 [
1720 "dune"
1821 "build"
2629 ]
2730 ]
2831 dev-repo: "git+https://github.com/savonet/ocaml-faad.git"
29 depexts: [
30 ["faad2-dev"] {os-distribution = "alpine"}
31 ["faad2"] {os-distribution = "arch"}
32 ["faad2-devel"] {os-distribution = "centos"}
33 ["faad2-devel"] {os-distribution = "fedora"}
34 ["faad2-devel"] {os-family = "suse"}
35 ["libfaad-dev"] {os-family = "debian"}
36 ["faad2"] {os = "macos" & os-distribution = "homebrew"}
37 ]
+0
-9
faad.opam.template less more
0 depexts: [
1 ["faad2-dev"] {os-distribution = "alpine"}
2 ["faad2"] {os-distribution = "arch"}
3 ["faad2-devel"] {os-distribution = "centos"}
4 ["faad2-devel"] {os-distribution = "fedora"}
5 ["faad2-devel"] {os-family = "suse"}
6 ["libfaad-dev"] {os-family = "debian"}
7 ["faad2"] {os = "macos" & os-distribution = "homebrew"}
8 ]
00 module C = Configurator.V1
11
2 let faad_test_code = {|
3 #include <neaacdec.h>
4
5 int main()
6 {
7 NeAACDecHandle hAac = NeAACDecOpen();
8 unsigned char input[1024];
9 size_t input_size = 0;
10 unsigned long samplerate;
11 unsigned char channels;
12
13 char err = NeAACDecInit(hAac, input, input_size, &samplerate, &channels);
14
15 return 0;
16 }
17 |}
18
192 let () =
20 C.main ~name:"has_faad" (fun c ->
21 let has_faad = C.c_test c faad_test_code ~link_flags:["-lfaad -lm"] in
22
23 C.C_define.gen_header_file c ~fname:"config.h"
24 [ "HAS_FAAD", Switch has_faad ]);
3 C.main ~name:"faad2-pkg-config" (fun c ->
4 let default : C.Pkg_config.package_conf =
5 { libs = ["-lfaad2"]; cflags = [] }
6 in
7 let conf =
8 match C.Pkg_config.get c with
9 | None -> default
10 | Some pc -> (
11 match
12 C.Pkg_config.query_expr_err pc ~package:"faad2" ~expr:"faad2"
13 with
14 | Error msg -> failwith msg
15 | Ok deps -> deps)
16 in
17 C.Flags.write_sexp "c_flags.sexp" conf.cflags;
18 C.Flags.write_sexp "c_library_flags.sexp" conf.libs)
33 (synopsis "Ocaml bindings to libfaad")
44 (foreign_stubs
55 (language c)
6 (extra_deps config.h)
7 (names
8 faad_stubs
9 mp4atom
10 mp4ff
11 mp4meta
12 mp4sample
13 mp4tagupdate
14 mp4util)
15 (flags -DUSE_TAGGING))
16 (c_library_flags "-lfaad -lm"))
6 (names faad_stubs mp4atom mp4ff mp4meta mp4sample mp4tagupdate mp4util)
7 (flags
8 -DUSE_TAGGING
9 (:include c_flags.sexp)))
10 (c_library_flags
11 (:include c_library_flags.sexp)))
1712
1813 (rule
19 (targets config.h)
20 (action (run ./config/discover.exe)))
14 (targets c_flags.sexp c_library_flags.sexp)
15 (action
16 (run ./config/discover.exe)))
1919 type t
2020
2121 exception Error of int
22
2322 exception Failed
2423
2524 external error_message : int -> string = "ocaml_faad_get_error_message"
2827 Callback.register_exception "ocaml_faad_exn_error" (Error 0);
2928 Callback.register_exception "ocaml_faad_exn_failed" Failed
3029
31 external min_bytes_per_channel : unit -> int = "ocaml_faad_min_bytes_per_channel"
30 external min_bytes_per_channel : unit -> int
31 = "ocaml_faad_min_bytes_per_channel"
3232
3333 let min_bytes_per_channel = min_bytes_per_channel ()
3434
3535 external create : unit -> t = "ocaml_faad_open"
3636
37 external init : t -> Bytes.t -> int -> int -> int * int * int = "ocaml_faad_init"
37 external init : t -> Bytes.t -> int -> int -> int * int * int
38 = "ocaml_faad_init"
3839
39 external decode : t -> Bytes.t -> int -> int -> int * (float array array) = "ocaml_faad_decode"
40 external decode : t -> Bytes.t -> int -> int -> int * float array array
41 = "ocaml_faad_decode"
4042
4143 external post_sync_reset : t -> unit = "ocaml_faad_post_seek_reset"
4244
4345 let find_frame buf =
4446 let i = ref 0 in
4547 let found = ref false in
46 while !i < String.length buf - 1 && not !found do
47 if buf.[!i] = '\255' then
48 if int_of_char buf.[!i+1] land 0xf6 = 0xf0 then
49 found := true
50 else
51 incr i
52 else
53 incr i
54 done;
55 if !found then !i else raise Not_found
48 while !i < String.length buf - 1 && not !found do
49 if buf.[!i] = '\255' then
50 if int_of_char buf.[!i + 1] land 0xf6 = 0xf0 then found := true
51 else incr i
52 else incr i
53 done;
54 if !found then !i else raise Not_found
5655
57 module Mp4 =
58 struct
56 module Mp4 = struct
5957 type decoder = t
60
6158 type t
62
6359 type track = int
64
6560 type sample = int
66
6761 type read = bytes -> int -> int -> int
6862
6963 let is_mp4 s =
7064 assert (String.length s >= 8);
7165 s.[4] = 'f' && s.[5] = 't' && s.[6] = 'y' && s.[7] = 'p'
7266
73 external open_read : bool -> read -> (Bytes.t -> int) option -> (int -> int) option -> (unit -> int) option -> t = "ocaml_faad_mp4_open_read"
67 external open_read :
68 bool ->
69 read ->
70 (Bytes.t -> int) option ->
71 (int -> int) option ->
72 (unit -> int) option ->
73 t = "ocaml_faad_mp4_open_read"
7474
75 external open_read_fd : bool -> Unix.file_descr -> t = "ocaml_faad_mp4_open_read_fd"
75 external open_read_fd : bool -> Unix.file_descr -> t
76 = "ocaml_faad_mp4_open_read_fd"
7677
7778 let openfile ?write ?seek ?trunc read = open_read false read write seek trunc
78
7979 let openfile_fd = open_read_fd false
8080
81 external seek : t -> track -> int -> int*int = "ocaml_faad_mp4_seek"
81 external seek : t -> track -> int -> int * int = "ocaml_faad_mp4_seek"
8282
83 let seek mp4 track offset =
84 let sample,to_skip = seek mp4 track offset in
85 if sample < 0 then
86 raise Failed
87 else
88 sample,to_skip
83 let seek mp4 track offset =
84 let sample, to_skip = seek mp4 track offset in
85 if sample < 0 then raise Failed else (sample, to_skip)
8986
9087 external tracks : t -> int = "ocaml_faad_mp4_total_tracks"
91
9288 external find_aac_track : t -> track = "ocaml_faad_mp4_find_aac_track"
93
9489 external init : t -> decoder -> track -> int * int = "ocaml_faad_mp4_init"
95
9690 external samples : t -> track -> int = "ocaml_faad_mp4_num_samples"
9791
98 external read_sample : t -> track -> sample -> string = "ocaml_faad_mp4_read_sample"
92 external read_sample : t -> track -> sample -> string
93 = "ocaml_faad_mp4_read_sample"
9994
100 external decode : t -> track -> sample -> decoder -> float array array = "ocaml_faad_mp4_decode"
95 external decode : t -> track -> sample -> decoder -> float array array
96 = "ocaml_faad_mp4_decode"
10197
10298 external metadata : t -> (string * string) array = "ocaml_faad_mp4_metadata"
10399 end
104
2727
2828 (** An error occured... *)
2929 exception Error of int
30
3031 exception Failed
3132
3233 (** Get the error message corresponding to a raised [Error]. *)
4849 * starting at offset [ofs]. It returns the number of bytes actually decoded
4950 * and the decoded data (non-interleaved).
5051 *)
51 val decode : t -> Bytes.t -> int -> int -> int * (float array array)
52 val decode : t -> Bytes.t -> int -> int -> int * float array array
5253
5354 val post_sync_reset : t -> unit
5455
5556 (** Heuristic guess of the offset of the begining of a frame. *)
5657 val find_frame : string -> int
5758
58 module Mp4 :
59 sig
59 module Mp4 : sig
6060 type decoder = t
6161
6262 (** An MP4 reader. *)
7575 val is_mp4 : string -> bool
7676
7777 (** Open an MP4 file. *)
78 val openfile : ?write:(Bytes.t -> int) ->
79 ?seek:(int -> int) ->
80 ?trunc:(unit -> int) -> read -> t
78 val openfile :
79 ?write:(Bytes.t -> int) ->
80 ?seek:(int -> int) ->
81 ?trunc:(unit -> int) ->
82 read ->
83 t
8184
8285 val openfile_fd : Unix.file_descr -> t
8386
9598 * [sample] is the new current (mp4) sample
9699 * and [toskip] is an amount of audio sample
97100 * that should be skipped. *)
98 val seek : t -> track -> int -> int*int
101 val seek : t -> track -> int -> int * int
99102
100103 val samples : t -> track -> int
101
102104 val read_sample : t -> track -> sample -> string
103
104105 val decode : t -> track -> sample -> decoder -> float array array
105
106106 val metadata : t -> (string * string) array
107107 end
501501 mp4_t *mp = Mp4_val(m);
502502 int t = Int_val(track);
503503 int s = Int_val(sample);
504 unsigned char *buf = NULL;
504 int8_t *buf = NULL;
505505 unsigned int buflen = 0;
506506 int ret;
507507
511511 check_err(ret);
512512
513513 ans = caml_alloc_string(buflen);
514 memcpy(String_val(ans), buf, buflen);
514 memcpy((void *)String_val(ans), buf, buflen);
515515 free(buf);
516516
517517 CAMLreturn(ans);
527527 int s = Int_val(sample);
528528 NeAACDecHandle dec = Dec_val(dh);
529529 NeAACDecFrameInfo frameInfo;
530 unsigned char *inbuf = NULL;
530 int8_t *inbuf = NULL;
531531 unsigned int inbuflen = 0;
532532 float *data;
533533 int c, i, ret;
539539 check_err(ret);
540540
541541 caml_release_runtime_system();
542 data = NeAACDecDecode(dec, &frameInfo, inbuf, inbuflen);
542 data = NeAACDecDecode(dec, &frameInfo, (uint8_t *)inbuf, inbuflen);
543543 caml_acquire_runtime_system();
544544
545545 free(inbuf);
436436 }
437437
438438 int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
439 uint8_t **audio_buffer, uint32_t *bytes)
439 int8_t **audio_buffer, uint32_t *bytes)
440440 {
441441 int32_t result = 0;
442442
444444
445445 if (*bytes==0) return 0;
446446
447 *audio_buffer = (uint8_t*)malloc(*bytes);
447 *audio_buffer = (int8_t*)malloc(*bytes);
448448
449449 mp4ff_set_sample_position(f, track, sample);
450450
474474 int32_t size = mp4ff_audio_frame_size(f,track,sample);
475475 if (size<=0) return 0;
476476 mp4ff_set_sample_position(f, track, sample);
477 result = mp4ff_read_data(f,buffer,size);
477 result = mp4ff_read_data(f,(int8_t *)buffer,size);
478478
479479 #ifdef ITUNES_DRM
480480 if (f->track[track]->p_drms != NULL)
110110 int32_t *ctts_sample_offset;
111111
112112 /* esde */
113 uint8_t *decoderConfig;
113 int8_t *decoderConfig;
114114 int32_t decoderConfigLen;
115115
116116 uint32_t maxBitrate;
164164 int32_t mp4ff_find_sample_use_offsets(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
165165
166166 int32_t mp4ff_read_sample(mp4ff_t *f, const int track, const int sample,
167 unsigned char **audio_buffer, unsigned int *bytes);
167 int8_t **audio_buffer, unsigned int *bytes);
168168
169169 int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer);//returns 0 on error, number of bytes read on success, use mp4ff_read_sample_getsize() to check buffer size needed
170170 int32_t mp4ff_read_sample_getsize(mp4ff_t *f, const int track, const int sample);//returns 0 on error, buffer size needed for mp4ff_read_sample_v2() on success
219219 int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
220220
221221 int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
222 uint8_t **audio_buffer, uint32_t *bytes);
222 int8_t **audio_buffer, uint32_t *bytes);
223223 int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
224224 uint8_t** ppBuf, uint32_t* pBufSize);
225225 int32_t mp4ff_total_tracks(const mp4ff_t *f);
142142 bufptr = membuffer_get_ptr(buf);
143143 if (bufptr==0) return 0;
144144
145 if ((unsigned)mp4ff_read_data(src,(char*)bufptr + oldsize,bytes)!=bytes)
145 if ((unsigned)mp4ff_read_data(src,(int8_t *)bufptr + oldsize,bytes)!=bytes)
146146 {
147147 membuffer_set_error(buf);
148148 return 0;
364364 {
365365 uint32_t index = mp4ff_meta_genre_to_index(genre_ptr);
366366 if (index==0)
367 membuffer_write_std_tag(buf,"©gen",genre_ptr);
367 membuffer_write_std_tag(buf,"\u0040gen",genre_ptr);
368368 else
369369 membuffer_write_int16_tag(buf,"gnre",(uint16_t)index);
370370 }
416416 if (remaining < 8) break;
417417 atom_size = mp4ff_read_int32(f);
418418 if (atom_size > remaining || atom_size < 8) break;
419 mp4ff_read_data(f,atom_name,4);
419 mp4ff_read_data(f,(int8_t *)atom_name,4);
420420
421421 if (!memcmp(atom_name,name,4))
422422 {
511511 uint32_t new_ilst_size;
512512 void * new_ilst_buffer;
513513
514 uint8_t * p_out;
514 int8_t * p_out;
515515 int32_t size_delta;
516516
517517
580580 return 0;
581581 }
582582
583 p_out = (uint8_t*)*out_buffer;
583 p_out = (int8_t*)*out_buffer;
584584
585585 mp4ff_set_position(f,total_base);
586586 mp4ff_read_data(f,p_out,(uint32_t)(udta_offset - total_base )); p_out += (uint32_t)(udta_offset - total_base );
632632
633633 /* rename old moov to free */
634634 mp4ff_set_position(ff, ff->moov_offset + 4);
635 mp4ff_write_data(ff, free_data, 4);
635 mp4ff_write_data(ff, (int8_t *)free_data, 4);
636636
637637 mp4ff_set_position(ff, ff->file_size);
638638 mp4ff_write_int32(ff,new_moov_size + 8);
639 mp4ff_write_data(ff,"moov",4);
639 mp4ff_write_data(ff,(int8_t *)"moov",4);
640640 mp4ff_write_data(ff, new_moov_data, new_moov_size);
641641 }
642642 else
643643 {
644644 mp4ff_set_position(ff, ff->moov_offset);
645645 mp4ff_write_int32(ff,new_moov_size + 8);
646 mp4ff_write_data(ff,"moov",4);
646 mp4ff_write_data(ff,(int8_t *)"moov",4);
647647 mp4ff_write_data(ff, new_moov_data, new_moov_size);
648648 }
649649
7474
7575 result = (a<<24) | (b<<16) | (c<<8) | d;
7676
77 return mp4ff_write_data(f,(uint8_t*)&result,sizeof(result));
77 return mp4ff_write_data(f,(int8_t*)&result,sizeof(result));
7878 }
7979
8080 int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position)
9292
9393 uint64_t mp4ff_read_int64(mp4ff_t *f)
9494 {
95 uint8_t data[8];
95 int8_t data[8];
9696 uint64_t result = 0;
9797 int8_t i;
9898
156156 char * str = (char*)malloc(length + 1);
157157 if (str!=0)
158158 {
159 if ((uint32_t)mp4ff_read_data(f,str,length)!=length)
159 if ((uint32_t)mp4ff_read_data(f,(int8_t *)str,length)!=length)
160160 {
161161 free(str);
162162 str = 0;
171171
172172 uint8_t mp4ff_read_char(mp4ff_t *f)
173173 {
174 uint8_t output;
174 int8_t output;
175175 mp4ff_read_data(f, &output, 1);
176176 return output;
177177 }