[MPlayer-dev-eng] [patch][rfc] screenshot
Arpi
arpi at mplayerhq.hu
Mon Jul 4 04:10:17 CEST 2005
Hi,
I needed a screenshot feature, to print frames from a video...
so i implemented it. actually first i did RTFA, and found an
ugly hack, refused on this list. i tried to do the right way,
although i had no time to do whole clean implementation, with
support for all colorspaces, filename as parameter etc...
do it if you want, and commit if you want. here is it:
(try with -vop scale,screenshot,scale and press 's' while playing
and gui disabled, otherwise 's' is mapped for gui's stop...)
note: mplayer already has half support for screenshot:
's' was mapped to MP_CMD_SCREENSHOT, and this command was
mapped to VOCTRL_SCREENSHOT, but it was not implemented
in any vo driver... anyway it should be in vf, not vo,
so i done it in a filter... it has fallback to vo, if no
filter responding to this command.
vf_screenshot.c:
---------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <png.h>
#include "../config.h"
#include "../mp_msg.h"
#include "img_format.h"
#include "mp_image.h"
#include "vf.h"
#include "../libvo/fastmemcpy.h"
#include "../postproc/rgb2rgb.h"
struct vf_priv_s {
int frameno;
int shot;
};
//===========================================================================//
static int config(struct vf_instance_s* vf,
int width, int height, int d_width, int d_height,
unsigned int flags, unsigned int outfmt){
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
}
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
mp_image_t *dmpi;
int bpp=mpi->bpp/8;
int w,h,x,y,shrink_by;
dmpi=vf_get_image(vf->next,mpi->imgfmt,
MP_IMGTYPE_EXPORT, 0,
mpi->w, mpi->h);
dmpi->planes[0]=mpi->planes[0];
dmpi->planes[1]=mpi->planes[1];
dmpi->planes[2]=mpi->planes[2];
dmpi->stride[0]=mpi->stride[0];
dmpi->stride[1]=mpi->stride[1];
dmpi->stride[2]=mpi->stride[2];
dmpi->width=mpi->width;
dmpi->height=mpi->height;
if(vf->priv->shot){
vf->priv->shot=0;
// ------------------------ write to PNG --------------------------
char fname[102];
FILE * fp;
png_structp png_ptr;
png_infop info_ptr;
snprintf (fname, 100, "shot%04d.png", ++vf->priv->frameno);
mp_msg(MSGT_VFILTER,MSGL_INFO,"*** screenshot '%s' ***\n",fname);
png_ptr = png_create_write_struct
(PNG_LIBPNG_VER_STRING, NULL,
NULL, NULL);
info_ptr = png_create_info_struct(png_ptr);
fp=NULL;
if (setjmp(png_ptr->jmpbuf)) {
// if(verbose > 1) printf("PNG Internal error!\n");
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
return 0;
}
fp = fopen (fname, "wb");
if (fp == NULL) {
printf("\nPNG Error opening %s for writing!\n", fname);
return 0;
}
png_init_io(png_ptr, fp);
png_set_compression_level(png_ptr, 0);
png_set_IHDR(png_ptr, info_ptr, mpi->width, mpi->height,
// 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
png_set_bgr(png_ptr);
png_byte *row_pointers[mpi->height];
int k;
for ( k = 0; k <mpi->height; k++ ){
unsigned char* s=mpi->planes[0] + mpi->stride[0]*k;
row_pointers[k] = s;
}
png_write_image(png_ptr, row_pointers);
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose (fp);
// -------------------------------------------------------------
}
return vf_next_put_image(vf,dmpi);
}
int control (vf_instance_t *vf, int request, void *data){
if(request==VFCTRL_SCREENSHOT) {
vf->priv->shot=1;
return CONTROL_TRUE;
}
return vf_next_control (vf, request, data);
}
//===========================================================================//
static int query_format(struct vf_instance_s* vf, unsigned int fmt){
switch(fmt){
case IMGFMT_BGR24:
// case IMGFMT_RGB24:
// case IMGFMT_BGR32:
// case IMGFMT_RGB32:
return vf_next_query_format(vf, fmt);
}
return 0;
}
static int open(vf_instance_t *vf, char* args){
vf->config=config;
vf->control=control;
vf->put_image=put_image;
vf->query_format=query_format;
vf->priv=malloc(sizeof(struct vf_priv_s));
vf->priv->frameno=0;
vf->priv->shot=0;
return 1;
}
vf_info_t vf_info_screenshot = {
"screenshot to file",
"screenshot",
"A'rpi",
"",
open,
NULL
};
//===========================================================================//
and the patch:
? libmpcodecs/vf_screenshot.c
Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.854
diff -u -r1.854 mplayer.c
--- mplayer.c 3 Jul 2005 10:09:09 -0000 1.854
+++ mplayer.c 4 Jul 2005 02:02:42 -0000
@@ -3566,7 +3566,11 @@
}
break;
case MP_CMD_SCREENSHOT :
- if(vo_config_count) video_out->control(VOCTRL_SCREENSHOT, NULL);
+ if(vo_config_count){
+ mp_msg(MSGT_CPLAYER,MSGL_INFO,"sending VFCTRL_SCREENSHOT!\n");
+ if(CONTROL_OK!=((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_SCREENSHOT, 0))
+ video_out->control(VOCTRL_SCREENSHOT, NULL);
+ }
break;
case MP_CMD_VF_CHANGE_RECTANGLE:
set_rectangle(sh_video, cmd->args[0].v.i, cmd->args[1].v.i);
Index: libmpcodecs/Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/Makefile,v
retrieving revision 1.144
diff -u -r1.144 Makefile
--- libmpcodecs/Makefile 19 Jun 2005 22:52:55 -0000 1.144
+++ libmpcodecs/Makefile 4 Jul 2005 02:02:43 -0000
@@ -112,6 +112,7 @@
vf_rotate.c \
vf_sab.c \
vf_scale.c \
+ vf_screenshot.c \
vf_smartblur.c \
vf_softpulldown.c \
vf_softskip.c \
Index: libmpcodecs/vf.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/vf.c,v
retrieving revision 1.115
diff -u -r1.115 vf.c
--- libmpcodecs/vf.c 8 Jun 2005 15:29:26 -0000 1.115
+++ libmpcodecs/vf.c 4 Jul 2005 02:02:43 -0000
@@ -97,6 +97,7 @@
extern vf_info_t vf_info_divtc;
extern vf_info_t vf_info_harddup;
extern vf_info_t vf_info_softskip;
+extern vf_info_t vf_info_screenshot;
// list of available filters:
static vf_info_t* filter_list[]={
@@ -183,6 +184,7 @@
&vf_info_divtc,
&vf_info_harddup,
&vf_info_softskip,
+ &vf_info_screenshot,
NULL
};
Index: libmpcodecs/vf.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/vf.h,v
retrieving revision 1.27
diff -u -r1.27 vf.h
--- libmpcodecs/vf.h 1 Mar 2005 20:21:58 -0000 1.27
+++ libmpcodecs/vf.h 4 Jul 2005 02:02:43 -0000
@@ -74,6 +74,7 @@
#define VFCTRL_DUPLICATE_FRAME 11 /* For encoding - encode zero-change frame */
#define VFCTRL_SKIP_NEXT_FRAME 12 /* For encoding - drop the next frame that passes thru */
#define VFCTRL_FLUSH_FRAMES 13 /* For encoding - flush delayed frames */
+#define VFCTRL_SCREENSHOT 14
#include "vfcap.h"
A'rpi / MPlayer, Astral & ESP-team
--
Girls are like internet domain names, the ones I like are already taken.
More information about the MPlayer-dev-eng
mailing list