static gboolean caps_handoff_cb( GstElement* p_ele, GstCaps *p_caps, gpointer p_data ) { VLC_UNUSED( p_ele ); decoder_t *p_dec = p_data; decoder_sys_t *p_sys = p_dec->p_sys; msg_Info( p_dec, "got new caps %s", gst_caps_to_string( p_caps )); if( !gst_video_info_from_caps( &p_sys->vinfo, p_caps )) { msg_Err( p_dec, "failed to negotiate" ); return FALSE; } gst_vlc_dec_ensure_empty_queue( p_dec ); return gst_vlc_set_vout_fmt( &p_sys->vinfo, p_caps, p_dec ); }
static bool gst_vlc_video_info_from_vout( GstVideoInfo *p_info, GstVideoAlignment *p_align, GstCaps *p_caps, decoder_t *p_dec, picture_t *p_pic_info ) { const GstVideoFormatInfo *p_vinfo = p_info->finfo; picture_t *p_pic = NULL; int i; /* Ensure the queue is empty */ gst_vlc_dec_ensure_empty_queue( p_dec ); gst_video_info_align( p_info, p_align ); if( !gst_vlc_set_vout_fmt( p_info, p_align, p_caps, p_dec )) { msg_Err( p_dec, "failed to set output format to vout" ); return false; } /* Acquire a picture and release it. This is to get the picture * stride/offsets info for the Gstreamer decoder looking to use * downstream bufferpool directly; Zero-Copy */ if( !decoder_UpdateVideoFormat( p_dec ) ) p_pic = decoder_NewPicture( p_dec ); if( !p_pic ) { msg_Err( p_dec, "failed to acquire picture from vout; for pic info" ); return false; } /* reject if strides don't match */ for( i = 0; i < p_pic->i_planes; i++ ) if( p_info->stride[i] != p_pic->p[i].i_pitch ) goto strides_mismatch; p_info->offset[0] = 0; for( i = 1; i < p_pic->i_planes; i++ ) { p_info->offset[i] = p_info->offset[i-1] + p_pic->p[i-1].i_pitch * p_pic->p[i-1].i_lines; } GST_VIDEO_INFO_SIZE( p_info ) = p_info->offset[i-1] + p_pic->p[i-1].i_pitch * p_pic->p[i-1].i_lines; for( i = 0; i < p_pic->i_planes; i++ ) { int i_v_edge, i_h_edge; i_h_edge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH( p_vinfo, i, p_align->padding_left); i_v_edge = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT( p_vinfo, i, p_align->padding_top); p_info->offset[i] += ( i_v_edge * p_info->stride[i] ) + ( i_h_edge * GST_VIDEO_FORMAT_INFO_PSTRIDE( p_vinfo, i )); } memcpy( p_pic_info, p_pic, sizeof( picture_t )); picture_Release( p_pic ); return true; strides_mismatch: msg_Err( p_dec, "strides mismatch" ); picture_Release( p_pic ); return false; }