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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * ps.h: Program Stream demuxer helper
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 the VideoLAN team
  5.  * $Id: fed3ab0ac93a33ed4380d333ce14ca16136df08a $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. #include <vlc_demux.h>
  24. #include <assert.h>
  25. /* 256-0xC0 for normal stream, 256 for 0xbd stream, 256 for 0xfd stream */
  26. #define PS_TK_COUNT (768 - 0xc0)
  27. #define PS_ID_TO_TK( id ) ((id) <= 0xff ? (id) - 0xc0 : 
  28.             ((id)&0xff) + (((id)&0xff00) == 0xbd00 ? 256-0xC0 : 512-0xc0) )
  29. typedef struct ps_psm_t ps_psm_t;
  30. static inline int ps_id_to_type( const ps_psm_t *, int );
  31. static inline const uint8_t *ps_id_to_lang( const ps_psm_t *, int );
  32. typedef struct
  33. {
  34.     bool  b_seen;
  35.     int         i_skip;
  36.     int         i_id;
  37.     es_out_id_t *es;
  38.     es_format_t fmt;
  39.     mtime_t     i_first_pts;
  40.     mtime_t     i_last_pts;
  41. } ps_track_t;
  42. /* Init a set of track */
  43. static inline void ps_track_init( ps_track_t tk[PS_TK_COUNT] )
  44. {
  45.     int i;
  46.     for( i = 0; i < PS_TK_COUNT; i++ )
  47.     {
  48.         tk[i].b_seen = false;
  49.         tk[i].i_skip = 0;
  50.         tk[i].i_id   = 0;
  51.         tk[i].es     = NULL;
  52.         tk[i].i_first_pts = -1;
  53.         tk[i].i_last_pts = -1;
  54.         es_format_Init( &tk[i].fmt, UNKNOWN_ES, 0 );
  55.     }
  56. }
  57. /* From id fill i_skip and es_format_t */
  58. static inline int ps_track_fill( ps_track_t *tk, ps_psm_t *p_psm, int i_id )
  59. {
  60.     tk->i_skip = 0;
  61.     tk->i_id = i_id;
  62.     if( ( i_id&0xff00 ) == 0xbd00 )
  63.     {
  64.         if( ( i_id&0xf8 ) == 0x88 || (i_id&0xf8) == 0x98 )
  65.         {
  66.             es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('d','t','s',' ') );
  67.             tk->i_skip = 4;
  68.         }
  69.         else if( ( i_id&0xf0 ) == 0x80
  70.                ||  (i_id&0xf0) == 0xc0 ) /* AC-3, Can also be used for DD+/E-AC-3 */
  71.         {
  72.             es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('a','5','2',' ') );
  73.             tk->i_skip = 4;
  74.         }
  75.         else if( (i_id&0xf0) == 0xb0 )
  76.         {
  77.             es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('m','l','p',' ') );
  78.             /* FIXME / untested ... no known decoder (at least not in VLC/ffmpeg) */
  79.         }
  80.         else if( ( i_id&0xe0 ) == 0x20 )
  81.         {
  82.             es_format_Init( &tk->fmt, SPU_ES, VLC_FOURCC('s','p','u',' ') );
  83.             tk->i_skip = 1;
  84.         }
  85.         else if( ( i_id&0xf0 ) == 0xa0 )
  86.         {
  87.             es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('l','p','c','m') );
  88.             tk->i_skip = 1;
  89.         }
  90.         else if( ( i_id&0xff ) == 0x70 )
  91.         {
  92.             es_format_Init( &tk->fmt, SPU_ES, VLC_FOURCC('o','g','t',' ') );
  93.         }
  94.         else if( ( i_id&0xfc ) == 0x00 )
  95.         {
  96.             es_format_Init( &tk->fmt, SPU_ES, VLC_FOURCC('c','v','d',' ') );
  97.         }
  98.         else if( ( i_id&0xff ) == 0x10 )
  99.         {
  100.             es_format_Init( &tk->fmt, SPU_ES, VLC_FOURCC('t','e','l','x') );
  101.         }
  102.         else
  103.         {
  104.             es_format_Init( &tk->fmt, UNKNOWN_ES, 0 );
  105.             return VLC_EGENERIC;
  106.         }
  107.     }
  108.     else if( (i_id&0xff00) == 0xfd00 )
  109.     {
  110.         uint8_t i_sub_id = i_id & 0xff;
  111.         if( i_sub_id >= 0x55 && i_sub_id <= 0x5f )
  112.         {
  113.             es_format_Init( &tk->fmt, VIDEO_ES, VLC_FOURCC('W','V','C','1') );
  114.         }
  115.         else
  116.         {
  117.             es_format_Init( &tk->fmt, UNKNOWN_ES, 0 );
  118.             return VLC_EGENERIC;
  119.         }
  120.     }
  121.     else
  122.     {
  123.         int i_type = ps_id_to_type( p_psm , i_id );
  124.         es_format_Init( &tk->fmt, UNKNOWN_ES, 0 );
  125.         if( (i_id&0xf0) == 0xe0 && i_type == 0x1b )
  126.         {
  127.             es_format_Init( &tk->fmt, VIDEO_ES, VLC_FOURCC('h','2','6','4') );
  128.         }
  129.         else if( (i_id&0xf0) == 0xe0 && i_type == 0x10 )
  130.         {
  131.             es_format_Init( &tk->fmt, VIDEO_ES, VLC_FOURCC('m','p','4','v') );
  132.         }
  133.         else if( (i_id&0xf0) == 0xe0 && i_type == 0x02 )
  134.         {
  135.             es_format_Init( &tk->fmt, VIDEO_ES, VLC_FOURCC('m','p','g','v') );
  136.         }
  137.         else if( ( i_id&0xe0 ) == 0xc0 && i_type == 0x0f )
  138.         {
  139.             es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('m','p','4','a') );
  140.         }
  141.         else if( ( i_id&0xe0 ) == 0xc0 && i_type == 0x11 )
  142.         {
  143.             es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('m','p','4','a') );
  144.         }
  145.         else if( ( i_id&0xe0 ) == 0xc0 && i_type == 0x03 )
  146.         {
  147.             es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('m','p','g','a') );
  148.         }
  149.         if( tk->fmt.i_cat == UNKNOWN_ES && ( i_id&0xf0 ) == 0xe0 )
  150.         {
  151.             es_format_Init( &tk->fmt, VIDEO_ES, VLC_FOURCC('m','p','g','v') );
  152.         }
  153.         else if( tk->fmt.i_cat == UNKNOWN_ES && ( i_id&0xe0 ) == 0xc0 )
  154.         {
  155.             es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('m','p','g','a') );
  156.         }
  157.         else if( tk->fmt.i_cat == UNKNOWN_ES ) return VLC_EGENERIC;
  158.     }
  159.     /* PES packets usually contain truncated frames */
  160.     tk->fmt.b_packetized = false;
  161.     if( ps_id_to_lang( p_psm, i_id ) )
  162.     {
  163.         tk->fmt.psz_language = malloc( 4 );
  164.         if( tk->fmt.psz_language )
  165.         {
  166.             memcpy( tk->fmt.psz_language, ps_id_to_lang( p_psm , i_id ), 3 );
  167.             tk->fmt.psz_language[3] = 0;
  168.         }
  169.     }
  170.     return VLC_SUCCESS;
  171. }
  172. /* return the id of a PES (should be valid) */
  173. static inline int ps_pkt_id( block_t *p_pkt )
  174. {
  175.     if( p_pkt->p_buffer[3] == 0xbd &&
  176.         p_pkt->i_buffer >= 9 &&
  177.         p_pkt->i_buffer >= 9 + (size_t)p_pkt->p_buffer[8] )
  178.     {
  179.         /* VOB extension */
  180.         return 0xbd00 | p_pkt->p_buffer[9+p_pkt->p_buffer[8]];
  181.     }
  182.     else if( p_pkt->p_buffer[3] == 0xfd &&
  183.              p_pkt->i_buffer >= 9 &&
  184.              (p_pkt->p_buffer[6]&0xC0) == 0x80 &&   /* mpeg2 */
  185.              (p_pkt->p_buffer[7]&0x01) == 0x01 )    /* extension_flag */
  186.     {
  187.         /* ISO 13818 amendment 2 and SMPTE RP 227 */
  188.         const uint8_t i_flags = p_pkt->p_buffer[7];
  189.         unsigned int i_skip = 9;
  190.         /* Find PES extension */
  191.         if( (i_flags & 0x80 ) )
  192.         {
  193.             i_skip += 5;        /* pts */
  194.             if( (i_flags & 0x40) )
  195.                 i_skip += 5;    /* dts */
  196.         }
  197.         if( (i_flags & 0x20 ) )
  198.             i_skip += 6;
  199.         if( (i_flags & 0x10 ) )
  200.             i_skip += 3;
  201.         if( (i_flags & 0x08 ) )
  202.             i_skip += 1;
  203.         if( (i_flags & 0x04 ) )
  204.             i_skip += 1;
  205.         if( (i_flags & 0x02 ) )
  206.             i_skip += 2;
  207.         if( i_skip < p_pkt->i_buffer && (p_pkt->p_buffer[i_skip]&0x01) )
  208.         {
  209.             const uint8_t i_flags2 = p_pkt->p_buffer[i_skip];
  210.             /* Find PES extension 2 */
  211.             i_skip += 1;
  212.             if( i_flags2 & 0x80 )
  213.                 i_skip += 16;
  214.             if( (i_flags2 & 0x40) && i_skip < p_pkt->i_buffer )
  215.                 i_skip += 1 + p_pkt->p_buffer[i_skip];
  216.             if( i_flags2 & 0x20 )
  217.                 i_skip += 2;
  218.             if( i_flags2 & 0x10 )
  219.                 i_skip += 2;
  220.             if( i_skip + 1 < p_pkt->i_buffer )
  221.             {
  222.                 const int i_extension_field_length = p_pkt->p_buffer[i_skip]&0x7f;
  223.                 if( i_extension_field_length >=1 )
  224.                 {
  225.                     int i_stream_id_extension_flag = (p_pkt->p_buffer[i_skip+1] >> 7)&0x1;
  226.                     if( i_stream_id_extension_flag == 0 )
  227.                         return 0xfd00 | (p_pkt->p_buffer[i_skip+1]&0x7f);
  228.                 }
  229.             }
  230.         }
  231.     }
  232.     return p_pkt->p_buffer[3];
  233. }
  234. /* return the size of the next packet
  235.  * You need to give him at least 14 bytes (and it need to start as a
  236.  * valid packet) It does not handle less than 6 bytes */
  237. static inline int ps_pkt_size( const uint8_t *p, int i_peek )
  238. {
  239.     assert( i_peek >= 6 );
  240.     if( p[3] == 0xb9 && i_peek >= 4 )
  241.     {
  242.         return 4;
  243.     }
  244.     else if( p[3] == 0xba )
  245.     {
  246.         if( (p[4] >> 6) == 0x01 && i_peek >= 14 )
  247.         {
  248.             return 14 + (p[13]&0x07);
  249.         }
  250.         else if( (p[4] >> 4) == 0x02 && i_peek >= 12 )
  251.         {
  252.             return 12;
  253.         }
  254.         return -1;
  255.     }
  256.     else if( i_peek >= 6 )
  257.     {
  258.         return 6 + ((p[4]<<8) | p[5] );
  259.     }
  260.     return -1;
  261. }
  262. /* parse a PACK PES */
  263. static inline int ps_pkt_parse_pack( block_t *p_pkt, int64_t *pi_scr,
  264.                                      int *pi_mux_rate )
  265. {
  266.     uint8_t *p = p_pkt->p_buffer;
  267.     if( p_pkt->i_buffer >= 14 && (p[4] >> 6) == 0x01 )
  268.     {
  269.         *pi_scr =((((int64_t)p[4]&0x38) << 27 )|
  270.                   (((int64_t)p[4]&0x03) << 28 )|
  271.                    ((int64_t)p[5] << 20 )|
  272.                   (((int64_t)p[6]&0xf8) << 12 )|
  273.                   (((int64_t)p[6]&0x03) << 13 )|
  274.                    ((int64_t)p[7] << 5 )|
  275.                    ((int64_t)p[8] >> 3 )) * 100 / 9;
  276.         *pi_mux_rate = ( p[10] << 14 )|( p[11] << 6 )|( p[12] >> 2);
  277.     }
  278.     else if( p_pkt->i_buffer >= 12 && (p[4] >> 4) == 0x02 )
  279.     {
  280.         *pi_scr =((((int64_t)p[4]&0x0e) << 29 )|
  281.                    ((int64_t)p[5] << 22 )|
  282.                   (((int64_t)p[6]&0xfe) << 14 )|
  283.                    ((int64_t)p[7] <<  7 )|
  284.                    ((int64_t)p[8] >> 1 )) * 100 / 9;
  285.         *pi_mux_rate = ( ( p[9]&0x7f )<< 15 )|( p[10] << 7 )|( p[11] >> 1);
  286.     }
  287.     else
  288.     {
  289.         return VLC_EGENERIC;
  290.     }
  291.     return VLC_SUCCESS;
  292. }
  293. /* Parse a SYSTEM PES */
  294. static inline int ps_pkt_parse_system( block_t *p_pkt, ps_psm_t *p_psm,
  295.                                        ps_track_t tk[PS_TK_COUNT] )
  296. {
  297.     uint8_t *p = &p_pkt->p_buffer[6 + 3 + 1 + 1 + 1];
  298.     /* System header is not useable if it references private streams (0xBD)
  299.      * or 'all audio streams' (0xB8) or 'all video streams' (0xB9) */
  300.     while( p < &p_pkt->p_buffer[p_pkt->i_buffer] )
  301.     {
  302.         int i_id = p[0];
  303.         /* fprintf( stderr, "   SYSTEM_START_CODEEE: id=0x%xn", p[0] ); */
  304.         if( p[0] >= 0xBC || p[0] == 0xB8 || p[0] == 0xB9 ) p += 2;
  305.         p++;
  306.         if( i_id >= 0xc0 )
  307.         {
  308.             int i_tk = PS_ID_TO_TK( i_id );
  309.             if( !tk[i_tk].b_seen )
  310.             {
  311.                 if( !ps_track_fill( &tk[i_tk], p_psm, i_id ) )
  312.                 {
  313.                     tk[i_tk].b_seen = true;
  314.                 }
  315.             }
  316.         }
  317.     }
  318.     return VLC_SUCCESS;
  319. }
  320. /* Parse a PES (and skip i_skip_extra in the payload) */
  321. static inline int ps_pkt_parse_pes( block_t *p_pes, int i_skip_extra )
  322. {
  323.     uint8_t header[34];
  324.     unsigned int i_skip  = 0;
  325.     memcpy( header, p_pes->p_buffer, __MIN( p_pes->i_buffer, 34 ) );
  326.     switch( header[3] )
  327.     {
  328.         case 0xBC:  /* Program stream map */
  329.         case 0xBE:  /* Padding */
  330.         case 0xBF:  /* Private stream 2 */
  331.         case 0xB0:  /* ECM */
  332.         case 0xB1:  /* EMM */
  333.         case 0xFF:  /* Program stream directory */
  334.         case 0xF2:  /* DSMCC stream */
  335.         case 0xF8:  /* ITU-T H.222.1 type E stream */
  336.             i_skip = 6;
  337.             break;
  338.         default:
  339.             if( ( header[6]&0xC0 ) == 0x80 )
  340.             {
  341.                 /* mpeg2 PES */
  342.                 i_skip = header[8] + 9;
  343.                 if( header[7]&0x80 )    /* has pts */
  344.                 {
  345.                     p_pes->i_pts = ((mtime_t)(header[ 9]&0x0e ) << 29)|
  346.                                     (mtime_t)(header[10] << 22)|
  347.                                    ((mtime_t)(header[11]&0xfe) << 14)|
  348.                                     (mtime_t)(header[12] << 7)|
  349.                                     (mtime_t)(header[13] >> 1);
  350.                     if( header[7]&0x40 )    /* has dts */
  351.                     {
  352.                          p_pes->i_dts = ((mtime_t)(header[14]&0x0e ) << 29)|
  353.                                          (mtime_t)(header[15] << 22)|
  354.                                         ((mtime_t)(header[16]&0xfe) << 14)|
  355.                                          (mtime_t)(header[17] << 7)|
  356.                                          (mtime_t)(header[18] >> 1);
  357.                     }
  358.                 }
  359.             }
  360.             else
  361.             {
  362.                 i_skip = 6;
  363.                 while( i_skip < 23 && header[i_skip] == 0xff )
  364.                 {
  365.                     i_skip++;
  366.                 }
  367.                 if( i_skip == 23 )
  368.                 {
  369.                     /* msg_Err( p_demux, "too much MPEG-1 stuffing" ); */
  370.                     return VLC_EGENERIC;
  371.                 }
  372.                 if( ( header[i_skip] & 0xC0 ) == 0x40 )
  373.                 {
  374.                     i_skip += 2;
  375.                 }
  376.                 if(  header[i_skip]&0x20 )
  377.                 {
  378.                      p_pes->i_pts = ((mtime_t)(header[i_skip]&0x0e ) << 29)|
  379.                                      (mtime_t)(header[i_skip+1] << 22)|
  380.                                     ((mtime_t)(header[i_skip+2]&0xfe) << 14)|
  381.                                      (mtime_t)(header[i_skip+3] << 7)|
  382.                                      (mtime_t)(header[i_skip+4] >> 1);
  383.                     if( header[i_skip]&0x10 )    /* has dts */
  384.                     {
  385.                          p_pes->i_dts = ((mtime_t)(header[i_skip+5]&0x0e ) << 29)|
  386.                                          (mtime_t)(header[i_skip+6] << 22)|
  387.                                         ((mtime_t)(header[i_skip+7]&0xfe) << 14)|
  388.                                          (mtime_t)(header[i_skip+8] << 7)|
  389.                                          (mtime_t)(header[i_skip+9] >> 1);
  390.                          i_skip += 10;
  391.                     }
  392.                     else
  393.                     {
  394.                         i_skip += 5;
  395.                     }
  396.                 }
  397.                 else
  398.                 {
  399.                     i_skip += 1;
  400.                 }
  401.             }
  402.     }
  403.     i_skip += i_skip_extra;
  404.     if( p_pes->i_buffer <= i_skip )
  405.     {
  406.         return VLC_EGENERIC;
  407.     }
  408.     p_pes->p_buffer += i_skip;
  409.     p_pes->i_buffer -= i_skip;
  410.     p_pes->i_dts = 100 * p_pes->i_dts / 9;
  411.     p_pes->i_pts = 100 * p_pes->i_pts / 9;
  412.     return VLC_SUCCESS;
  413. }
  414. /* Program stream map handling */
  415. typedef struct ps_es_t
  416. {
  417.     int i_type;
  418.     int i_id;
  419.     int i_descriptor;
  420.     uint8_t *p_descriptor;
  421.     /* Language is iso639-2T */
  422.     uint8_t lang[3];
  423. } ps_es_t;
  424. struct ps_psm_t
  425. {
  426.     int i_version;
  427.     int     i_es;
  428.     ps_es_t **es;
  429. };
  430. static inline int ps_id_to_type( const ps_psm_t *p_psm, int i_id )
  431. {
  432.     int i;
  433.     for( i = 0; p_psm && i < p_psm->i_es; i++ )
  434.     {
  435.         if( p_psm->es[i]->i_id == i_id ) return p_psm->es[i]->i_type;
  436.     }
  437.     return 0;
  438. }
  439. static inline const uint8_t *ps_id_to_lang( const ps_psm_t *p_psm, int i_id )
  440. {
  441.     int i;
  442.     for( i = 0; p_psm && i < p_psm->i_es; i++ )
  443.     {
  444.         if( p_psm->es[i]->i_id == i_id ) return p_psm->es[i]->lang;
  445.     }
  446.     return 0;
  447. }
  448. static inline void ps_psm_init( ps_psm_t *p_psm )
  449. {
  450.     p_psm->i_version = 0xFFFF;
  451.     p_psm->i_es = 0;
  452.     p_psm->es = 0;
  453. }
  454. static inline void ps_psm_destroy( ps_psm_t *p_psm )
  455. {
  456.     while( p_psm->i_es-- )
  457.     {
  458.         free( p_psm->es[p_psm->i_es]->p_descriptor );
  459.         free( p_psm->es[p_psm->i_es] );
  460.     }
  461.     free( p_psm->es );
  462.     p_psm->es = 0;
  463.     p_psm->i_es = 0;
  464. }
  465. static inline int ps_psm_fill( ps_psm_t *p_psm, block_t *p_pkt,
  466.                                ps_track_t tk[PS_TK_COUNT], es_out_t *out )
  467. {
  468.     int i_buffer = p_pkt->i_buffer;
  469.     uint8_t *p_buffer = p_pkt->p_buffer;
  470.     int i_length, i_version, i_info_length, i_esm_length, i_es_base;
  471.     if( !p_psm || p_buffer[3] != 0xbc ) return VLC_EGENERIC;
  472.     i_length = (uint16_t)(p_buffer[4] << 8) + p_buffer[5] + 6;
  473.     if( i_length > i_buffer ) return VLC_EGENERIC;
  474.     //i_current_next_indicator = (p_buffer[6] && 0x01);
  475.     i_version = (p_buffer[6] && 0xf8);
  476.     if( p_psm->i_version == i_version ) return VLC_EGENERIC;
  477.     ps_psm_destroy( p_psm );
  478.     i_info_length = (uint16_t)(p_buffer[8] << 8) + p_buffer[9];
  479.     if( i_info_length + 10 > i_length ) return VLC_EGENERIC;
  480.     /* Elementary stream map */
  481.     i_esm_length = (uint16_t)(p_buffer[ 10 + i_info_length ] << 8) +
  482.         p_buffer[ 11 + i_info_length];
  483.     i_es_base = 12 + i_info_length;
  484.     while( i_es_base + 4 < i_length )
  485.     {
  486.         ps_es_t **tmp_es;
  487.         ps_es_t es;
  488.         es.lang[0] = es.lang[1] = es.lang[2] = 0;
  489.         es.i_type = p_buffer[ i_es_base  ];
  490.         es.i_id = p_buffer[ i_es_base + 1 ];
  491.         i_info_length = (uint16_t)(p_buffer[ i_es_base + 2 ] << 8) +
  492.             p_buffer[ i_es_base + 3 ];
  493.         if( i_es_base + 4 + i_info_length > i_length ) break;
  494.         /* TODO Add support for VC-1 stream:
  495.          *      stream_type=0xea, stream_id=0xfd AND registration
  496.          *      descriptor 0x5 with format_identifier == 0x56432D31 (VC-1)
  497.          *      (I need a sample that use PSM with VC-1) */
  498.         es.p_descriptor = 0;
  499.         es.i_descriptor = i_info_length;
  500.         if( i_info_length > 0 )
  501.         {
  502.             int i = 0;
  503.             es.p_descriptor = malloc( i_info_length );
  504.             if( es.p_descriptor )
  505.             {
  506.                 memcpy( es.p_descriptor, p_buffer + i_es_base + 4, i_info_length);
  507.                 while( i <= es.i_descriptor - 2 )
  508.                 {
  509.                     /* Look for the ISO639 language descriptor */
  510.                     if( es.p_descriptor[i] != 0x0a )
  511.                     {
  512.                         i += es.p_descriptor[i+1] + 2;
  513.                         continue;
  514.                     }
  515.                     if( i <= es.i_descriptor - 6 )
  516.                     {
  517.                         es.lang[0] = es.p_descriptor[i+2];
  518.                         es.lang[1] = es.p_descriptor[i+3];
  519.                         es.lang[2] = es.p_descriptor[i+4];
  520.                     }
  521.                     break;
  522.                 }
  523.             }
  524.         }
  525.         tmp_es = realloc( p_psm->es, sizeof(ps_es_t *) * (p_psm->i_es+1) );
  526.         if( tmp_es )
  527.         {
  528.             p_psm->es = tmp_es;
  529.             p_psm->es[p_psm->i_es] = malloc( sizeof(ps_es_t) );
  530.             if( p_psm->es[p_psm->i_es] )
  531.             {
  532.                 *p_psm->es[p_psm->i_es++] = es;
  533.                 i_es_base += 4 + i_info_length;
  534.             }
  535.         }
  536.     }
  537.     /* TODO: CRC */
  538.     p_psm->i_version = i_version;
  539.     /* Check/Modify our existing tracks */
  540.     for( int i = 0; i < PS_TK_COUNT; i++ )
  541.     {
  542.         ps_track_t tk_tmp;
  543.         if( !tk[i].b_seen || !tk[i].es ) continue;
  544.         if( ps_track_fill( &tk_tmp, p_psm, tk[i].i_id ) != VLC_SUCCESS )
  545.             continue;
  546.         if( tk_tmp.fmt.i_codec == tk[i].fmt.i_codec ) continue;
  547.         es_out_Del( out, tk[i].es );
  548.         tk[i] = tk_tmp;
  549.         tk[i].b_seen = true;
  550.         tk[i].es = es_out_Add( out, &tk[i].fmt );
  551.     }
  552.     return VLC_SUCCESS;
  553. }