+ if( p_sys->i_sar_num == i_old_sar_num &&
+ p_sys->i_sar_den == i_old_sar_den )
+ return;
+
+ if( p_sys->p_info->sequence->frame_period > 0 )
+ msg_Dbg( p_dec,
+ "%dx%d (display %d,%d), sar %i:%i, %u.%03u fps",
+ p_sys->p_info->sequence->picture_width,
+ p_sys->p_info->sequence->picture_height,
+ p_sys->p_info->sequence->display_width,
+ p_sys->p_info->sequence->display_height,
+ p_sys->i_sar_num, p_sys->i_sar_den,
+ (uint32_t)((uint64_t)1001000000 * 27 /
+ p_sys->p_info->sequence->frame_period / 1001),
+ (uint32_t)((uint64_t)1001000000 * 27 /
+ p_sys->p_info->sequence->frame_period % 1001) );
+ else
+ msg_Dbg( p_dec, "bad frame period" );
+}
+
+/*****************************************************************************
+ * PutPicture: Put a picture_t in mpeg2 context
+ *****************************************************************************/
+static void PutPicture( decoder_t *p_dec, picture_t *p_picture )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ /* */
+ uint8_t *pp_buf[3];
+ for( int j = 0; j < 3; j++ )
+ pp_buf[j] = p_picture ? p_picture->p[j].p_pixels : NULL;
+ mpeg2_set_buf( p_sys->p_mpeg2dec, pp_buf, p_picture );
+
+ /* Completly broken API, why the hell does it suppose
+ * the stride of the chroma planes ! */
+ if( p_picture )
+ mpeg2_stride( p_sys->p_mpeg2dec, p_picture->p[Y_PLANE].i_pitch );
+}
+
+
+/**
+ * Initialize a virtual Decoded Picture Buffer to workaround
+ * libmpeg2 deficient API
+ */
+static void DpbInit( decoder_t *p_dec )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ for( int i = 0; i < DPB_COUNT; i++ )
+ p_sys->p_dpb[i].p_picture = NULL;
+}
+/**
+ * Empty and reset the current DPB
+ */
+static void DpbClean( decoder_t *p_dec )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ for( int i = 0; i < DPB_COUNT; i++ )
+ {
+ picture_dpb_t *p = &p_sys->p_dpb[i];
+ if( !p->p_picture )
+ continue;
+ if( p->b_linked )
+ decoder_UnlinkPicture( p_dec, p->p_picture );
+ if( !p->b_displayed )
+ decoder_DeletePicture( p_dec, p->p_picture );
+
+ p->p_picture = NULL;
+ }
+}
+/**
+ * Retreive a picture and reserve a place in the DPB
+ */
+static picture_t *DpbNewPicture( decoder_t *p_dec )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ picture_dpb_t *p;
+ int i;
+
+ for( i = 0; i < DPB_COUNT; i++ )
+ {
+ p = &p_sys->p_dpb[i];
+ if( !p->p_picture )
+ break;
+ }
+ if( i >= DPB_COUNT )
+ {
+ msg_Err( p_dec, "Leaking picture" );
+ return NULL;
+ }
+
+ p->p_picture = GetNewPicture( p_dec );
+ if( p->p_picture )
+ {
+ decoder_LinkPicture( p_dec, p->p_picture );
+ p->b_linked = true;
+ p->b_displayed = false;
+
+ p->p_picture->date = 0;
+ }
+ return p->p_picture;
+}
+static picture_dpb_t *DpbFindPicture( decoder_t *p_dec, picture_t *p_picture )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ for( int i = 0; i < DPB_COUNT; i++ )
+ {
+ picture_dpb_t *p = &p_sys->p_dpb[i];
+ if( p->p_picture == p_picture )
+ return p;
+ }
+ return NULL;
+}
+/**
+ * Unlink the provided picture and ensure that the decoder
+ * does not own it anymore.
+ */
+static void DpbUnlinkPicture( decoder_t *p_dec, picture_t *p_picture )
+{
+ picture_dpb_t *p = DpbFindPicture( p_dec, p_picture );
+
+ /* XXX it is needed to workaround libmpeg2 bugs */
+ if( !p || !p->b_linked )
+ {
+ msg_Err( p_dec, "DpbUnlinkPicture called on an invalid picture" );
+ return;
+ }
+
+ assert( p && p->b_linked );
+
+ decoder_UnlinkPicture( p_dec, p->p_picture );
+ p->b_linked = false;
+
+ if( !p->b_displayed )
+ decoder_DeletePicture( p_dec, p->p_picture );
+ p->p_picture = NULL;