/* ------------------------------------------------------------------------- *//* * vo_md5sum.c, md5sum Video Output Driver for MPlayer * * Written by Ivo van Poorten. (C) Copyright 2004, 2005, 2006. * * This program 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. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * *//* ------------------------------------------------------------------------- *//* Global Includes */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>/* ------------------------------------------------------------------------- *//* Local Includes */#include "config.h"#include "subopt-helper.h"#include "mp_msg.h"#include "video_out.h"#include "video_out_internal.h"#include "mplayer.h" /* for exit_player() */#include "help_mp.h"#include "libavutil/md5.h"/* ------------------------------------------------------------------------- *//* Defines *//* Used for temporary buffers to store file- and pathnames */#define BUFLENGTH 512/* ------------------------------------------------------------------------- *//* Info */static const vo_info_t info={ "md5sum of each frame", "md5sum", "Ivo van Poorten (ivop@euronet.nl)", ""};const LIBVO_EXTERN (md5sum)/* ------------------------------------------------------------------------- *//* Global Variables */char *md5sum_outfile = NULL;FILE *md5sum_fd;int framenum = 0;/* ------------------------------------------------------------------------- *//** \brief An error occured while writing to a file. * * The program failed to write data to a file. * It displays a message and exits the player. * * \return nothing It does not return. */static void md5sum_write_error(void) { mp_msg(MSGT_VO, MSGL_ERR, MSGTR_ErrorWritingFile, info.short_name); exit_player(MSGTR_Exit_error);}/* ------------------------------------------------------------------------- *//** \brief Pre-initialisation. * * This function is called before initialising the video output driver. It * parses all suboptions and sets variables accordingly. If an error occurs * (like an option being out of range, not having any value or an unknown * option is stumbled upon) the player will exit. It also sets default * values if necessary. * * \param arg A string containing all the suboptions passed to the video * output driver. * * \return 0 All went well. */static int preinit(const char *arg){ opt_t subopts[] = { {"outfile", OPT_ARG_MSTRZ, &md5sum_outfile, NULL, 0}, {NULL, 0, NULL, NULL, 0} }; mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, MSGTR_VO_ParsingSuboptions); md5sum_outfile = strdup("md5sums"); if (subopt_parse(arg, subopts) != 0) { return -1; } mp_msg(MSGT_VO, MSGL_V, "%s: outfile --> %s\n", info.short_name, md5sum_outfile); mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, MSGTR_VO_SuboptionsParsedOK); return 0;}/* ------------------------------------------------------------------------- *//** \brief Configure the video output driver. * * This functions configures the video output driver. It opens the output * file to which this driver will write all the MD5 sums. If something * goes wrong, the player will exit. * * \return 0 All went well. */static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format){ if (vo_config_count > 0 ) { /* Already configured */ return 0; } if ( (md5sum_fd = fopen(md5sum_outfile, "w") ) == NULL ) { mp_msg(MSGT_VO, MSGL_ERR, "\n%s: %s\n", info.short_name, MSGTR_VO_CantCreateFile); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, MSGTR_VO_GenericError, strerror(errno) ); exit_player(MSGTR_Exit_error); } return 0;}/* ------------------------------------------------------------------------- *//** \brief Write MD5 sum to output file. * * This function writes an ASCII representation of a 16-byte hexadecimal * MD5 sum to our output file. The file descriptor is a global variable. * * \param md5sum Sixteen bytes that represent an MD5 sum. * * \return None The player will exit if a write error occurs. */static void md5sum_output_sum(unsigned char *md5sum) { int i; for(i=0; i<16; i++) { if ( fprintf(md5sum_fd, "%02x", md5sum[i]) < 0 ) md5sum_write_error(); } if ( fprintf(md5sum_fd, " frame%08d\n", framenum) < 0 ) md5sum_write_error(); framenum++;}/* ------------------------------------------------------------------------- */static int draw_frame(uint8_t *src[]){ mp_msg(MSGT_VO, MSGL_V, "%s: draw_frame() is called!\n", info.short_name); return -1;}/* ------------------------------------------------------------------------- */static uint32_t draw_image(mp_image_t *mpi){ unsigned char md5sum[16]; uint32_t w = mpi->w; uint32_t h = mpi->h; uint8_t *rgbimage = mpi->planes[0]; uint8_t *planeY = mpi->planes[0]; uint8_t *planeU = mpi->planes[1]; uint8_t *planeV = mpi->planes[2]; uint32_t strideY = mpi->stride[0]; uint32_t strideU = mpi->stride[1]; uint32_t strideV = mpi->stride[2]; uint8_t md5_context_memory[av_md5_size]; struct AVMD5 *md5_context = (struct AVMD5*) md5_context_memory; unsigned int i; if (mpi->flags & MP_IMGFLAG_PLANAR) { /* Planar */ if (mpi->flags & MP_IMGFLAG_YUV) { /* Planar YUV */ av_md5_init(md5_context); for (i=0; i<h; i++) { av_md5_update(md5_context, planeY + i * strideY, w); } w = w / 2; h = h / 2; for (i=0; i<h; i++) { av_md5_update(md5_context, planeU + i * strideU, w); av_md5_update(md5_context, planeV + i * strideV, w); } av_md5_final(md5_context, md5sum); md5sum_output_sum(md5sum); return VO_TRUE; } else { /* Planar RGB */ return VO_FALSE; } } else { /* Packed */ if (mpi->flags & MP_IMGFLAG_YUV) { /* Packed YUV */ return VO_FALSE; } else { /* Packed RGB */ av_md5_sum(md5sum, rgbimage, mpi->w * (mpi->bpp >> 3) * mpi->h); md5sum_output_sum(md5sum); return VO_TRUE; } } return VO_FALSE;}/* ------------------------------------------------------------------------- */static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y){ return 0;}/* ------------------------------------------------------------------------- */static int query_format(uint32_t format){ switch (format) { case IMGFMT_RGB24: case IMGFMT_YV12: return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW; default: return 0; }}/* ------------------------------------------------------------------------- */static int control(uint32_t request, void *data, ...){ switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_DRAW_IMAGE: return draw_image(data); } return VO_NOTIMPL;}/* ------------------------------------------------------------------------- */static void uninit(void){ if (md5sum_outfile) { free(md5sum_outfile); md5sum_outfile = NULL; } if (md5sum_fd) fclose(md5sum_fd);}/* ------------------------------------------------------------------------- */static void check_events(void){}/* ------------------------------------------------------------------------- */static void draw_osd(void){}/* ------------------------------------------------------------------------- */static void flip_page (void){}/* ------------------------------------------------------------------------- */#undef BUFLENGTH#undef MD5SUM_RGB_MODE#undef MD5SUM_YUV_MODE/* ------------------------------------------------------------------------- */