From 8c0f717365d78d108d601eeb6de48cad0a0760a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Dubreil?= Date: Sat, 24 Feb 2018 23:59:26 +0100 Subject: [PATCH] Fix wrong plane count and wrong plane copy --- examples/encoding/encoding.ml | 7 +--- src/avutil.ml | 5 --- src/avutil.mli | 6 --- src/avutil_stubs.c | 79 +++-------------------------------- src/avutil_stubs.h | 6 +-- 5 files changed, 11 insertions(+), 92 deletions(-) diff --git a/examples/encoding/encoding.ml b/examples/encoding/encoding.ml index 800af8d4..a9e33779 100644 --- a/examples/encoding/encoding.ml +++ b/examples/encoding/encoding.ml @@ -72,8 +72,6 @@ let () = Av.set_metadata ovs ["Media", "Video"]; let frame = Video.create_frame width height pixel_format in - let planes = Video.copy_frame_to_planes frame in - let video_on_off = [|fill_image_on; fill_image_off|] in (* let oss = Av.new_subtitle_stream ~codec_name:Sys.argv.(4) dst in @@ -92,9 +90,8 @@ let () = for i = 0 to frame_rate * duration - 1 do let b = (i mod frame_rate) / 13 in - video_on_off.(b) width height i planes; - Video.copy_planes_to_frame frame planes; - Av.write ovs frame; + Video.frame_visit ~make_writable:true (video_on_off.(b) width height i) frame + |> Av.write ovs; done; Av.close dst; diff --git a/src/avutil.ml b/src/avutil.ml index 76249703..539c408e 100644 --- a/src/avutil.ml +++ b/src/avutil.ml @@ -65,11 +65,6 @@ module Video = struct external frame_get_linesize : video frame -> int -> int = "ocaml_avutil_video_frame_get_linesize" - external copy_frame_to_planes : video frame -> planes = "ocaml_avutil_video_copy_frame_to_bigarray_planes" - - external copy_planes_to_frame : video frame -> planes -> unit = "ocaml_avutil_video_copy_bigarray_planes_to_frame" - - external get_frame_planes : video frame -> bool -> planes = "ocaml_avutil_video_get_frame_bigarray_planes" let frame_visit ~make_writable visit frame = visit(get_frame_planes frame make_writable); frame diff --git a/src/avutil.mli b/src/avutil.mli index 0ff7d7fd..9c8aacec 100644 --- a/src/avutil.mli +++ b/src/avutil.mli @@ -95,12 +95,6 @@ module Video : sig val frame_get_linesize : video frame -> int -> int (** [Avutil.Video.frame_get_linesize vf n] return the line size of the [n] plane of the [vf] video frame. @raise Failure if [n] is out of boundaries. *) - val copy_frame_to_planes : video frame -> planes - (** [Avutil.Video.copy_frame_to_planes vf] copy the video frame [vf] data to fresh arrays. *) - - val copy_planes_to_frame : video frame -> planes -> unit - (** [Avutil.Video.copy_planes_to_frame vf planes] copy the [planes] to the video frame [vf]. @raise Failure if the make frame writable operation failed or if the planes lines sizes and the frame lines sizes are different. *) - val frame_visit : make_writable:bool -> (planes -> unit) -> video frame -> video frame (** [Avutil.Video.frame_visit ~make_writable:wrt f vf] call the [f] function with planes wrapping the [vf] video frame data. The make_writable:[wrt] parameter must be set to true if the [f] function writes in the planes. Access to the frame through the planes is safe as long as it occurs in the [f] function and the frame is not sent to an encoder. The same frame is returned for convenience. @raise Failure if the make frame writable operation failed. *) end diff --git a/src/avutil_stubs.c b/src/avutil_stubs.c index aceb69f9..d15aea83 100644 --- a/src/avutil_stubs.c +++ b/src/avutil_stubs.c @@ -172,71 +172,6 @@ CAMLprim value ocaml_avutil_video_frame_get_linesize(value _frame, value _line) #endif } -CAMLprim value ocaml_avutil_video_copy_frame_to_bigarray_planes(value _frame) -{ - CAMLparam1(_frame); - CAMLlocal3(ans, data, plane); -#ifndef HAS_FRAME - caml_failwith("Not implemented."); -#else - AVFrame *frame = Frame_val(_frame); - int i, nb_planes; - - for(nb_planes = 0; frame->buf[nb_planes]; nb_planes++); - - ans = caml_alloc_tuple(nb_planes); - - for(i = 0; i < nb_planes; i++) { - AVBufferRef* buffer = frame->buf[i]; - intnat out_size = buffer->size; - - data = caml_ba_alloc(CAML_BA_C_LAYOUT | CAML_BA_UINT8, 1, NULL, &out_size); - - memcpy(Caml_ba_data_val(data), buffer->data, buffer->size); - - plane = caml_alloc_tuple(2); - - Store_field(plane, 0, data); - Store_field(plane, 1, Val_int(frame->linesize[i])); - Store_field(ans, i, plane); - } -#endif - CAMLreturn(ans); -} - - -CAMLprim value ocaml_avutil_video_copy_bigarray_planes_to_frame(value _frame, value _planes) -{ - CAMLparam2(_planes, _frame); - CAMLlocal2(data, plane); -#ifndef HAS_FRAME - caml_failwith("Not implemented."); -#else - int i, nb_planes = Wosize_val(_planes); - AVFrame *frame = Frame_val(_frame); - - int ret = av_frame_make_writable(frame); - if (ret < 0) Raise(EXN_FAILURE, "Failed to make frame writable : %s", av_err2str(ret)); - - for(i = 0; i < nb_planes && frame->buf[i]; i++) { - AVBufferRef* buffer = frame->buf[i]; - plane = Field(_planes, i); - data = Field(plane, 0); - int src_linesize = Int_val(Field(plane, 1)); - - if(src_linesize != frame->linesize[i]) Raise(EXN_FAILURE, "Failed to copy planes to frame : incompatible linesize"); - - size_t size = buffer->size; - - if(Caml_ba_array_val(data)->dim[0] < size) size = Caml_ba_array_val(data)->dim[0]; - - memcpy(buffer->data, Caml_ba_data_val(data), size); - } -#endif - CAMLreturn(Val_unit); -} - - CAMLprim value ocaml_avutil_video_get_frame_bigarray_planes(value _frame, value _make_writable) { CAMLparam1(_frame); @@ -245,25 +180,23 @@ CAMLprim value ocaml_avutil_video_get_frame_bigarray_planes(value _frame, value caml_failwith("Not implemented."); #else AVFrame *frame = Frame_val(_frame); - int i, nb_planes; + int i; if(Bool_val(_make_writable)) { int ret = av_frame_make_writable(frame); if (ret < 0) Raise(EXN_FAILURE, "Failed to make frame writable : %s", av_err2str(ret)); } - - for(nb_planes = 0; frame->buf[nb_planes]; nb_planes++); + int nb_planes = av_pix_fmt_count_planes((enum AVPixelFormat)frame->format); + if(nb_planes < 0) Raise(EXN_FAILURE, "Failed to get frame planes count : %s", av_err2str(nb_planes)); + ans = caml_alloc_tuple(nb_planes); for(i = 0; i < nb_planes; i++) { - AVBufferRef* buffer = av_frame_get_plane_buffer(frame, i); - if( ! buffer) Raise(EXN_FAILURE, "Failed to get frame plane buffer"); - - intnat out_size = buffer->size; + intnat out_size = frame->linesize[i] * frame->height; plane = caml_alloc_tuple(2); - Store_field(plane, 0, caml_ba_alloc(CAML_BA_C_LAYOUT | CAML_BA_UINT8, 1, buffer->data, &out_size)); + Store_field(plane, 0, caml_ba_alloc(CAML_BA_C_LAYOUT | CAML_BA_UINT8, 1, frame->data[i], &out_size)); Store_field(plane, 1, Val_int(frame->linesize[i])); Store_field(ans, i, plane); } diff --git a/src/avutil_stubs.h b/src/avutil_stubs.h index e5f8d968..993a5dde 100644 --- a/src/avutil_stubs.h +++ b/src/avutil_stubs.h @@ -24,9 +24,9 @@ #define Log(...) snprintf(ocaml_av_error_msg, ERROR_MSG_SIZE, __VA_ARGS__) -#define Fail(...) { \ - Log(__VA_ARGS__); \ - return NULL; \ +#define Fail(...) { \ + snprintf(ocaml_av_error_msg, ERROR_MSG_SIZE, __VA_ARGS__); \ + return NULL; \ } #define Raise(exn, ...) { \