Mercurial > mplayer.hg
changeset 35155:303bf4bab982
libmpcodecs: Add vd_black
New video "decoder" dedicated to just outputting black frames.
Can be used to e.g. test filters and video outputs.
Initially implemented inside vd null by Xidorn Quan >quanxunzhen gmail.com<
separated into vd black plus some minor (mostly style) changes by me.
author | al |
---|---|
date | Mon, 15 Oct 2012 19:43:15 +0000 |
parents | 0dce150a6f51 |
children | 101333b48b4e |
files | Makefile codec-cfg.c etc/codecs.conf libmpcodecs/vd.c libmpcodecs/vd_black.c |
diffstat | 5 files changed, 200 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Sun Oct 14 20:06:09 2012 +0000 +++ b/Makefile Mon Oct 15 19:43:15 2012 +0000 @@ -349,6 +349,7 @@ libmpcodecs/vd_null.c \ libmpcodecs/vd_raw.c \ libmpcodecs/vd_sgi.c \ + libmpcodecs/vd_black.c \ libmpcodecs/vf.c \ libmpcodecs/vf_1bpp.c \ libmpcodecs/vf_2xsai.c \
--- a/codec-cfg.c Sun Oct 14 20:06:09 2012 +0000 +++ b/codec-cfg.c Mon Oct 15 19:43:15 2012 +0000 @@ -870,8 +870,8 @@ for (/* NOTHING */; i--; c++) { if(start && c<=start) continue; for (j = 0; j < CODECS_MAX_FOURCC; j++) { - // FIXME: do NOT hardwire 'null' name here: - if (c->fourcc[j]==fourcc || !strcmp(c->drv,"null")) { + // FIXME: do NOT hardwire 'null' and 'black' here: + if (c->fourcc[j]==fourcc || !strcmp(c->drv,"null") || !strcmp(c->drv,"black")) { if (fourccmap) *fourccmap = c->fourccmap[j]; return c;
--- a/etc/codecs.conf Sun Oct 14 20:06:09 2012 +0000 +++ b/etc/codecs.conf Mon Oct 15 19:43:15 2012 +0000 @@ -4217,6 +4217,17 @@ out YVU9 out BGR32,BGR24,BGR16,BGR15 +videocodec black + info "black codec (no decoding just output black frames!)" + status working + comment "for unknown/unsupported codecs or testing" + driver black + out YV12 + out I420 + out YUY2 + out UYVY + out RGB24,BGR32 + ;============================================================================= ; AUDIO CODECS ;=============================================================================
--- a/libmpcodecs/vd.c Sun Oct 14 20:06:09 2012 +0000 +++ b/libmpcodecs/vd.c Mon Oct 15 19:43:15 2012 +0000 @@ -37,6 +37,7 @@ #include "vf.h" extern const vd_functions_t mpcodecs_vd_null; +extern const vd_functions_t mpcodecs_vd_black; extern const vd_functions_t mpcodecs_vd_ffmpeg; extern const vd_functions_t mpcodecs_vd_theora; extern const vd_functions_t mpcodecs_vd_dshow; @@ -65,6 +66,7 @@ const vd_functions_t * const mpcodecs_vd_drivers[] = { &mpcodecs_vd_null, + &mpcodecs_vd_black, #ifdef CONFIG_FFMPEG &mpcodecs_vd_ffmpeg, #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpcodecs/vd_black.c Mon Oct 15 19:43:15 2012 +0000 @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2012 Xidorn Quan + * + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <stdlib.h> + +#include "config.h" +#include "mp_msg.h" + +#include "vd_internal.h" + +static const vd_info_t info = { + "black video generator", + "black", + "", + "Xidorn Quan", + "no decoding, always outputs black frames" +}; + +LIBVD_EXTERN(black) + +typedef struct { + unsigned char *planes[MP_MAX_PLANES]; + int stride[MP_MAX_PLANES]; + int w, h; +} vd_black_ctx; + +static const unsigned int fmt_list[] = { + IMGFMT_YV12, + IMGFMT_IYUV, + IMGFMT_I420, + IMGFMT_UYVY, + IMGFMT_YUY2, + IMGFMT_BGR24, + IMGFMT_RGB24, + 0 +}; + +// to set/get/query special features/parameters +static int control(sh_video_t *sh, int cmd, void *arg, ...) +{ + unsigned int format; + const unsigned int *p; + + switch (cmd) { + case VDCTRL_QUERY_FORMAT: + format = *(unsigned int *)arg; + for (p = fmt_list; *p; ++p) + if (format == *p) + return CONTROL_TRUE; + return CONTROL_FALSE; + } + + return CONTROL_UNKNOWN; +} + +// init driver +static int init(sh_video_t *sh) +{ + unsigned int format; + vd_black_ctx *ctx; + int w, h; + int i; + + ctx = sh->context = calloc(1, sizeof(*ctx)); + if (!ctx) + return 0; + + ctx->w = w = sh->disp_w; + ctx->h = h = sh->disp_h; + if (!mpcodecs_config_vo(sh, w, h, IMGFMT_BGR24)) + goto error; + format = sh->codec->outfmt[sh->outfmtidx]; + + mp_msg(MSGT_DECVIDEO, MSGL_INFO, "[vd_black] format: %s\n", vo_format_name(format)); + switch (format) { + case IMGFMT_RGB24: + case IMGFMT_BGR24: + ctx->planes[0] = malloc(w * h * 3); + if (!ctx->planes[0]) + goto error; + ctx->stride[0] = w * 3; + memset(ctx->planes[0], 0, w * h * 3); + break; + case IMGFMT_UYVY: + case IMGFMT_YUY2: + ctx->planes[0] = malloc(w * h * 2); + ctx->stride[0] = w * 2; + if (format == IMGFMT_UYVY) { + for (i = 0; i < w * h * 2; i += 4) { + ctx->planes[0][i + 0] = 128; + ctx->planes[0][i + 1] = 16; + ctx->planes[0][i + 2] = 128; + ctx->planes[0][i + 3] = 16; + } + } else { + for (i = 0; i < w * h * 2; i += 4) { + ctx->planes[0][i + 0] = 16; + ctx->planes[0][i + 1] = 128; + ctx->planes[0][i + 2] = 16; + ctx->planes[0][i + 3] = 128; + } + } + + break; + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + ctx->planes[0] = malloc(w * h); + ctx->planes[1] = malloc(w * h / 4); + ctx->planes[2] = malloc(w * h / 4); + if (!ctx->planes[0] || !ctx->planes[1] || !ctx->planes[2]) + goto error; + ctx->stride[0] = w; + ctx->stride[1] = w / 2; + ctx->stride[2] = w / 2; + memset(ctx->planes[0], 16, w * h); + memset(ctx->planes[1], 128, w * h / 4); + memset(ctx->planes[2], 128, w * h / 4); + break; + default: + goto error; + } + + return 1; + +error: + uninit(sh); + return 0; +} + +// uninit driver +static void uninit(sh_video_t *sh) +{ + int i; + vd_black_ctx *ctx = sh->context; + + for (i = 0; i < MP_MAX_PLANES; ++i) { + if (ctx->planes[i]) { + free(ctx->planes[i]); + ctx->planes[i] = NULL; + } + } + + free(ctx); +} + +// decode a frame +static mp_image_t* decode(sh_video_t *sh, void *data, int len, int flags) +{ + mp_image_t *mpi = NULL; + vd_black_ctx *ctx = sh->context; + int i; + + if (sh->num_buffered_pts != + sizeof(sh->buffered_pts) / sizeof(sh->buffered_pts[0]) - 1) + return NULL; + + mpi = mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, MP_IMGFLAG_PRESERVE, + ctx->w, ctx->h); + if (!mpi) + return NULL; + for (i = 0; i < MP_MAX_PLANES; ++i) { + mpi->planes[i] = ctx->planes[i]; + mpi->stride[i] = ctx->stride[i]; + } + return mpi; +}