35155
|
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];
|
35411
|
41 int buffer_filled;
|
35155
|
42 int w, h;
|
|
43 } vd_black_ctx;
|
|
44
|
|
45 static const unsigned int fmt_list[] = {
|
|
46 IMGFMT_YV12,
|
|
47 IMGFMT_IYUV,
|
|
48 IMGFMT_I420,
|
|
49 IMGFMT_UYVY,
|
|
50 IMGFMT_YUY2,
|
|
51 IMGFMT_BGR24,
|
|
52 IMGFMT_RGB24,
|
|
53 0
|
|
54 };
|
|
55
|
|
56 // to set/get/query special features/parameters
|
|
57 static int control(sh_video_t *sh, int cmd, void *arg, ...)
|
|
58 {
|
|
59 unsigned int format;
|
|
60 const unsigned int *p;
|
|
61
|
|
62 switch (cmd) {
|
|
63 case VDCTRL_QUERY_FORMAT:
|
|
64 format = *(unsigned int *)arg;
|
|
65 for (p = fmt_list; *p; ++p)
|
|
66 if (format == *p)
|
|
67 return CONTROL_TRUE;
|
|
68 return CONTROL_FALSE;
|
|
69 }
|
|
70
|
|
71 return CONTROL_UNKNOWN;
|
|
72 }
|
|
73
|
|
74 // init driver
|
|
75 static int init(sh_video_t *sh)
|
|
76 {
|
|
77 unsigned int format;
|
|
78 vd_black_ctx *ctx;
|
|
79 int w, h;
|
|
80 int i;
|
|
81
|
|
82 ctx = sh->context = calloc(1, sizeof(*ctx));
|
|
83 if (!ctx)
|
|
84 return 0;
|
|
85
|
|
86 ctx->w = w = sh->disp_w;
|
|
87 ctx->h = h = sh->disp_h;
|
|
88 if (!mpcodecs_config_vo(sh, w, h, IMGFMT_BGR24))
|
|
89 goto error;
|
|
90 format = sh->codec->outfmt[sh->outfmtidx];
|
|
91
|
|
92 mp_msg(MSGT_DECVIDEO, MSGL_INFO, "[vd_black] format: %s\n", vo_format_name(format));
|
|
93 switch (format) {
|
|
94 case IMGFMT_RGB24:
|
|
95 case IMGFMT_BGR24:
|
|
96 ctx->planes[0] = malloc(w * h * 3);
|
|
97 if (!ctx->planes[0])
|
|
98 goto error;
|
|
99 ctx->stride[0] = w * 3;
|
|
100 memset(ctx->planes[0], 0, w * h * 3);
|
|
101 break;
|
|
102 case IMGFMT_UYVY:
|
|
103 case IMGFMT_YUY2:
|
|
104 ctx->planes[0] = malloc(w * h * 2);
|
|
105 ctx->stride[0] = w * 2;
|
|
106 if (format == IMGFMT_UYVY) {
|
|
107 for (i = 0; i < w * h * 2; i += 4) {
|
|
108 ctx->planes[0][i + 0] = 128;
|
|
109 ctx->planes[0][i + 1] = 16;
|
|
110 ctx->planes[0][i + 2] = 128;
|
|
111 ctx->planes[0][i + 3] = 16;
|
|
112 }
|
|
113 } else {
|
|
114 for (i = 0; i < w * h * 2; i += 4) {
|
|
115 ctx->planes[0][i + 0] = 16;
|
|
116 ctx->planes[0][i + 1] = 128;
|
|
117 ctx->planes[0][i + 2] = 16;
|
|
118 ctx->planes[0][i + 3] = 128;
|
|
119 }
|
|
120 }
|
|
121
|
|
122 break;
|
|
123 case IMGFMT_YV12:
|
|
124 case IMGFMT_IYUV:
|
|
125 case IMGFMT_I420:
|
|
126 ctx->planes[0] = malloc(w * h);
|
|
127 ctx->planes[1] = malloc(w * h / 4);
|
|
128 ctx->planes[2] = malloc(w * h / 4);
|
|
129 if (!ctx->planes[0] || !ctx->planes[1] || !ctx->planes[2])
|
|
130 goto error;
|
|
131 ctx->stride[0] = w;
|
|
132 ctx->stride[1] = w / 2;
|
|
133 ctx->stride[2] = w / 2;
|
|
134 memset(ctx->planes[0], 16, w * h);
|
|
135 memset(ctx->planes[1], 128, w * h / 4);
|
|
136 memset(ctx->planes[2], 128, w * h / 4);
|
|
137 break;
|
|
138 default:
|
|
139 goto error;
|
|
140 }
|
|
141
|
|
142 return 1;
|
|
143
|
|
144 error:
|
|
145 uninit(sh);
|
|
146 return 0;
|
|
147 }
|
|
148
|
|
149 // uninit driver
|
|
150 static void uninit(sh_video_t *sh)
|
|
151 {
|
|
152 int i;
|
|
153 vd_black_ctx *ctx = sh->context;
|
|
154
|
|
155 for (i = 0; i < MP_MAX_PLANES; ++i) {
|
35188
|
156 free(ctx->planes[i]);
|
|
157 ctx->planes[i] = NULL;
|
35155
|
158 }
|
|
159
|
|
160 free(ctx);
|
|
161 }
|
|
162
|
|
163 // decode a frame
|
|
164 static mp_image_t* decode(sh_video_t *sh, void *data, int len, int flags)
|
|
165 {
|
|
166 mp_image_t *mpi = NULL;
|
|
167 vd_black_ctx *ctx = sh->context;
|
|
168 int i;
|
|
169
|
35411
|
170 if (sh->num_buffered_pts == FF_ARRAY_ELEMS(sh->buffered_pts) - 1)
|
|
171 ctx->buffer_filled = 1;
|
|
172 if (!ctx->buffer_filled || !sh->num_buffered_pts)
|
35155
|
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 }
|