+ p_cc = block_New( p_dec, p_sys->cc.i_data);
+ if( p_cc )
+ {
+ memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data );
+ p_cc->i_dts =
+ p_cc->i_pts = p_sys->cc.b_reorder ? p_sys->i_cc_pts : p_sys->i_cc_dts;
+ p_cc->i_flags = ( p_sys->cc.b_reorder ? p_sys->i_cc_flags : BLOCK_FLAG_TYPE_P ) & ( BLOCK_FLAG_TYPE_I|BLOCK_FLAG_TYPE_P|BLOCK_FLAG_TYPE_B);
+ }
+ cc_Flush( &p_sys->cc );
+ return p_cc;
+}
+#endif
+
+/*****************************************************************************
+ * GetAR: Get aspect ratio
+ *****************************************************************************/
+static void GetAR( decoder_t *p_dec )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ int i_old_sar_num = p_sys->i_sar_num;
+ int i_old_sar_den = p_sys->i_sar_den;
+
+ /* Check whether the input gave a particular aspect ratio */
+ if( p_dec->fmt_in.video.i_sar_num > 0 &&
+ p_dec->fmt_in.video.i_sar_den > 0 )
+ {
+ p_sys->i_sar_num = p_dec->fmt_in.video.i_sar_num;
+ p_sys->i_sar_den = p_dec->fmt_in.video.i_sar_den;
+ }
+ else
+ {
+ /* Use the value provided in the MPEG sequence header */
+ if( p_sys->p_info->sequence->pixel_height > 0 )
+ {
+ p_sys->i_sar_num = p_sys->p_info->sequence->pixel_width;
+ p_sys->i_sar_den = p_sys->p_info->sequence->pixel_height;
+ }
+ else
+ {
+ /* Invalid aspect, assume 4:3.
+ * This shouldn't happen and if it does it is a bug
+ * in libmpeg2 (likely triggered by an invalid stream) */
+ p_sys->i_sar_num = p_sys->p_info->sequence->picture_height * 4;
+ p_sys->i_sar_den = p_sys->p_info->sequence->picture_width * 3;
+ }
+ }
+
+ 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;