Skip to content

Commit

Permalink
Fix wrong plane count and wrong plane copy
Browse files Browse the repository at this point in the history
  • Loading branch information
gndl committed Feb 24, 2018
1 parent bbbe95c commit 8c0f717
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 92 deletions.
7 changes: 2 additions & 5 deletions examples/encoding/encoding.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down
5 changes: 0 additions & 5 deletions src/avutil.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 0 additions & 6 deletions src/avutil.mli
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
79 changes: 6 additions & 73 deletions src/avutil_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down
6 changes: 3 additions & 3 deletions src/avutil_stubs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, ...) { \
Expand Down

0 comments on commit 8c0f717

Please sign in to comment.