[FFmpeg-devel] [SOCIS] Qualification task
Stefano Sabatini
stefasab at gmail.com
Wed Aug 1 02:16:26 CEST 2012
On date Tuesday 2012-07-31 22:17:15 +0200, Michele Orrù encoded:
> https://github.com/mmaker/FFmpeg/commits/master
>
> The link above summarizes what I've done during those days playing
> with libavfilter.
> I'm sorry for submitting one existent filter, and another non working,
> but there is something I am missing when using planes, and
> unfortunately I did not have had the time to go in depth about this
> topic.
Inline review follows.
> /*
> * This file is part of FFmpeg.
Missing copyright, and of the original author in case this is a port
(in that case make sure that the original author agrees in case or
relicensing).
> *
> * FFmpeg is free software; you can redistribute it and/or
> * modify it under the terms of the GNU Lesser General Public
> * License as published by the Free Software Foundation; either
> * version 2.1 of the License, or (at your option) any later version.
> *
> * FFmpeg is distributed in the hope that it will be useful,
> * but WITHOUT ANY WARRANTY; without even the implied warranty of
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> * Lesser General Public License for more details.
> *
> * You should have received a copy of the GNU Lesser General Public
> * License along with FFmpeg; if not, write to the Free Software
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> */
>
> /**
> * @file
> * puzzle video filter
> */
>
> #include "avfilter.h"
> #include "internal.h"
> #include "video.h"
> #include "libavutil/lfg.h"
>
> typedef struct {
> int* xoffsets;
> int* yoffsets;
> int xs;
> int ys;
Add doxy to these fields, should ease code review/understanding.
> } PuzzleContext;
>
>
> static void shuffle(int* arr, size_t len)
> {
> int replace, index;
>
> if (len <= 1) return;
>
> av_lfg_get(&index);
I suppose you need to pass an LFG context here, also this statement
has no effects.
> index = 1 + index % len;
> replace = arr[0];
> arr[0] = arr[index];
> arr[index] = replace;
>
> shuffle(arr+1, len-1);
> }
>
> static void memflip(char *a, char *b, size_t n)
> {
> static char tmp;
> for (; n; a++, b++, n--) {
> tmp = *a;
> *a = *b;
> *b = *a;
> }
> }
>
> static av_cold int init(AVFilterContext *ctx, const char *args)
> {
> PuzzleContext *puzzle = ctx->priv;
>
>
> if (args)
> sscanf(args, "%d:%d", &puzzle->xs, &puzzle->ys);
missing validation
> else
> puzzle->xs = puzzle->ys = 5;
>
> if (!((puzzle->xoffsets = av_calloc(sizeof(int), puzzle->xs)) &&
> (puzzle->yoffsets = av_calloc(sizeof(int), puzzle->ys))))
> return AVERROR(ENOMEM);
>
> return 0;
> }
>
> static void uninit(AVFilterContext *ctx)
> {
> PuzzleContext *puzzle = ctx->priv;
>
> av_free(puzzle->xoffsets);
> av_free(puzzle->yoffsets);
> }
>
> static int config_props(AVFilterLink* link)
nit: link -> inlink
> {
> PuzzleContext *puzzle = link->dst->priv;
> size_t i;
>
> for (i = 0; i != puzzle->xs; i++)
> puzzle->xoffsets[i] = i;
> for (i = 0; i != puzzle->ys; i++)
> puzzle->yoffsets[i] = i;
>
> /* shuffle */
> shuffle(puzzle->yoffsets, puzzle->ys);
> shuffle(puzzle->xoffsets, puzzle->xs);
Maybe you can do this in init(), should avoid the need of the
config_props() callback.
> return 0;
>
> }
>
>
> static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
> {
nit: inlink
> PuzzleContext *puzzle = link->dst->priv;
> AVFilterBufferRef *pic = link->cur_buf;
> const int block = link->w / puzzle->xs;
block_size seems more meaningful
> unsigned char *p;
> size_t item, i;
again "item" seems confusing, maybe block_index or index
>
> p = pic->data[0] + y * pic->linesize[0];
> for (i = 0; i != h; i++) {
> for (item = 0; item != puzzle->xs; item++) {
> memflip(p + block * item, p + puzzle->xoffsets[block] * item,
> block-1);
In this case I don't think you can do inplace processing, and it will
be inefficient using a pixel-per-pixel memflip, in this case I'd
allocate a new buffer (automatically put in outlink->out_buf if you
use the standard start_frame() callback) and move data from
inlink->cur_buf with memcpy from block line to block line.
Also if you want to shuffle lines, you'll need to process the whole
frame in end_frame(), so it seems per-slice processing won't be
easy/convenient in this case.
> // put white pixel in the middle
> p[block*item] = 0xff;
> }
> p += pic->linesize[0];
> }
> return 0;
> }
Note: this code seems to work only with gray8 data, you need to
declare this in query_formats() (the default query_formats() will
accepts *all* formats) and then extend the filter once you get the
gray8 case working.
> static int end_frame(AVFilterLink *link)
> {
> return ff_null_end_frame(link);
> }
pointless wrapper
> AVFilter avfilter_vf_puzzle = {
> .name = "puzzle",
> .description = NULL_IF_CONFIG_SMALL("Create a fuckin' puzzle from the given video"),
Make sure that little boys/girls won't read this ;-).
Nit: missing ending point.
[...]
--
FFmpeg = Fierce and Free Monstrous Peaceless Elected Game
More information about the ffmpeg-devel
mailing list