comparison libmpcodecs/vd_black.c @ 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
children 36d09dcaf732
comparison
equal deleted inserted replaced
35154:0dce150a6f51 35155:303bf4bab982
1 /*
2 * Copyright (C) 2012 Xidorn Quan
3 *
4 * This file is part of MPlayer.
5 *
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * MPlayer 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include <stdlib.h>
22
23 #include "config.h"
24 #include "mp_msg.h"
25
26 #include "vd_internal.h"
27
28 static const vd_info_t info = {
29 "black video generator",
30 "black",
31 "",
32 "Xidorn Quan",
33 "no decoding, always outputs black frames"
34 };
35
36 LIBVD_EXTERN(black)
37
38 typedef struct {
39 unsigned char *planes[MP_MAX_PLANES];
40 int stride[MP_MAX_PLANES];
41 int w, h;
42 } vd_black_ctx;
43
44 static const unsigned int fmt_list[] = {
45 IMGFMT_YV12,
46 IMGFMT_IYUV,
47 IMGFMT_I420,
48 IMGFMT_UYVY,
49 IMGFMT_YUY2,
50 IMGFMT_BGR24,
51 IMGFMT_RGB24,
52 0
53 };
54
55 // to set/get/query special features/parameters
56 static int control(sh_video_t *sh, int cmd, void *arg, ...)
57 {
58 unsigned int format;
59 const unsigned int *p;
60
61 switch (cmd) {
62 case VDCTRL_QUERY_FORMAT:
63 format = *(unsigned int *)arg;
64 for (p = fmt_list; *p; ++p)
65 if (format == *p)
66 return CONTROL_TRUE;
67 return CONTROL_FALSE;
68 }
69
70 return CONTROL_UNKNOWN;
71 }
72
73 // init driver
74 static int init(sh_video_t *sh)
75 {
76 unsigned int format;
77 vd_black_ctx *ctx;
78 int w, h;
79 int i;
80
81 ctx = sh->context = calloc(1, sizeof(*ctx));
82 if (!ctx)
83 return 0;
84
85 ctx->w = w = sh->disp_w;
86 ctx->h = h = sh->disp_h;
87 if (!mpcodecs_config_vo(sh, w, h, IMGFMT_BGR24))
88 goto error;
89 format = sh->codec->outfmt[sh->outfmtidx];
90
91 mp_msg(MSGT_DECVIDEO, MSGL_INFO, "[vd_black] format: %s\n", vo_format_name(format));
92 switch (format) {
93 case IMGFMT_RGB24:
94 case IMGFMT_BGR24:
95 ctx->planes[0] = malloc(w * h * 3);
96 if (!ctx->planes[0])
97 goto error;
98 ctx->stride[0] = w * 3;
99 memset(ctx->planes[0], 0, w * h * 3);
100 break;
101 case IMGFMT_UYVY:
102 case IMGFMT_YUY2:
103 ctx->planes[0] = malloc(w * h * 2);
104 ctx->stride[0] = w * 2;
105 if (format == IMGFMT_UYVY) {
106 for (i = 0; i < w * h * 2; i += 4) {
107 ctx->planes[0][i + 0] = 128;
108 ctx->planes[0][i + 1] = 16;
109 ctx->planes[0][i + 2] = 128;
110 ctx->planes[0][i + 3] = 16;
111 }
112 } else {
113 for (i = 0; i < w * h * 2; i += 4) {
114 ctx->planes[0][i + 0] = 16;
115 ctx->planes[0][i + 1] = 128;
116 ctx->planes[0][i + 2] = 16;
117 ctx->planes[0][i + 3] = 128;
118 }
119 }
120
121 break;
122 case IMGFMT_YV12:
123 case IMGFMT_IYUV:
124 case IMGFMT_I420:
125 ctx->planes[0] = malloc(w * h);
126 ctx->planes[1] = malloc(w * h / 4);
127 ctx->planes[2] = malloc(w * h / 4);
128 if (!ctx->planes[0] || !ctx->planes[1] || !ctx->planes[2])
129 goto error;
130 ctx->stride[0] = w;
131 ctx->stride[1] = w / 2;
132 ctx->stride[2] = w / 2;
133 memset(ctx->planes[0], 16, w * h);
134 memset(ctx->planes[1], 128, w * h / 4);
135 memset(ctx->planes[2], 128, w * h / 4);
136 break;
137 default:
138 goto error;
139 }
140
141 return 1;
142
143 error:
144 uninit(sh);
145 return 0;
146 }
147
148 // uninit driver
149 static void uninit(sh_video_t *sh)
150 {
151 int i;
152 vd_black_ctx *ctx = sh->context;
153
154 for (i = 0; i < MP_MAX_PLANES; ++i) {
155 if (ctx->planes[i]) {
156 free(ctx->planes[i]);
157 ctx->planes[i] = NULL;
158 }
159 }
160
161 free(ctx);
162 }
163
164 // decode a frame
165 static mp_image_t* decode(sh_video_t *sh, void *data, int len, int flags)
166 {
167 mp_image_t *mpi = NULL;
168 vd_black_ctx *ctx = sh->context;
169 int i;
170
171 if (sh->num_buffered_pts !=
172 sizeof(sh->buffered_pts) / sizeof(sh->buffered_pts[0]) - 1)
173 return NULL;
174
175 mpi = mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, MP_IMGFLAG_PRESERVE,
176 ctx->w, ctx->h);
177 if (!mpi)
178 return NULL;
179 for (i = 0; i < MP_MAX_PLANES; ++i) {
180 mpi->planes[i] = ctx->planes[i];
181 mpi->stride[i] = ctx->stride[i];
182 }
183 return mpi;
184 }