diff -Naur MPlayer-0.90/libmpcodecs/Makefile MPlayer-0.90-pngcap/libmpcodecs/Makefile --- MPlayer-0.90/libmpcodecs/Makefile 2003-03-10 16:18:06.000000000 +0000 +++ MPlayer-0.90-pngcap/libmpcodecs/Makefile 2003-06-28 13:24:55.000000000 +0000 @@ -25,6 +25,7 @@ ifeq ($(PNG),yes) VIDEO_SRCS += vd_mpng.c +VFILTER_SRCS += vf_pngcap.c endif ifeq ($(JPEG),yes) diff -Naur MPlayer-0.90/libmpcodecs/vf.c MPlayer-0.90-pngcap/libmpcodecs/vf.c --- MPlayer-0.90/libmpcodecs/vf.c 2003-03-10 16:18:06.000000000 +0000 +++ MPlayer-0.90-pngcap/libmpcodecs/vf.c 2003-06-28 13:25:00.000000000 +0000 @@ -59,7 +59,12 @@ extern vf_info_t vf_info_detc; extern vf_info_t vf_info_telecine; extern vf_info_t vf_info_tfields; +#ifdef HAVE_PNG +extern vf_info_t vf_info_pngcap; +#endif +int screenshot_filters = 0; +volatile int screenshot = 0; char** vo_plugin_args=(char**) NULL; // list of available filters: @@ -111,6 +116,9 @@ &vf_info_detc, &vf_info_telecine, &vf_info_tfields, +#ifdef HAVE_PNG + &vf_info_pngcap, +#endif NULL }; diff -Naur MPlayer-0.90/libmpcodecs/vf_pngcap.c MPlayer-0.90-pngcap/libmpcodecs/vf_pngcap.c --- MPlayer-0.90/libmpcodecs/vf_pngcap.c 1970-01-01 00:00:00.000000000 +0000 +++ MPlayer-0.90-pngcap/libmpcodecs/vf_pngcap.c 2003-06-28 13:27:41.000000000 +0000 @@ -0,0 +1,215 @@ +#include +#include +#include + +#include "../config.h" +#include "../mp_msg.h" + +#include + +#include "img_format.h" +#include "mp_image.h" +#include "vf.h" + +#include +#include "../libvo/fastmemcpy.h" +#include "../postproc/swscale.h" + +extern int screenshot_filters; +extern volatile int screenshot; + +struct vf_priv_s { + char *prefix; + int frameno; + int compression; + SwsContext *ctx; +}; + +struct pngdata { + FILE *fp; + png_structp png_ptr; + png_infop info_ptr; + enum {OK,ERROR} status; +}; + +//===========================================================================// +static struct pngdata create_png (char *fname, + int image_width, int image_height, int compression, + int swapped) { + struct pngdata png; + + /*png_structp png_ptr = png_create_write_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn);*/ + //png_byte *row_pointers[image_height]; + png.png_ptr = png_create_write_struct + (PNG_LIBPNG_VER_STRING, NULL, + NULL, NULL); + png.info_ptr = png_create_info_struct(png.png_ptr); + + if (!png.png_ptr) { + png.status = ERROR; + return png; + } + + if (!png.info_ptr) { + png_destroy_write_struct(&png.png_ptr, + (png_infopp)NULL); + png.status = ERROR; + return png; + } + + if (setjmp(png.png_ptr->jmpbuf)) { + png_destroy_write_struct(&png.png_ptr, &png.info_ptr); + fclose(png.fp); + png.status = ERROR; + return png; + } + + png.fp = fopen (fname, "wb"); + if (png.fp == NULL) { + //printf("\nPNG Error opening %s for writing!\n", strerror(errno)); + png.status = ERROR; + return png; + } + + png_init_io(png.png_ptr, png.fp); + + /* set the zlib compression level */ + png_set_compression_level(png.png_ptr, compression); + + + /*png_set_IHDR(png_ptr, info_ptr, width, height, + bit_depth, color_type, interlace_type, + compression_type, filter_type)*/ + png_set_IHDR(png.png_ptr, png.info_ptr, image_width, image_height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + png_write_info(png.png_ptr, png.info_ptr); + + if(swapped) { + png_set_bgr(png.png_ptr); + } + + png.status = OK; + return png; +} + +static int destroy_png(struct pngdata png) { + + png_write_end(png.png_ptr, png.info_ptr); + + png_destroy_write_struct(&png.png_ptr, &png.info_ptr); + + fclose (png.fp); + + return 0; +} + +//===========================================================================// + +static int config(struct vf_instance_s* vf, + int width, int height, int d_width, int d_height, + unsigned int flags, unsigned int outfmt){ + SwsFilter *srcFilter, *dstFilter; + int int_sws_flags=0; + if(vf->priv->ctx) freeSwsContext(vf->priv->ctx); + swsGetFlagsAndFilterFromCmdLine(&int_sws_flags, &srcFilter, &dstFilter); + vf->priv->ctx=getSwsContext(width,height, + ((outfmt==IMGFMT_I420 || outfmt==IMGFMT_IYUV)?IMGFMT_YV12:outfmt), + width,height,IMGFMT_RGB24,int_sws_flags,srcFilter,dstFilter); + if(!vf->priv->ctx){ + mp_msg(MSGT_VFILTER,MSGL_WARN, + "Couldn't init SwScaler for this setup\n"); + return 0; + } + return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); +} + +static int cap(struct vf_instance_s* vf, mp_image_t *mpi) { + struct pngdata png; + char fn[160]; + int swapped = mpi->flags & MP_IMGFLAG_SWAPPED; + int k; + png_byte *row_pointers[mpi->h]; + + if(IMGFMT_IS_RGB(mpi->imgfmt) || IMGFMT_IS_BGR(mpi->imgfmt)) { + snprintf(fn,sizeof(fn),"%s%06d.png", + vf->priv->prefix,vf->priv->frameno++); + png = create_png(fn, mpi->w, mpi->h, vf->priv->compression, swapped); + if(png.status == ERROR) { + destroy_png(png); + return 1; + } + for(k = 0; k < mpi->h; k++) + row_pointers[k] = mpi->planes[0] + mpi->stride[0]*k; + png_write_image(png.png_ptr,row_pointers); + destroy_png(png); + } + return 0; +} + +static int put_image(struct vf_instance_s* vf, mp_image_t *mpi) { + mp_image_t *dmpi; + if(screenshot) { + if(vf->priv->ctx) { + dmpi = vf_get_image( + vf->next, + IMGFMT_RGB24,MP_IMGTYPE_TEMP, + MP_IMGFLAG_ACCEPT_STRIDE | + MP_IMGFLAG_PREFER_ALIGNED_STRIDE, + mpi->w, mpi->h); + + vf->priv->ctx->swScale(vf->priv->ctx, + mpi->planes, + mpi->stride, + 0,mpi->h, + dmpi->planes, + dmpi->stride); + cap(vf,dmpi); + //free_mp_image(dmpi); + } + screenshot -= 1; + } + return vf_next_put_image(vf,mpi); +} + +static void uninit(struct vf_instance_s* vf) { + free(vf->priv->prefix); + free(vf->priv); + vf->priv = NULL; +} + +//===========================================================================// + +static int open(vf_instance_t *vf, char *args){ + vf->config = config; + vf->put_image = put_image; + //vf->query_format = query_format; + vf->uninit = uninit; + vf->default_reqs = VFCAP_ACCEPT_STRIDE; + vf->priv = malloc(sizeof(struct vf_priv_s)); + vf->priv->prefix = malloc(sizeof(char)*128); + vf->priv->prefix[0] = '\0'; + vf->priv->frameno = 1; + vf->priv->compression = 1; + if(args) sscanf(args, "%d:%127s", &vf->priv->compression, vf->priv->prefix); + if(vf->priv->compression < 0 || vf->priv->compression > 9) + vf->priv->compression = 1; + mp_msg(MSGT_VFILTER, MSGL_INFO, "PNGCap: Compression: %d ; Prefix: %s\n", + vf->priv->compression, + vf->priv->prefix); + screenshot_filters += 1; + return 1; +} + +vf_info_t vf_info_pngcap = { + "PNG Frame Capture Engine", + "pngcap", + "Carl Ritson (critson@perlfu.co.uk)", + "based on vo_png.c", + open +}; + +//===========================================================================// diff -Naur MPlayer-0.90/mplayer.c MPlayer-0.90-pngcap/mplayer.c --- MPlayer-0.90/mplayer.c 2003-03-10 14:02:18.000000000 +0000 +++ MPlayer-0.90-pngcap/mplayer.c 2003-06-28 13:24:07.000000000 +0000 @@ -261,6 +261,9 @@ // codec outfmt flags (defined in libmpcodecs/vd.c) extern int vo_flags; +extern int screenshot_filters; +extern volatile int screenshot; + // sub: char *font_name=NULL; float font_factor=0.75; @@ -2761,6 +2764,7 @@ } case MP_CMD_SCREENSHOT : if(vo_config_count) video_out->control(VOCTRL_SCREENSHOT, NULL); + screenshot = screenshot_filters; break; case MP_CMD_VF_CHANGE_RECTANGLE: set_rectangle(sh_video, cmd->args[0].v.i, cmd->args[1].v.i);