]> git.sesse.net Git - vlc/blobdiff - src/misc/image.c
* modules/video_output/directx/directx.c,glwin32.c: revert backport of 13050 for...
[vlc] / src / misc / image.c
index d8888fe6b7f6ca4428fbb6ac31cc1ca2c5f6dc1a..7e20fb276ad0b62df100e14157dcce0f7477e2c9 100644 (file)
@@ -46,6 +46,8 @@ static int ImageWriteUrl( image_handler_t *, picture_t *,
 
 static picture_t *ImageConvert( image_handler_t *, picture_t *,
                                 video_format_t *, video_format_t * );
+static picture_t *ImageFilter( image_handler_t *, picture_t *,
+                               video_format_t *, const char *psz_module );
 
 static decoder_t *CreateDecoder( vlc_object_t *, video_format_t * );
 static void DeleteDecoder( decoder_t * );
@@ -53,7 +55,7 @@ static encoder_t *CreateEncoder( vlc_object_t *, video_format_t *,
                                  video_format_t * );
 static void DeleteEncoder( encoder_t * );
 static filter_t *CreateFilter( vlc_object_t *, es_format_t *,
-                               video_format_t * );
+                               video_format_t *, const char * );
 static void DeleteFilter( filter_t * );
 
 static vlc_fourcc_t Ext2Fourcc( const char * );
@@ -75,6 +77,7 @@ image_handler_t *__image_HandlerCreate( vlc_object_t *p_this )
     p_image->pf_write = ImageWrite;
     p_image->pf_write_url = ImageWriteUrl;
     p_image->pf_convert = ImageConvert;
+    p_image->pf_filter = ImageFilter;
 
     return p_image;
 }
@@ -103,7 +106,7 @@ static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block,
                              video_format_t *p_fmt_in,
                              video_format_t *p_fmt_out )
 {
-    picture_t *p_pic;
+    picture_t *p_pic = NULL, *p_tmp;
 
     /* Check if we can reuse the current decoder */
     if( p_image->p_dec &&
@@ -121,17 +124,29 @@ static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block,
     }
 
     p_block->i_pts = p_block->i_dts = mdate();
-    p_pic = p_image->p_dec->pf_decode_video( p_image->p_dec, &p_block );
-    p_image->p_dec->pf_decode_video( p_image->p_dec, &p_block );
+    while( (p_tmp = p_image->p_dec->pf_decode_video( p_image->p_dec, &p_block ))
+             != NULL )
+    {
+        if ( p_pic != NULL )
+            p_pic->pf_release( p_pic );
+        p_pic = p_tmp;
+    }
 
-    if( !p_pic )
+    if( p_pic == NULL )
     {
-        msg_Dbg( p_image->p_parent, "no image decoded" );
+        msg_Warn( p_image->p_parent, "no image decoded" );
         return 0;
     }
 
     if( !p_fmt_out->i_chroma )
         p_fmt_out->i_chroma = p_image->p_dec->fmt_out.video.i_chroma;
+    if( !p_fmt_out->i_width && p_fmt_out->i_height )
+        p_fmt_out->i_width = p_fmt_out->i_height
+                              * p_image->p_dec->fmt_out.video.i_aspect
+                              / VOUT_ASPECT_FACTOR;
+    if( !p_fmt_out->i_height && p_fmt_out->i_width )
+        p_fmt_out->i_height = p_fmt_out->i_width * VOUT_ASPECT_FACTOR
+                               / p_image->p_dec->fmt_out.video.i_aspect;
     if( !p_fmt_out->i_width )
         p_fmt_out->i_width = p_image->p_dec->fmt_out.video.i_width;
     if( !p_fmt_out->i_height )
@@ -157,7 +172,7 @@ static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block,
         {
             p_image->p_filter =
                 CreateFilter( p_image->p_parent, &p_image->p_dec->fmt_out,
-                              p_fmt_out );
+                              p_fmt_out, NULL );
 
             if( !p_image->p_filter )
             {
@@ -276,7 +291,7 @@ static block_t *ImageWrite( image_handler_t *p_image, picture_t *p_pic,
 
             p_image->p_filter =
                 CreateFilter( p_image->p_parent, &fmt_in,
-                              &p_image->p_enc->fmt_in.video );
+                              &p_image->p_enc->fmt_in.video, NULL );
 
             if( !p_image->p_filter )
             {
@@ -396,7 +411,7 @@ static picture_t *ImageConvert( image_handler_t *p_image, picture_t *p_pic,
         fmt_in.video = *p_fmt_in;
 
         p_image->p_filter =
-            CreateFilter( p_image->p_parent, &fmt_in, p_fmt_out );
+            CreateFilter( p_image->p_parent, &fmt_in, p_fmt_out, NULL );
 
         if( !p_image->p_filter )
         {
@@ -427,6 +442,47 @@ static picture_t *ImageConvert( image_handler_t *p_image, picture_t *p_pic,
     return p_pif;
 }
 
+/**
+ * Filter an image with a psz_module filter
+ *
+ */
+
+static picture_t *ImageFilter( image_handler_t *p_image, picture_t *p_pic,
+                               video_format_t *p_fmt, const char *psz_module )
+{
+    void (*pf_release)( picture_t * );
+    picture_t *p_pif;
+
+    /* Start a filter */
+    if( !p_image->p_filter )
+    {
+        es_format_t fmt;
+        es_format_Init( &fmt, VIDEO_ES, p_fmt->i_chroma );
+        fmt.video = *p_fmt;
+
+        p_image->p_filter =
+            CreateFilter( p_image->p_parent, &fmt, &fmt.video, psz_module );
+
+        if( !p_image->p_filter )
+        {
+            return NULL;
+        }
+    }
+    else
+    {
+        /* Filters should handle on-the-fly size changes */
+        p_image->p_filter->fmt_in.video = *p_fmt;
+        p_image->p_filter->fmt_out.video = *p_fmt;
+    }
+
+    pf_release = p_pic->pf_release;
+    p_pic->pf_release = PicRelease; /* Small hack */
+    p_pif = p_image->p_filter->pf_video_filter( p_image->p_filter, p_pic );
+    p_pic->pf_release = pf_release;
+
+    return p_pif;
+}
+
 /**
  * Misc functions
  *
@@ -446,6 +502,16 @@ static struct
     { VLC_FOURCC('p','g','m','y'), "pgmyuv" },
     { VLC_FOURCC('p','b','m',' '), "pbm" },
     { VLC_FOURCC('p','a','m',' '), "pam" },
+    { VLC_FOURCC('t','g','a',' '), "tga" },
+    { VLC_FOURCC('b','m','p',' '), "bmp" },
+    { VLC_FOURCC('p','n','m',' '), "pnm" },
+    { VLC_FOURCC('x','p','m',' '), "xpm" },
+    { VLC_FOURCC('x','c','f',' '), "xcf" },
+    { VLC_FOURCC('p','c','x',' '), "pcx" },
+    { VLC_FOURCC('g','i','f',' '), "gif" },
+    { VLC_FOURCC('t','i','f','f'), "tif" },
+    { VLC_FOURCC('t','i','f','f'), "tiff" },
+    { VLC_FOURCC('l','b','m',' '), "lbm" },
     { 0, NULL }
 };
 
@@ -665,7 +731,8 @@ static void DeleteEncoder( encoder_t * p_enc )
 }
 
 static filter_t *CreateFilter( vlc_object_t *p_this, es_format_t *p_fmt_in,
-                               video_format_t *p_fmt_out )
+                               video_format_t *p_fmt_out,
+                               const char *psz_module )
 {
     filter_t *p_filter;
 
@@ -681,7 +748,8 @@ static filter_t *CreateFilter( vlc_object_t *p_this, es_format_t *p_fmt_in,
     p_filter->fmt_out = *p_fmt_in;
     p_filter->fmt_out.i_codec = p_fmt_out->i_chroma;
     p_filter->fmt_out.video = *p_fmt_out;
-    p_filter->p_module = module_Need( p_filter, "video filter2", 0, 0 );
+    p_filter->p_module = module_Need( p_filter, "video filter2", psz_module,
+                                      0 );
 
     if( !p_filter->p_module )
     {