[FFmpeg-devel] [PATCH 4/4] lavfi/fieldorder: work with non writtable frames too
Stefano Sabatini
stefasab at gmail.com
Fri Sep 6 20:03:07 CEST 2013
On date Friday 2013-09-06 14:45:31 +0000, Paul B Mahol encoded:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
> libavfilter/vf_fieldorder.c | 46 +++++++++++++++++++++++++++++++--------------
> 1 file changed, 32 insertions(+), 14 deletions(-)
>
> diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
> index 15204e3..92c222c 100644
> --- a/libavfilter/vf_fieldorder.c
> +++ b/libavfilter/vf_fieldorder.c
> @@ -79,21 +79,35 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
> AVFilterContext *ctx = inlink->dst;
> FieldOrderContext *s = ctx->priv;
> AVFilterLink *outlink = ctx->outputs[0];
> - int h, plane, line_step, line_size, line;
> - uint8_t *data;
> + int h, plane, src_line_step, dst_line_step, line_size, line;
> + uint8_t *dst, *src;
> + AVFrame *out;
>
> if (!frame->interlaced_frame ||
> frame->top_field_first == s->dst_tff)
> return ff_filter_frame(outlink, frame);
>
> + if (av_frame_is_writable(frame)) {
> + out = frame;
> + } else {
> + out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
> + if (!out) {
> + av_frame_free(&frame);
> + return AVERROR(ENOMEM);
> + }
> + av_frame_copy_props(out, frame);
> + }
> +
> av_dlog(ctx,
> "picture will move %s one line\n",
> s->dst_tff ? "up" : "down");
> h = frame->height;
> for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) {
> - line_step = frame->linesize[plane];
> + dst_line_step = out->linesize[plane];
> + src_line_step = frame->linesize[plane];
> line_size = s->line_size[plane];
> - data = frame->data[plane];
> + dst = out->data[plane];
> + src = frame->data[plane];
> if (s->dst_tff) {
> /** Move every line up one line, working from
> * the top to the bottom of the frame.
> @@ -102,11 +116,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
> * penultimate line from that field. */
> for (line = 0; line < h; line++) {
> if (1 + line < frame->height) {
> - memcpy(data, data + line_step, line_size);
> + memcpy(dst, src + src_line_step, line_size);
> } else {
> - memcpy(data, data - line_step - line_step, line_size);
> + memcpy(dst, src - 2 * src_line_step, line_size);
> }
> - data += line_step;
> + dst += dst_line_step;
> + src += src_line_step;
> }
> } else {
> /** Move every line down one line, working from
> @@ -114,20 +129,24 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
> * The original bottom line is lost.
> * The new first line is created as a copy of the
> * second line from that field. */
> - data += (h - 1) * line_step;
> + dst += (h - 1) * dst_line_step;
> + src += (h - 1) * src_line_step;
> for (line = h - 1; line >= 0 ; line--) {
> if (line > 0) {
> - memcpy(data, data - line_step, line_size);
> + memcpy(dst, src - src_line_step, line_size);
> } else {
> - memcpy(data, data + line_step + line_step, line_size);
> + memcpy(dst, src + 2 * src_line_step, line_size);
> }
> - data -= line_step;
> + dst -= dst_line_step;
> + src -= src_line_step;
> }
> }
> }
> - frame->top_field_first = s->dst_tff;
> + out->top_field_first = s->dst_tff;
>
> - return ff_filter_frame(outlink, frame);
> + if (frame != out)
> + av_frame_free(&frame);
> + return ff_filter_frame(outlink, out);
> }
>
> #define OFFSET(x) offsetof(FieldOrderContext, x)
> @@ -148,7 +167,6 @@ static const AVFilterPad avfilter_vf_fieldorder_inputs[] = {
> .type = AVMEDIA_TYPE_VIDEO,
> .config_props = config_input,
> .filter_frame = filter_frame,
> - .needs_writable = 1,
All four patches look good to me, assuming they have been tested, thanks.
--
FFmpeg = Frightening and Freak Minimalistic Pacific Elastic Gospel
More information about the ffmpeg-devel
mailing list