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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * vc1.c
  3.  *****************************************************************************
  4.  * Copyright (C) 2001, 2002, 2006 the VideoLAN team
  5.  * $Id: c422f7a3dc73fed98bbb6f0b4e78bd5648496f03 $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *          Gildas Bazin <gbazin@videolan.org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #include <vlc_common.h>
  31. #include <vlc_plugin.h>
  32. #include <vlc_codec.h>
  33. #include <vlc_block.h>
  34. #include "vlc_bits.h"
  35. #include "vlc_block_helper.h"
  36. #include "packetizer_helper.h"
  37. /*****************************************************************************
  38.  * Module descriptor
  39.  *****************************************************************************/
  40. static int  Open ( vlc_object_t * );
  41. static void Close( vlc_object_t * );
  42. vlc_module_begin ()
  43.     set_category( CAT_SOUT )
  44.     set_subcategory( SUBCAT_SOUT_PACKETIZER )
  45.     set_description( N_("VC-1 packetizer") )
  46.     set_capability( "packetizer", 50 )
  47.     set_callbacks( Open, Close )
  48. vlc_module_end ()
  49. /*****************************************************************************
  50.  * Local prototypes
  51.  *****************************************************************************/
  52. struct decoder_sys_t
  53. {
  54.     /*
  55.      * Input properties
  56.      */
  57.     packetizer_t packetizer;
  58.     /* Current sequence header */
  59.     bool b_sequence_header;
  60.     struct
  61.     {
  62.         block_t *p_sh;
  63.         bool b_advanced_profile;
  64.         bool b_interlaced;
  65.         bool b_frame_interpolation;
  66.         bool b_range_reduction;
  67.         bool b_has_bframe;
  68.     } sh;
  69.     bool b_entry_point;
  70.     struct
  71.     {
  72.         block_t *p_ep;
  73.     } ep;
  74.     /* */
  75.     bool  b_frame;
  76.     /* Current frame being built */
  77.     mtime_t    i_frame_dts;
  78.     mtime_t    i_frame_pts;
  79.     block_t    *p_frame;
  80.     block_t    **pp_last;
  81.     mtime_t i_interpolated_dts;
  82.     bool    b_check_startcode;
  83. };
  84. typedef enum
  85. {
  86.     IDU_TYPE_SEQUENCE_HEADER = 0x0f,
  87.     IDU_TYPE_ENTRY_POINT = 0x0e,
  88.     IDU_TYPE_FRAME = 0x0D,
  89.     IDU_TYPE_FIELD = 0x0C,
  90.     IDU_TYPE_SLICE = 0x0B,
  91.     IDU_TYPE_END_OF_SEQUENCE = 0x0A,
  92.     IDU_TYPE_SEQUENCE_LEVEL_USER_DATA = 0x1F,
  93.     IDU_TYPE_ENTRY_POINT_USER_DATA = 0x1E,
  94.     IDU_TYPE_FRAME_USER_DATA = 0x1D,
  95.     IDU_TYPE_FIELD_USER_DATA = 0x1C,
  96.     IDU_TYPE_SLICE_USER_DATA = 0x1B,
  97. } idu_type_t;
  98. static block_t *Packetize( decoder_t *p_dec, block_t **pp_block );
  99. static void PacketizeReset( void *p_private, bool b_broken );
  100. static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t * );
  101. static int PacketizeValidate( void *p_private, block_t * );
  102. static block_t *ParseIDU( decoder_t *p_dec, bool *pb_used_ts, block_t *p_frag );
  103. static const uint8_t p_vc1_startcode[3] = { 0x00, 0x00, 0x01 };
  104. /*****************************************************************************
  105.  * Open: probe the packetizer and return score
  106.  *****************************************************************************
  107.  * Tries to launch a decoder and return score so that the interface is able
  108.  * to choose.
  109.  *****************************************************************************/
  110. static int Open( vlc_object_t *p_this )
  111. {
  112.     decoder_t     *p_dec = (decoder_t*)p_this;
  113.     decoder_sys_t *p_sys;
  114.     if( p_dec->fmt_in.i_codec !=  VLC_FOURCC( 'W', 'V', 'C', '1' ) )
  115.         return VLC_EGENERIC;
  116.     p_dec->pf_packetize = Packetize;
  117.     /* Create the output format */
  118.     es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
  119.     p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
  120.     packetizer_Init( &p_sys->packetizer,
  121.                      p_vc1_startcode, sizeof(p_vc1_startcode),
  122.                      NULL, 0,
  123.                      PacketizeReset, PacketizeParse, PacketizeValidate, p_dec );
  124.     p_sys->b_sequence_header = false;
  125.     p_sys->sh.p_sh = NULL;
  126.     p_sys->b_entry_point = false;
  127.     p_sys->ep.p_ep = NULL;
  128.     p_sys->i_frame_dts = VLC_TS_INVALID;
  129.     p_sys->i_frame_pts = VLC_TS_INVALID;
  130.     p_sys->b_frame = false;
  131.     p_sys->p_frame = NULL;
  132.     p_sys->pp_last = &p_sys->p_frame;
  133.     p_sys->i_interpolated_dts = VLC_TS_INVALID;
  134.     p_sys->b_check_startcode = p_dec->fmt_in.b_packetized;
  135.     if( p_dec->fmt_out.i_extra > 0 )
  136.     {
  137.         uint8_t *p_extra = p_dec->fmt_out.p_extra;
  138.         /* With (some) ASF the first byte has to be stripped */
  139.         if( p_extra[0] != 0x00 )
  140.         {
  141.             memcpy( &p_extra[0], &p_extra[1], p_dec->fmt_out.i_extra - 1 );
  142.             p_dec->fmt_out.i_extra--;
  143.         }
  144.         /* */
  145.         if( p_dec->fmt_out.i_extra > 0 )
  146.             packetizer_Header( &p_sys->packetizer,
  147.                                p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );
  148.     }
  149.     return VLC_SUCCESS;
  150. }
  151. /*****************************************************************************
  152.  * Close:
  153.  *****************************************************************************/
  154. static void Close( vlc_object_t *p_this )
  155. {
  156.     decoder_t     *p_dec = (decoder_t*)p_this;
  157.     decoder_sys_t *p_sys = p_dec->p_sys;
  158.     packetizer_Clean( &p_sys->packetizer );
  159.     if( p_sys->p_frame )
  160.         block_Release( p_sys->p_frame );
  161.     free( p_sys );
  162. }
  163. /*****************************************************************************
  164.  * Packetize: packetize an access unit
  165.  *****************************************************************************/
  166. static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
  167. {
  168.     decoder_sys_t *p_sys = p_dec->p_sys;
  169.     if( p_sys->b_check_startcode && pp_block && *pp_block )
  170.     {
  171.         /* Fix syntax for (some?) VC1 from asf */
  172.         const int i_startcode = sizeof(p_vc1_startcode);
  173.         block_t *p_block = *pp_block;
  174.         if( p_block->i_buffer > 0 &&
  175.             ( p_block->i_buffer < i_startcode ||
  176.               memcmp( p_block->p_buffer, p_vc1_startcode, i_startcode ) ) )
  177.         {
  178.             *pp_block = p_block = block_Realloc( p_block, i_startcode+1, p_block->i_buffer );
  179.             if( p_block )
  180.             {
  181.                 memcpy( p_block->p_buffer, p_vc1_startcode, i_startcode );
  182.                 if( p_sys->b_sequence_header && p_sys->sh.b_interlaced &&
  183.                     p_block->i_buffer > i_startcode+1 &&
  184.                     (p_block->p_buffer[i_startcode+1] & 0xc0) == 0xc0 )
  185.                     p_block->p_buffer[i_startcode] = IDU_TYPE_FIELD;
  186.                 else
  187.                     p_block->p_buffer[i_startcode] = IDU_TYPE_FRAME;
  188.             }
  189.         }
  190.         p_sys->b_check_startcode = false;
  191.     }
  192.     block_t *p_au = packetizer_Packetize( &p_sys->packetizer, pp_block );
  193.     if( !p_au )
  194.         p_sys->b_check_startcode = p_dec->fmt_in.b_packetized;
  195.     return p_au;
  196. }
  197. static void PacketizeReset( void *p_private, bool b_broken )
  198. {
  199.     decoder_t *p_dec = p_private;
  200.     decoder_sys_t *p_sys = p_dec->p_sys;
  201.     if( b_broken )
  202.     {
  203.         if( p_sys->p_frame )
  204.             block_ChainRelease( p_sys->p_frame );
  205.         p_sys->p_frame = NULL;
  206.         p_sys->pp_last = &p_sys->p_frame;
  207.         p_sys->b_frame = false;
  208.     }
  209.     p_sys->i_frame_dts = VLC_TS_INVALID;
  210.     p_sys->i_frame_pts = VLC_TS_INVALID;
  211.     p_sys->i_interpolated_dts = VLC_TS_INVALID;
  212. }
  213. static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t *p_block )
  214. {
  215.     decoder_t *p_dec = p_private;
  216.     return ParseIDU( p_dec, pb_ts_used, p_block );
  217. }
  218. static int PacketizeValidate( void *p_private, block_t *p_au )
  219. {
  220.     decoder_t *p_dec = p_private;
  221.     decoder_sys_t *p_sys = p_dec->p_sys;
  222.     if( p_sys->i_interpolated_dts <= VLC_TS_INVALID )
  223.     {
  224.         msg_Dbg( p_dec, "need a starting pts/dts" );
  225.         return VLC_EGENERIC;
  226.     }
  227.     VLC_UNUSED(p_au);
  228.     return VLC_SUCCESS;
  229. }
  230. /* DecodeRIDU: decode the startcode emulation prevention (same than h264) */
  231. static void DecodeRIDU( uint8_t *p_ret, int *pi_ret, uint8_t *src, int i_src )
  232. {
  233.     uint8_t *end = &src[i_src];
  234.     uint8_t *dst_end = &p_ret[*pi_ret];
  235.     uint8_t *dst = p_ret;
  236.     while( src < end && dst < dst_end )
  237.     {
  238.         if( src < end - 3 && src[0] == 0x00 && src[1] == 0x00 &&
  239.             src[2] == 0x03 )
  240.         {
  241.             *dst++ = 0x00;
  242.             *dst++ = 0x00;
  243.             src += 3;
  244.             continue;
  245.         }
  246.         *dst++ = *src++;
  247.     }
  248.     *pi_ret = dst - p_ret;
  249. }
  250. /* BuildExtraData: gather sequence header and entry point */
  251. static void BuildExtraData( decoder_t *p_dec )
  252. {
  253.     decoder_sys_t *p_sys = p_dec->p_sys;
  254.     es_format_t *p_es = &p_dec->fmt_out;
  255.     int i_extra;
  256.     if( !p_sys->b_sequence_header || !p_sys->b_entry_point )
  257.         return;
  258.     i_extra = p_sys->sh.p_sh->i_buffer + p_sys->ep.p_ep->i_buffer;
  259.     if( p_es->i_extra != i_extra )
  260.     {
  261.         p_es->i_extra = i_extra;
  262.         p_es->p_extra = realloc( p_dec->fmt_out.p_extra, p_es->i_extra );
  263.     }
  264.     memcpy( p_es->p_extra,
  265.             p_sys->sh.p_sh->p_buffer, p_sys->sh.p_sh->i_buffer );
  266.     memcpy( (uint8_t*)p_es->p_extra + p_sys->sh.p_sh->i_buffer,
  267.             p_sys->ep.p_ep->p_buffer, p_sys->ep.p_ep->i_buffer );
  268. }
  269. /* ParseIDU: parse an Independent Decoding Unit */
  270. static block_t *ParseIDU( decoder_t *p_dec, bool *pb_used_ts, block_t *p_frag )
  271. {
  272.     decoder_sys_t *p_sys = p_dec->p_sys;
  273.     block_t *p_pic;
  274.     const idu_type_t idu = p_frag->p_buffer[3];
  275.     *pb_used_ts = false;
  276.     if( !p_sys->b_sequence_header && idu != IDU_TYPE_SEQUENCE_HEADER )
  277.     {
  278.         msg_Warn( p_dec, "waiting for sequence header" );
  279.         block_Release( p_frag );
  280.         return NULL;
  281.     }
  282.     if( p_sys->b_sequence_header && !p_sys->b_entry_point && idu != IDU_TYPE_ENTRY_POINT )
  283.     {
  284.         msg_Warn( p_dec, "waiting for entry point" );
  285.         block_Release( p_frag );
  286.         return NULL;
  287.     }
  288.     /* TODO we do not gather ENTRY_POINT and SEQUENCE_DATA user data
  289.      * But It should not be a problem for decoder */
  290.     /* Do we have completed a frame */
  291.     p_pic = NULL;
  292.     if( p_sys->b_frame &&
  293.         idu != IDU_TYPE_FRAME_USER_DATA &&
  294.         idu != IDU_TYPE_FIELD && idu != IDU_TYPE_FIELD_USER_DATA &&
  295.         idu != IDU_TYPE_SLICE && idu != IDU_TYPE_SLICE_USER_DATA &&
  296.         idu != IDU_TYPE_END_OF_SEQUENCE )
  297.     {
  298.         /* Prepend SH and EP on I */
  299.         if( p_sys->p_frame->i_flags & BLOCK_FLAG_TYPE_I )
  300.         {
  301.             block_t *p_list = block_Duplicate( p_sys->sh.p_sh );
  302.             block_ChainAppend( &p_list, block_Duplicate( p_sys->ep.p_ep ) );
  303.             block_ChainAppend( &p_list, p_sys->p_frame );
  304.             p_list->i_flags = p_sys->p_frame->i_flags;
  305.             p_sys->p_frame = p_list;
  306.         }
  307.         /* */
  308.         p_pic = block_ChainGather( p_sys->p_frame );
  309.         p_pic->i_dts = p_sys->i_frame_dts;
  310.         p_pic->i_pts = p_sys->i_frame_pts;
  311.         /* */
  312.         if( p_pic->i_dts > VLC_TS_INVALID )
  313.             p_sys->i_interpolated_dts = p_pic->i_dts;
  314.         /* We can interpolate dts/pts only if we have a frame rate */
  315.         if( p_dec->fmt_out.video.i_frame_rate != 0 && p_dec->fmt_out.video.i_frame_rate_base != 0 )
  316.         {
  317.             if( p_sys->i_interpolated_dts > VLC_TS_INVALID )
  318.                 p_sys->i_interpolated_dts += INT64_C(1000000) *
  319.                                              p_dec->fmt_out.video.i_frame_rate_base /
  320.                                              p_dec->fmt_out.video.i_frame_rate;
  321.             //msg_Dbg( p_dec, "-------------- XXX0 dts=%"PRId64" pts=%"PRId64" interpolated=%"PRId64,
  322.             //         p_pic->i_dts, p_pic->i_pts, p_sys->i_interpolated_dts );
  323.             if( p_pic->i_dts <= VLC_TS_INVALID )
  324.                 p_pic->i_dts = p_sys->i_interpolated_dts;
  325.             if( p_pic->i_pts <= VLC_TS_INVALID )
  326.             {
  327.                 if( !p_sys->sh.b_has_bframe || (p_pic->i_flags & BLOCK_FLAG_TYPE_B ) )
  328.                     p_pic->i_pts = p_pic->i_dts;
  329.                 /* TODO compute pts for other case */
  330.             }
  331.         }
  332.         //msg_Dbg( p_dec, "-------------- dts=%"PRId64" pts=%"PRId64, p_pic->i_dts, p_pic->i_pts );
  333.         /* Reset context */
  334.         p_sys->b_frame = false;
  335.         p_sys->i_frame_dts = VLC_TS_INVALID;
  336.         p_sys->i_frame_pts = VLC_TS_INVALID;
  337.         p_sys->p_frame = NULL;
  338.         p_sys->pp_last = &p_sys->p_frame;
  339.     }
  340.     /*  */
  341.     if( p_sys->i_frame_dts <= VLC_TS_INVALID && p_sys->i_frame_pts <= VLC_TS_INVALID )
  342.     {
  343.         p_sys->i_frame_dts = p_frag->i_dts;
  344.         p_sys->i_frame_pts = p_frag->i_pts;
  345.         *pb_used_ts = true;
  346.     }
  347.     /* We will add back SH and EP on I frames */
  348.     block_t *p_release = NULL;
  349.     if( idu != IDU_TYPE_SEQUENCE_HEADER && idu != IDU_TYPE_ENTRY_POINT )
  350.         block_ChainLastAppend( &p_sys->pp_last, p_frag );
  351.     else
  352.         p_release = p_frag;
  353.     /* Parse IDU */
  354.     if( idu == IDU_TYPE_SEQUENCE_HEADER )
  355.     {
  356.         es_format_t *p_es = &p_dec->fmt_out;
  357.         bs_t s;
  358.         int i_profile;
  359.         uint8_t ridu[32];
  360.         int     i_ridu = sizeof(ridu);
  361.         /* */
  362.         if( p_sys->sh.p_sh )
  363.             block_Release( p_sys->sh.p_sh );
  364.         p_sys->sh.p_sh = block_Duplicate( p_frag );
  365.         /* Extract the raw IDU */
  366.         DecodeRIDU( ridu, &i_ridu, &p_frag->p_buffer[4], p_frag->i_buffer - 4 );
  367.         /* Auto detect VC-1_SPMP_PESpacket_PayloadFormatHeader (SMPTE RP 227) for simple/main profile
  368.          * TODO find a test case and valid it */
  369.         if( i_ridu > 4 && (ridu[0]&0x80) == 0 ) /* for advanced profile, the first bit is 1 */
  370.         {
  371.             video_format_t *p_v = &p_dec->fmt_in.video;
  372.             const size_t i_potential_width  = GetWBE( &ridu[0] );
  373.             const size_t i_potential_height = GetWBE( &ridu[2] );
  374.             if( i_potential_width >= 2  && i_potential_width <= 8192 &&
  375.                 i_potential_height >= 2 && i_potential_height <= 8192 )
  376.             {
  377.                 if( ( p_v->i_width <= 0 && p_v->i_height <= 0  ) ||
  378.                     ( p_v->i_width  == i_potential_width &&  p_v->i_height == i_potential_height ) )
  379.                 {
  380.                     static const uint8_t startcode[4] = { 0x00, 0x00, 0x01, IDU_TYPE_SEQUENCE_HEADER };
  381.                     p_es->video.i_width  = i_potential_width;
  382.                     p_es->video.i_height = i_potential_height;
  383.                     /* Remove it */
  384.                     p_frag->p_buffer += 4;
  385.                     p_frag->i_buffer -= 4;
  386.                     memcpy( p_frag->p_buffer, startcode, sizeof(startcode) );
  387.                 }
  388.             }
  389.         }
  390.         /* Parse it */
  391.         bs_init( &s, ridu, i_ridu );
  392.         i_profile = bs_read( &s, 2 );
  393.         if( i_profile == 3 )
  394.         {
  395.             const int i_level = bs_read( &s, 3 );
  396.             /* Advanced profile */
  397.             p_sys->sh.b_advanced_profile = true;
  398.             p_sys->sh.b_range_reduction = false;
  399.             p_sys->sh.b_has_bframe = true;
  400.             bs_skip( &s, 2+3+5+1 ); // chroma format + frame rate Q + bit rate Q + postprocflag
  401.             p_es->video.i_width  = 2*bs_read( &s, 12 )+2;
  402.             p_es->video.i_height = 2*bs_read( &s, 12 )+2;
  403.             if( !p_sys->b_sequence_header )
  404.                 msg_Dbg( p_dec, "found sequence header for advanced profile level L%d resolution %dx%d",
  405.                          i_level, p_es->video.i_width, p_es->video.i_height);
  406.             bs_skip( &s, 1 );// pulldown
  407.             p_sys->sh.b_interlaced = bs_read( &s, 1 );
  408.             bs_skip( &s, 1 );// frame counter
  409.             p_sys->sh.b_frame_interpolation = bs_read( &s, 1 );
  410.             bs_skip( &s, 1 );       // Reserved
  411.             bs_skip( &s, 1 );       // Psf
  412.             if( bs_read( &s, 1 ) )  /* Display extension */
  413.             {
  414.                 const int i_display_width  = bs_read( &s, 14 )+1;
  415.                 const int i_display_height = bs_read( &s, 14 )+1;
  416.                 p_es->video.i_aspect = VOUT_ASPECT_FACTOR * i_display_width / i_display_height;
  417.                 if( !p_sys->b_sequence_header )
  418.                     msg_Dbg( p_dec, "display size %dx%d", i_display_width, i_display_height );
  419.                 if( bs_read( &s, 1 ) )  /* Pixel aspect ratio (PAR/SAR) */
  420.                 {
  421.                     static const int p_ar[16][2] = {
  422.                         { 0, 0}, { 1, 1}, {12,11}, {10,11}, {16,11}, {40,33},
  423.                         {24,11}, {20,11}, {32,11}, {80,33}, {18,11}, {15,11},
  424.                         {64,33}, {160,99},{ 0, 0}, { 0, 0}
  425.                     };
  426.                     int i_ar = bs_read( &s, 4 );
  427.                     unsigned i_ar_w, i_ar_h;
  428.                     if( i_ar == 15 )
  429.                     {
  430.                         i_ar_w = bs_read( &s, 8 );
  431.                         i_ar_h = bs_read( &s, 8 );
  432.                     }
  433.                     else
  434.                     {
  435.                         i_ar_w = p_ar[i_ar][0];
  436.                         i_ar_h = p_ar[i_ar][1];
  437.                     }
  438.                     vlc_ureduce( &i_ar_w, &i_ar_h, i_ar_w, i_ar_h, 0 );
  439.                     if( !p_sys->b_sequence_header )
  440.                         msg_Dbg( p_dec, "aspect ratio %d:%d", i_ar_w, i_ar_h );
  441.                 }
  442.             }
  443.             if( bs_read( &s, 1 ) )  /* Frame rate */
  444.             {
  445.                 int i_fps_num = 0;
  446.                 int i_fps_den = 0;
  447.                 if( bs_read( &s, 1 ) )
  448.                 {
  449.                     i_fps_num = bs_read( &s, 16 )+1;
  450.                     i_fps_den = 32;
  451.                 }
  452.                 else
  453.                 {
  454.                     const int i_nr = bs_read( &s, 8 );
  455.                     const int i_dn = bs_read( &s, 4 );
  456.                     switch( i_nr )
  457.                     {
  458.                     case 1: i_fps_num = 24000; break;
  459.                     case 2: i_fps_num = 25000; break;
  460.                     case 3: i_fps_num = 30000; break;
  461.                     case 4: i_fps_num = 50000; break;
  462.                     case 5: i_fps_num = 60000; break;
  463.                     case 6: i_fps_num = 48000; break;
  464.                     case 7: i_fps_num = 72000; break;
  465.                     }
  466.                     switch( i_dn )
  467.                     {
  468.                     case 1: i_fps_den = 1000; break;
  469.                     case 2: i_fps_den = 1001; break;
  470.                     }
  471.                 }
  472.                 if( i_fps_num != 0 && i_fps_den != 0 )
  473.                     vlc_ureduce( &p_es->video.i_frame_rate, &p_es->video.i_frame_rate_base, i_fps_num, i_fps_den, 0 );
  474.                 if( !p_sys->b_sequence_header )
  475.                     msg_Dbg( p_dec, "frame rate %d/%d", p_es->video.i_frame_rate, p_es->video.i_frame_rate_base );
  476.             }
  477.         }
  478.         else
  479.         {
  480.             /* Simple and main profile */
  481.             p_sys->sh.b_advanced_profile = false;
  482.             p_sys->sh.b_interlaced = false;
  483.             if( !p_sys->b_sequence_header )
  484.                 msg_Dbg( p_dec, "found sequence header for %s profile", i_profile == 0 ? "simple" : "main" );
  485.             bs_skip( &s, 2+3+5+1+1+     // reserved + frame rate Q + bit rate Q + loop filter + reserved
  486.                          1+1+1+1+2+     // multiresolution + reserved + fast uv mc + extended mv + dquant
  487.                          1+1+1+1 );     // variable size transform + reserved + overlap + sync marker
  488.             p_sys->sh.b_range_reduction = bs_read( &s, 1 );
  489.             if( bs_read( &s, 3 ) > 0 )
  490.                 p_sys->sh.b_has_bframe = true;
  491.             else
  492.                 p_sys->sh.b_has_bframe = false;
  493.             bs_skip( &s, 2 );           // quantizer
  494.             p_sys->sh.b_frame_interpolation = bs_read( &s, 1 );
  495.         }
  496.         p_sys->b_sequence_header = true;
  497.         BuildExtraData( p_dec );
  498.     }
  499.     else if( idu == IDU_TYPE_ENTRY_POINT )
  500.     {
  501.         if( p_sys->ep.p_ep )
  502.             block_Release( p_sys->ep.p_ep );
  503.         p_sys->ep.p_ep = block_Duplicate( p_frag );
  504.         if( !p_sys->b_entry_point )
  505.             msg_Dbg( p_dec, "found entry point" );
  506.         p_sys->b_entry_point = true;
  507.         BuildExtraData( p_dec );
  508.     }
  509.     else if( idu == IDU_TYPE_FRAME )
  510.     {
  511.         bs_t s;
  512.         uint8_t ridu[8];
  513.         int     i_ridu = sizeof(ridu);
  514.         /* Extract the raw IDU */
  515.         DecodeRIDU( ridu, &i_ridu, &p_frag->p_buffer[4], p_frag->i_buffer - 4 );
  516.         /* Parse it + interpolate pts/dts if possible */
  517.         bs_init( &s, ridu, i_ridu );
  518.         if( p_sys->sh.b_advanced_profile )
  519.         {
  520.             int i_fcm = 0;
  521.             if( p_sys->sh.b_interlaced )
  522.             {
  523.                 if( bs_read( &s, 1 ) )
  524.                 {
  525.                     if( bs_read( &s, 1 ) )
  526.                         i_fcm = 1;  /* interlaced field */
  527.                     else
  528.                         i_fcm = 2;  /* interlaced frame */
  529.                 }
  530.             }
  531.             if( i_fcm == 1 ) /*interlaced field */
  532.             {
  533.                 /* XXX for mixed I/P we should check reference usage before marking them I (too much work) */
  534.                 switch( bs_read( &s, 3 ) )
  535.                 {
  536.                 case 0: /* II */
  537.                 case 1: /* IP */
  538.                 case 2: /* PI */
  539.                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
  540.                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
  541.                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
  542.                     break;
  543.                 case 3: /* PP */
  544.                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;
  545.                     break;
  546.                 case 4: /* BB */
  547.                 case 5: /* BBi */
  548.                 case 6: /* BiB */
  549.                 case 7: /* BiBi */
  550.                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;
  551.                     break;
  552.                 }
  553.             }
  554.             else
  555.             {
  556.                 if( !bs_read( &s, 1 ) )
  557.                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;
  558.                 else if( !bs_read( &s, 1 ) )
  559.                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;
  560.                 else if( !bs_read( &s, 1 ) )
  561.                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
  562.                 else if( !bs_read( &s, 1 ) )
  563.                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;   /* Bi */
  564.                 else
  565.                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;   /* P Skip */
  566.             }
  567.         }
  568.         else
  569.         {
  570.             if( p_sys->sh.b_frame_interpolation )
  571.                 bs_skip( &s, 1 );   // interpolate
  572.             bs_skip( &s, 2 );       // frame count
  573.             if( p_sys->sh.b_range_reduction )
  574.                 bs_skip( &s, 1 );   // range reduction
  575.             if( bs_read( &s, 1 ) )
  576.                 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;
  577.             else if( !p_sys->sh.b_has_bframe || bs_read( &s, 1 ) )
  578.                 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
  579.             else
  580.                 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;
  581.         }
  582.         p_sys->b_frame = true;
  583.     }
  584.     if( p_release )
  585.         block_Release( p_release );
  586.     return p_pic;
  587. }