mpegvideo.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:21k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mpegvideo.c: parse and packetize an MPEG1/2 video stream
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2006 the VideoLAN team
  5.  * $Id: a3a4020cfb57a89edda885b03f58bb6ec3e218d3 $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *          Eric Petit <titer@videolan.org>
  9.  *          Gildas Bazin <gbazin@videolan.org>
  10.  *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  25.  *****************************************************************************/
  26. /*****************************************************************************
  27.  * Problem with this implementation:
  28.  *
  29.  * Although we should time-stamp each picture with a PTS, this isn't possible
  30.  * with the current implementation.
  31.  * The problem comes from the fact that for non-low-delay streams we can't
  32.  * calculate the PTS of pictures used as backward reference. Even the temporal
  33.  * reference number doesn't help here because all the pictures don't
  34.  * necessarily have the same duration (eg. 3:2 pulldown).
  35.  *
  36.  * However this doesn't really matter as far as the MPEG muxers are concerned
  37.  * because they allow having empty PTS fields. --gibalou
  38.  *****************************************************************************/
  39. /*****************************************************************************
  40.  * Preamble
  41.  *****************************************************************************/
  42. #ifdef HAVE_CONFIG_H
  43. # include "config.h"
  44. #endif
  45. #include <vlc_common.h>
  46. #include <vlc_plugin.h>
  47. #include <vlc_block.h>
  48. #include <vlc_codec.h>
  49. #include <vlc_block_helper.h>
  50. #include "../codec/cc.h"
  51. #include "packetizer_helper.h"
  52. #define SYNC_INTRAFRAME_TEXT N_("Sync on Intra Frame")
  53. #define SYNC_INTRAFRAME_LONGTEXT N_("Normally the packetizer would " 
  54.     "sync on the next full frame. This flags instructs the packetizer " 
  55.     "to sync on the first Intra Frame found.")
  56. /*****************************************************************************
  57.  * Module descriptor
  58.  *****************************************************************************/
  59. static int  Open ( vlc_object_t * );
  60. static void Close( vlc_object_t * );
  61. vlc_module_begin ()
  62.     set_category( CAT_SOUT )
  63.     set_subcategory( SUBCAT_SOUT_PACKETIZER )
  64.     set_description( N_("MPEG-I/II video packetizer") )
  65.     set_shortname( N_("MPEG Video") )
  66.     set_capability( "packetizer", 50 )
  67.     set_callbacks( Open, Close )
  68.     add_bool( "packetizer-mpegvideo-sync-iframe", 0, NULL, SYNC_INTRAFRAME_TEXT,
  69.               SYNC_INTRAFRAME_LONGTEXT, true )
  70. vlc_module_end ()
  71. /*****************************************************************************
  72.  * Local prototypes
  73.  *****************************************************************************/
  74. struct decoder_sys_t
  75. {
  76.     /*
  77.      * Input properties
  78.      */
  79.     packetizer_t packetizer;
  80.     /* Sequence header and extension */
  81.     block_t *p_seq;
  82.     block_t *p_ext;
  83.     /* Current frame being built */
  84.     block_t    *p_frame;
  85.     block_t    **pp_last;
  86.     bool b_frame_slice;
  87.     mtime_t i_pts;
  88.     mtime_t i_dts;
  89.     /* Sequence properties */
  90.     int         i_frame_rate;
  91.     int         i_frame_rate_base;
  92.     bool  b_seq_progressive;
  93.     bool  b_low_delay;
  94.     int         i_aspect_ratio_info;
  95.     bool  b_inited;
  96.     /* Picture properties */
  97.     int i_temporal_ref;
  98.     int i_picture_type;
  99.     int i_picture_structure;
  100.     int i_top_field_first;
  101.     int i_repeat_first_field;
  102.     int i_progressive_frame;
  103.     mtime_t i_interpolated_dts;
  104.     mtime_t i_last_ref_pts;
  105.     bool b_second_field;
  106.     /* Number of pictures since last sequence header */
  107.     int i_seq_old;
  108.     /* Sync behaviour */
  109.     bool  b_sync_on_intra_frame;
  110.     bool  b_discontinuity;
  111.     /* */
  112.     bool b_cc_reset;
  113.     uint32_t i_cc_flags;
  114.     mtime_t i_cc_pts;
  115.     mtime_t i_cc_dts;
  116.     cc_data_t cc;
  117. };
  118. static block_t *Packetize( decoder_t *, block_t ** );
  119. static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] );
  120. static void PacketizeReset( void *p_private, bool b_broken );
  121. static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t * );
  122. static int PacketizeValidate( void *p_private, block_t * );
  123. static block_t *ParseMPEGBlock( decoder_t *, block_t * );
  124. static const uint8_t p_mp2v_startcode[3] = { 0x00, 0x00, 0x01 };
  125. /*****************************************************************************
  126.  * Open:
  127.  *****************************************************************************/
  128. static int Open( vlc_object_t *p_this )
  129. {
  130.     decoder_t *p_dec = (decoder_t*)p_this;
  131.     decoder_sys_t *p_sys;
  132.     if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', 'g', '1' ) &&
  133.         p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', 'g', '2' ) &&
  134.         p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', 'g', 'v' ) )
  135.     {
  136.         return VLC_EGENERIC;
  137.     }
  138.     es_format_Init( &p_dec->fmt_out, VIDEO_ES, VLC_FOURCC('m','p','g','v') );
  139.     p_dec->pf_packetize = Packetize;
  140.     p_dec->pf_get_cc = GetCc;
  141.     p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
  142.     if( !p_dec->p_sys )
  143.         return VLC_ENOMEM;
  144.     memset( p_dec->p_sys, 0, sizeof( decoder_sys_t ) );
  145.     /* Misc init */
  146.     packetizer_Init( &p_sys->packetizer,
  147.                      p_mp2v_startcode, sizeof(p_mp2v_startcode),
  148.                      NULL, 0,
  149.                      PacketizeReset, PacketizeParse, PacketizeValidate, p_dec );
  150.     p_sys->p_seq = NULL;
  151.     p_sys->p_ext = NULL;
  152.     p_sys->p_frame = NULL;
  153.     p_sys->pp_last = &p_sys->p_frame;
  154.     p_sys->b_frame_slice = false;
  155.     p_sys->i_dts = p_sys->i_pts = 0;
  156.     p_sys->i_frame_rate = 1;
  157.     p_sys->i_frame_rate_base = 1;
  158.     p_sys->b_seq_progressive = true;
  159.     p_sys->b_low_delay = true;
  160.     p_sys->i_seq_old = 0;
  161.     p_sys->i_temporal_ref = 0;
  162.     p_sys->i_picture_type = 0;
  163.     p_sys->i_picture_structure = 0x03; /* frame */
  164.     p_sys->i_top_field_first = 0;
  165.     p_sys->i_repeat_first_field = 0;
  166.     p_sys->i_progressive_frame = 0;
  167.     p_sys->b_inited = 0;
  168.     p_sys->i_interpolated_dts = 0;
  169.     p_sys->i_last_ref_pts = 0;
  170.     p_sys->b_second_field = 0;
  171.     p_sys->b_discontinuity = false;
  172.     p_sys->b_sync_on_intra_frame = var_CreateGetBool( p_dec, "packetizer-mpegvideo-sync-iframe" );
  173.     if( p_sys->b_sync_on_intra_frame )
  174.         msg_Dbg( p_dec, "syncing on intra frame now" );
  175.     p_sys->b_cc_reset = false;
  176.     p_sys->i_cc_pts = 0;
  177.     p_sys->i_cc_dts = 0;
  178.     p_sys->i_cc_flags = 0;
  179.     cc_Init( &p_sys->cc );
  180.     return VLC_SUCCESS;
  181. }
  182. /*****************************************************************************
  183.  * Close:
  184.  *****************************************************************************/
  185. static void Close( vlc_object_t *p_this )
  186. {
  187.     decoder_t     *p_dec = (decoder_t*)p_this;
  188.     decoder_sys_t *p_sys = p_dec->p_sys;
  189.     if( p_sys->p_seq )
  190.     {
  191.         block_Release( p_sys->p_seq );
  192.     }
  193.     if( p_sys->p_ext )
  194.     {
  195.         block_Release( p_sys->p_ext );
  196.     }
  197.     if( p_sys->p_frame )
  198.     {
  199.         block_ChainRelease( p_sys->p_frame );
  200.     }
  201.     packetizer_Clean( &p_sys->packetizer );
  202.     var_Destroy( p_dec, "packetizer-mpegvideo-sync-iframe" );
  203.     free( p_sys );
  204. }
  205. /*****************************************************************************
  206.  * Packetize:
  207.  *****************************************************************************/
  208. static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
  209. {
  210.     decoder_sys_t *p_sys = p_dec->p_sys;
  211.     return packetizer_Packetize( &p_sys->packetizer, pp_block );
  212. }
  213. /*****************************************************************************
  214.  * GetCc:
  215.  *****************************************************************************/
  216. static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] )
  217. {
  218.     decoder_sys_t *p_sys = p_dec->p_sys;
  219.     block_t *p_cc;
  220.     int i;
  221.     for( i = 0; i < 4; i++ )
  222.         pb_present[i] = p_sys->cc.pb_present[i];
  223.     if( p_sys->cc.i_data <= 0 )
  224.         return NULL;
  225.     p_cc = block_New( p_dec, p_sys->cc.i_data);
  226.     if( p_cc )
  227.     {
  228.         memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data );
  229.         p_cc->i_dts = 
  230.         p_cc->i_pts = p_sys->cc.b_reorder ? p_sys->i_cc_pts : p_sys->i_cc_dts;
  231.         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);
  232.     }
  233.     cc_Flush( &p_sys->cc );
  234.     return p_cc;
  235. }
  236. /*****************************************************************************
  237.  * Helpers:
  238.  *****************************************************************************/
  239. static void PacketizeReset( void *p_private, bool b_broken )
  240. {
  241.     decoder_t *p_dec = p_private;
  242.     decoder_sys_t *p_sys = p_dec->p_sys;
  243.     if( b_broken )
  244.     {
  245.         p_sys->b_discontinuity = true;
  246.         if( p_sys->p_frame )
  247.             block_ChainRelease( p_sys->p_frame );
  248.         p_sys->p_frame = NULL;
  249.         p_sys->pp_last = &p_sys->p_frame;
  250.         p_sys->b_frame_slice = false;
  251.     }
  252.     p_sys->i_dts = 0;
  253.     p_sys->i_pts = 0;
  254.     p_sys->i_interpolated_dts = 0;
  255.     p_sys->i_last_ref_pts = 0;
  256. }
  257. static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t *p_block )
  258. {
  259.     decoder_t *p_dec = p_private;
  260.     /* Check if we have a picture start code */
  261.     *pb_ts_used = p_block->i_buffer >= 4 && p_block->p_buffer[3] == 0x00;
  262.     return ParseMPEGBlock( p_dec, p_block );
  263. }
  264. static int PacketizeValidate( void *p_private, block_t *p_au )
  265. {
  266.     decoder_t *p_dec = p_private;
  267.     decoder_sys_t *p_sys = p_dec->p_sys;
  268.     /* If a discontinuity has been encountered, then wait till
  269.      * the next Intra frame before continuing with packetizing */
  270.     if( p_sys->b_discontinuity &&
  271.         p_sys->b_sync_on_intra_frame )
  272.     {
  273.         if( (p_au->i_flags & BLOCK_FLAG_TYPE_I) == 0 )
  274.         {
  275.             msg_Dbg( p_dec, "waiting on intra frame" );
  276.             return VLC_EGENERIC;
  277.         }
  278.         msg_Dbg( p_dec, "synced on intra frame" );
  279.         p_sys->b_discontinuity = false;
  280.         p_au->i_flags |= BLOCK_FLAG_DISCONTINUITY;
  281.     }
  282.     /* We've just started the stream, wait for the first PTS.
  283.      * We discard here so we can still get the sequence header. */
  284.     if( p_sys->i_dts <= 0 && p_sys->i_pts <= 0 &&
  285.         p_sys->i_interpolated_dts <= 0 )
  286.     {
  287.         msg_Dbg( p_dec, "need a starting pts/dts" );
  288.         return VLC_EGENERIC;
  289.     }
  290.     /* When starting the stream we can have the first frame with
  291.      * a null DTS (i_interpolated_pts is initialized to 0) */
  292.     if( !p_au->i_dts )
  293.         p_au->i_dts = p_au->i_pts;
  294.     return VLC_SUCCESS;
  295. }
  296. /*****************************************************************************
  297.  * ParseMPEGBlock: Re-assemble fragments into a block containing a picture
  298.  *****************************************************************************/
  299. static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag )
  300. {
  301.     decoder_sys_t *p_sys = p_dec->p_sys;
  302.     block_t *p_pic = NULL;
  303.     /*
  304.      * Check if previous picture is finished
  305.      */
  306.     if( ( p_sys->b_frame_slice &&
  307.           (p_frag->p_buffer[3] == 0x00 || p_frag->p_buffer[3] > 0xaf) ) &&
  308.           p_sys->p_seq == NULL )
  309.     {
  310.         /* We have a picture but without a sequence header we can't
  311.          * do anything */
  312.         msg_Dbg( p_dec, "waiting for sequence start" );
  313.         if( p_sys->p_frame ) block_ChainRelease( p_sys->p_frame );
  314.         p_sys->p_frame = NULL;
  315.         p_sys->pp_last = &p_sys->p_frame;
  316.         p_sys->b_frame_slice = false;
  317.     }
  318.     else if( p_sys->b_frame_slice &&
  319.              (p_frag->p_buffer[3] == 0x00 || p_frag->p_buffer[3] > 0xaf) )
  320.     {
  321.         const bool b_eos = p_frag->p_buffer[3] == 0xb7;
  322.         mtime_t i_duration;
  323.         if( b_eos )
  324.         {
  325.             block_ChainLastAppend( &p_sys->pp_last, p_frag );
  326.             p_frag = NULL;
  327.         }
  328.         p_pic = block_ChainGather( p_sys->p_frame );
  329.         if( b_eos )
  330.             p_pic->i_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
  331.         i_duration = (mtime_t)( 1000000 * p_sys->i_frame_rate_base /
  332.                                 p_sys->i_frame_rate );
  333.         if( !p_sys->b_seq_progressive && p_sys->i_picture_structure != 0x03 )
  334.         {
  335.             i_duration /= 2;
  336.         }
  337.         if( p_sys->b_seq_progressive )
  338.         {
  339.             if( p_sys->i_top_field_first == 0 &&
  340.                 p_sys->i_repeat_first_field == 1 )
  341.             {
  342.                 i_duration *= 2;
  343.             }
  344.             else if( p_sys->i_top_field_first == 1 &&
  345.                      p_sys->i_repeat_first_field == 1 )
  346.             {
  347.                 i_duration *= 3;
  348.             }
  349.         }
  350.         else
  351.         {
  352.             if( p_sys->i_picture_structure == 0x03 )
  353.             {
  354.                 if( p_sys->i_progressive_frame && p_sys->i_repeat_first_field )
  355.                 {
  356.                     i_duration += i_duration / 2;
  357.                 }
  358.             }
  359.         }
  360.         if( p_sys->b_low_delay || p_sys->i_picture_type == 0x03 )
  361.         {
  362.             /* Trivial case (DTS == PTS) */
  363.             /* Correct interpolated dts when we receive a new pts/dts */
  364.             if( p_sys->i_pts > 0 ) p_sys->i_interpolated_dts = p_sys->i_pts;
  365.             if( p_sys->i_dts > 0 ) p_sys->i_interpolated_dts = p_sys->i_dts;
  366.         }
  367.         else
  368.         {
  369.             /* Correct interpolated dts when we receive a new pts/dts */
  370.             if( p_sys->i_last_ref_pts > 0 && !p_sys->b_second_field )
  371.                 p_sys->i_interpolated_dts = p_sys->i_last_ref_pts;
  372.             if( p_sys->i_dts > 0 ) p_sys->i_interpolated_dts = p_sys->i_dts;
  373.             if( !p_sys->b_second_field )
  374.                 p_sys->i_last_ref_pts = p_sys->i_pts;
  375.         }
  376.         p_pic->i_dts = p_sys->i_interpolated_dts;
  377.         p_sys->i_interpolated_dts += i_duration;
  378.         /* Set PTS only if we have a B frame or if it comes from the stream */
  379.         if( p_sys->i_pts > 0 )
  380.         {
  381.             p_pic->i_pts = p_sys->i_pts;
  382.         }
  383.         else if( p_sys->i_picture_type == 0x03 )
  384.         {
  385.             p_pic->i_pts = p_pic->i_dts;
  386.         }
  387.         else
  388.         {
  389.             p_pic->i_pts = 0;
  390.         }
  391.         switch ( p_sys->i_picture_type )
  392.         {
  393.         case 0x01:
  394.             p_pic->i_flags |= BLOCK_FLAG_TYPE_I;
  395.             break;
  396.         case 0x02:
  397.             p_pic->i_flags |= BLOCK_FLAG_TYPE_P;
  398.             break;
  399.         case 0x03:
  400.             p_pic->i_flags |= BLOCK_FLAG_TYPE_B;
  401.             break;
  402.         }
  403.         p_pic->i_length = p_sys->i_interpolated_dts - p_pic->i_dts;
  404. #if 0
  405.         msg_Dbg( p_dec, "pic: type=%d dts=%"PRId64" pts-dts=%"PRId64,
  406.         p_sys->i_picture_type, p_pic->i_dts, p_pic->i_pts - p_pic->i_dts);
  407. #endif
  408.         /* Reset context */
  409.         p_sys->p_frame = NULL;
  410.         p_sys->pp_last = &p_sys->p_frame;
  411.         p_sys->b_frame_slice = false;
  412.         if( p_sys->i_picture_structure != 0x03 )
  413.         {
  414.             p_sys->b_second_field = !p_sys->b_second_field;
  415.         }
  416.         else
  417.         {
  418.             p_sys->b_second_field = 0;
  419.         }
  420.         /* CC */
  421.         p_sys->b_cc_reset = true;
  422.         p_sys->i_cc_pts = p_pic->i_pts;
  423.         p_sys->i_cc_dts = p_pic->i_dts;
  424.         p_sys->i_cc_flags = p_pic->i_flags;
  425.     }
  426.     if( !p_pic && p_sys->b_cc_reset )
  427.     {
  428.         p_sys->b_cc_reset = false;
  429.         cc_Flush( &p_sys->cc );
  430.     }
  431.     if( !p_frag )
  432.         return p_pic;
  433.     /*
  434.      * Check info of current fragment
  435.      */
  436.     if( p_frag->p_buffer[3] == 0xb8 )
  437.     {
  438.         /* Group start code */
  439.         if( p_sys->p_seq &&
  440.             p_sys->i_seq_old > p_sys->i_frame_rate/p_sys->i_frame_rate_base )
  441.         {
  442.             /* Usefull for mpeg1: repeat sequence header every second */
  443.             block_ChainLastAppend( &p_sys->pp_last, block_Duplicate( p_sys->p_seq ) );
  444.             if( p_sys->p_ext )
  445.             {
  446.                 block_ChainLastAppend( &p_sys->pp_last, block_Duplicate( p_sys->p_ext ) );
  447.             }
  448.             p_sys->i_seq_old = 0;
  449.         }
  450.     }
  451.     else if( p_frag->p_buffer[3] == 0xb3 && p_frag->i_buffer >= 8 )
  452.     {
  453.         /* Sequence header code */
  454.         static const int code_to_frame_rate[16][2] =
  455.         {
  456.             { 1, 1 },  /* invalid */
  457.             { 24000, 1001 }, { 24, 1 }, { 25, 1 },       { 30000, 1001 },
  458.             { 30, 1 },       { 50, 1 }, { 60000, 1001 }, { 60, 1 },
  459.             /* Unofficial 15fps from Xing*/
  460.             { 15, 1001 },
  461.             /* Unofficial economy rates from libmpeg3 */
  462.             { 5, 1001 }, { 10, 1001 }, { 12, 1001 }, { 15, 1001 },
  463.             { 1, 1 },  { 1, 1 }  /* invalid */
  464.         };
  465.         if( p_sys->p_seq ) block_Release( p_sys->p_seq );
  466.         if( p_sys->p_ext ) block_Release( p_sys->p_ext );
  467.         p_sys->p_seq = block_Duplicate( p_frag );
  468.         p_sys->i_seq_old = 0;
  469.         p_sys->p_ext = NULL;
  470.         p_dec->fmt_out.video.i_width =
  471.             ( p_frag->p_buffer[4] << 4)|(p_frag->p_buffer[5] >> 4 );
  472.         p_dec->fmt_out.video.i_height =
  473.             ( (p_frag->p_buffer[5]&0x0f) << 8 )|p_frag->p_buffer[6];
  474.         p_sys->i_aspect_ratio_info = p_frag->p_buffer[7] >> 4;
  475.         /* TODO: MPEG1 aspect ratio */
  476.         p_sys->i_frame_rate = code_to_frame_rate[p_frag->p_buffer[7]&0x0f][0];
  477.         p_sys->i_frame_rate_base =
  478.             code_to_frame_rate[p_frag->p_buffer[7]&0x0f][1];
  479.         p_dec->fmt_out.video.i_frame_rate = p_sys->i_frame_rate;
  480.         p_dec->fmt_out.video.i_frame_rate_base = p_sys->i_frame_rate_base;
  481.         p_sys->b_seq_progressive = true;
  482.         p_sys->b_low_delay = true;
  483.         if ( !p_sys->b_inited )
  484.         {
  485.             msg_Dbg( p_dec, "size %dx%d fps=%.3f",
  486.                  p_dec->fmt_out.video.i_width, p_dec->fmt_out.video.i_height,
  487.                  p_sys->i_frame_rate / (float)p_sys->i_frame_rate_base );
  488.             p_sys->b_inited = 1;
  489.         }
  490.     }
  491.     else if( p_frag->p_buffer[3] == 0xb5 )
  492.     {
  493.         int i_type = p_frag->p_buffer[4] >> 4;
  494.         /* Extension start code */
  495.         if( i_type == 0x01 )
  496.         {
  497. #if 0
  498.             static const int mpeg2_aspect[16][2] =
  499.             {
  500.                 {0,1}, {1,1}, {4,3}, {16,9}, {221,100},
  501.                 {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1},
  502.                 {0,1}, {0,1}
  503.             };
  504. #endif
  505.             /* sequence extension */
  506.             if( p_sys->p_ext) block_Release( p_sys->p_ext );
  507.             p_sys->p_ext = block_Duplicate( p_frag );
  508.             if( p_frag->i_buffer >= 10 )
  509.             {
  510.                 p_sys->b_seq_progressive =
  511.                     p_frag->p_buffer[5]&0x08 ? true : false;
  512.                 p_sys->b_low_delay =
  513.                     p_frag->p_buffer[9]&0x80 ? true : false;
  514.             }
  515.             /* Do not set aspect ratio : in case we're transcoding,
  516.              * transcode will take our fmt_out as a fmt_in to libmpeg2.
  517.              * libmpeg2.c will then believe that the user has requested
  518.              * a specific aspect ratio, which she hasn't. Thus in case
  519.              * of aspect ratio change, we're screwed. --Meuuh
  520.              */
  521. #if 0
  522.             p_dec->fmt_out.video.i_aspect =
  523.                 mpeg2_aspect[p_sys->i_aspect_ratio_info][0] *
  524.                 VOUT_ASPECT_FACTOR /
  525.                 mpeg2_aspect[p_sys->i_aspect_ratio_info][1];
  526. #endif
  527.         }
  528.         else if( i_type == 0x08 )
  529.         {
  530.             /* picture extension */
  531.             p_sys->i_picture_structure = p_frag->p_buffer[6]&0x03;
  532.             p_sys->i_top_field_first   = p_frag->p_buffer[7] >> 7;
  533.             p_sys->i_repeat_first_field= (p_frag->p_buffer[7]>>1)&0x01;
  534.             p_sys->i_progressive_frame = p_frag->p_buffer[8] >> 7;
  535.         }
  536.     }
  537.     else if( p_frag->p_buffer[3] == 0xb2 && p_frag->i_buffer > 4 )
  538.     {
  539.         cc_Extract( &p_sys->cc, &p_frag->p_buffer[4], p_frag->i_buffer - 4 );
  540.     }
  541.     else if( p_frag->p_buffer[3] == 0x00 )
  542.     {
  543.         /* Picture start code */
  544.         p_sys->i_seq_old++;
  545.         if( p_frag->i_buffer >= 6 )
  546.         {
  547.             p_sys->i_temporal_ref =
  548.                 ( p_frag->p_buffer[4] << 2 )|(p_frag->p_buffer[5] >> 6);
  549.             p_sys->i_picture_type = ( p_frag->p_buffer[5] >> 3 ) & 0x03;
  550.         }
  551.         p_sys->i_dts = p_frag->i_dts;
  552.         p_sys->i_pts = p_frag->i_pts;
  553.     }
  554.     else if( p_frag->p_buffer[3] >= 0x01 && p_frag->p_buffer[3] <= 0xaf )
  555.     {
  556.         /* Slice start code */
  557.         p_sys->b_frame_slice = true;
  558.     }
  559.     /* Append the block */
  560.     block_ChainLastAppend( &p_sys->pp_last, p_frag );
  561.     return p_pic;
  562. }