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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * asf.c : ASF demux module
  3.  *****************************************************************************
  4.  * Copyright (C) 2002-2003 the VideoLAN team
  5.  * $Id: 1f63bbd9e2b4d1d562ae4202d78d21f3193e39da $
  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. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <vlc_common.h>
  30. #include <vlc_plugin.h>
  31. #include <vlc_demux.h>
  32. #include <vlc_dialog.h>
  33. #include <vlc_meta.h>
  34. #include <vlc_access.h>                /* GET_PRIVATE_ID_STATE */
  35. #include <vlc_codecs.h>                /* BITMAPINFOHEADER, WAVEFORMATEX */
  36. #include "libasf.h"
  37. /* TODO
  38.  *  - add support for the newly added object: language, bitrate,
  39.  *                                            extended stream properties.
  40.  */
  41. /*****************************************************************************
  42.  * Module descriptor
  43.  *****************************************************************************/
  44. static int  Open  ( vlc_object_t * );
  45. static void Close ( vlc_object_t * );
  46. vlc_module_begin ()
  47.     set_category( CAT_INPUT )
  48.     set_subcategory( SUBCAT_INPUT_DEMUX )
  49.     set_description( N_("ASF v1.0 demuxer") )
  50.     set_capability( "demux", 200 )
  51.     set_callbacks( Open, Close )
  52.     add_shortcut( "asf" )
  53. vlc_module_end ()
  54. /*****************************************************************************
  55.  * Local prototypes
  56.  *****************************************************************************/
  57. static int Demux  ( demux_t * );
  58. static int Control( demux_t *, int i_query, va_list args );
  59. typedef struct
  60. {
  61.     int i_cat;
  62.     es_out_id_t     *p_es;
  63.     asf_object_stream_properties_t *p_sp;
  64.     mtime_t i_time;
  65.     block_t         *p_frame; /* use to gather complete frame */
  66. } asf_track_t;
  67. struct demux_sys_t
  68. {
  69.     mtime_t             i_time;     /* s */
  70.     mtime_t             i_length;   /* length of file file */
  71.     int64_t             i_bitrate;  /* global file bitrate */
  72.     asf_object_root_t            *p_root;
  73.     asf_object_file_properties_t *p_fp;
  74.     unsigned int        i_track;
  75.     asf_track_t         *track[128]; /* track number is stored on 7 bits */
  76.     int64_t             i_data_begin;
  77.     int64_t             i_data_end;
  78.     bool          b_index;
  79.     vlc_meta_t          *meta;
  80. };
  81. static mtime_t  GetMoviePTS( demux_sys_t * );
  82. static int      DemuxInit( demux_t * );
  83. static void     DemuxEnd( demux_t * );
  84. static int      DemuxPacket( demux_t * );
  85. /*****************************************************************************
  86.  * Open: check file and initializes ASF structures
  87.  *****************************************************************************/
  88. static int Open( vlc_object_t * p_this )
  89. {
  90.     demux_t     *p_demux = (demux_t *)p_this;
  91.     demux_sys_t *p_sys;
  92.     guid_t      guid;
  93.     const uint8_t     *p_peek;
  94.     /* A little test to see if it could be a asf stream */
  95.     if( stream_Peek( p_demux->s, &p_peek, 16 ) < 16 ) return VLC_EGENERIC;
  96.     ASF_GetGUID( &guid, p_peek );
  97.     if( !ASF_CmpGUID( &guid, &asf_object_header_guid ) ) return VLC_EGENERIC;
  98.     /* Set p_demux fields */
  99.     p_demux->pf_demux = Demux;
  100.     p_demux->pf_control = Control;
  101.     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
  102.     memset( p_sys, 0, sizeof( demux_sys_t ) );
  103.     /* Load the headers */
  104.     if( DemuxInit( p_demux ) )
  105.     {
  106.         free( p_sys );
  107.         return VLC_EGENERIC;
  108.     }
  109.     return VLC_SUCCESS;
  110. }
  111. /*****************************************************************************
  112.  * Demux: read packet and send them to decoders
  113.  *****************************************************************************/
  114. static int Demux( demux_t *p_demux )
  115. {
  116.     demux_sys_t *p_sys = p_demux->p_sys;
  117.     for( ;; )
  118.     {
  119.         const uint8_t *p_peek;
  120.         mtime_t i_length;
  121.         mtime_t i_time_begin = GetMoviePTS( p_sys );
  122.         int i_result;
  123.         if( !vlc_object_alive (p_demux) )
  124.             break;
  125. #if 0
  126.         /* FIXME: returns EOF too early for some mms streams */
  127.         if( p_sys->i_data_end >= 0 &&
  128.                 stream_Tell( p_demux->s ) >= p_sys->i_data_end )
  129.             return 0; /* EOF */
  130. #endif
  131.         /* Check if we have concatenated files */
  132.         if( stream_Peek( p_demux->s, &p_peek, 16 ) == 16 )
  133.         {
  134.             guid_t guid;
  135.             ASF_GetGUID( &guid, p_peek );
  136.             if( ASF_CmpGUID( &guid, &asf_object_header_guid ) )
  137.             {
  138.                 msg_Warn( p_demux, "found a new ASF header" );
  139.                 /* We end this stream */
  140.                 DemuxEnd( p_demux );
  141.                 /* And we prepare to read the next one */
  142.                 if( DemuxInit( p_demux ) )
  143.                 {
  144.                     msg_Err( p_demux, "failed to load the new header" );
  145.                     dialog_Fatal( p_demux, _("Could not demux ASF stream"), "%s",
  146.                                     _("VLC failed to load the ASF header.") );
  147.                     return 0;
  148.                 }
  149.                 es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
  150.                 continue;
  151.             }
  152.         }
  153.         /* Read and demux a packet */
  154.         if( ( i_result = DemuxPacket( p_demux ) ) <= 0 )
  155.         {
  156.             return i_result;
  157.         }
  158.         if( i_time_begin == -1 )
  159.         {
  160.             i_time_begin = GetMoviePTS( p_sys );
  161.         }
  162.         else
  163.         {
  164.             i_length = GetMoviePTS( p_sys ) - i_time_begin;
  165.             if( i_length < 0 || i_length >= 40 * 1000 ) break;
  166.         }
  167.     }
  168.     /* Set the PCR */
  169.     p_sys->i_time = GetMoviePTS( p_sys );
  170.     if( p_sys->i_time >= 0 )
  171.     {
  172.         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_time+1 );
  173.     }
  174.     return 1;
  175. }
  176. /*****************************************************************************
  177.  * Close: frees unused data
  178.  *****************************************************************************/
  179. static void Close( vlc_object_t * p_this )
  180. {
  181.     demux_t     *p_demux = (demux_t *)p_this;
  182.     DemuxEnd( p_demux );
  183.     free( p_demux->p_sys );
  184. }
  185. /*****************************************************************************
  186.  * SeekIndex: goto to i_date or i_percent
  187.  *****************************************************************************/
  188. static int SeekIndex( demux_t *p_demux, mtime_t i_date, float f_pos )
  189. {
  190.     demux_sys_t *p_sys = p_demux->p_sys;
  191.     asf_object_index_t *p_index;
  192.     int64_t i_pos;
  193.     msg_Dbg( p_demux, "seek with index: %i seconds, position %f",
  194.              (int)(i_date/1000000), f_pos );
  195.     p_index = ASF_FindObject( p_sys->p_root, &asf_object_index_guid, 0 );
  196.     if( i_date < 0 ) i_date = p_sys->i_length * f_pos;
  197.     i_pos = i_date * 10 / p_index->i_index_entry_time_interval;
  198.     i_pos = p_index->index_entry[i_pos].i_packet_number *
  199.         p_sys->p_fp->i_min_data_packet_size;
  200.     return stream_Seek( p_demux->s, p_sys->i_data_begin + i_pos );
  201. }
  202. static void SeekPrepare( demux_t *p_demux )
  203. {
  204.     demux_sys_t *p_sys = p_demux->p_sys;
  205.     p_sys->i_time = -1;
  206.     for( int i = 0; i < 128 ; i++ )
  207.     {
  208.         asf_track_t *tk = p_sys->track[i];
  209.         if( !tk )
  210.             continue;
  211.         tk->i_time = 1;
  212.         if( tk->p_frame )
  213.             block_ChainRelease( tk->p_frame );
  214.         tk->p_frame = NULL;
  215.     }
  216. }
  217. /*****************************************************************************
  218.  * Control:
  219.  *****************************************************************************/
  220. static int Control( demux_t *p_demux, int i_query, va_list args )
  221. {
  222.     demux_sys_t *p_sys = p_demux->p_sys;
  223.     vlc_meta_t  *p_meta;
  224.     int64_t     i64, *pi64;
  225.     double      f, *pf;
  226.     switch( i_query )
  227.     {
  228.     case DEMUX_GET_LENGTH:
  229.         pi64 = (int64_t*)va_arg( args, int64_t * );
  230.         *pi64 = p_sys->i_length;
  231.         return VLC_SUCCESS;
  232.     case DEMUX_GET_TIME:
  233.         pi64 = (int64_t*)va_arg( args, int64_t * );
  234.         if( p_sys->i_time < 0 ) return VLC_EGENERIC;
  235.         *pi64 = p_sys->i_time;
  236.         return VLC_SUCCESS;
  237.     case DEMUX_SET_TIME:
  238.         SeekPrepare( p_demux );
  239.         if( p_sys->b_index && p_sys->i_length > 0 )
  240.         {
  241.             i64 = (int64_t)va_arg( args, int64_t );
  242.             return SeekIndex( p_demux, i64, -1 );
  243.         }
  244.         else
  245.         {
  246.             return demux_vaControlHelper( p_demux->s, p_sys->i_data_begin,
  247.                                            p_sys->i_data_end, p_sys->i_bitrate,
  248.                                            p_sys->p_fp->i_min_data_packet_size,
  249.                                            i_query, args );
  250.         }
  251.     case DEMUX_GET_POSITION:
  252.         if( p_sys->i_time < 0 ) return VLC_EGENERIC;
  253.         if( p_sys->i_length > 0 )
  254.         {
  255.             pf = (double*)va_arg( args, double * );
  256.             *pf = p_sys->i_time / (double)p_sys->i_length;
  257.             return VLC_SUCCESS;
  258.         }
  259.         return demux_vaControlHelper( p_demux->s, p_sys->i_data_begin,
  260.                                        p_sys->i_data_end, p_sys->i_bitrate,
  261.                                        p_sys->p_fp->i_min_data_packet_size,
  262.                                        i_query, args );
  263.     case DEMUX_SET_POSITION:
  264.         SeekPrepare( p_demux );
  265.         if( p_sys->b_index && p_sys->i_length > 0 )
  266.         {
  267.             f = (double)va_arg( args, double );
  268.             return SeekIndex( p_demux, -1, f );
  269.         }
  270.         else
  271.         {
  272.             return demux_vaControlHelper( p_demux->s, p_sys->i_data_begin,
  273.                                            p_sys->i_data_end, p_sys->i_bitrate,
  274.                                            p_sys->p_fp->i_min_data_packet_size,
  275.                                            i_query, args );
  276.         }
  277.     case DEMUX_GET_META:
  278.         p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
  279.         vlc_meta_Merge( p_meta, p_sys->meta );
  280.         return VLC_SUCCESS;
  281.     default:
  282.         return demux_vaControlHelper( p_demux->s, p_sys->i_data_begin,
  283.                                        p_sys->i_data_end, p_sys->i_bitrate,
  284.                                        p_sys->p_fp->i_min_data_packet_size,
  285.                                        i_query, args );
  286.     }
  287. }
  288. /*****************************************************************************
  289.  *
  290.  *****************************************************************************/
  291. static mtime_t GetMoviePTS( demux_sys_t *p_sys )
  292. {
  293.     mtime_t i_time = -1;
  294.     int     i;
  295.     for( i = 0; i < 128 ; i++ )
  296.     {
  297.         asf_track_t *tk = p_sys->track[i];
  298.         if( tk && tk->p_es && tk->i_time > 0)
  299.         {
  300.             if( i_time < 0 ) i_time = tk->i_time;
  301.             else i_time = __MIN( i_time, tk->i_time );
  302.         }
  303.     }
  304.     return i_time;
  305. }
  306. #define GETVALUE2b( bits, var, def ) 
  307.     switch( (bits)&0x03 ) 
  308.     { 
  309.         case 1: var = p_peek[i_skip]; i_skip++; break; 
  310.         case 2: var = GetWLE( p_peek + i_skip );  i_skip+= 2; break; 
  311.         case 3: var = GetDWLE( p_peek + i_skip ); i_skip+= 4; break; 
  312.         case 0: 
  313.         default: var = def; break;
  314.     }
  315. static int DemuxPacket( demux_t *p_demux )
  316. {
  317.     demux_sys_t *p_sys = p_demux->p_sys;
  318.     int         i_data_packet_min = p_sys->p_fp->i_min_data_packet_size;
  319.     const uint8_t *p_peek;
  320.     int         i_skip;
  321.     int         i_packet_size_left;
  322.     int         i_packet_flags;
  323.     int         i_packet_property;
  324.     int         b_packet_multiple_payload;
  325.     int         i_packet_length;
  326.     int         i_packet_sequence;
  327.     int         i_packet_padding_length;
  328.     uint32_t    i_packet_send_time;
  329.     uint16_t    i_packet_duration;
  330.     int         i_payload;
  331.     int         i_payload_count;
  332.     int         i_payload_length_type;
  333.     if( stream_Peek( p_demux->s, &p_peek,i_data_packet_min)<i_data_packet_min )
  334.     {
  335.         msg_Warn( p_demux, "cannot peek while getting new packet, EOF ?" );
  336.         return 0;
  337.     }
  338.     i_skip = 0;
  339.     /* *** parse error correction if present *** */
  340.     if( p_peek[0]&0x80 )
  341.     {
  342.         unsigned int i_error_correction_length_type;
  343.         unsigned int i_error_correction_data_length;
  344.         unsigned int i_opaque_data_present;
  345.         i_error_correction_data_length = p_peek[0] & 0x0f;  // 4bits
  346.         i_opaque_data_present = ( p_peek[0] >> 4 )& 0x01;    // 1bit
  347.         i_error_correction_length_type = ( p_peek[0] >> 5 ) & 0x03; // 2bits
  348.         i_skip += 1; // skip error correction flags
  349.         if( i_error_correction_length_type != 0x00 ||
  350.             i_opaque_data_present != 0 ||
  351.             i_error_correction_data_length != 0x02 )
  352.         {
  353.             goto loop_error_recovery;
  354.         }
  355.         i_skip += i_error_correction_data_length;
  356.     }
  357.     else
  358.     {
  359.         msg_Warn( p_demux, "p_peek[0]&0x80 != 0x80" );
  360.     }
  361.     /* sanity check */
  362.     if( i_skip + 2 >= i_data_packet_min )
  363.     {
  364.         goto loop_error_recovery;
  365.     }
  366.     i_packet_flags = p_peek[i_skip]; i_skip++;
  367.     i_packet_property = p_peek[i_skip]; i_skip++;
  368.     b_packet_multiple_payload = i_packet_flags&0x01;
  369.     /* read some value */
  370.     GETVALUE2b( i_packet_flags >> 5, i_packet_length, i_data_packet_min );
  371.     GETVALUE2b( i_packet_flags >> 1, i_packet_sequence, 0 );
  372.     GETVALUE2b( i_packet_flags >> 3, i_packet_padding_length, 0 );
  373.     if( i_packet_padding_length > i_packet_length )
  374.     {
  375.         msg_Warn( p_demux, "Too large padding: %d", i_packet_padding_length );
  376.         goto loop_error_recovery;
  377.     }
  378.     i_packet_send_time = GetDWLE( p_peek + i_skip ); i_skip += 4;
  379.     i_packet_duration  = GetWLE( p_peek + i_skip ); i_skip += 2;
  380.     /* FIXME I have to do that for some file, I don't known why */
  381.     i_packet_size_left = i_data_packet_min /*i_packet_length*/ ;
  382.     if( b_packet_multiple_payload )
  383.     {
  384.         i_payload_count = p_peek[i_skip] & 0x3f;
  385.         i_payload_length_type = ( p_peek[i_skip] >> 6 )&0x03;
  386.         i_skip++;
  387.     }
  388.     else
  389.     {
  390.         i_payload_count = 1;
  391.         i_payload_length_type = 0x02; // unused
  392.     }
  393.     for( i_payload = 0; i_payload < i_payload_count ; i_payload++ )
  394.     {
  395.         asf_track_t   *tk;
  396.         int i_packet_keyframe;
  397.         int i_stream_number;
  398.         int i_media_object_number;
  399.         int i_media_object_offset;
  400.         int i_replicated_data_length;
  401.         int i_payload_data_length;
  402.         int i_payload_data_pos;
  403.         int i_sub_payload_data_length;
  404.         int i_tmp;
  405.         mtime_t i_pts;
  406.         mtime_t i_pts_delta;
  407.         if( i_skip >= i_packet_size_left )
  408.         {
  409.             /* prevent some segfault with invalid file */
  410.             break;
  411.         }
  412.         i_packet_keyframe = p_peek[i_skip] >> 7;
  413.         i_stream_number = p_peek[i_skip++] & 0x7f;
  414.         GETVALUE2b( i_packet_property >> 4, i_media_object_number, 0 );
  415.         GETVALUE2b( i_packet_property >> 2, i_tmp, 0 );
  416.         GETVALUE2b( i_packet_property, i_replicated_data_length, 0 );
  417.         if( i_replicated_data_length > 1 ) // should be at least 8 bytes
  418.         {
  419.             i_pts = (mtime_t)GetDWLE( p_peek + i_skip + 4 ) * 1000;
  420.             i_skip += i_replicated_data_length;
  421.             i_pts_delta = 0;
  422.             i_media_object_offset = i_tmp;
  423.             if( i_skip >= i_packet_size_left )
  424.             {
  425.                 break;
  426.             }
  427.         }
  428.         else if( i_replicated_data_length == 1 )
  429.         {
  430.             /* msg_Dbg( p_demux, "found compressed payload" ); */
  431.             i_pts = (mtime_t)i_tmp * 1000;
  432.             i_pts_delta = (mtime_t)p_peek[i_skip] * 1000; i_skip++;
  433.             i_media_object_offset = 0;
  434.         }
  435.         else
  436.         {
  437.             i_pts = (mtime_t)i_packet_send_time * 1000;
  438.             i_pts_delta = 0;
  439.             i_media_object_offset = i_tmp;
  440.         }
  441.         i_pts = __MAX( i_pts - p_sys->p_fp->i_preroll * 1000, 0 );
  442.         if( b_packet_multiple_payload )
  443.         {
  444.             GETVALUE2b( i_payload_length_type, i_payload_data_length, 0 );
  445.         }
  446.         else
  447.         {
  448.             i_payload_data_length = i_packet_length -
  449.                                     i_packet_padding_length - i_skip;
  450.         }
  451.         if( i_payload_data_length < 0 || i_payload_data_length > i_packet_size_left )
  452.         {
  453.             break;
  454.         }
  455. #if 0
  456.          msg_Dbg( p_demux,
  457.                   "payload(%d/%d) stream_number:%d media_object_number:%d media_object_offset:%d replicated_data_length:%d payload_data_length %d",
  458.                   i_payload + 1, i_payload_count, i_stream_number, i_media_object_number,
  459.                   i_media_object_offset, i_replicated_data_length, i_payload_data_length );
  460. #endif
  461.         if( ( tk = p_sys->track[i_stream_number] ) == NULL )
  462.         {
  463.             msg_Warn( p_demux,
  464.                       "undeclared stream[Id 0x%x]", i_stream_number );
  465.             i_skip += i_payload_data_length;
  466.             continue;   // over payload
  467.         }
  468.         if( !tk->p_es )
  469.         {
  470.             i_skip += i_payload_data_length;
  471.             continue;
  472.         }
  473.         for( i_payload_data_pos = 0;
  474.              i_payload_data_pos < i_payload_data_length &&
  475.                     i_packet_size_left > 0;
  476.              i_payload_data_pos += i_sub_payload_data_length )
  477.         {
  478.             block_t *p_frag;
  479.             int i_read;
  480.             // read sub payload length
  481.             if( i_replicated_data_length == 1 )
  482.             {
  483.                 i_sub_payload_data_length = p_peek[i_skip]; i_skip++;
  484.                 i_payload_data_pos++;
  485.             }
  486.             else
  487.             {
  488.                 i_sub_payload_data_length = i_payload_data_length;
  489.             }
  490.             /* FIXME I don't use i_media_object_number, sould I ? */
  491.             if( tk->p_frame && i_media_object_offset == 0 )
  492.             {
  493.                 /* send complete packet to decoder */
  494.                 block_t *p_gather = block_ChainGather( tk->p_frame );
  495.                 tk->i_time = p_gather->i_dts;
  496.                 if( p_sys->i_time < 0 )
  497.                     es_out_Control( p_demux->out, ES_OUT_SET_PCR, tk->i_time+1 );
  498.                 es_out_Send( p_demux->out, tk->p_es, p_gather );
  499.                 tk->p_frame = NULL;
  500.             }
  501.             i_read = i_sub_payload_data_length + i_skip;
  502.             if( ( p_frag = stream_Block( p_demux->s, i_read ) ) == NULL )
  503.             {
  504.                 msg_Warn( p_demux, "cannot read data" );
  505.                 return 0;
  506.             }
  507.             i_packet_size_left -= i_read;
  508.             p_frag->p_buffer += i_skip;
  509.             p_frag->i_buffer -= i_skip;
  510.             if( tk->p_frame == NULL )
  511.             {
  512.                 p_frag->i_pts = i_pts + i_payload * (mtime_t)i_pts_delta;
  513.                 if( tk->i_cat != VIDEO_ES )
  514.                     p_frag->i_dts = p_frag->i_pts;
  515.                 else
  516.                 {
  517.                     p_frag->i_dts = p_frag->i_pts;
  518.                     p_frag->i_pts = 0;
  519.                 }
  520.             }
  521.             block_ChainAppend( &tk->p_frame, p_frag );
  522.             i_skip = 0;
  523.             if( i_packet_size_left > 0 )
  524.             {
  525.                 if( stream_Peek( p_demux->s, &p_peek, i_packet_size_left )
  526.                                                          < i_packet_size_left )
  527.                 {
  528.                     msg_Warn( p_demux, "cannot peek, EOF ?" );
  529.                     return 0;
  530.                 }
  531.             }
  532.         }
  533.     }
  534.     if( i_packet_size_left > 0 )
  535.     {
  536. #ifdef ASF_DEBUG
  537.         if( i_packet_size_left > i_packet_padding_length )
  538.             msg_Warn( p_demux, "Didn't read %d bytes in the packet",
  539.                             i_packet_size_left - i_packet_padding_length );
  540.         else if( i_packet_size_left < i_packet_padding_length )
  541.             msg_Warn( p_demux, "Read %d too much bytes in the packet",
  542.                             i_packet_padding_length - i_packet_size_left );
  543. #endif
  544.         if( stream_Read( p_demux->s, NULL, i_packet_size_left )
  545.                                                          < i_packet_size_left )
  546.         {
  547.             msg_Err( p_demux, "cannot skip data, EOF ?" );
  548.             return 0;
  549.         }
  550.     }
  551.     return 1;
  552. loop_error_recovery:
  553.     msg_Warn( p_demux, "unsupported packet header" );
  554.     if( p_sys->p_fp->i_min_data_packet_size != p_sys->p_fp->i_max_data_packet_size )
  555.     {
  556.         msg_Err( p_demux, "unsupported packet header, fatal error" );
  557.         return -1;
  558.     }
  559.     if( stream_Read( p_demux->s, NULL, i_data_packet_min ) != i_data_packet_min )
  560.     {
  561.         msg_Warn( p_demux, "cannot skip data, EOF ?" );
  562.         return 0;
  563.     }
  564.     return 1;
  565. }
  566. /*****************************************************************************
  567.  *
  568.  *****************************************************************************/
  569. static int DemuxInit( demux_t *p_demux )
  570. {
  571.     demux_sys_t *p_sys = p_demux->p_sys;
  572.     bool b_seekable;
  573.     unsigned int i_stream;
  574.     asf_object_content_description_t *p_cd;
  575.     asf_object_index_t *p_index;
  576.     bool b_index;
  577.     /* init context */
  578.     p_sys->i_time   = -1;
  579.     p_sys->i_length = 0;
  580.     p_sys->i_bitrate = 0;
  581.     p_sys->p_root   = NULL;
  582.     p_sys->p_fp     = NULL;
  583.     p_sys->b_index  = 0;
  584.     p_sys->i_track  = 0;
  585.     for( int i = 0; i < 128; i++ )
  586.     {
  587.         p_sys->track[i] = NULL;
  588.     }
  589.     p_sys->i_data_begin = -1;
  590.     p_sys->i_data_end   = -1;
  591.     p_sys->meta         = NULL;
  592.     /* Now load all object ( except raw data ) */
  593.     stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b_seekable );
  594.     if( !(p_sys->p_root = ASF_ReadObjectRoot(p_demux->s, b_seekable)) )
  595.     {
  596.         msg_Warn( p_demux, "ASF plugin discarded (not a valid file)" );
  597.         return VLC_EGENERIC;
  598.     }
  599.     p_sys->p_fp = p_sys->p_root->p_fp;
  600.     if( p_sys->p_fp->i_min_data_packet_size != p_sys->p_fp->i_max_data_packet_size )
  601.     {
  602.         msg_Warn( p_demux, "ASF plugin discarded (invalid file_properties object)" );
  603.         goto error;
  604.     }
  605.     p_sys->i_track = ASF_CountObject( p_sys->p_root->p_hdr,
  606.                                       &asf_object_stream_properties_guid );
  607.     if( p_sys->i_track <= 0 )
  608.     {
  609.         msg_Warn( p_demux, "ASF plugin discarded (cannot find any stream!)" );
  610.         goto error;
  611.     }
  612.     /* check if index is available */
  613.     p_index = ASF_FindObject( p_sys->p_root, &asf_object_index_guid, 0 );
  614.     b_index = p_index && p_index->i_index_entry_count;
  615.     msg_Dbg( p_demux, "found %d streams", p_sys->i_track );
  616.     for( i_stream = 0; i_stream < p_sys->i_track; i_stream ++ )
  617.     {
  618.         asf_track_t    *tk;
  619.         asf_object_stream_properties_t *p_sp;
  620.         asf_object_extended_stream_properties_t *p_esp;
  621.         asf_object_t *p_hdr_ext;
  622.         bool b_access_selected;
  623.         p_sp = ASF_FindObject( p_sys->p_root->p_hdr,
  624.                                &asf_object_stream_properties_guid,
  625.                                i_stream );
  626.         p_esp = NULL;
  627.         tk = p_sys->track[p_sp->i_stream_number] = malloc( sizeof( asf_track_t ) );
  628.         memset( tk, 0, sizeof( asf_track_t ) );
  629.         tk->i_time = -1;
  630.         tk->p_sp = p_sp;
  631.         tk->p_es = NULL;
  632.         tk->p_frame = NULL;
  633.         /* Check (in case of mms) if this track is selected (ie will receive data) */
  634.         if( !stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_GET_PRIVATE_ID_STATE,
  635.                              p_sp->i_stream_number, &b_access_selected ) &&
  636.             !b_access_selected )
  637.         {
  638.             tk->i_cat = UNKNOWN_ES;
  639.             msg_Dbg( p_demux, "ignoring not selected stream(ID:%d) (by access)",
  640.                      p_sp->i_stream_number );
  641.             continue;
  642.         }
  643.         /* Find the associated extended_stream_properties if any */
  644.         p_hdr_ext = ASF_FindObject( p_sys->p_root->p_hdr,
  645.                                     &asf_object_header_extension_guid, 0 );
  646.         if( p_hdr_ext )
  647.         {
  648.             int i_ext_stream = ASF_CountObject( p_hdr_ext,
  649.                                                 &asf_object_extended_stream_properties );
  650.             for( int i = 0; i < i_ext_stream; i++ )
  651.             {
  652.                 asf_object_t *p_tmp =
  653.                     ASF_FindObject( p_hdr_ext,
  654.                                     &asf_object_extended_stream_properties, i );
  655.                 if( p_tmp->ext_stream.i_stream_number == p_sp->i_stream_number )
  656.                 {
  657.                     p_esp = &p_tmp->ext_stream;
  658.                     break;
  659.                 }
  660.             }
  661.         }
  662.         if( ASF_CmpGUID( &p_sp->i_stream_type, &asf_object_stream_type_audio ) &&
  663.             p_sp->i_type_specific_data_length >= sizeof( WAVEFORMATEX ) - 2 )
  664.         {
  665.             es_format_t fmt;
  666.             uint8_t *p_data = p_sp->p_type_specific_data;
  667.             int i_format;
  668.             es_format_Init( &fmt, AUDIO_ES, 0 );
  669.             i_format = GetWLE( &p_data[0] );
  670.             wf_tag_to_fourcc( i_format, &fmt.i_codec, NULL );
  671.             fmt.audio.i_channels        = GetWLE(  &p_data[2] );
  672.             fmt.audio.i_rate      = GetDWLE( &p_data[4] );
  673.             fmt.i_bitrate         = GetDWLE( &p_data[8] ) * 8;
  674.             fmt.audio.i_blockalign      = GetWLE(  &p_data[12] );
  675.             fmt.audio.i_bitspersample   = GetWLE(  &p_data[14] );
  676.             if( p_sp->i_type_specific_data_length > sizeof( WAVEFORMATEX ) &&
  677.                 i_format != WAVE_FORMAT_MPEGLAYER3 &&
  678.                 i_format != WAVE_FORMAT_MPEG )
  679.             {
  680.                 fmt.i_extra = __MIN( GetWLE( &p_data[16] ),
  681.                                      p_sp->i_type_specific_data_length -
  682.                                      sizeof( WAVEFORMATEX ) );
  683.                 fmt.p_extra = malloc( fmt.i_extra );
  684.                 memcpy( fmt.p_extra, &p_data[sizeof( WAVEFORMATEX )],
  685.                         fmt.i_extra );
  686.             }
  687.             tk->i_cat = AUDIO_ES;
  688.             tk->p_es = es_out_Add( p_demux->out, &fmt );
  689.             es_format_Clean( &fmt );
  690.             msg_Dbg( p_demux, "added new audio stream(codec:0x%x,ID:%d)",
  691.                     GetWLE( p_data ), p_sp->i_stream_number );
  692.         }
  693.         else if( ASF_CmpGUID( &p_sp->i_stream_type,
  694.                               &asf_object_stream_type_video ) &&
  695.                  p_sp->i_type_specific_data_length >= 11 +
  696.                  sizeof( BITMAPINFOHEADER ) )
  697.         {
  698.             es_format_t  fmt;
  699.             uint8_t      *p_data = &p_sp->p_type_specific_data[11];
  700.             es_format_Init( &fmt, VIDEO_ES,
  701.                             VLC_FOURCC( p_data[16], p_data[17],
  702.                                         p_data[18], p_data[19] ) );
  703.             fmt.video.i_width = GetDWLE( p_data + 4 );
  704.             fmt.video.i_height= GetDWLE( p_data + 8 );
  705.             if( p_esp && p_esp->i_average_time_per_frame > 0 )
  706.             {
  707.                 fmt.video.i_frame_rate = 10000000;
  708.                 fmt.video.i_frame_rate_base = p_esp->i_average_time_per_frame;
  709.             }
  710.             if( fmt.i_codec == VLC_FOURCC( 'D','V','R',' ') )
  711.             {
  712.                 /* DVR-MS special ASF */
  713.                 fmt.i_codec = VLC_FOURCC( 'm','p','g','2' ) ;
  714.                 fmt.b_packetized = false;
  715.             }
  716.             if( p_sp->i_type_specific_data_length > 11 +
  717.                 sizeof( BITMAPINFOHEADER ) )
  718.             {
  719.                 fmt.i_extra = __MIN( GetDWLE( p_data ),
  720.                                      p_sp->i_type_specific_data_length - 11 -
  721.                                      sizeof( BITMAPINFOHEADER ) );
  722.                 fmt.p_extra = malloc( fmt.i_extra );
  723.                 memcpy( fmt.p_extra, &p_data[sizeof( BITMAPINFOHEADER )],
  724.                         fmt.i_extra );
  725.             }
  726.             /* Look for an aspect ratio */
  727.             if( p_sys->p_root->p_metadata )
  728.             {
  729.                 asf_object_metadata_t *p_meta = p_sys->p_root->p_metadata;
  730.                 int i_aspect_x = 0, i_aspect_y = 0;
  731.                 unsigned int i;
  732.                 for( i = 0; i < p_meta->i_record_entries_count; i++ )
  733.                 {
  734.                     if( !strcmp( p_meta->record[i].psz_name, "AspectRatioX" ) )
  735.                     {
  736.                         if( (!i_aspect_x && !p_meta->record[i].i_stream) ||
  737.                             p_meta->record[i].i_stream ==
  738.                             p_sp->i_stream_number )
  739.                             i_aspect_x = p_meta->record[i].i_val;
  740.                     }
  741.                     if( !strcmp( p_meta->record[i].psz_name, "AspectRatioY" ) )
  742.                     {
  743.                         if( (!i_aspect_y && !p_meta->record[i].i_stream) ||
  744.                             p_meta->record[i].i_stream ==
  745.                             p_sp->i_stream_number )
  746.                             i_aspect_y = p_meta->record[i].i_val;
  747.                     }
  748.                 }
  749.                 if( i_aspect_x && i_aspect_y )
  750.                 {
  751.                     fmt.video.i_aspect = i_aspect_x *
  752.                         (int64_t)fmt.video.i_width * VOUT_ASPECT_FACTOR /
  753.                         fmt.video.i_height / i_aspect_y;
  754.                 }
  755.             }
  756.             tk->i_cat = VIDEO_ES;
  757.             tk->p_es = es_out_Add( p_demux->out, &fmt );
  758.             es_format_Clean( &fmt );
  759.             /* If there is a video track then use the index for seeking */
  760.             p_sys->b_index = b_index;
  761.             msg_Dbg( p_demux, "added new video stream(ID:%d)",
  762.                      p_sp->i_stream_number );
  763.         }
  764.         else if( ASF_CmpGUID( &p_sp->i_stream_type, &asf_object_extended_stream_header ) &&
  765.             p_sp->i_type_specific_data_length >= 64 )
  766.         {
  767.             /* Now follows a 64 byte header of which we don't know much */
  768.             es_format_t fmt;
  769.             guid_t  *p_ref  = (guid_t *)p_sp->p_type_specific_data;
  770.             uint8_t *p_data = p_sp->p_type_specific_data + 64;
  771.             unsigned int i_data = p_sp->i_type_specific_data_length - 64;
  772.             msg_Dbg( p_demux, "Ext stream header detected. datasize = %d", p_sp->i_type_specific_data_length );
  773.             if( ASF_CmpGUID( p_ref, &asf_object_extended_stream_type_audio ) &&
  774.                 i_data >= sizeof( WAVEFORMATEX ) - 2)
  775.             {
  776.                 int      i_format;
  777.                 es_format_Init( &fmt, AUDIO_ES, 0 );
  778.                 i_format = GetWLE( &p_data[0] );
  779.                 if( i_format == 0 )
  780.                     fmt.i_codec = VLC_FOURCC( 'a','5','2',' ');
  781.                 else
  782.                     wf_tag_to_fourcc( i_format, &fmt.i_codec, NULL );
  783.                 fmt.audio.i_channels        = GetWLE(  &p_data[2] );
  784.                 fmt.audio.i_rate      = GetDWLE( &p_data[4] );
  785.                 fmt.i_bitrate         = GetDWLE( &p_data[8] ) * 8;
  786.                 fmt.audio.i_blockalign      = GetWLE(  &p_data[12] );
  787.                 fmt.audio.i_bitspersample   = GetWLE(  &p_data[14] );
  788.                 fmt.b_packetized = true;
  789.                 if( p_sp->i_type_specific_data_length > sizeof( WAVEFORMATEX ) &&
  790.                     i_format != WAVE_FORMAT_MPEGLAYER3 &&
  791.                     i_format != WAVE_FORMAT_MPEG )
  792.                 {
  793.                     fmt.i_extra = __MIN( GetWLE( &p_data[16] ),
  794.                                          p_sp->i_type_specific_data_length -
  795.                                          sizeof( WAVEFORMATEX ) );
  796.                     fmt.p_extra = malloc( fmt.i_extra );
  797.                     memcpy( fmt.p_extra, &p_data[sizeof( WAVEFORMATEX )],
  798.                         fmt.i_extra );
  799.                 }
  800.                 tk->i_cat = AUDIO_ES;
  801.                 tk->p_es = es_out_Add( p_demux->out, &fmt );
  802.                 es_format_Clean( &fmt );
  803.                 msg_Dbg( p_demux, "added new audio stream (codec:0x%x,ID:%d)",
  804.                     i_format, p_sp->i_stream_number );
  805.             }
  806.         }
  807.         else
  808.         {
  809.             tk->i_cat = UNKNOWN_ES;
  810.             msg_Dbg( p_demux, "ignoring unknown stream(ID:%d)",
  811.                      p_sp->i_stream_number );
  812.         }
  813.     }
  814.     p_sys->i_data_begin = p_sys->p_root->p_data->i_object_pos + 50;
  815.     if( p_sys->p_root->p_data->i_object_size != 0 )
  816.     { /* local file */
  817.         p_sys->i_data_end = p_sys->p_root->p_data->i_object_pos +
  818.                                     p_sys->p_root->p_data->i_object_size;
  819.     }
  820.     else
  821.     { /* live/broacast */
  822.         p_sys->i_data_end = -1;
  823.     }
  824.     /* go to first packet */
  825.     stream_Seek( p_demux->s, p_sys->i_data_begin );
  826.     /* try to calculate movie time */
  827.     if( p_sys->p_fp->i_data_packets_count > 0 )
  828.     {
  829.         int64_t i_count;
  830.         int64_t i_size = stream_Size( p_demux->s );
  831.         if( p_sys->i_data_end > 0 && i_size > p_sys->i_data_end )
  832.         {
  833.             i_size = p_sys->i_data_end;
  834.         }
  835.         /* real number of packets */
  836.         i_count = ( i_size - p_sys->i_data_begin ) /
  837.                   p_sys->p_fp->i_min_data_packet_size;
  838.         /* calculate the time duration in micro-s */
  839.         p_sys->i_length = (mtime_t)p_sys->p_fp->i_play_duration / 10 *
  840.                    (mtime_t)i_count /
  841.                    (mtime_t)p_sys->p_fp->i_data_packets_count;
  842.         if( p_sys->i_length > 0 )
  843.         {
  844.             p_sys->i_bitrate = 8 * i_size * (int64_t)1000000 / p_sys->i_length;
  845.         }
  846.     }
  847.     /* Create meta information */
  848.     p_sys->meta = vlc_meta_New();
  849.     if( ( p_cd = ASF_FindObject( p_sys->p_root->p_hdr,
  850.                                  &asf_object_content_description_guid, 0 ) ) )
  851.     {
  852.         if( p_cd->psz_title && *p_cd->psz_title )
  853.         {
  854.             vlc_meta_SetTitle( p_sys->meta, p_cd->psz_title );
  855.         }
  856.         if( p_cd->psz_artist && *p_cd->psz_artist )
  857.         {
  858.              vlc_meta_SetArtist( p_sys->meta, p_cd->psz_artist );
  859.         }
  860.         if( p_cd->psz_copyright && *p_cd->psz_copyright )
  861.         {
  862.             vlc_meta_SetCopyright( p_sys->meta, p_cd->psz_copyright );
  863.         }
  864.         if( p_cd->psz_description && *p_cd->psz_description )
  865.         {
  866.             vlc_meta_SetDescription( p_sys->meta, p_cd->psz_description );
  867.         }
  868.         if( p_cd->psz_rating && *p_cd->psz_rating )
  869.         {
  870.             vlc_meta_SetRating( p_sys->meta, p_cd->psz_rating );
  871.         }
  872.     }
  873.     /// tood Fix Child meta for ASF tracks
  874. #if 0
  875.     for( i_stream = 0, i = 0; i < 128; i++ )
  876.     {
  877.         asf_object_codec_list_t *p_cl = ASF_FindObject( p_sys->p_root->p_hdr,
  878.                                                         &asf_object_codec_list_guid, 0 );
  879.         if( p_sys->track[i] )
  880.         {
  881.             vlc_meta_t *tk = vlc_meta_New();
  882.             TAB_APPEND( p_sys->meta->i_track, p_sys->meta->track, tk );
  883.             if( p_cl && i_stream < p_cl->i_codec_entries_count )
  884.             {
  885.                 if( p_cl->codec[i_stream].psz_name &&
  886.                     *p_cl->codec[i_stream].psz_name )
  887.                 {
  888.                     vlc_meta_Add( tk, VLC_META_CODEC_NAME,
  889.                                   p_cl->codec[i_stream].psz_name );
  890.                 }
  891.                 if( p_cl->codec[i_stream].psz_description &&
  892.                     *p_cl->codec[i_stream].psz_description )
  893.                 {
  894.                     vlc_meta_Add( tk, VLC_META_CODEC_DESCRIPTION,
  895.                                   p_cl->codec[i_stream].psz_description );
  896.                 }
  897.             }
  898.             i_stream++;
  899.         }
  900.     }
  901. #endif
  902.     return VLC_SUCCESS;
  903. error:
  904.     ASF_FreeObjectRoot( p_demux->s, p_sys->p_root );
  905.     return VLC_EGENERIC;
  906. }
  907. /*****************************************************************************
  908.  *
  909.  *****************************************************************************/
  910. static void DemuxEnd( demux_t *p_demux )
  911. {
  912.     demux_sys_t *p_sys = p_demux->p_sys;
  913.     int         i;
  914.     if( p_sys->p_root )
  915.     {
  916.         ASF_FreeObjectRoot( p_demux->s, p_sys->p_root );
  917.         p_sys->p_root = NULL;
  918.     }
  919.     if( p_sys->meta )
  920.     {
  921.         vlc_meta_Delete( p_sys->meta );
  922.         p_sys->meta = NULL;
  923.     }
  924.     for( i = 0; i < 128; i++ )
  925.     {
  926.         asf_track_t *tk = p_sys->track[i];
  927.         if( tk )
  928.         {
  929.             if( tk->p_frame )
  930.             {
  931.                 block_ChainRelease( tk->p_frame );
  932.             }
  933.             if( tk->p_es )
  934.             {
  935.                 es_out_Del( p_demux->out, tk->p_es );
  936.             }
  937.             free( tk );
  938.         }
  939.         p_sys->track[i] = 0;
  940.     }
  941. }