[vlc-devel] [PATCH] picture: export: Allow source picture to be cropped

Hugo Beauzée-Luyssen hugo at beauzee.fr
Tue Jun 18 17:56:24 CEST 2019


---
 include/vlc_picture.h                     |  7 +++--
 lib/picture.c                             |  2 +-
 modules/misc/medialibrary/Thumbnailer.cpp |  2 +-
 src/misc/picture.c                        | 36 +++++++++++++++++++----
 src/video_output/video_output.c           |  2 +-
 5 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/include/vlc_picture.h b/include/vlc_picture.h
index 58aba49445..c314c9c207 100644
--- a/include/vlc_picture.h
+++ b/include/vlc_picture.h
@@ -260,10 +260,13 @@ VLC_API picture_t *picture_Clone(picture_t *pic);
  *  - if strictly lower than 0, the original dimension will be used.
  *  - if equal to 0, it will be deduced from the other dimension which must be
  *  different to 0.
- *  - if strictly higher than 0, it will override the dimension.
+ *  - if strictly higher than 0, it will either override the dimension if b_crop
+ *  is false, or crop the picture to the provided size if b_crop is true.
  * If at most one of them is > 0 then the picture aspect ratio will be kept.
  */
-VLC_API int picture_Export( vlc_object_t *p_obj, block_t **pp_image, video_format_t *p_fmt, picture_t *p_picture, vlc_fourcc_t i_format, int i_override_width, int i_override_height );
+VLC_API int picture_Export( vlc_object_t *p_obj, block_t **pp_image, video_format_t *p_fmt,
+                            picture_t *p_picture, vlc_fourcc_t i_format, int i_override_width,
+                            int i_override_height, bool b_crop );
 
 /**
  * This function will setup all fields of a picture_t without allocating any
diff --git a/lib/picture.c b/lib/picture.c
index 0a4541baf7..5a7d9cb6e6 100644
--- a/lib/picture.c
+++ b/lib/picture.c
@@ -69,7 +69,7 @@ libvlc_picture_t* libvlc_picture_new( vlc_object_t* p_obj, picture_t* input,
             vlc_assert_unreachable();
     }
     if ( picture_Export( p_obj, &pic->converted, &pic->fmt,
-                         input, format, width, height ) != VLC_SUCCESS )
+                         input, format, width, height, false ) != VLC_SUCCESS )
     {
         free( pic );
         return NULL;
diff --git a/modules/misc/medialibrary/Thumbnailer.cpp b/modules/misc/medialibrary/Thumbnailer.cpp
index 013077f54a..5bc5b4f029 100644
--- a/modules/misc/medialibrary/Thumbnailer.cpp
+++ b/modules/misc/medialibrary/Thumbnailer.cpp
@@ -93,7 +93,7 @@ bool Thumbnailer::generate( const std::string& mrl, uint32_t desiredWidth,
 
     block_t* block;
     if ( picture_Export( VLC_OBJECT( m_ml ), &block, nullptr, ctx.thumbnail,
-                         VLC_CODEC_JPEG, desiredWidth, desiredHeight ) != VLC_SUCCESS )
+                         VLC_CODEC_JPEG, desiredWidth, desiredHeight, true ) != VLC_SUCCESS )
         return false;
     auto blockPtr = vlc::wrap_cptr( block, &block_Release );
 
diff --git a/src/misc/picture.c b/src/misc/picture.c
index cd463d4034..cdde6f9951 100644
--- a/src/misc/picture.c
+++ b/src/misc/picture.c
@@ -438,7 +438,8 @@ int picture_Export( vlc_object_t *p_obj,
                     video_format_t *p_fmt,
                     picture_t *p_picture,
                     vlc_fourcc_t i_format,
-                    int i_override_width, int i_override_height )
+                    int i_override_width, int i_override_height,
+                    bool b_crop )
 {
     /* */
     video_format_t fmt_in = p_picture->format;
@@ -479,10 +480,35 @@ int picture_Export( vlc_object_t *p_obj,
     }
 
     /* */
-    fmt_out.i_width  = ( i_override_width < 0 ) ?
-                       i_original_width : (unsigned)i_override_width;
-    fmt_out.i_height = ( i_override_height < 0 ) ?
-                       i_original_height : (unsigned)i_override_height;
+    if( b_crop && i_override_width > 0 && i_override_height > 0 )
+    {
+        float f_ar_dest = (float)i_override_width / i_override_height;
+        float f_ar_src = (float)i_width / i_height;
+        unsigned int i_crop_width, i_crop_height;
+        if ( f_ar_dest > f_ar_src )
+        {
+            i_crop_width = i_width;
+            i_crop_height = (float)i_crop_width / f_ar_dest;
+        }
+        else
+        {
+            i_crop_height = i_height;
+            i_crop_width = (float)i_crop_height * f_ar_dest;
+        }
+        fmt_out.i_width = i_override_width;
+        fmt_out.i_height = i_override_height;
+        fmt_in.i_visible_width = i_crop_width;
+        fmt_in.i_visible_height = i_crop_height;
+        fmt_in.i_x_offset += (i_width - i_crop_width) / 2;
+        fmt_in.i_y_offset += (i_height - i_crop_height) / 2;
+    }
+    else
+    {
+        fmt_out.i_width  = ( i_override_width < 0 ) ?
+                           i_original_width : (unsigned)i_override_width;
+        fmt_out.i_height = ( i_override_height < 0 ) ?
+                           i_original_height : (unsigned)i_override_height;
+    }
 
     /* scale if only one direction is provided */
     if( fmt_out.i_height == 0 && fmt_out.i_width > 0 )
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 14333044dc..2a5865af3f 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -373,7 +373,7 @@ int vout_GetSnapshot(vout_thread_t *vout,
         const int override_height = var_InheritInteger(vout, "snapshot-height");
 
         if (picture_Export(VLC_OBJECT(vout), image_dst, fmt,
-                           picture, codec, override_width, override_height)) {
+                           picture, codec, override_width, override_height, false)) {
             msg_Err(vout, "Failed to convert image for snapshot");
             picture_Release(picture);
             return VLC_EGENERIC;
-- 
2.20.1



More information about the vlc-devel mailing list