mirror of
https://github.com/mpv-player/mpv
synced 2025-01-24 19:37:30 +01: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:
parent
44f23e36e8
commit
6ecfa42a46
3
Makefile
3
Makefile
@ -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
34
configure
vendored
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
@ -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)
|
||||
{
|
||||
}
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user