Skip to content

Commit 231725f

Browse files
committed
Add set_decoder to specify explicit decoder for stream.
1 parent 8f110be commit 231725f

12 files changed

+54
-28
lines changed

.ocamlformat

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version=0.18.0
1+
version=0.19.0
22
profile = conventional
33
break-separators = after
44
space-around-lists = false

av/av.ml

+20-11
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,15 @@ external input_obj : input container -> 'a = "ocaml_av_input_obj"
121121
let input_obj c = Obj.magic (input_obj c, c)
122122

123123
(* Input Stream *)
124-
type ('a, 'b, 'c) stream = { container : 'a container; index : int }
124+
type ('a, 'b, 'c) stream = {
125+
container : 'a container;
126+
index : int;
127+
mutable decoder : ('b, Avcodec.decode) Avcodec.codec option;
128+
}
129+
125130
type media_type = MT_audio | MT_video | MT_subtitle
126131

127-
let mk_stream container index = { container; index }
132+
let mk_stream container index = { container; index; decoder = None }
128133

129134
external get_codec_params : (_, 'm, _) stream -> 'm Avcodec.params
130135
= "ocaml_av_get_stream_codec_parameters"
@@ -153,6 +158,7 @@ let get_streams input media_type =
153158
let get_audio_streams input = get_streams input MT_audio
154159
let get_video_streams input = get_streams input MT_video
155160
let get_subtitle_streams input = get_streams input MT_subtitle
161+
let set_decoder s decoder = s.decoder <- Some decoder
156162

157163
external _find_best_stream : input container -> media_type -> int
158164
= "ocaml_av_find_best_stream"
@@ -182,26 +188,29 @@ type input_result =
182188
| `Subtitle_frame of int * subtitle frame ]
183189

184190
(** Reads the selected streams if any or all streams otherwise. *)
185-
external read_input : int array -> int array -> input container -> input_result
186-
= "ocaml_av_read_input"
191+
external read_input :
192+
(int * ('a, Avcodec.decode) Avcodec.codec option) array ->
193+
(int * ('a, Avcodec.decode) Avcodec.codec option) array ->
194+
input container ->
195+
input_result = "ocaml_av_read_input"
187196

188-
let get_id input =
189-
List.map (fun { index; container } ->
197+
let _get input =
198+
List.map (fun { index; container; decoder } ->
190199
if container != input then
191200
raise (Failure "Inconsistent stream and input!");
192-
index)
201+
(index, Obj.magic decoder))
193202

194203
let read_input ?(audio_packet = []) ?(audio_frame = []) ?(video_packet = [])
195204
?(video_frame = []) ?(subtitle_packet = []) ?(subtitle_frame = []) input =
196205
let packet =
197206
Array.of_list
198-
(get_id input audio_packet @ get_id input video_packet
199-
@ get_id input subtitle_packet)
207+
(_get input audio_packet @ _get input video_packet
208+
@ _get input subtitle_packet)
200209
in
201210
let frame =
202211
Array.of_list
203-
(get_id input audio_frame @ get_id input video_frame
204-
@ get_id input subtitle_frame)
212+
(_get input audio_frame @ _get input video_frame
213+
@ _get input subtitle_frame)
205214
in
206215
read_input packet frame input
207216

av/av.mli

+4
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ val get_duration : ?format:Time_format.t -> (input, _, _) stream -> Int64.t
136136
(** Same as {!Av.get_input_metadata} for the input streams. *)
137137
val get_metadata : (input, _, _) stream -> (string * string) list
138138

139+
(** For the use of a specific decoder for the given input stream. *)
140+
val set_decoder :
141+
(input, 'a, _) stream -> ('a, Avcodec.decode) Avcodec.codec -> unit
142+
139143
type input_result =
140144
[ `Audio_packet of int * audio Avcodec.Packet.t
141145
| `Audio_frame of int * audio frame

av/av_stubs.c

+21-16
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ static stream_t *allocate_stream_context(av_t *av, int index, AVCodec *codec) {
784784
return stream;
785785
}
786786

787-
static stream_t *open_stream_index(av_t *av, int index) {
787+
static stream_t *open_stream_index(av_t *av, int index, AVCodec *dec) {
788788
int err;
789789

790790
if (!av->format_context)
@@ -798,10 +798,11 @@ static stream_t *open_stream_index(av_t *av, int index) {
798798

799799
// find decoder for the stream
800800
AVCodecParameters *dec_param = av->format_context->streams[index]->codecpar;
801-
802-
caml_release_runtime_system();
803-
AVCodec *dec = avcodec_find_decoder(dec_param->codec_id);
804-
caml_acquire_runtime_system();
801+
if (!dec) {
802+
caml_release_runtime_system();
803+
dec = avcodec_find_decoder(dec_param->codec_id);
804+
caml_acquire_runtime_system();
805+
}
805806

806807
if (!dec)
807808
ocaml_avutil_raise_error(AVERROR_DECODER_NOT_FOUND);
@@ -829,12 +830,6 @@ static stream_t *open_stream_index(av_t *av, int index) {
829830
return stream;
830831
}
831832

832-
#define Check_stream(av, index) \
833-
{ \
834-
if (!(av)->streams || !(av)->streams[(index)]) \
835-
open_stream_index((av), (index)); \
836-
}
837-
838833
CAMLprim value ocaml_av_find_best_stream(value _av, value _media_type) {
839834
CAMLparam2(_av, _media_type);
840835
av_t *av = Av_val(_av);
@@ -924,6 +919,8 @@ CAMLprim value ocaml_av_read_input(value _packet, value _frame, value _av) {
924919
av_t *av = Av_val(_av);
925920
AVFrame *frame;
926921
int i, ret, frame_kind, skip;
922+
value _dec;
923+
AVCodec *dec = NULL;
927924

928925
if (!av->streams && !allocate_input_context(av))
929926
caml_raise_out_of_memory();
@@ -948,21 +945,29 @@ CAMLprim value ocaml_av_read_input(value _packet, value _frame, value _av) {
948945

949946
skip = 1;
950947
for (i = 0; i < Wosize_val(_packet); i++)
951-
if (Int_val(Field(_packet, i)) == packet->stream_index)
948+
if (Int_val(Field(Field(_packet, i), 0)) == packet->stream_index) {
949+
_dec = Field(Field(_packet, i), 1);
952950
skip = 0;
951+
}
953952

954953
for (i = 0; i < Wosize_val(_frame); i++)
955-
if (Int_val(Field(_frame, i)) == packet->stream_index)
954+
if (Int_val(Field(Field(_frame, i), 0)) == packet->stream_index) {
955+
_dec = Field(Field(_frame, i), 1);
956956
skip = 0;
957+
}
957958

958959
if (skip)
959960
continue;
960961

962+
if (_dec != Val_none) {
963+
dec = (AVCodec *)Some_val(_dec);
964+
}
965+
961966
if ((stream = streams[packet->stream_index]) == NULL)
962-
stream = open_stream_index(av, packet->stream_index);
967+
stream = open_stream_index(av, packet->stream_index, dec);
963968

964969
for (i = 0; i < Wosize_val(_packet); i++) {
965-
if (Int_val(Field(_packet, i)) == packet->stream_index) {
970+
if (Int_val(Field(Field(_packet, i), 0)) == packet->stream_index) {
966971
decoded_content = caml_alloc_tuple(2);
967972
Field(decoded_content, 0) = Val_int(packet->stream_index);
968973
Field(decoded_content, 1) = value_of_ffmpeg_packet(packet);
@@ -999,7 +1004,7 @@ CAMLprim value ocaml_av_read_input(value _packet, value _frame, value _av) {
9991004

10001005
skip = 1;
10011006
for (i = 0; i < Wosize_val(_frame); i++) {
1002-
if (Int_val(Field(_frame, i)) == stream->index) {
1007+
if (Int_val(Field(Field(_frame, i), 0)) == stream->index) {
10031008
skip = 0;
10041009
}
10051010
}

ffmpeg-av.opam

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ conflicts: [
2121
"ffmpeg" {< "0.5.0"}
2222
]
2323
build: [
24+
["dune" "subst"] {dev}
2425
[
2526
"dune"
2627
"build"

ffmpeg-avcodec.opam

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ conflicts: [
2020
"ffmpeg" {< "0.5.0"}
2121
]
2222
build: [
23+
["dune" "subst"] {dev}
2324
[
2425
"dune"
2526
"build"

ffmpeg-avdevice.opam

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ conflicts: [
2020
"ffmpeg" {< "0.5.0"}
2121
]
2222
build: [
23+
["dune" "subst"] {dev}
2324
[
2425
"dune"
2526
"build"

ffmpeg-avfilter.opam

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ conflicts: [
2020
"ffmpeg" {< "0.5.0"}
2121
]
2222
build: [
23+
["dune" "subst"] {dev}
2324
[
2425
"dune"
2526
"build"

ffmpeg-avutil.opam

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ conflicts: [
2020
"ffmpeg" {< "0.5.0"}
2121
]
2222
build: [
23+
["dune" "subst"] {dev}
2324
[
2425
"dune"
2526
"build"

ffmpeg-swresample.opam

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ conflicts: [
2121
"ffmpeg" {< "0.5.0"}
2222
]
2323
build: [
24+
["dune" "subst"] {dev}
2425
[
2526
"dune"
2627
"build"

ffmpeg-swscale.opam

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ conflicts: [
2020
"ffmpeg" {< "0.5.0"}
2121
]
2222
build: [
23+
["dune" "subst"] {dev}
2324
[
2425
"dune"
2526
"build"

ffmpeg.opam

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ depends: [
2020
"odoc" {with-doc}
2121
]
2222
build: [
23+
["dune" "subst"] {dev}
2324
[
2425
"dune"
2526
"build"

0 commit comments

Comments
 (0)