]> git.sesse.net Git - vlc/blobdiff - src/video_output/vout_pictures.c
a macro to automate the choice of "folder"/"directory" string version according to...
[vlc] / src / video_output / vout_pictures.c
index a84920059310706beed0955f9428edde3641ebd4..98b8e41412203bd3494e9979ee91f34b7c958bb4 100644 (file)
@@ -317,18 +317,6 @@ void vout_UnlinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
     vlc_mutex_unlock( &p_vout->picture_lock );
 }
 
-static int vout_LockPicture( vout_thread_t *p_vout, picture_t *p_picture )
-{
-    if( p_picture->pf_lock )
-        return p_picture->pf_lock( p_vout, p_picture );
-    return VLC_SUCCESS;
-}
-static void vout_UnlockPicture( vout_thread_t *p_vout, picture_t *p_picture )
-{
-    if( p_picture->pf_unlock )
-        p_picture->pf_unlock( p_vout, p_picture );
-}
-
 /**
  * Render a picture
  *
@@ -342,111 +330,63 @@ picture_t *vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic,
     if( p_pic == NULL )
         return NULL;
 
-    if( p_pic->i_type == DIRECT_PICTURE )
+    if( p_pic->i_type == DIRECT_PICTURE && !p_subpic )
     {
-        /* Picture is in a direct buffer. */
-
-        if( p_subpic != NULL )
-        {
-            /* We have subtitles. First copy the picture to
-             * the spare direct buffer, then render the
-             * subtitles. */
-            if( vout_LockPicture( p_vout, PP_OUTPUTPICTURE[0] ) )
-                return NULL;
-
-            picture_Copy( PP_OUTPUTPICTURE[0], p_pic );
-
-            spu_RenderSubpictures( p_vout->p_spu,
-                                   PP_OUTPUTPICTURE[0], &p_vout->fmt_out,
-                                   p_subpic, &p_vout->fmt_in, render_date );
-
-            vout_UnlockPicture( p_vout, PP_OUTPUTPICTURE[0] );
-
-            return PP_OUTPUTPICTURE[0];
-        }
-
         /* No subtitles, picture is in a directbuffer so
          * we can display it directly (even if it is still
          * in use or not). */
         return p_pic;
     }
 
-    /* Not a direct buffer. We either need to copy it to a direct buffer,
-     * or render it if the chroma isn't the same. */
-    if( p_vout->p->b_direct )
-    {
-        /* Picture is not in a direct buffer, but is exactly the
-         * same size as the direct buffers. A memcpy() is enough,
-         * then render the subtitles. */
-
-        if( vout_LockPicture( p_vout, PP_OUTPUTPICTURE[0] ) )
-            return NULL;
-
-        picture_Copy( PP_OUTPUTPICTURE[0], p_pic );
-        spu_RenderSubpictures( p_vout->p_spu,
-                               PP_OUTPUTPICTURE[0], &p_vout->fmt_out,
-                               p_subpic, &p_vout->fmt_in, render_date );
-
-        vout_UnlockPicture( p_vout, PP_OUTPUTPICTURE[0] );
-
-        return PP_OUTPUTPICTURE[0];
-    }
-
-    /* Picture is not in a direct buffer, and needs to be converted to
-     * another size/chroma. Then the subtitles need to be rendered as
-     * well. This usually means software YUV, or hardware YUV with a
-     * different chroma. */
-
-    if( p_subpic != NULL && p_vout->p_picture[0].b_slow )
+    /* It is either because:
+     *  - the picture is not a direct buffer
+     *  - we have to render subtitles (we can never do it on the given
+     *  picture even if not referenced).
+     */
+    picture_t *p_render;
+    if( p_subpic != NULL && PP_OUTPUTPICTURE[0]->b_slow )
     {
         /* The picture buffer is in slow memory. We'll use
          * the "2 * VOUT_MAX_PICTURES + 1" picture as a temporary
          * one for subpictures rendering. */
-        picture_t *p_tmp_pic = &p_vout->p_picture[2 * VOUT_MAX_PICTURES];
-        if( p_tmp_pic->i_status == FREE_PICTURE )
+        p_render = &p_vout->p_picture[2 * VOUT_MAX_PICTURES];
+        if( p_render->i_status == FREE_PICTURE )
         {
             vout_AllocatePicture( VLC_OBJECT(p_vout),
-                                  p_tmp_pic, p_vout->fmt_out.i_chroma,
+                                  p_render, p_vout->fmt_out.i_chroma,
                                   p_vout->fmt_out.i_width,
                                   p_vout->fmt_out.i_height,
                                   p_vout->fmt_out.i_sar_num,
                                   p_vout->fmt_out.i_sar_den );
-            p_tmp_pic->i_type = MEMORY_PICTURE;
-            p_tmp_pic->i_status = RESERVED_PICTURE;
+            p_render->i_type = MEMORY_PICTURE;
+            p_render->i_status = RESERVED_PICTURE;
         }
-
-        /* Convert image to the first direct buffer */
-        p_vout->p->p_chroma->p_owner = (filter_owner_sys_t *)p_tmp_pic;
-        p_vout->p->p_chroma->pf_video_filter( p_vout->p->p_chroma, p_pic );
-
-        /* Render subpictures on the first direct buffer */
-        spu_RenderSubpictures( p_vout->p_spu,
-                               p_tmp_pic, &p_vout->fmt_out,
-                               p_subpic, &p_vout->fmt_in, render_date );
-
-        if( vout_LockPicture( p_vout, &p_vout->p_picture[0] ) )
-            return NULL;
-
-        picture_Copy( &p_vout->p_picture[0], p_tmp_pic );
     }
     else
     {
-        if( vout_LockPicture( p_vout, &p_vout->p_picture[0] ) )
-            return NULL;
-
-        /* Convert image to the first direct buffer */
-        p_vout->p->p_chroma->p_owner = (filter_owner_sys_t *)&p_vout->p_picture[0];
+        /* We can directly render into a direct buffer */
+        p_render = PP_OUTPUTPICTURE[0];
+    }
+    /* Copy or convert */
+    if( p_vout->p->b_direct )
+    {
+        picture_Copy( p_render, p_pic );
+    }
+    else
+    {
+        p_vout->p->p_chroma->p_owner = (filter_owner_sys_t *)p_render;
         p_vout->p->p_chroma->pf_video_filter( p_vout->p->p_chroma, p_pic );
-
-        /* Render subpictures on the first direct buffer */
+    }
+    /* Render the subtitles if present */
+    if( p_subpic )
         spu_RenderSubpictures( p_vout->p_spu,
-                               &p_vout->p_picture[0], &p_vout->fmt_out,
+                               p_render, &p_vout->fmt_out,
                                p_subpic, &p_vout->fmt_in, render_date );
-    }
-
-    vout_UnlockPicture( p_vout, &p_vout->p_picture[0] );
+    /* Copy in case we used a temporary fast buffer */
+    if( p_render != PP_OUTPUTPICTURE[0] )
+        picture_Copy( PP_OUTPUTPICTURE[0], p_render );
 
-    return &p_vout->p_picture[0];
+    return PP_OUTPUTPICTURE[0];
 }
 
 /**
@@ -546,6 +486,7 @@ void vout_PlacePicture( const vout_thread_t *p_vout,
     }
 }
 
+#undef vout_AllocatePicture
 /**
  * Allocate a new picture in the heap.
  *
@@ -553,10 +494,10 @@ void vout_PlacePicture( const vout_thread_t *p_vout,
  * used exactly like a video buffer. The video output thread then manages
  * how it gets displayed.
  */
-int __vout_AllocatePicture( vlc_object_t *p_this, picture_t *p_pic,
-                            vlc_fourcc_t i_chroma,
-                            int i_width, int i_height,
-                            int i_sar_num, int i_sar_den )
+int vout_AllocatePicture( vlc_object_t *p_this, picture_t *p_pic,
+                          vlc_fourcc_t i_chroma,
+                          int i_width, int i_height,
+                          int i_sar_num, int i_sar_den )
 {
     VLC_UNUSED(p_this);
     int i_index, i_width_aligned, i_height_aligned;
@@ -583,7 +524,7 @@ int __vout_AllocatePicture( vlc_object_t *p_this, picture_t *p_pic,
     size_t i_bytes = 0;
     /* i_width_aligned is a multiple of 16, so we can divide by 8 now */
     size_t i_width_aligned_divided = i_width_aligned / 8;
-    if( i_width_aligned_divided <= (SIZE_MAX/i_height_aligned) )
+    if( i_height_aligned > 0 && i_width_aligned_divided <= (SIZE_MAX/i_height_aligned) )
     {
         size_t i_pixels_divided = i_width_aligned_divided * i_height_aligned;
         size_t i_bpp = p_pic->format.i_bits_per_pixel;
@@ -710,8 +651,6 @@ int picture_Setup( picture_t *p_picture, vlc_fourcc_t i_chroma,
 
     p_picture->pf_release = NULL;
     p_picture->p_release_sys = NULL;
-    p_picture->pf_lock = NULL;
-    p_picture->pf_unlock = NULL;
     p_picture->i_refcount = 0;
 
     p_picture->i_qtype = QTYPE_NONE;
@@ -744,6 +683,7 @@ int picture_Setup( picture_t *p_picture, vlc_fourcc_t i_chroma,
         p_picture->i_planes = 3;
         break;
 
+    case VLC_CODEC_YV9:
     case VLC_CODEC_I410:
         p_picture->p[ Y_PLANE ].i_lines = i_height_aligned;
         p_picture->p[ Y_PLANE ].i_visible_lines = i_height;
@@ -979,9 +919,9 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r
     }
     else
     {
-        if( __vout_AllocatePicture( NULL, p_picture,
-                                    fmt.i_chroma, fmt.i_width, fmt.i_height,
-                                    fmt.i_sar_num, fmt.i_sar_den ) )
+        if( vout_AllocatePicture( (vlc_object_t *)NULL, p_picture,
+                                  fmt.i_chroma, fmt.i_width, fmt.i_height,
+                                  fmt.i_sar_num, fmt.i_sar_den ) )
         {
             free( p_picture );
             return NULL;