13395
|
1 /* ------------------------------------------------------------------------- */
|
|
2
|
|
3 /*
|
|
4 * vo_md5sum.c, md5sum Video Output Driver for MPlayer
|
|
5 *
|
|
6 *
|
|
7 * Written by Ivo van Poorten. (GPL)2004
|
|
8 *
|
|
9 *
|
|
10 * Changelog
|
|
11 *
|
|
12 * 2004-09-13 First draft.
|
|
13 * 2004-09-16 Second draft. It now acts on VOCTRL_DRAW_IMAGE and does not
|
|
14 * maintain a local copy of the image if the format is YV12.
|
|
15 * Speed improvement and uses less memory.
|
|
16 *
|
|
17 */
|
|
18
|
|
19 /* ------------------------------------------------------------------------- */
|
|
20
|
|
21 /* Global Includes */
|
|
22
|
|
23 #include <stdio.h>
|
|
24 #include <stdlib.h>
|
|
25 #include <string.h>
|
|
26 #include <errno.h>
|
|
27
|
|
28 /* ------------------------------------------------------------------------- */
|
|
29
|
|
30 /* Local Includes */
|
|
31
|
|
32 #include "config.h"
|
|
33 #include "mp_msg.h"
|
|
34 #include "video_out.h"
|
|
35 #include "video_out_internal.h"
|
|
36 #include "mplayer.h" /* for exit_player() */
|
|
37 #include "help_mp.h"
|
|
38 #include "md5sum.h"
|
|
39
|
|
40 /* ------------------------------------------------------------------------- */
|
|
41
|
|
42 /* Defines */
|
|
43
|
|
44 /* Used for temporary buffers to store file- and pathnames */
|
|
45 #define BUFLENGTH 512
|
|
46
|
|
47 /* ------------------------------------------------------------------------- */
|
|
48
|
|
49 /* Info */
|
|
50
|
|
51 static vo_info_t info=
|
|
52 {
|
|
53 "md5sum of each frame",
|
|
54 "md5sum",
|
|
55 "Ivo van Poorten (ivop@euronet.nl)",
|
|
56 ""
|
|
57 };
|
|
58
|
|
59 LIBVO_EXTERN (md5sum)
|
|
60
|
|
61 /* ------------------------------------------------------------------------- */
|
|
62
|
|
63 /* Global Variables */
|
|
64
|
|
65 char *md5sum_outfile = NULL;
|
|
66
|
|
67 FILE *md5sum_fd;
|
|
68 int framenum = 0;
|
|
69
|
|
70 /* ------------------------------------------------------------------------- */
|
|
71
|
|
72 /** \brief Memory allocation failed.
|
|
73 *
|
|
74 * The video output driver failed to allocate a block of memory it needed.
|
|
75 * It displays a message and exits the player.
|
|
76 *
|
|
77 * \return nothing It does not return.
|
|
78 */
|
|
79
|
|
80 void md5sum_malloc_failed(void) {
|
|
81 mp_msg(MSGT_VO, MSGL_ERR, "%s: %s\n", info.short_name,
|
|
82 MSGTR_MemAllocFailed);
|
|
83 exit_player(MSGTR_Exit_error);
|
|
84 }
|
|
85
|
|
86 /* ------------------------------------------------------------------------- */
|
|
87
|
|
88 /** \brief An error occured while writing to a file.
|
|
89 *
|
|
90 * The program failed to write data to a file.
|
|
91 * It displays a message and exits the player.
|
|
92 *
|
|
93 * \return nothing It does not return.
|
|
94 */
|
|
95
|
|
96 void md5sum_write_error(void) {
|
|
97 mp_msg(MSGT_VO, MSGL_ERR, MSGTR_ErrorWritingFile, info.short_name);
|
|
98 exit_player(MSGTR_Exit_error);
|
|
99 }
|
|
100
|
|
101 /* ------------------------------------------------------------------------- */
|
|
102
|
|
103 /** \brief Pre-initialisation.
|
|
104 *
|
|
105 * This function is called before initialising the video output driver. It
|
|
106 * parses all suboptions and sets variables accordingly. If an error occurs
|
|
107 * (like an option being out of range, not having any value or an unknown
|
|
108 * option is stumbled upon) the player will exit. It also sets default
|
|
109 * values if necessary.
|
|
110 *
|
|
111 * \param arg A string containing all the suboptions passed to the video
|
|
112 * output driver.
|
|
113 *
|
|
114 * \return 0 All went well.
|
|
115 */
|
|
116
|
|
117 static uint32_t preinit(const char *arg)
|
|
118 {
|
|
119 char *buf; /* buf is used to store parsed string values */
|
|
120
|
|
121 mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name,
|
|
122 MSGTR_VO_ParsingSuboptions);
|
|
123
|
|
124 if (arg) {
|
|
125
|
|
126 while (*arg != '\0') {
|
|
127 if (!strncmp(arg, ":", 1)) {
|
|
128 arg++;
|
|
129 continue; /* multiple ':' is not really an error */
|
|
130 } else if (!strncmp(arg, "outfile=", 8)) {
|
|
131 arg += 8;
|
|
132 buf = malloc(strlen(arg)+1); /* maximum length possible */
|
|
133 if (!buf) {
|
|
134 md5sum_malloc_failed(); /* message and exit_player! */
|
|
135 }
|
|
136 if (sscanf(arg, "%[^:]", buf) == 1) {
|
|
137 mp_msg(MSGT_VO, MSGL_INFO, "%s: %s --> %s\n",
|
|
138 info.short_name, "outfile", buf);
|
|
139 arg += strlen(buf);
|
|
140 md5sum_outfile = strdup(buf);
|
|
141 if (!md5sum_outfile) md5sum_malloc_failed();
|
|
142 free(buf);
|
|
143 } else {
|
|
144 mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n",
|
|
145 info.short_name, "outfile",
|
|
146 MSGTR_VO_NoValueSpecified);
|
|
147 exit_player(MSGTR_Exit_error);
|
|
148 }
|
|
149 } else {
|
|
150 mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %-20s...\n", info.short_name,
|
|
151 MSGTR_VO_UnknownSuboptions, arg);
|
|
152 exit_player(MSGTR_Exit_error);
|
|
153 }
|
|
154 } /* end while */
|
|
155 } /* endif */
|
|
156
|
|
157 /* If md5sum_outfile is not set by an option, resort to default of
|
|
158 "md5sums" */
|
|
159 if (!md5sum_outfile) {
|
|
160 md5sum_outfile = strdup("md5sums");
|
|
161 if (!md5sum_outfile) md5sum_malloc_failed();
|
|
162 }
|
|
163
|
|
164 mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name,
|
|
165 MSGTR_VO_SuboptionsParsedOK);
|
|
166 return 0;
|
|
167 }
|
|
168
|
|
169 /* ------------------------------------------------------------------------- */
|
|
170
|
|
171 /** \brief Configure the video output driver.
|
|
172 *
|
|
173 * This functions configures the video output driver. It opens the output
|
|
174 * file to which this driver will write all the MD5 sums. If something
|
|
175 * goes wrong, the player will exit.
|
|
176 *
|
|
177 * \return 0 All went well.
|
|
178 */
|
|
179
|
|
180 static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width,
|
|
181 uint32_t d_height, uint32_t fullscreen, char *title,
|
|
182 uint32_t format)
|
|
183 {
|
|
184 if (vo_config_count > 0 ) { /* Already configured */
|
|
185 return 0;
|
|
186 }
|
|
187
|
|
188 if ( (md5sum_fd = fopen(md5sum_outfile, "w") ) == NULL ) {
|
|
189 mp_msg(MSGT_VO, MSGL_ERR, "\n%s: %s\n", info.short_name,
|
|
190 MSGTR_VO_CantCreateFile);
|
|
191 mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n",
|
|
192 info.short_name, MSGTR_VO_GenericError, strerror(errno) );
|
|
193 exit_player(MSGTR_Exit_error);
|
|
194 }
|
|
195
|
|
196 return 0;
|
|
197 }
|
|
198
|
|
199 /* ------------------------------------------------------------------------- */
|
|
200
|
|
201 /** \brief Write MD5 sum to output file.
|
|
202 *
|
|
203 * This function writes an ASCII representation of a 16-byte hexadecimal
|
|
204 * MD5 sum to our output file. The file descriptor is a global variable.
|
|
205 *
|
|
206 * \param md5sum Sixteen bytes that represent an MD5 sum.
|
|
207 *
|
|
208 * \return None The player will exit if a write error occurs.
|
|
209 */
|
|
210
|
|
211 static void md5sum_output_sum(unsigned char *md5sum) {
|
|
212 int i;
|
|
213
|
|
214 for(i=0; i<16; i++) {
|
|
215 if ( fprintf(md5sum_fd, "%02x", md5sum[i]) < 0 ) md5sum_write_error();
|
|
216 }
|
|
217 if ( fprintf(md5sum_fd, " frame%08d\n", framenum) < 0 )
|
|
218 md5sum_write_error();
|
|
219
|
|
220 framenum++;
|
|
221 }
|
|
222
|
|
223 /* ------------------------------------------------------------------------- */
|
|
224
|
|
225 static uint32_t draw_frame(uint8_t *src[])
|
|
226 {
|
|
227 mp_msg(MSGT_VO, MSGL_V, "%s: draw_frame() is called!\n", info.short_name);
|
|
228 return -1;
|
|
229 }
|
|
230
|
|
231 /* ------------------------------------------------------------------------- */
|
|
232
|
|
233 static uint32_t draw_image(mp_image_t *mpi)
|
|
234 {
|
|
235 unsigned char md5sum[16];
|
|
236 uint32_t w = mpi->w;
|
|
237 uint32_t h = mpi->h;
|
|
238 uint8_t *rgbimage = mpi->planes[0];
|
|
239 uint8_t *planeY = mpi->planes[0];
|
|
240 uint8_t *planeU = mpi->planes[1];
|
|
241 uint8_t *planeV = mpi->planes[2];
|
|
242 uint32_t strideY = mpi->stride[0];
|
|
243 uint32_t strideU = mpi->stride[1];
|
|
244 uint32_t strideV = mpi->stride[2];
|
|
245
|
|
246 auth_md5Ctx md5_context;
|
|
247 int i;
|
|
248
|
|
249 if (mpi->flags & MP_IMGFLAG_PLANAR) { /* Planar */
|
|
250 if (mpi->flags & MP_IMGFLAG_YUV) { /* Planar YUV */
|
|
251 auth_md5InitCtx(&md5_context);
|
|
252 for (i=0; i<h; i++) {
|
|
253 auth_md5SumCtx(&md5_context, planeY + i * strideY, w);
|
|
254 }
|
|
255 w = w / 2;
|
|
256 h = h / 2;
|
|
257 for (i=0; i<h; i++) {
|
|
258 auth_md5SumCtx(&md5_context, planeU + i * strideU, w);
|
|
259 auth_md5SumCtx(&md5_context, planeV + i * strideV, w);
|
|
260 }
|
|
261 auth_md5CloseCtx(&md5_context, md5sum);
|
|
262 md5sum_output_sum(md5sum);
|
|
263 return VO_TRUE;
|
|
264 } else { /* Planar RGB */
|
|
265 return VO_FALSE;
|
|
266 }
|
|
267 } else { /* Packed */
|
|
268 if (mpi->flags & MP_IMGFLAG_YUV) { /* Packed YUV */
|
|
269
|
|
270 return VO_FALSE;
|
|
271 } else { /* Packed RGB */
|
|
272 auth_md5Sum(md5sum, rgbimage, mpi->w * (mpi->bpp >> 3) * mpi->h);
|
|
273 md5sum_output_sum(md5sum);
|
|
274 return VO_TRUE;
|
|
275 }
|
|
276 }
|
|
277
|
|
278 return VO_FALSE;
|
|
279 }
|
|
280
|
|
281 /* ------------------------------------------------------------------------- */
|
|
282
|
|
283 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h,
|
|
284 int x, int y)
|
|
285 {
|
|
286 return 0;
|
|
287 }
|
|
288
|
|
289 /* ------------------------------------------------------------------------- */
|
|
290
|
|
291 static uint32_t query_format(uint32_t format)
|
|
292 {
|
|
293 switch (format) {
|
|
294 case IMGFMT_RGB24:
|
|
295 case IMGFMT_YV12:
|
|
296 return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW;
|
|
297 default:
|
|
298 return 0;
|
|
299 }
|
|
300 }
|
|
301
|
|
302 /* ------------------------------------------------------------------------- */
|
|
303
|
|
304 static uint32_t control(uint32_t request, void *data, ...)
|
|
305 {
|
|
306 switch (request) {
|
|
307 case VOCTRL_QUERY_FORMAT:
|
|
308 return query_format(*((uint32_t*)data));
|
|
309 case VOCTRL_DRAW_IMAGE:
|
|
310 return draw_image(data);
|
|
311 }
|
|
312 return VO_NOTIMPL;
|
|
313 }
|
|
314
|
|
315 /* ------------------------------------------------------------------------- */
|
|
316
|
|
317 static void uninit(void)
|
|
318 {
|
|
319 if (md5sum_outfile) {
|
|
320 free(md5sum_outfile);
|
|
321 md5sum_outfile = NULL;
|
|
322 }
|
|
323 if (md5sum_fd) fclose(md5sum_fd);
|
|
324 }
|
|
325
|
|
326 /* ------------------------------------------------------------------------- */
|
|
327
|
|
328 static void check_events(void)
|
|
329 {
|
|
330 }
|
|
331
|
|
332 /* ------------------------------------------------------------------------- */
|
|
333
|
|
334 static void draw_osd(void)
|
|
335 {
|
|
336 }
|
|
337
|
|
338 /* ------------------------------------------------------------------------- */
|
|
339
|
|
340 static void flip_page (void)
|
|
341 {
|
|
342 }
|
|
343
|
|
344 /* ------------------------------------------------------------------------- */
|
|
345
|
|
346 #undef BUFLENGTH
|
|
347 #undef MD5SUM_RGB_MODE
|
|
348 #undef MD5SUM_YUV_MODE
|
|
349
|
|
350 /* ------------------------------------------------------------------------- */
|
|
351
|