1
mirror of https://github.com/mpv-player/mpv synced 2024-08-24 07:21:49 +02:00

VO: remove vo_gif89a, vo_md5sum, vo_yuv4mpeg

The encoding branch by divverent can handle of these via libavformat.

Note: for some reason, libav/ffmpeg have a GIF muxer only, and no
demuxer. The gif configure checks needef for the mplayer internal gif
demuxer can't be removed yet.
This commit is contained in:
wm4 2012-08-06 18:58:17 +02:00
parent 44f23e36e8
commit 6ecfa42a46
6 changed files with 0 additions and 1033 deletions

View File

@ -386,7 +386,6 @@ SRCS_MPLAYER-$(SHAREDBUFFER) += libvo/vo_sharedbuffer.m
SRCS_MPLAYER-$(DIRECT3D) += libvo/vo_direct3d.c libvo/w32_common.c
SRCS_MPLAYER-$(DIRECTFB) += libvo/vo_directfb2.c
SRCS_MPLAYER-$(DIRECTX) += libao2/ao_dsound.c libvo/vo_directx.c
SRCS_MPLAYER-$(GIF) += libvo/vo_gif89a.c
SRCS_MPLAYER-$(GL) += libvo/gl_common.c libvo/vo_gl.c libvo/vo_gl3.c \
pnm_loader.c
SRCS_MPLAYER-$(GL_WIN32) += libvo/w32_common.c
@ -395,7 +394,6 @@ SRCS_MPLAYER-$(GL_X11) += libvo/x11_common.c
SRCS_MPLAYER-$(JACK) += libao2/ao_jack.c
SRCS_MPLAYER-$(JOYSTICK) += input/joystick.c
SRCS_MPLAYER-$(LIRC) += input/lirc.c
SRCS_MPLAYER-$(MD5SUM) += libvo/vo_md5sum.c
SRCS_MPLAYER-$(OPENAL) += libao2/ao_openal.c
SRCS_MPLAYER-$(OSS) += libao2/ao_oss.c
SRCS_MPLAYER-$(PULSE) += libao2/ao_pulse.c
@ -407,7 +405,6 @@ SRCS_MPLAYER-$(VDPAU) += libvo/vo_vdpau.c
SRCS_MPLAYER-$(X11) += libvo/vo_x11.c libvo/x11_common.c
SRCS_MPLAYER-$(XV) += libvo/vo_xv.c
SRCS_MPLAYER-$(YUV4MPEG) += libvo/vo_yuv4mpeg.c
SRCS_MPLAYER = command.c \
m_property.c \

34
configure vendored
View File

@ -371,8 +371,6 @@ Video output:
--enable-xshape enable XShape support [autodetect]
--disable-xss disable screensaver support via xss [autodetect]
--enable-directfb enable DirectFB video output [autodetect]
--disable-md5sum disable md5sum video output [enable]
--disable-yuv4mpeg disable yuv4mpeg video output [enable]
--disable-corevideo disable CoreVideo video output [autodetect]
--disable-cocoa disable Cocoa OpenGL backend [autodetect]
--disable-sharedbuffer disable OSX shared buffer video output [autodetect]
@ -460,8 +458,6 @@ _nas=auto
_png=auto
_mng=auto
_jpeg=auto
_md5sum=yes
_yuv4mpeg=yes
_gif=auto
_gl=auto
_aa=auto
@ -683,10 +679,6 @@ for ac_option do
--disable-mng) _mng=no ;;
--enable-jpeg) _jpeg=yes ;;
--disable-jpeg) _jpeg=no ;;
--enable-md5sum) _md5sum=yes ;;
--disable-md5sum) _md5sum=no ;;
--enable-yuv4mpeg) _yuv4mpeg=yes ;;
--disable-yuv4mpeg) _yuv4mpeg=no ;;
--enable-gif) _gif=yes ;;
--disable-gif) _gif=no ;;
--enable-gl) _gl=yes ;;
@ -2054,28 +2046,6 @@ echores "$_libquvi"
#########
echocheck "md5sum support"
if test "$_md5sum" = yes; then
def_md5sum="#define CONFIG_MD5SUM 1"
vomodules="md5sum $vomodules"
else
def_md5sum="#undef CONFIG_MD5SUM"
novomodules="md5sum $novomodules"
fi
echores "$_md5sum"
echocheck "yuv4mpeg support"
if test "$_yuv4mpeg" = yes; then
def_yuv4mpeg="#define CONFIG_YUV4MPEG 1"
vomodules="yuv4mpeg $vomodules"
else
def_yuv4mpeg="#undef CONFIG_YUV4MPEG"
novomodules="yuv4mpeg $novomodules"
fi
echores "$_yuv4mpeg"
echocheck "DirectFB"
if test "$_directfb" = auto ; then
_directfb=no
@ -3975,7 +3945,6 @@ LIBTHEORA = $_theora
LIRC = $_lirc
LIVE555 = $_live
MACOSX_FINDER = $_macosx_finder
MD5SUM = $_md5sum
MNG = $_mng
MPG123 = $_mpg123
NETWORKING = $networking
@ -4008,7 +3977,6 @@ WIN32_EMULATION = $_win32_emulation
X11 = $_x11
XANIM_CODECS = $_xanim
XV = $_xv
YUV4MPEG = $_yuv4mpeg
# FFmpeg
FFMPEG_INTERNALS = $ffmpeg_internals
@ -4269,7 +4237,6 @@ $def_gl_cocoa
$def_gl_win32
$def_gl_x11
$def_jpeg
$def_md5sum
$def_mng
$def_png
$def_v4l2
@ -4281,7 +4248,6 @@ $def_xf86keysym
$def_xinerama
$def_xss
$def_xv
$def_yuv4mpeg
/* FFmpeg */

View File

@ -83,16 +83,13 @@ extern struct vo_driver video_out_gl3;
extern struct vo_driver video_out_null;
extern struct vo_driver video_out_image;
extern struct vo_driver video_out_caca;
extern struct vo_driver video_out_yuv4mpeg;
extern struct vo_driver video_out_direct3d;
extern struct vo_driver video_out_direct3d_shaders;
extern struct vo_driver video_out_directx;
extern struct vo_driver video_out_v4l2;
extern struct vo_driver video_out_gif89a;
extern struct vo_driver video_out_directfb;
extern struct vo_driver video_out_corevideo;
extern struct vo_driver video_out_sharedbuffer;
extern struct vo_driver video_out_md5sum;
const struct vo_driver *video_out_drivers[] =
{
@ -138,17 +135,8 @@ const struct vo_driver *video_out_drivers[] =
#ifdef CONFIG_DIRECTFB
// vo directfb can call exit() if initialization fails
&video_out_directfb,
#endif
#ifdef CONFIG_YUV4MPEG
&video_out_yuv4mpeg,
#endif
&video_out_image,
#ifdef CONFIG_GIF
&video_out_gif89a,
#endif
#ifdef CONFIG_MD5SUM
&video_out_md5sum,
#endif
#ifdef CONFIG_X11
#ifdef CONFIG_GL
&video_out_gl_nosw,

View File

@ -1,376 +0,0 @@
/*
* MPlayer video driver for animated GIF output
*
* copyright (C) 2002 Joey Parrish <joey@nicewarrior.org>
* based on vo_directfb2.c
*
* This file is part of MPlayer.
*
* MPlayer is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* MPlayer 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Notes:
* when setting output framerate, frames will be ignored as needed
* to achieve the desired rate. no frames will be duplicated.
*
* output framerate can be specified as a float
* value now, instead of just an int.
*
* adjustments will be made to both the frame drop cycle and the
* delay per frame to achieve the desired output framerate.
*
* time values are in centiseconds, because that's
* what the gif spec uses for it's delay values.
*
* preinit looks for arguments in one of the following formats (in this order):
* fps:filename -- sets the framerate (float) and output file
* fps -- sets the framerate (float), default file out.gif
* filename -- defaults to 5 fps, sets output file
* (none) -- defaults to 5 fps, output file out.gif
*
* trying to put the filename before the framerate will result in the
* entire argument being interpretted as the filename.
*/
#include <gif_lib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "subopt-helper.h"
#include "video_out.h"
#include "video_out_internal.h"
#include "mp_msg.h"
#define MPLAYER_VERSION 0.90
#define VO_GIF_REVISION 6
static const vo_info_t info = {
"animated GIF output",
"gif89a",
"Joey Parrish joey@nicewarrior.org",
""
};
const LIBVO_EXTERN(gif89a)
// how many frames per second we are aiming for during output.
static float target_fps;
// default value for output fps.
static const float default_fps = 5.00;
// the ideal gif delay per frame.
static float ideal_delay;
// the ideal time thus far.
static float ideal_time;
// actual time thus far.
static int real_time;
// nominal framedrop cycle length in frames
static float frame_cycle;
// position in the framedrop cycle
static int cycle_pos;
// adjustment of the framedrop cycle
static float frame_adj;
// the output width and height
static uint32_t img_width;
static uint32_t img_height;
// image data for slice rendering
static uint8_t *slice_data = NULL;
// reduced image data for flip_page
static uint8_t *reduce_data = NULL;
// reduced color map for flip_page
static ColorMapObject *reduce_cmap = NULL;
// a pointer to the gif structure
static GifFileType *new_gif = NULL;
// a string to contain the filename of the output gif
static char *gif_filename = NULL;
// the default output filename
#define DEFAULT_FILE "out.gif"
static const opt_t subopts[] = {
{"output", OPT_ARG_MSTRZ, &gif_filename, NULL},
{"fps", OPT_ARG_FLOAT, &target_fps, NULL},
{NULL, 0, NULL, NULL}
};
static int preinit(const char *arg)
{
target_fps = 0;
if (subopt_parse(arg, subopts) != 0) {
mp_msg(MSGT_VO, MSGL_FATAL,
"\n-vo gif89a command line help:\n"
"Example: mplayer -vo gif89a:output=file.gif:fps=4.9\n"
"\nOptions:\n"
" output=<filename>\n"
" Specify the output file. The default is out.gif.\n"
" fps=<rate>\n"
" Specify the target framerate. The default is 5.0.\n"
"\n");
return -1;
}
if (target_fps > vo_fps)
target_fps = vo_fps; // i will not duplicate frames.
if (target_fps <= 0) {
target_fps = default_fps;
mp_msg(MSGT_VO, MSGL_V, "GIF89a: default, %.2f fps\n", target_fps);
} else {
mp_msg(MSGT_VO, MSGL_V, "GIF89a: output fps forced to %.2f\n", target_fps);
}
ideal_delay = 100 / target_fps; // in centiseconds
frame_cycle = vo_fps / target_fps;
// we make one output frame every (frame_cycle) frames, on average.
if (gif_filename == NULL) {
gif_filename = strdup(DEFAULT_FILE);
mp_msg(MSGT_VO, MSGL_V, "GIF89a: default, file \"%s\"\n", gif_filename);
} else {
mp_msg(MSGT_VO, MSGL_V, "GIF89a: file forced to \"%s\"\n", gif_filename);
}
mp_msg(MSGT_VO, MSGL_DBG2, "GIF89a: Preinit OK\n");
return 0;
}
static int config(uint32_t s_width, uint32_t s_height, uint32_t d_width,
uint32_t d_height, uint32_t flags, char *title,
uint32_t format)
{
#ifdef CONFIG_GIF_4
// these are control blocks for the gif looping extension.
char LB1[] = "NETSCAPE2.0";
char LB2[] = { 1, 0, 0 };
#endif
mp_msg(MSGT_VO, MSGL_DBG2, "GIF89a: Config entered [%dx%d]\n", s_width,s_height);
mp_msg(MSGT_VO, MSGL_DBG2, "GIF89a: With requested format: %s\n", vo_format_name(format));
// save these for later.
img_width = s_width;
img_height = s_height;
// multiple configs without uninit are not allowed.
// this is because config opens a new gif file.
if (vo_config_count > 0) {
mp_msg(MSGT_VO, MSGL_V, "GIF89a: Reconfigure attempted.\n");
return 0;
}
// reconfigure need not be a fatal error, so return 0.
// multiple configs without uninit will result in two
// movies concatenated in one gif file. the output
// gif will have the dimensions of the first movie.
if (format != IMGFMT_RGB24) {
mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: Error - given unsupported colorspace.\n");
return 1;
}
// the EGifSetGifVersion line causes segfaults in certain
// earlier versions of libungif. i don't know exactly which,
// but certainly in all those before v4. if you have problems,
// you need to upgrade your gif library.
#ifdef CONFIG_GIF_4
EGifSetGifVersion("89a");
#else
mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: Your version of libungif needs to be upgraded.\n");
mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: Some functionality has been disabled.\n");
#endif
new_gif = EGifOpenFileName(gif_filename, 0);
if (new_gif == NULL) {
mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: error opening file \"%s\" for output.\n", gif_filename);
return 1;
}
slice_data = malloc(img_width * img_height * 3);
if (slice_data == NULL) {
mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: malloc failed.\n");
return 1;
}
reduce_data = malloc(img_width * img_height);
if (reduce_data == NULL) {
free(slice_data); slice_data = NULL;
mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: malloc failed.\n");
return 1;
}
reduce_cmap = MakeMapObject(256, NULL);
if (reduce_cmap == NULL) {
free(slice_data); slice_data = NULL;
free(reduce_data); reduce_data = NULL;
mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: malloc failed.\n");
return 1;
}
// initialize the delay and framedrop variables.
ideal_time = 0;
real_time = 0;
cycle_pos = 0;
frame_adj = 0;
// set the initial width and height info.
EGifPutScreenDesc(new_gif, s_width, s_height, 256, 0, reduce_cmap);
#ifdef CONFIG_GIF_4
// version 3 of libungif does not support multiple control blocks.
// looping requires multiple control blocks.
// therefore, looping is only enabled for v4 and up.
EGifPutExtensionFirst(new_gif, 0xFF, 11, LB1);
EGifPutExtensionLast(new_gif, 0, 3, LB2);
#endif
mp_msg(MSGT_VO, MSGL_DBG2, "GIF89a: Config finished.\n");
return 0;
}
// we do not draw osd.
void draw_osd(void) {}
// we do not handle events.
static void check_events(void) {}
static int gif_reduce(int width, int height, uint8_t *src, uint8_t *dst, GifColorType *colors)
{
unsigned char Ra[width * height];
unsigned char Ga[width * height];
unsigned char Ba[width * height];
unsigned char *R, *G, *B;
int size = 256;
int i;
R = Ra; G = Ga; B = Ba;
for (i = 0; i < width * height; i++)
{
*R++ = *src++;
*G++ = *src++;
*B++ = *src++;
}
R = Ra; G = Ga; B = Ba;
return QuantizeBuffer(width, height, &size, R, G, B, dst, colors);
}
static void flip_page(void)
{
char CB[4]; // control block
int delay = 0;
int ret;
cycle_pos++;
if (cycle_pos < frame_cycle - frame_adj)
return; // we are skipping this frame
// quantize the image
ret = gif_reduce(img_width, img_height, slice_data, reduce_data, reduce_cmap->Colors);
if (ret == GIF_ERROR) {
mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: Quantize failed.\n");
return;
}
// calculate frame delays and frame skipping
ideal_time += ideal_delay;
delay = (int)(ideal_time - real_time);
real_time += delay;
frame_adj += cycle_pos;
frame_adj -= frame_cycle;
cycle_pos = 0;
// set up the delay control block
CB[0] = (char)(delay >> 8);
CB[1] = (char)(delay & 0xff);
CB[2] = 0;
CB[3] = 0;
// put the control block with delay info
EGifPutExtension(new_gif, 0xF9, 0x04, CB);
// put the image description
EGifPutImageDesc(new_gif, 0, 0, img_width, img_height, 0, reduce_cmap);
// put the image itself
EGifPutLine(new_gif, reduce_data, img_width * img_height);
}
static int draw_frame(uint8_t *src[])
{
return 1;
}
static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
{
uint8_t *dst, *frm;
int i;
dst = slice_data + (img_width * y + x) * 3;
frm = src[0];
for (i = 0; i < h; i++) {
memcpy(dst, frm, w * 3);
dst += (img_width * 3);
frm += stride[0];
}
return 0;
}
static int query_format(uint32_t format)
{
if (format == IMGFMT_RGB24)
return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_TIMER | VFCAP_ACCEPT_STRIDE;
return 0;
}
static int control(uint32_t request, void *data)
{
if (request == VOCTRL_QUERY_FORMAT) {
return query_format(*((uint32_t*)data));
}
if (request == VOCTRL_DUPLICATE_FRAME) {
flip_page();
return VO_TRUE;
}
return VO_NOTIMPL;
}
static void uninit(void)
{
mp_msg(MSGT_VO, MSGL_DBG2, "GIF89a: Uninit entered\n");
if (new_gif != NULL) {
char temp[256];
// comment the gif and close it
snprintf(temp, 256, "MPlayer gif output v%2.2f-%d (c) %s\r\n",
MPLAYER_VERSION, VO_GIF_REVISION,
"joey@nicewarrior.org");
EGifPutComment(new_gif, temp);
EGifCloseFile(new_gif); // also frees gif storage space.
}
// free our allocated ram
free(gif_filename);
free(slice_data);
free(reduce_data);
if (reduce_cmap != NULL) FreeMapObject(reduce_cmap);
// set the pointers back to null.
new_gif = NULL;
gif_filename = NULL;
slice_data = NULL;
reduce_data = NULL;
reduce_cmap = NULL;
}

View File

@ -1,298 +0,0 @@
/* ------------------------------------------------------------------------- */
/*
* md5sum video output driver
*
* Copyright (C) 2004, 2005, 2006 Ivo van Poorten
*
* This file is part of MPlayer.
*
* MPlayer 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.
*
* MPlayer 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 MPlayer; 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 "libavutil/md5.h"
/* ------------------------------------------------------------------------- */
/* 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_tmsg(MSGT_VO, MSGL_ERR, "%s: Error writing file.\n", info.short_name);
}
/* ------------------------------------------------------------------------- */
/** \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)
{
const opt_t subopts[] = {
{"outfile", OPT_ARG_MSTRZ, &md5sum_outfile, NULL},
{NULL, 0, NULL, NULL}
};
mp_msg(MSGT_VO, MSGL_V, "%s: %s\n", info.short_name,
"Parsing suboptions.");
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_V, "%s: %s\n", info.short_name,
"Suboptions parsed OK.");
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 (strcmp(md5sum_outfile, "-") == 0)
md5sum_fd = stdout;
else
if ( (md5sum_fd = fopen(md5sum_outfile, "w") ) == NULL ) {
mp_msg(MSGT_VO, MSGL_ERR, "\n%s: %s\n", info.short_name,
_("Unable to create output file."));
mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n",
info.short_name, _("This error has occurred"), strerror(errno) );
return -1;
}
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);
}
for (i=0; i<h; i++) {
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)
{
free(md5sum_outfile);
md5sum_outfile = NULL;
if (md5sum_fd && md5sum_fd != stdout) fclose(md5sum_fd);
}
/* ------------------------------------------------------------------------- */
static void check_events(void)
{
}
/* ------------------------------------------------------------------------- */
static void draw_osd(void)
{
}
/* ------------------------------------------------------------------------- */
static void flip_page (void)
{
}

View File

@ -1,310 +0,0 @@
/*
* yuv4mpeg (mjpegtools) interface
*
* Thrown together by Robert Kesterson <robertk@robertk.com>
* Based on the pgm output plugin, the rgb2rgb postproc filter, divxdec,
* and probably others.
*
* This is undoubtedly incomplete, inaccurate, or just plain wrong. :-)
*
* 2002/06/19 Klaus Stengel <Klaus.Stengel@asamnet.de>
* - added support for interlaced output
* Activate by using '-vo yuv4mpeg:interlaced'
* or '-vo yuv4mpeg:interlaced_bf' if your source has
* bottom fields first
* - added some additional checks to catch problems
*
* 2002/04/17 Juergen Hammelmann <juergen.hammelmann@gmx.de>
* - added support for output of subtitles
* best, if you give option '-osdlevel 0' to mplayer for
* no watching the seek+timer
*
* This file is part of MPlayer.
*
* MPlayer 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.
*
* MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include "config.h"
#include "subopt-helper.h"
#include "video_out.h"
#include "video_out_internal.h"
#include "mp_msg.h"
#include "sub/sub.h"
#include "fastmemcpy.h"
#include "libavutil/rational.h"
static const vo_info_t info =
{
"yuv4mpeg output for mjpegtools",
"yuv4mpeg",
"Robert Kesterson <robertk@robertk.com>",
""
};
const LIBVO_EXTERN (yuv4mpeg)
static int image_width = 0;
static int image_height = 0;
static float image_fps = 0;
static uint8_t *image = NULL;
static uint8_t *image_y = NULL;
static uint8_t *image_u = NULL;
static uint8_t *image_v = NULL;
static char *yuv_filename = NULL;
static int using_format = 0;
static FILE *yuv_out;
static int write_bytes;
#define Y4M_ILACE_NONE 'p' /* non-interlaced, progressive frame */
#define Y4M_ILACE_TOP_FIRST 't' /* interlaced, top-field first */
#define Y4M_ILACE_BOTTOM_FIRST 'b' /* interlaced, bottom-field first */
/* Set progressive mode as default */
static int config_interlace = Y4M_ILACE_NONE;
#define Y4M_IS_INTERLACED (config_interlace != Y4M_ILACE_NONE)
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)
{
AVRational pixelaspect = av_div_q((AVRational){d_width, d_height},
(AVRational){width, height});
AVRational fps_frac = av_d2q(vo_fps, vo_fps * 1001 + 2);
if (image_width == width && image_height == height &&
image_fps == vo_fps && vo_config_count)
return 0;
if (vo_config_count) {
mp_msg(MSGT_VO, MSGL_WARN,
"Video formats differ (w:%i=>%i, h:%i=>%i, fps:%f=>%f), "
"restarting output.\n",
image_width, width, image_height, height, image_fps, vo_fps);
}
image_height = height;
image_width = width;
image_fps = vo_fps;
using_format = format;
if (Y4M_IS_INTERLACED)
{
if (height % 4)
{
mp_tmsg(MSGT_VO,MSGL_FATAL,
"Interlaced mode requires image height to be divisible by 4.");
return -1;
}
}
if (width % 2)
{
mp_tmsg(MSGT_VO,MSGL_FATAL,
"Image width must be divisible by 2.");
return -1;
}
write_bytes = image_width * image_height * 3 / 2;
free(image);
image = malloc(write_bytes);
if (!yuv_out)
yuv_out = strcmp(yuv_filename, "-") ? fopen(yuv_filename, "wb") : stdout;
if (!yuv_out || image == 0)
{
mp_tmsg(MSGT_VO,MSGL_FATAL,
"Can't get memory or file handle to write \"%s\"!",
yuv_filename);
return -1;
}
image_y = image;
image_u = image_y + image_width * image_height;
image_v = image_u + image_width * image_height / 4;
fprintf(yuv_out, "YUV4MPEG2 W%d H%d F%d:%d I%c A%d:%d\n",
image_width, image_height, fps_frac.num, fps_frac.den,
config_interlace,
pixelaspect.num, pixelaspect.den);
fflush(yuv_out);
return 0;
}
static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
unsigned char *srca, int stride) {
vo_draw_alpha_yv12(w, h, src, srca, stride,
image + y0 * image_width + x0, image_width);
}
static void draw_osd(void)
{
vo_draw_text(image_width, image_height, draw_alpha);
}
static void vo_y4m_write(const void *ptr, const size_t num_bytes)
{
if (fwrite(ptr, 1, num_bytes, yuv_out) != num_bytes)
mp_tmsg(MSGT_VO,MSGL_ERR,
"Error writing image to output!");
fflush(yuv_out);
}
static int write_last_frame(void)
{
fprintf(yuv_out, "FRAME\n");
vo_y4m_write(image, write_bytes);
return VO_TRUE;
}
static void flip_page (void)
{
fprintf(yuv_out, "FRAME\n");
vo_y4m_write(image, write_bytes);
}
static int draw_slice(uint8_t *srcimg[], int stride[], int w,int h,int x,int y)
{
int i;
uint8_t *dst, *src = srcimg[0];
// copy Y:
dst = image_y + image_width * y + x;
for (i = 0; i < h; i++)
{
fast_memcpy(dst, src, w);
src += stride[0];
dst += image_width;
}
{
// copy U + V:
int imgstride = image_width >> 1;
uint8_t *src1 = srcimg[1];
uint8_t *src2 = srcimg[2];
uint8_t *dstu = image_u + imgstride * (y >> 1) + (x >> 1);
uint8_t *dstv = image_v + imgstride * (y >> 1) + (x >> 1);
for (i = 0; i < h / 2; i++)
{
fast_memcpy(dstu, src1 , w >> 1);
fast_memcpy(dstv, src2, w >> 1);
src1 += stride[1];
src2 += stride[2];
dstu += imgstride;
dstv += imgstride;
}
}
return 0;
}
static int draw_frame(uint8_t * src[])
{
// gets done in draw_slice
return 0;
}
static int query_format(uint32_t format)
{
if (format == IMGFMT_YV12)
return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_OSD|VFCAP_ACCEPT_STRIDE;
return 0;
}
// WARNING: config(...) also uses this
static void uninit(void)
{
free(image);
image = NULL;
if(yuv_out && yuv_out != stdout)
fclose(yuv_out);
yuv_out = NULL;
free(yuv_filename);
yuv_filename = NULL;
image_width = 0;
image_height = 0;
image_fps = 0;
}
static void check_events(void)
{
}
static int preinit(const char *arg)
{
int il, il_bf;
const opt_t subopts[] = {
{"interlaced", OPT_ARG_BOOL, &il, NULL},
{"interlaced_bf", OPT_ARG_BOOL, &il_bf, NULL},
{"file", OPT_ARG_MSTRZ, &yuv_filename, NULL},
{NULL}
};
il = 0;
il_bf = 0;
yuv_filename = strdup("stream.yuv");
if (subopt_parse(arg, subopts) != 0) {
mp_tmsg(MSGT_VO, MSGL_FATAL, "Unknown subdevice: %s", arg);
return -1;
}
config_interlace = Y4M_ILACE_NONE;
if (il)
config_interlace = Y4M_ILACE_TOP_FIRST;
if (il_bf)
config_interlace = Y4M_ILACE_BOTTOM_FIRST;
/* Inform user which output mode is used */
switch (config_interlace)
{
case Y4M_ILACE_TOP_FIRST:
mp_tmsg(MSGT_VO,MSGL_STATUS,
"Using interlaced output mode, top-field first.");
break;
case Y4M_ILACE_BOTTOM_FIRST:
mp_tmsg(MSGT_VO,MSGL_STATUS,
"Using interlaced output mode, bottom-field first.");
break;
default:
mp_tmsg(MSGT_VO,MSGL_STATUS,
"Using (default) progressive frame mode.");
break;
}
return 0;
}
static int control(uint32_t request, void *data)
{
switch (request) {
case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data));
case VOCTRL_DUPLICATE_FRAME:
return write_last_frame();
}
return VO_NOTIMPL;
}