1 /* ------------------------------------------------------------------------- */
4 * vo_md5sum.c, md5sum Video Output Driver for MPlayer
7 * Written by Ivo van Poorten. (GPL)2004
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.
19 /* ------------------------------------------------------------------------- */
28 /* ------------------------------------------------------------------------- */
34 #include "video_out.h"
35 #include "video_out_internal.h"
36 #include "mplayer.h" /* for exit_player() */
40 /* ------------------------------------------------------------------------- */
44 /* Used for temporary buffers to store file- and pathnames */
47 /* ------------------------------------------------------------------------- */
51 static vo_info_t info
=
53 "md5sum of each frame",
55 "Ivo van Poorten (ivop@euronet.nl)",
61 /* ------------------------------------------------------------------------- */
63 /* Global Variables */
65 char *md5sum_outfile
= NULL
;
70 /* ------------------------------------------------------------------------- */
72 /** \brief Memory allocation failed.
74 * The video output driver failed to allocate a block of memory it needed.
75 * It displays a message and exits the player.
77 * \return nothing It does not return.
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
);
86 /* ------------------------------------------------------------------------- */
88 /** \brief An error occured while writing to a file.
90 * The program failed to write data to a file.
91 * It displays a message and exits the player.
93 * \return nothing It does not return.
96 void md5sum_write_error(void) {
97 mp_msg(MSGT_VO
, MSGL_ERR
, MSGTR_ErrorWritingFile
, info
.short_name
);
98 exit_player(MSGTR_Exit_error
);
101 /* ------------------------------------------------------------------------- */
103 /** \brief Pre-initialisation.
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.
111 * \param arg A string containing all the suboptions passed to the video
114 * \return 0 All went well.
117 static uint32_t preinit(const char *arg
)
119 char *buf
; /* buf is used to store parsed string values */
121 mp_msg(MSGT_VO
, MSGL_INFO
, "%s: %s\n", info
.short_name
,
122 MSGTR_VO_ParsingSuboptions
);
126 while (*arg
!= '\0') {
127 if (!strncmp(arg
, ":", 1)) {
129 continue; /* multiple ':' is not really an error */
130 } else if (!strncmp(arg
, "outfile=", 8)) {
132 buf
= malloc(strlen(arg
)+1); /* maximum length possible */
134 md5sum_malloc_failed(); /* message and exit_player! */
136 if (sscanf(arg
, "%[^:]", buf
) == 1) {
137 mp_msg(MSGT_VO
, MSGL_INFO
, "%s: %s --> %s\n",
138 info
.short_name
, "outfile", buf
);
140 md5sum_outfile
= strdup(buf
);
141 if (!md5sum_outfile
) md5sum_malloc_failed();
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
);
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
);
157 /* If md5sum_outfile is not set by an option, resort to default of
159 if (!md5sum_outfile
) {
160 md5sum_outfile
= strdup("md5sums");
161 if (!md5sum_outfile
) md5sum_malloc_failed();
164 mp_msg(MSGT_VO
, MSGL_INFO
, "%s: %s\n", info
.short_name
,
165 MSGTR_VO_SuboptionsParsedOK
);
169 /* ------------------------------------------------------------------------- */
171 /** \brief Configure the video output driver.
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.
177 * \return 0 All went well.
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
,
184 if (vo_config_count
> 0 ) { /* Already configured */
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
);
199 /* ------------------------------------------------------------------------- */
201 /** \brief Write MD5 sum to output file.
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.
206 * \param md5sum Sixteen bytes that represent an MD5 sum.
208 * \return None The player will exit if a write error occurs.
211 static void md5sum_output_sum(unsigned char *md5sum
) {
214 for(i
=0; i
<16; i
++) {
215 if ( fprintf(md5sum_fd
, "%02x", md5sum
[i
]) < 0 ) md5sum_write_error();
217 if ( fprintf(md5sum_fd
, " frame%08d\n", framenum
) < 0 )
218 md5sum_write_error();
223 /* ------------------------------------------------------------------------- */
225 static uint32_t draw_frame(uint8_t *src
[])
227 mp_msg(MSGT_VO
, MSGL_V
, "%s: draw_frame() is called!\n", info
.short_name
);
231 /* ------------------------------------------------------------------------- */
233 static uint32_t draw_image(mp_image_t
*mpi
)
235 unsigned char md5sum
[16];
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];
246 auth_md5Ctx md5_context
;
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
);
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
);
261 auth_md5CloseCtx(&md5_context
, md5sum
);
262 md5sum_output_sum(md5sum
);
264 } else { /* Planar RGB */
267 } else { /* Packed */
268 if (mpi
->flags
& MP_IMGFLAG_YUV
) { /* Packed YUV */
271 } else { /* Packed RGB */
272 auth_md5Sum(md5sum
, rgbimage
, mpi
->w
* (mpi
->bpp
>> 3) * mpi
->h
);
273 md5sum_output_sum(md5sum
);
281 /* ------------------------------------------------------------------------- */
283 static uint32_t draw_slice(uint8_t *src
[], int stride
[], int w
, int h
,
289 /* ------------------------------------------------------------------------- */
291 static uint32_t query_format(uint32_t format
)
296 return VFCAP_CSP_SUPPORTED
|VFCAP_CSP_SUPPORTED_BY_HW
;
302 /* ------------------------------------------------------------------------- */
304 static uint32_t control(uint32_t request
, void *data
, ...)
307 case VOCTRL_QUERY_FORMAT
:
308 return query_format(*((uint32_t*)data
));
309 case VOCTRL_DRAW_IMAGE
:
310 return draw_image(data
);
315 /* ------------------------------------------------------------------------- */
317 static void uninit(void)
319 if (md5sum_outfile
) {
320 free(md5sum_outfile
);
321 md5sum_outfile
= NULL
;
323 if (md5sum_fd
) fclose(md5sum_fd
);
326 /* ------------------------------------------------------------------------- */
328 static void check_events(void)
332 /* ------------------------------------------------------------------------- */
334 static void draw_osd(void)
338 /* ------------------------------------------------------------------------- */
340 static void flip_page (void)
344 /* ------------------------------------------------------------------------- */
347 #undef MD5SUM_RGB_MODE
348 #undef MD5SUM_YUV_MODE
350 /* ------------------------------------------------------------------------- */