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
*
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];
}
/**
}
}
+#undef vout_AllocatePicture
/**
* Allocate a new picture in the heap.
*
* 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;
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;
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;
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;
}
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;