[MPlayer-dev-eng] patch for PNG output

Vincent Chapdelaine-Couture chapdelv at iro.umontreal.ca
Thu Oct 18 15:05:12 CEST 2007


Hi,

We propose a simple change to the PNG output module to create
concatenated PNG data in a single file instead of multiple files.

Currently, there is no way to extract a stream of "lossless high
quality" images from mplayer without saving the images to disk. All the output 
modules generating images are either lossy (jpeg, gif89a) or saved in single 
files (png, pnm, tga). Having a stream of PNG is ideal for automatic processing 
of the images.

A new option is added to the "-vo png" module:

single=<PNG filename>

Eg./ mplayer -vo png:z=0:single=<PNG filename> my_movie.mpg

This can also be useful to pipe the mplayer output in PNG format to
another program.

Eg./ mplayer -vo png:z=1:single=/dev/stdout my_movie.mpg | <some program
reading PNG data>

Note that we could instead have created a new module to output an animated PNG 
file instead (such as vo_mng.c for the MNG standard, or vo_apng.c for APNG). 
However, these standards (APNG and MNG) are not well supported and this patch 
is both simple and lightweight.

Regards,
-Vincent Couture
-------------- next part --------------
Index: libvo/vo_png.c
===================================================================
--- libvo/vo_png.c	(revision 24685)
+++ libvo/vo_png.c	(working copy)
@@ -34,6 +34,8 @@
 
 int z_compression = Z_NO_COMPRESSION;
 static int framenum = 0;
+char *single_file_name=NULL; // if not null, then output there
+FILE *single_file=NULL;	// NULL -> regulier. Not null: send all images there
 
 struct pngdata {
 	FILE * fp;
@@ -97,12 +99,16 @@
         return png;
     }
     
-    png.fp = fopen (fname, "wb");
-    if (png.fp == NULL) {
- 	mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_PNG_ErrorOpeningForWriting, strerror(errno));
-       	png.status = ERROR;
-       	return png;
-    }	    
+    if( single_file ) {
+	    png.fp = single_file;
+    }else{
+	    png.fp = fopen (fname, "wb");
+	    if (png.fp == NULL) {
+		mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_PNG_ErrorOpeningForWriting, strerror(errno));
+		png.status = ERROR;
+		return png;
+	    }	    
+    }
     
     if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
         mp_msg(MSGT_VO,MSGL_DBG2, "PNG Init IO\n"); }
@@ -143,7 +149,9 @@
         mp_msg(MSGT_VO,MSGL_DBG2, "PNG Destroy Write Struct\n"); }
     png_destroy_write_struct(&png.png_ptr, &png.info_ptr);
     
-    fclose (png.fp);
+    if( !single_file ) {
+	    fclose (png.fp);
+    }
 
     return 0;
 }
@@ -208,7 +216,12 @@
     return 0;
 }
 
-static void uninit(void){}
+static void uninit(void){
+	if( single_file ) {
+		fclose(single_file);
+		single_file=NULL;
+	}
+}
 
 static void check_events(void){}
 
@@ -219,8 +232,19 @@
     return 1;
 }
 
+static int test_single_file_name(const char **name) {
+	single_file=fopen(*name,"wb");
+	if( single_file==NULL ) {
+		fprintf(stderr,"UNABLE TO OPEN %s for writing\n",*name);
+        	return 0; // not supported
+	}
+	return 1;
+}
+
+
 static opt_t subopts[] = {
     {"z",   OPT_ARG_INT, &z_compression, (opt_test_f)int_zero_to_nine},
+    {"single",   OPT_ARG_MSTRZ, &single_file_name, (opt_test_f)test_single_file_name},
     {NULL}
 };
 


More information about the MPlayer-dev-eng mailing list