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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mpls.c: BluRay Disc MPLS
  3.  *****************************************************************************
  4.  * Copyright (C) 2009 the VideoLAN team
  5.  * $Id: 4f597dd336dd0eed1bd49cae6aaf261b9fb08295 $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
  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. #ifdef HAVE_CONFIG_H
  24. # include "config.h"
  25. #endif
  26. #include <limits.h>
  27. #include <vlc_common.h>
  28. #include <vlc_bits.h>
  29. #include "mpls.h"
  30. /* MPLS */
  31. void bd_mpls_stream_Parse( bd_mpls_stream_t *p_stream, bs_t *s, int i_class )
  32. {
  33.     /* Stream entry parsing */
  34.     const int i_entry_length = bs_read( s, 8 );
  35.     const int i_entry_start = bs_pos( s ) / 8;
  36.     p_stream->i_type = bs_read( s, 8 );
  37.     p_stream->i_class = i_class;
  38.     if( p_stream->i_type == BD_MPLS_STREAM_TYPE_PLAY_ITEM )
  39.     {
  40.         p_stream->play_item.i_pid = bs_read( s, 16 );
  41.     }
  42.     else if( p_stream->i_type == BD_MPLS_STREAM_TYPE_SUB_PATH )
  43.     {
  44.         p_stream->sub_path.i_sub_path_id = bs_read( s, 8 );
  45.         p_stream->sub_path.i_sub_clip_id = bs_read( s, 8 );
  46.         p_stream->sub_path.i_pid = bs_read( s, 16 );
  47.     }
  48.     else if( p_stream->i_type == BD_MPLS_STREAM_TYPE_IN_MUX_SUB_PATH )
  49.     {
  50.         p_stream->in_mux_sub_path.i_sub_path_id = bs_read( s, 8 );
  51.         p_stream->in_mux_sub_path.i_pid = bs_read( s, 16 );
  52.     }
  53.     bs_skip( s, 8 * ( i_entry_start + i_entry_length ) - bs_pos( s ) );
  54.     /* Stream attributes parsing */
  55.     const int i_attributes_length = bs_read( s, 8 );
  56.     const int i_attributes_start = bs_pos( s ) / 8;
  57.     p_stream->i_stream_type = bs_read( s, 8 );
  58.     strcpy( p_stream->psz_language, "" );
  59.     p_stream->i_charset = -1;
  60.     if( p_stream->i_stream_type == 0x02 || /* MPEG-I/II */
  61.         p_stream->i_stream_type == 0x1b || /* AVC */
  62.         p_stream->i_stream_type == 0xea )  /* VC-1 */
  63.     {
  64.         /* Video */
  65.     }
  66.     else if( ( p_stream->i_stream_type >= 0x80 && p_stream->i_stream_type <= 0x8f ) ||
  67.              ( p_stream->i_stream_type >= 0xa0 && p_stream->i_stream_type <= 0xaf ) )
  68.     {
  69.         /* Audio */
  70.         bs_skip( s, 4 );
  71.         bs_skip( s, 4 );
  72.         for( int i = 0; i < 3; i++ )
  73.             p_stream->psz_language[i] = bs_read( s, 8 );
  74.         p_stream->psz_language[3] = '';
  75.     }
  76.     else if( p_stream->i_stream_type == 0x90 ||   /* PG stream */
  77.              p_stream->i_stream_type == 0x91 )    /* IG stream */
  78.     {
  79.         for( int i = 0; i < 3; i++ )
  80.             p_stream->psz_language[i] = bs_read( s, 8 );
  81.         p_stream->psz_language[3] = '';
  82.     }
  83.     else if( p_stream->i_stream_type == 0x92 )    /* Text stream */
  84.     {
  85.         p_stream->i_charset = bs_read( s, 8 );
  86.         for( int i = 0; i < 3; i++ )
  87.             p_stream->psz_language[i] = bs_read( s, 8 );
  88.         p_stream->psz_language[3] = '';
  89.     }
  90.     bs_skip( s, 8 * ( i_attributes_start + i_attributes_length ) - bs_pos( s ) );
  91. }
  92. void bd_mpls_play_item_Clean( bd_mpls_play_item_t *p_item )
  93. {
  94.     free( p_item->p_clpi );
  95.     free( p_item->p_stream );
  96. }
  97. void bd_mpls_play_item_Parse( bd_mpls_play_item_t *p_item, bs_t *s )
  98. {
  99.     const int i_length = bs_read( s, 16 );
  100.     const int i_start = bs_pos( s ) / 8;
  101.     char psz_name[5+1];
  102.     for( int j = 0; j < 5; j++ )
  103.         psz_name[j] = bs_read( s, 8 );
  104.     psz_name[5] = '';
  105.     p_item->clpi.i_id = strtol( psz_name, NULL, 10 );
  106.     bs_skip( s, 32 );
  107.     bs_skip( s, 11 );
  108.     const bool b_angle = bs_read( s, 1 );
  109.     p_item->i_connection = bs_read( s, 4 );
  110.     p_item->clpi.i_stc_id = bs_read( s, 8 );
  111.     p_item->i_in_time = bs_read( s, 32 );
  112.     p_item->i_out_time = bs_read( s, 32 );
  113.     bs_skip( s, 64 );
  114.     bs_skip( s, 1 );
  115.     bs_skip( s, 7 );
  116.     p_item->i_still = bs_read( s, 8 );
  117.     p_item->i_still_time = bs_read( s, 16 );
  118.     if( p_item->i_still == BD_MPLS_PLAY_ITEM_STILL_NONE )
  119.         p_item->i_still_time = 0;
  120.     else if( p_item->i_still == BD_MPLS_PLAY_ITEM_STILL_INFINITE )
  121.         p_item->i_still_time = INT_MAX;
  122.     if( b_angle )
  123.     {
  124.         const int i_angle = bs_read( s, 8 );
  125.         bs_skip( s, 6 );
  126.         p_item->b_angle_different_audio = bs_read( s, 1 );
  127.         p_item->b_angle_seamless = bs_read( s, 1 );
  128.         p_item->p_clpi = calloc( i_angle, sizeof(*p_item->p_clpi) );
  129.         for( p_item->i_clpi = 0; p_item->i_clpi < i_angle; p_item->i_clpi++ )
  130.         {
  131.             if( !p_item->p_clpi )
  132.                 break;
  133.             bd_mpls_clpi_t *p_clpi = &p_item->p_clpi[p_item->i_clpi];
  134.             char psz_name[5+1];
  135.             for( int j = 0; j < 5; j++ )
  136.                 psz_name[j] = bs_read( s, 8 );
  137.             psz_name[5] = '';
  138.             p_clpi->i_id = strtol( psz_name, NULL, 10 );
  139.             bs_skip( s, 32 );
  140.             p_clpi->i_stc_id = bs_read( s, 8 );
  141.         }
  142.     }
  143.     else
  144.     {
  145.         p_item->i_clpi = 0;
  146.         p_item->p_clpi = NULL;
  147.         p_item->b_angle_different_audio = false;
  148.         p_item->b_angle_seamless = true;
  149.     }
  150.     /* STN Table */
  151.     bs_skip( s, 16 );  /* Length */
  152.     bs_skip( s, 16 );
  153.     const int i_video = bs_read( s, 8 );
  154.     const int i_audio = bs_read( s, 8 );
  155.     const int i_pg = bs_read( s, 8 );
  156.     const int i_ig = bs_read( s, 8 );
  157.     const int i_audio_2 = bs_read( s, 8 );
  158.     const int i_video_2 = bs_read( s, 8 );
  159.     const int i_pip_pg = bs_read( s, 8 );
  160.     bs_skip( s, 40 );
  161.     p_item->i_stream = 0;
  162.     p_item->p_stream = calloc( i_video + i_audio + i_pg + i_ig,
  163.                                sizeof(*p_item->p_stream) );
  164.     for( int j = 0; j < i_video; j++, p_item->i_stream++ )
  165.     {
  166.         if( !p_item->p_stream )
  167.             break;
  168.         bd_mpls_stream_Parse( &p_item->p_stream[p_item->i_stream], s,
  169.                               BD_MPLS_STREAM_CLASS_PRIMARY_VIDEO );
  170.     }
  171.     for( int j = 0; j < i_audio; j++, p_item->i_stream++ )
  172.     {
  173.         if( !p_item->p_stream )
  174.             break;
  175.         bd_mpls_stream_Parse( &p_item->p_stream[p_item->i_stream], s,
  176.                               BD_MPLS_STREAM_CLASS_PRIMARY_AUDIO );
  177.     }
  178.     for( int j = 0; j < i_pg; j++, p_item->i_stream++ )
  179.     {
  180.         if( !p_item->p_stream )
  181.             break;
  182.         bd_mpls_stream_Parse( &p_item->p_stream[p_item->i_stream], s,
  183.                               BD_MPLS_STREAM_CLASS_PG );
  184.     }
  185.     for( int j = 0; j < i_ig; j++, p_item->i_stream++ )
  186.     {
  187.         if( !p_item->p_stream )
  188.             break;
  189.         bd_mpls_stream_Parse( &p_item->p_stream[p_item->i_stream], s,
  190.                               BD_MPLS_STREAM_CLASS_IG );
  191.     }
  192.     for( int j = 0; j < i_audio_2; j++ )
  193.     {
  194.         /* TODO I need samples */
  195.     }
  196.     for( int j = 0; j < i_video_2; j++ )
  197.     {
  198.         /* TODO I need samples */
  199.     }
  200.     for( int j = 0; j < i_pip_pg; j++ )
  201.     {
  202.         /* TODO I need samples */
  203.     }
  204.     bs_skip( s, 8 * ( i_start + i_length ) - bs_pos( s ) );
  205. }
  206. void bd_mpls_sub_path_Parse( bd_mpls_sub_path_t *p_path, bs_t *s )
  207. {
  208.     const uint32_t i_length = bs_read( s, 32 );
  209.     const int i_start = bs_pos( s ) / 8;
  210.     bs_skip( s, 8 );
  211.     p_path->i_type = bs_read( s, 8 );
  212.     bs_skip( s, 15 );
  213.     p_path->b_repeat = bs_read( s, 1 );
  214.     bs_skip( s, 8 );
  215.     p_path->i_item = bs_read( s, 8 );
  216.     for( int j = 0; j < p_path->i_item; j++ )
  217.     {
  218.         const int i_length = bs_read( s, 16 );
  219.         const int i_start = bs_pos( s ) / 8;
  220.         /* TODO */
  221.         bs_skip( s, 8 * ( i_start + i_length ) - bs_pos( s ) );
  222.     }
  223.     bs_skip( s, 8 * ( i_start + i_length ) - bs_pos( s ) );
  224. }
  225. void bd_mpls_mark_Parse( bd_mpls_mark_t *p_mark, bs_t *s )
  226. {
  227.     bs_skip( s, 8 );
  228.     p_mark->i_type = bs_read( s, 8 );
  229.     p_mark->i_play_item_id = bs_read( s, 16 );
  230.     p_mark->i_time = bs_read( s, 32 );
  231.     p_mark->i_entry_es_pid = bs_read( s, 16 );
  232.     bs_skip( s, 32 );
  233. }
  234. void bd_mpls_Clean( bd_mpls_t *p_mpls )
  235. {
  236.     for( int i = 0; i < p_mpls->i_play_item; i++ )
  237.         bd_mpls_play_item_Clean( &p_mpls->p_play_item[i] );
  238.     free( p_mpls->p_play_item );
  239.     free( p_mpls->p_sub_path );
  240.     free( p_mpls->p_mark );
  241. }
  242. int bd_mpls_Parse( bd_mpls_t *p_mpls, bs_t *s, int i_id )
  243. {
  244.     const int i_start = bs_pos( s ) / 8;
  245.     /* */
  246.     if( bs_read( s, 32 ) != 0x4d504c53 )
  247.         return VLC_EGENERIC;
  248.     const uint32_t i_version = bs_read( s, 32 );
  249.     if( i_version != 0x30313030 && i_version != 0x30323030 )
  250.         return VLC_EGENERIC;
  251.     const uint32_t i_play_item_start = bs_read( s, 32 );
  252.     const uint32_t i_mark_start = bs_read( s, 32 );
  253.     bs_skip( s, 32 );   /* Extension start */
  254.     /* */
  255.     p_mpls->i_id = i_id;
  256.     /* Read AppInfo: ignored */
  257.     /* Read Playlist */
  258.     bs_t ps = *s;
  259.     bs_skip( &ps, 8 * ( i_start + i_play_item_start ) - bs_pos( s ) );
  260.     bs_skip( &ps, 32 ); /* Length */
  261.     bs_skip( &ps, 16 );
  262.     const int i_play_item = bs_read( &ps, 16 );
  263.     const int i_sub_path = bs_read( &ps, 16 );
  264.     p_mpls->p_play_item = calloc( i_play_item, sizeof(*p_mpls->p_play_item) );
  265.     for( p_mpls->i_play_item = 0; p_mpls->i_play_item < i_play_item; p_mpls->i_play_item++ )
  266.     {
  267.         if( !p_mpls->p_play_item )
  268.             break;
  269.         bd_mpls_play_item_t *p_item = &p_mpls->p_play_item[p_mpls->i_play_item];
  270.         bd_mpls_play_item_Parse( p_item, &ps );
  271.     }
  272.     p_mpls->p_sub_path = calloc( i_sub_path, sizeof(*p_mpls->p_sub_path) );
  273.     for( p_mpls->i_sub_path = 0; p_mpls->i_sub_path < i_sub_path; p_mpls->i_sub_path++ )
  274.     {
  275.         if( !p_mpls->p_sub_path )
  276.             break;
  277.         bd_mpls_sub_path_t *p_sub = &p_mpls->p_sub_path[p_mpls->i_sub_path];
  278.         bd_mpls_sub_path_Parse( p_sub, &ps );
  279.     }
  280.     /* Read Mark */
  281.     bs_t ms = *s;
  282.     bs_skip( &ms, 8 * ( i_start + i_mark_start ) - bs_pos( s ) );
  283.     bs_skip( &ms, 32 );
  284.     const int i_mark = bs_read( &ms, 16 );
  285.     p_mpls->p_mark = calloc( i_mark, sizeof(*p_mpls->p_mark) );
  286.     for( p_mpls->i_mark = 0; p_mpls->i_mark < i_mark; p_mpls->i_mark++ )
  287.     {
  288.         if( !p_mpls->p_mark )
  289.             break;
  290.         bd_mpls_mark_t *p_mark = &p_mpls->p_mark[p_mpls->i_mark];
  291.         bd_mpls_mark_Parse( p_mark, &ms );
  292.     }
  293.     /* Read Extension: ignored */
  294.     return VLC_SUCCESS;
  295. }