yading@10: /* yading@10: * Copyright (c) 2009 Stefano Sabatini yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: /** yading@10: * @file yading@10: * pixdesc test filter yading@10: */ yading@10: yading@10: #include "libavutil/common.h" yading@10: #include "libavutil/pixdesc.h" yading@10: #include "avfilter.h" yading@10: #include "internal.h" yading@10: #include "video.h" yading@10: yading@10: typedef struct { yading@10: const AVPixFmtDescriptor *pix_desc; yading@10: uint16_t *line; yading@10: } PixdescTestContext; yading@10: yading@10: static av_cold void uninit(AVFilterContext *ctx) yading@10: { yading@10: PixdescTestContext *priv = ctx->priv; yading@10: av_freep(&priv->line); yading@10: } yading@10: yading@10: static int config_props(AVFilterLink *inlink) yading@10: { yading@10: PixdescTestContext *priv = inlink->dst->priv; yading@10: yading@10: priv->pix_desc = av_pix_fmt_desc_get(inlink->format); yading@10: yading@10: if (!(priv->line = av_malloc(sizeof(*priv->line) * inlink->w))) yading@10: return AVERROR(ENOMEM); yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: static int filter_frame(AVFilterLink *inlink, AVFrame *in) yading@10: { yading@10: PixdescTestContext *priv = inlink->dst->priv; yading@10: AVFilterLink *outlink = inlink->dst->outputs[0]; yading@10: AVFrame *out; yading@10: int i, c, w = inlink->w, h = inlink->h; yading@10: yading@10: out = ff_get_video_buffer(outlink, outlink->w, outlink->h); yading@10: if (!out) { yading@10: av_frame_free(&in); yading@10: return AVERROR(ENOMEM); yading@10: } yading@10: yading@10: av_frame_copy_props(out, in); yading@10: yading@10: for (i = 0; i < 4; i++) { yading@10: int h = outlink->h; yading@10: h = i == 1 || i == 2 ? h>>priv->pix_desc->log2_chroma_h : h; yading@10: if (out->data[i]) { yading@10: uint8_t *data = out->data[i] + yading@10: (out->linesize[i] > 0 ? 0 : out->linesize[i] * (h-1)); yading@10: memset(data, 0, FFABS(out->linesize[i]) * h); yading@10: } yading@10: } yading@10: yading@10: /* copy palette */ yading@10: if (priv->pix_desc->flags & PIX_FMT_PAL || yading@10: priv->pix_desc->flags & PIX_FMT_PSEUDOPAL) yading@10: memcpy(out->data[1], in->data[1], AVPALETTE_SIZE); yading@10: yading@10: for (c = 0; c < priv->pix_desc->nb_components; c++) { yading@10: int w1 = c == 1 || c == 2 ? w>>priv->pix_desc->log2_chroma_w : w; yading@10: int h1 = c == 1 || c == 2 ? h>>priv->pix_desc->log2_chroma_h : h; yading@10: yading@10: for (i = 0; i < h1; i++) { yading@10: av_read_image_line(priv->line, yading@10: (void*)in->data, yading@10: in->linesize, yading@10: priv->pix_desc, yading@10: 0, i, c, w1, 0); yading@10: yading@10: av_write_image_line(priv->line, yading@10: out->data, yading@10: out->linesize, yading@10: priv->pix_desc, yading@10: 0, i, c, w1); yading@10: } yading@10: } yading@10: yading@10: av_frame_free(&in); yading@10: return ff_filter_frame(outlink, out); yading@10: } yading@10: yading@10: static const AVFilterPad avfilter_vf_pixdesctest_inputs[] = { yading@10: { yading@10: .name = "default", yading@10: .type = AVMEDIA_TYPE_VIDEO, yading@10: .filter_frame = filter_frame, yading@10: .config_props = config_props, yading@10: }, yading@10: { NULL } yading@10: }; yading@10: yading@10: static const AVFilterPad avfilter_vf_pixdesctest_outputs[] = { yading@10: { yading@10: .name = "default", yading@10: .type = AVMEDIA_TYPE_VIDEO, yading@10: }, yading@10: { NULL } yading@10: }; yading@10: yading@10: AVFilter avfilter_vf_pixdesctest = { yading@10: .name = "pixdesctest", yading@10: .description = NULL_IF_CONFIG_SMALL("Test pixel format definitions."), yading@10: yading@10: .priv_size = sizeof(PixdescTestContext), yading@10: .uninit = uninit, yading@10: yading@10: .inputs = avfilter_vf_pixdesctest_inputs, yading@10: yading@10: .outputs = avfilter_vf_pixdesctest_outputs, yading@10: };