1/* 2 * Copyright (c) 2009 Stefano Sabatini 3 * 4 * This file is part of Libav. 5 * 6 * Libav is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * Libav is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with Libav; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21/** 22 * @file 23 * pixdesc test filter 24 */ 25 26#include "libavutil/pixdesc.h" 27#include "avfilter.h" 28 29typedef struct { 30 const AVPixFmtDescriptor *pix_desc; 31 uint16_t *line; 32} PixdescTestContext; 33 34static av_cold void uninit(AVFilterContext *ctx) 35{ 36 PixdescTestContext *priv = ctx->priv; 37 av_freep(&priv->line); 38} 39 40static int config_props(AVFilterLink *inlink) 41{ 42 PixdescTestContext *priv = inlink->dst->priv; 43 44 priv->pix_desc = &av_pix_fmt_descriptors[inlink->format]; 45 46 if (!(priv->line = av_malloc(sizeof(*priv->line) * inlink->w))) 47 return AVERROR(ENOMEM); 48 49 return 0; 50} 51 52static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) 53{ 54 PixdescTestContext *priv = inlink->dst->priv; 55 AVFilterLink *outlink = inlink->dst->outputs[0]; 56 AVFilterBufferRef *outpicref; 57 int i; 58 59 outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, 60 outlink->w, outlink->h); 61 outpicref = outlink->out_buf; 62 avfilter_copy_buffer_ref_props(outpicref, picref); 63 64 for (i = 0; i < 4; i++) { 65 int h = outlink->h; 66 h = i == 1 || i == 2 ? h>>priv->pix_desc->log2_chroma_h : h; 67 if (outpicref->data[i]) { 68 uint8_t *data = outpicref->data[i] + 69 (outpicref->linesize[i] > 0 ? 0 : outpicref->linesize[i] * (h-1)); 70 memset(data, 0, FFABS(outpicref->linesize[i]) * h); 71 } 72 } 73 74 /* copy palette */ 75 if (priv->pix_desc->flags & PIX_FMT_PAL) 76 memcpy(outpicref->data[1], outpicref->data[1], 256*4); 77 78 avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); 79} 80 81static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) 82{ 83 PixdescTestContext *priv = inlink->dst->priv; 84 AVFilterBufferRef *inpic = inlink->cur_buf; 85 AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf; 86 int i, c, w = inlink->w; 87 88 for (c = 0; c < priv->pix_desc->nb_components; c++) { 89 int w1 = c == 1 || c == 2 ? w>>priv->pix_desc->log2_chroma_w : w; 90 int h1 = c == 1 || c == 2 ? h>>priv->pix_desc->log2_chroma_h : h; 91 int y1 = c == 1 || c == 2 ? y>>priv->pix_desc->log2_chroma_h : y; 92 93 for (i = y1; i < y1 + h1; i++) { 94 av_read_image_line(priv->line, 95 inpic->data, 96 inpic->linesize, 97 priv->pix_desc, 98 0, i, c, w1, 0); 99 100 av_write_image_line(priv->line, 101 outpic->data, 102 outpic->linesize, 103 priv->pix_desc, 104 0, i, c, w1); 105 } 106 } 107 108 avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); 109} 110 111AVFilter avfilter_vf_pixdesctest = { 112 .name = "pixdesctest", 113 .description = NULL_IF_CONFIG_SMALL("Test pixel format definitions."), 114 115 .priv_size = sizeof(PixdescTestContext), 116 .uninit = uninit, 117 118 .inputs = (AVFilterPad[]) {{ .name = "default", 119 .type = AVMEDIA_TYPE_VIDEO, 120 .start_frame = start_frame, 121 .draw_slice = draw_slice, 122 .config_props = config_props, 123 .min_perms = AV_PERM_READ, }, 124 { .name = NULL}}, 125 126 .outputs = (AVFilterPad[]) {{ .name = "default", 127 .type = AVMEDIA_TYPE_VIDEO, }, 128 { .name = NULL}}, 129}; 130