]> git.sesse.net Git - vlc/blobdiff - src/video_output/vout_pictures.c
rtp sout: fix duplicate slashes in RTSP URLs
[vlc] / src / video_output / vout_pictures.c
index e63935328df70a395560e094d943acf07911b3a5..a84920059310706beed0955f9428edde3641ebd4 100644 (file)
@@ -65,6 +65,7 @@ void vout_DisplayPicture( vout_thread_t *p_vout, picture_t *p_pic )
                          p_pic, p_pic->i_status );
     }
     p_vout->p->i_picture_qtype = p_pic->i_qtype;
+    p_vout->p->b_picture_interlaced = !p_pic->b_progressive;
 
     vlc_mutex_unlock( &p_vout->picture_lock );
 }
@@ -169,7 +170,8 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout,
         vout_AllocatePicture( VLC_OBJECT(p_vout),
                               p_freepic, p_vout->render.i_chroma,
                               p_vout->render.i_width, p_vout->render.i_height,
-                              p_vout->render.i_aspect );
+                              p_vout->render.i_aspect * p_vout->render.i_height,
+                              VOUT_ASPECT_FACTOR      * p_vout->render.i_width);
 
         if( p_freepic->i_planes )
         {
@@ -407,7 +409,8 @@ picture_t *vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic,
                                   p_tmp_pic, p_vout->fmt_out.i_chroma,
                                   p_vout->fmt_out.i_width,
                                   p_vout->fmt_out.i_height,
-                                  p_vout->fmt_out.i_aspect );
+                                  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;
         }
@@ -552,24 +555,49 @@ void vout_PlacePicture( const vout_thread_t *p_vout,
  */
 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_aspect )
+                            int i_width, int i_height,
+                            int i_sar_num, int i_sar_den )
 {
-    int i_bytes, i_index, i_width_aligned, i_height_aligned;
+    VLC_UNUSED(p_this);
+    int i_index, i_width_aligned, i_height_aligned;
 
     /* Make sure the real dimensions are a multiple of 16 */
     i_width_aligned = (i_width + 15) >> 4 << 4;
     i_height_aligned = (i_height + 15) >> 4 << 4;
 
-    if( picture_Setup( p_pic, i_chroma,
-                       i_width, i_height, i_aspect ) != VLC_SUCCESS )
+    if( picture_Setup( p_pic, i_chroma, i_width, i_height,
+                       i_sar_num, i_sar_den ) != VLC_SUCCESS )
     {
         p_pic->i_planes = 0;
         return VLC_EGENERIC;
     }
 
     /* Calculate how big the new image should be */
-    i_bytes = p_pic->format.i_bits_per_pixel *
-        i_width_aligned * i_height_aligned / 8;
+
+    /*
+     * bytes = width_aligned * height_aligned * bpp / 8
+     * We need to check for an integer overflow at each multiplication since
+     * height & width (and bpp?) could be arbitrary large
+     */
+
+    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) )
+    {
+        size_t i_pixels_divided = i_width_aligned_divided * i_height_aligned;
+        size_t i_bpp = p_pic->format.i_bits_per_pixel;
+        if( i_pixels_divided <= (SIZE_MAX/i_bpp) )
+        {
+            i_bytes = i_pixels_divided * i_bpp;
+        }
+    }
+
+    if( i_bytes == 0 )
+    {
+        p_pic->i_planes = 0;
+        return VLC_ENOMEM;
+    }
 
     p_pic->p_data = vlc_memalign( &p_pic->p_data_orig, 16, i_bytes );
 
@@ -668,7 +696,8 @@ void picture_Reset( picture_t *p_picture )
 /*****************************************************************************
  *
  *****************************************************************************/
-int picture_Setup( picture_t *p_picture, vlc_fourcc_t i_chroma, int i_width, int i_height, int i_aspect )
+int picture_Setup( picture_t *p_picture, vlc_fourcc_t i_chroma,
+                   int i_width, int i_height, int i_sar_num, int i_sar_den )
 {
     int i_index, i_width_aligned, i_height_aligned;
 
@@ -689,7 +718,8 @@ int picture_Setup( picture_t *p_picture, vlc_fourcc_t i_chroma, int i_width, int
     p_picture->i_qstride = 0;
     p_picture->p_q = NULL;
 
-    video_format_Setup( &p_picture->format, i_chroma, i_width, i_height, i_aspect );
+    video_format_Setup( &p_picture->format, i_chroma, i_width, i_height,
+                        i_sar_num, i_sar_den );
 
     /* Make sure the real dimensions are a multiple of 16 */
     i_width_aligned = (i_width + 15) >> 4 << 4;
@@ -824,7 +854,7 @@ int picture_Setup( picture_t *p_picture, vlc_fourcc_t i_chroma, int i_width, int
         p_picture->p->i_visible_lines = i_height;
         p_picture->p->i_pitch = i_width_aligned;
         p_picture->p->i_visible_pitch = i_width;
-        p_picture->p->i_pixel_pitch = 8;
+        p_picture->p->i_pixel_pitch = 1;
         p_picture->i_planes = 1;
         break;
 
@@ -845,7 +875,7 @@ int picture_Setup( picture_t *p_picture, vlc_fourcc_t i_chroma, int i_width, int
         p_picture->p->i_visible_lines = i_height;
         p_picture->p->i_pitch = i_width_aligned * 2;
         p_picture->p->i_visible_pitch = i_width * 2;
-        p_picture->p->i_pixel_pitch = 4;
+        p_picture->p->i_pixel_pitch = 2;
         p_picture->i_planes = 1;
         break;
 
@@ -922,7 +952,8 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r
 
     /* It is needed to be sure all informations are filled */
     video_format_Setup( &fmt, p_fmt->i_chroma,
-                              p_fmt->i_width, p_fmt->i_height, p_fmt->i_aspect );
+                              p_fmt->i_width, p_fmt->i_height,
+                              p_fmt->i_sar_num, p_fmt->i_sar_den );
 
     /* */
     picture_t *p_picture = calloc( 1, sizeof(*p_picture) );
@@ -931,7 +962,8 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r
 
     if( p_resource )
     {
-        if( picture_Setup( p_picture, fmt.i_chroma, fmt.i_width, fmt.i_height, fmt.i_aspect ) )
+        if( picture_Setup( p_picture, fmt.i_chroma, fmt.i_width, fmt.i_height,
+                           fmt.i_sar_num, fmt.i_sar_den ) )
         {
             free( p_picture );
             return NULL;
@@ -948,7 +980,8 @@ 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_aspect ) )
+                                    fmt.i_chroma, fmt.i_width, fmt.i_height,
+                                    fmt.i_sar_num, fmt.i_sar_den ) )
         {
             free( p_picture );
             return NULL;
@@ -966,12 +999,13 @@ picture_t *picture_NewFromFormat( const video_format_t *p_fmt )
 {
     return picture_NewFromResource( p_fmt, NULL );
 }
-picture_t *picture_New( vlc_fourcc_t i_chroma, int i_width, int i_height, int i_aspect )
+picture_t *picture_New( vlc_fourcc_t i_chroma, int i_width, int i_height, int i_sar_num, int i_sar_den )
 {
     video_format_t fmt;
 
     memset( &fmt, 0, sizeof(fmt) );
-    video_format_Setup( &fmt, i_chroma, i_width, i_height, i_aspect );
+    video_format_Setup( &fmt, i_chroma, i_width, i_height,
+                        i_sar_num, i_sar_den );
 
     return picture_NewFromFormat( &fmt );
 }
@@ -1109,272 +1143,3 @@ int picture_Export( vlc_object_t *p_obj,
     return VLC_SUCCESS;
 }
 
-/*****************************************************************************
- *
- *****************************************************************************/
-struct picture_fifo_t
-{
-    vlc_mutex_t lock;
-    picture_t *p_first;
-    picture_t **pp_last;
-};
-
-static void PictureFifoReset( picture_fifo_t *p_fifo )
-{
-    p_fifo->p_first = NULL;
-    p_fifo->pp_last = &p_fifo->p_first;
-}
-static void PictureFifoPush( picture_fifo_t *p_fifo, picture_t *p_picture )
-{
-    assert( !p_picture->p_next );
-    *p_fifo->pp_last = p_picture;
-    p_fifo->pp_last = &p_picture->p_next;
-}
-static picture_t *PictureFifoPop( picture_fifo_t *p_fifo )
-{
-    picture_t *p_picture = p_fifo->p_first;
-
-    if( p_picture )
-    {
-        p_fifo->p_first = p_picture->p_next;
-        if( !p_fifo->p_first )
-            p_fifo->pp_last = &p_fifo->p_first;
-    }
-    return p_picture;
-}
-
-picture_fifo_t *picture_fifo_New(void)
-{
-    picture_fifo_t *p_fifo = malloc( sizeof(*p_fifo) );
-    if( !p_fifo )
-        return NULL;
-
-    vlc_mutex_init( &p_fifo->lock );
-    PictureFifoReset( p_fifo );
-    return p_fifo;
-}
-
-void picture_fifo_Push( picture_fifo_t *p_fifo, picture_t *p_picture )
-{
-    vlc_mutex_lock( &p_fifo->lock );
-    PictureFifoPush( p_fifo, p_picture );
-    vlc_mutex_unlock( &p_fifo->lock );
-}
-picture_t *picture_fifo_Pop( picture_fifo_t *p_fifo )
-{
-    vlc_mutex_lock( &p_fifo->lock );
-    picture_t *p_picture = PictureFifoPop( p_fifo );
-    vlc_mutex_unlock( &p_fifo->lock );
-
-    return p_picture;
-}
-picture_t *picture_fifo_Peek( picture_fifo_t *p_fifo )
-{
-    vlc_mutex_lock( &p_fifo->lock );
-    picture_t *p_picture = p_fifo->p_first;
-    if( p_picture )
-        picture_Hold( p_picture );
-    vlc_mutex_unlock( &p_fifo->lock );
-
-    return p_picture;
-}
-void picture_fifo_Flush( picture_fifo_t *p_fifo, mtime_t i_date, bool b_below )
-{
-    picture_t *p_picture;
-
-    vlc_mutex_lock( &p_fifo->lock );
-
-    p_picture = p_fifo->p_first;
-    PictureFifoReset( p_fifo );
-
-    picture_fifo_t tmp;
-    PictureFifoReset( &tmp );
-
-    while( p_picture )
-    {
-        picture_t *p_next = p_picture->p_next;
-
-        p_picture->p_next = NULL;
-        if( (  b_below && p_picture->date <= i_date ) ||
-            ( !b_below && p_picture->date >= i_date ) )
-            PictureFifoPush( &tmp, p_picture );
-        else
-            PictureFifoPush( p_fifo, p_picture );
-        p_picture = p_next;
-    }
-    vlc_mutex_unlock( &p_fifo->lock );
-
-    for( ;; )
-    {
-        picture_t *p_picture = PictureFifoPop( &tmp );
-        if( !p_picture )
-            break;
-        picture_Release( p_picture );
-    }
-}
-void picture_fifo_OffsetDate( picture_fifo_t *p_fifo, mtime_t i_delta )
-{
-    vlc_mutex_lock( &p_fifo->lock );
-    for( picture_t *p_picture = p_fifo->p_first; p_picture != NULL; )
-    {
-        p_picture->date += i_delta;
-        p_picture = p_picture->p_next;
-    }
-    vlc_mutex_unlock( &p_fifo->lock );
-}
-void picture_fifo_Delete( picture_fifo_t *p_fifo )
-{
-    picture_fifo_Flush( p_fifo, INT64_MAX, true );
-    vlc_mutex_destroy( &p_fifo->lock );
-}
-
-/*****************************************************************************
- *
- *****************************************************************************/
-struct picture_release_sys_t
-{
-    /* Saved release */
-    void (*pf_release)( picture_t * );
-    picture_release_sys_t *p_release_sys;
-
-    /* */
-    int64_t i_tick;
-};
-
-struct picture_pool_t
-{
-    int64_t i_tick;
-
-    int i_picture;
-    picture_t **pp_picture;
-};
-
-static void PicturePoolPictureRelease( picture_t * );
-
-picture_pool_t *picture_pool_New( int i_picture, picture_t *pp_picture[] )
-{
-    picture_pool_t *p_pool = calloc( 1, sizeof(*p_pool) );
-    if( !p_pool )
-        return NULL;
-
-    p_pool->i_tick = 1;
-    p_pool->i_picture = i_picture;
-    p_pool->pp_picture = calloc( p_pool->i_picture, sizeof(*p_pool->pp_picture) );
-
-    for( int i = 0; i < i_picture; i++ )
-    {
-        picture_t *p_picture = pp_picture[i];
-
-        /* The pool must be the only owner of the picture */
-        assert( p_picture->i_refcount == 1 );
-
-        /* Install the new release callback */
-        picture_release_sys_t *p_release_sys = malloc( sizeof(*p_release_sys) );
-        p_release_sys->pf_release = p_picture->pf_release;
-        p_release_sys->p_release_sys = p_picture->p_release_sys;
-        p_release_sys->i_tick = 0;
-
-        p_picture->i_refcount = 0;
-        p_picture->pf_release = PicturePoolPictureRelease;
-        p_picture->p_release_sys = p_release_sys;
-
-        /* */
-        p_pool->pp_picture[i] = p_picture;
-    }
-    return p_pool;
-}
-
-picture_pool_t *picture_pool_NewFromFormat( const video_format_t *p_fmt, int i_picture )
-{
-    picture_t *pp_picture[i_picture];
-
-    for( int i = 0; i < i_picture; i++ )
-    {
-        pp_picture[i] = picture_New( p_fmt->i_chroma,
-                                     p_fmt->i_width, p_fmt->i_height,
-                                     p_fmt->i_aspect );
-        if( !pp_picture[i] )
-            goto error;
-    }
-    picture_pool_t *p_pool = picture_pool_New( i_picture, pp_picture );
-    if( !p_pool )
-        goto error;
-
-    return p_pool;
-
-error:
-    for( int i = 0; i < i_picture; i++ )
-    {
-        if( !pp_picture[i] )
-            break;
-        picture_Release( pp_picture[i] );
-    }
-    return NULL;
-}
-
-void picture_pool_Delete( picture_pool_t *p_pool )
-{
-    for( int i = 0; i < p_pool->i_picture; i++ )
-    {
-        picture_t *p_picture = p_pool->pp_picture[i];
-        picture_release_sys_t *p_release_sys = p_picture->p_release_sys;
-
-        assert( p_picture->i_refcount == 0 );
-
-        /* Restore old release callback */
-        p_picture->i_refcount = 1;
-        p_picture->pf_release = p_release_sys->pf_release;
-        p_picture->p_release_sys = p_release_sys->p_release_sys;
-
-        picture_Release( p_picture );
-
-        free( p_release_sys );
-    }
-    free( p_pool );
-}
-
-picture_t *picture_pool_Get( picture_pool_t *p_pool )
-{
-    for( int i = 0; i < p_pool->i_picture; i++ )
-    {
-        picture_t *p_picture = p_pool->pp_picture[i];
-
-        if( p_picture->i_refcount <= 0 )
-        {
-            p_picture->p_release_sys->i_tick = p_pool->i_tick++;
-            picture_Hold( p_picture );
-            return p_picture;
-        }
-    }
-    return NULL;
-}
-
-void picture_pool_NonEmpty( picture_pool_t *p_pool, bool b_reset )
-{
-    picture_t *p_old = NULL;
-
-    for( int i = 0; i < p_pool->i_picture; i++ )
-    {
-        picture_t *p_picture = p_pool->pp_picture[i];
-
-        if( b_reset )
-            p_picture->i_refcount = 0;
-        else if( p_picture->i_refcount == 0 )
-            return;
-        else if( !p_old || p_picture->p_release_sys->i_tick < p_old->p_release_sys->i_tick )
-            p_old = p_picture;
-    }
-    if( !b_reset && p_old )
-        p_old->i_refcount = 0;
-}
-
-static void PicturePoolPictureRelease( picture_t *p_picture )
-{
-    assert( p_picture->i_refcount > 0 );
-
-    if( --p_picture->i_refcount > 0 )
-        return;
-
-    /* Nothing to do for the moment */
-}
-