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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mpc.c : MPC stream input module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2001 the VideoLAN team
  5.  * $Id: 374bb53dd3d9f2408ecd45778ab84400563d6042 $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr.com>
  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_input.h>
  33. #include <vlc_codec.h>
  34. #include <math.h>
  35. #ifdef HAVE_MPC_MPCDEC_H
  36. #include <mpc/mpcdec.h>
  37. #else
  38. #include <mpcdec/mpcdec.h>
  39. #endif
  40. /* TODO:
  41.  *  - test stream version 4..6
  42.  *  - test fixed float version
  43.  *  - ...
  44.  *
  45.  *  XXX:
  46.  *  It is done the ugly way (the demux does the decode stage... but it works
  47.  */
  48. /*****************************************************************************
  49.  * Module descriptor
  50.  *****************************************************************************/
  51. static int  Open  ( vlc_object_t * );
  52. static void Close ( vlc_object_t * );
  53. vlc_module_begin ()
  54.     set_category( CAT_INPUT )
  55.     set_subcategory( SUBCAT_INPUT_DEMUX )
  56.     set_description( N_("MusePack demuxer") )
  57.     set_capability( "demux", 145 )
  58.     set_callbacks( Open, Close )
  59.     add_shortcut( "mpc" )
  60. vlc_module_end ()
  61. /*****************************************************************************
  62.  * Local prototypes
  63.  *****************************************************************************/
  64. static int Demux  ( demux_t * );
  65. static int Control( demux_t *, int, va_list );
  66. struct demux_sys_t
  67. {
  68.     /* */
  69.     es_out_id_t   *p_es;
  70.     /* */
  71. #ifndef HAVE_MPC_MPCDEC_H
  72.     mpc_decoder    decoder;
  73. #else
  74.     mpc_demux     *decoder;
  75. #endif
  76.     mpc_reader     reader;
  77.     mpc_streaminfo info;
  78.     /* */
  79.     int64_t        i_position;
  80. };
  81. #ifndef HAVE_MPC_MPCDEC_H
  82. static mpc_int32_t ReaderRead( void *p_private, void *dst, mpc_int32_t i_size );
  83. static mpc_bool_t  ReaderSeek( void *p_private, mpc_int32_t i_offset );
  84. static mpc_int32_t ReaderTell( void *p_private);
  85. static mpc_int32_t ReaderGetSize( void *p_private );
  86. static mpc_bool_t  ReaderCanSeek( void *p_private );
  87. #else
  88. static mpc_int32_t ReaderRead( mpc_reader *p_private, void *dst, mpc_int32_t i_size );
  89. static mpc_bool_t  ReaderSeek( mpc_reader *p_private, mpc_int32_t i_offset );
  90. static mpc_int32_t ReaderTell( mpc_reader *p_private);
  91. static mpc_int32_t ReaderGetSize( mpc_reader *p_private );
  92. static mpc_bool_t  ReaderCanSeek( mpc_reader *p_private );
  93. #endif
  94. /*****************************************************************************
  95.  * Open: initializes ES structures
  96.  *****************************************************************************/
  97. static int Open( vlc_object_t * p_this )
  98. {
  99.     demux_t     *p_demux = (demux_t*)p_this;
  100.     demux_sys_t *p_sys;
  101.     es_format_t fmt;
  102.     const uint8_t *p_peek;
  103.     if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 )
  104.         return VLC_EGENERIC;
  105.     if( memcmp( p_peek, "MP+", 3 )
  106. #ifdef HAVE_MPC_MPCDEC_H
  107.         /* SV8 format */
  108.         && memcmp( p_peek, "MPCK", 4 )
  109. #endif
  110.       )
  111.     {
  112.         /* for v4..6 we check extension file */
  113.         const int i_version = (GetDWLE( p_peek ) >> 11)&0x3ff;
  114.         if( i_version  < 4 || i_version > 6 )
  115.             return VLC_EGENERIC;
  116.         if( !p_demux->b_force )
  117.         {
  118.             /* Check file name extension */
  119.             if( !demux_IsPathExtension( p_demux, ".mpc" ) &&
  120.                 !demux_IsPathExtension( p_demux, ".mp+" ) &&
  121.                 !demux_IsPathExtension( p_demux, ".mpp" ) )
  122.                 return VLC_EGENERIC;
  123.         }
  124.     }
  125.     /* */
  126.     p_sys = calloc( 1, sizeof( *p_sys ) );
  127.     if( !p_sys )
  128.         return VLC_ENOMEM;
  129.     p_sys->i_position = 0;
  130.     p_sys->reader.read = ReaderRead;
  131.     p_sys->reader.seek = ReaderSeek;
  132.     p_sys->reader.tell = ReaderTell;
  133.     p_sys->reader.get_size = ReaderGetSize;
  134.     p_sys->reader.canseek = ReaderCanSeek;
  135.     p_sys->reader.data = p_demux;
  136. #ifndef HAVE_MPC_MPCDEC_H
  137.     /* Load info */
  138.     mpc_streaminfo_init( &p_sys->info );
  139.     if( mpc_streaminfo_read( &p_sys->info, &p_sys->reader ) != ERROR_CODE_OK )
  140.         goto error;
  141.     /* */
  142.     mpc_decoder_setup( &p_sys->decoder, &p_sys->reader );
  143.     if( !mpc_decoder_initialize( &p_sys->decoder, &p_sys->info ) )
  144.         goto error;
  145. #else
  146.     p_sys->decoder = mpc_demux_init( &p_sys->reader );
  147.     if( !p_sys->decoder )
  148.         goto error;
  149.     mpc_demux_get_info( p_sys->decoder, &p_sys->info );
  150. #endif
  151.     /* Fill p_demux fields */
  152.     p_demux->pf_demux = Demux;
  153.     p_demux->pf_control = Control;
  154.     p_demux->p_sys = p_sys;
  155.     /* */
  156. #ifndef MPC_FIXED_POINT
  157.     es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'f', 'l', '3', '2' ) );
  158. #else
  159. #   ifdef WORDS_BIGENDIAN
  160.     es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 's', '3', '2', 'b' ) );
  161. #   else
  162.     es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 's', '3', '2', 'l' ) );
  163. #   endif
  164. #endif
  165.     fmt.audio.i_channels = p_sys->info.channels;
  166.     fmt.audio.i_rate = p_sys->info.sample_freq;
  167.     fmt.audio.i_blockalign = 4*fmt.audio.i_channels;
  168.     fmt.audio.i_bitspersample = 32;
  169.     fmt.i_bitrate = fmt.i_bitrate * fmt.audio.i_channels *
  170.                     fmt.audio.i_bitspersample;
  171.     if( p_sys->info.peak_title > 0 )
  172.     {
  173.         fmt.audio_replay_gain.pb_peak[AUDIO_REPLAY_GAIN_TRACK] = true;
  174.         fmt.audio_replay_gain.pf_peak[AUDIO_REPLAY_GAIN_TRACK] = (float)p_sys->info.peak_title / 32767.0;
  175.         fmt.audio_replay_gain.pb_gain[AUDIO_REPLAY_GAIN_TRACK] = true;
  176.         fmt.audio_replay_gain.pf_gain[AUDIO_REPLAY_GAIN_TRACK] = (float)p_sys->info.gain_title / 100.0;
  177.     }
  178.     if( p_sys->info.peak_album > 0 )
  179.     {
  180.         fmt.audio_replay_gain.pb_peak[AUDIO_REPLAY_GAIN_ALBUM] = true;
  181.         fmt.audio_replay_gain.pf_peak[AUDIO_REPLAY_GAIN_ALBUM] = (float)p_sys->info.peak_album / 32767.0;
  182.         fmt.audio_replay_gain.pb_gain[AUDIO_REPLAY_GAIN_ALBUM] = true;
  183.         fmt.audio_replay_gain.pf_gain[AUDIO_REPLAY_GAIN_ALBUM] = (float)p_sys->info.gain_album / 100.0;
  184.     }
  185.     p_sys->p_es = es_out_Add( p_demux->out, &fmt );
  186.     if( !p_sys->p_es )
  187.         goto error;
  188.     return VLC_SUCCESS;
  189. error:
  190.     free( p_sys );
  191.     return VLC_EGENERIC;
  192. }
  193. /*****************************************************************************
  194.  * Close: frees unused data
  195.  *****************************************************************************/
  196. static void Close( vlc_object_t * p_this )
  197. {
  198.     demux_t        *p_demux = (demux_t*)p_this;
  199.     demux_sys_t    *p_sys = p_demux->p_sys;
  200. #ifdef HAVE_MPC_MPCDEC_H
  201.     if( p_sys->decoder )
  202.     mpc_demux_exit( p_sys->decoder );
  203. #endif
  204.     free( p_sys );
  205. }
  206. /*****************************************************************************
  207.  * Demux:
  208.  *****************************************************************************
  209.  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
  210.  *****************************************************************************/
  211. static int Demux( demux_t *p_demux )
  212. {
  213.     demux_sys_t *p_sys = p_demux->p_sys;
  214.     block_t     *p_data;
  215.     int i_ret;
  216. #ifdef HAVE_MPC_MPCDEC_H
  217.     mpc_frame_info frame;
  218.     mpc_status err;
  219. #endif
  220.     p_data = block_New( p_demux,
  221.                         MPC_DECODER_BUFFER_LENGTH*sizeof(MPC_SAMPLE_FORMAT) );
  222.     if( !p_data )
  223.         return -1;
  224. #ifndef HAVE_MPC_MPCDEC_H
  225.     i_ret = mpc_decoder_decode( &p_sys->decoder,
  226.                                 (MPC_SAMPLE_FORMAT*)p_data->p_buffer,
  227.                                 NULL, NULL );
  228.     if( i_ret <= 0 )
  229.     {
  230.         block_Release( p_data );
  231.         return i_ret < 0 ? -1 : 0;
  232.     }
  233. #else
  234.     frame.buffer = (MPC_SAMPLE_FORMAT*)p_data->p_buffer;
  235.     err = mpc_demux_decode( p_sys->decoder, &frame );
  236.     if( err != MPC_STATUS_OK )
  237.     {
  238.         block_Release( p_data );
  239.         return -1;
  240.     }
  241.     else if( frame.bits == -1 )
  242.     {
  243.         block_Release( p_data );
  244.         return 0;
  245.     }
  246.     i_ret = frame.samples;
  247. #endif
  248.     /* */
  249.     p_data->i_buffer = i_ret * sizeof(MPC_SAMPLE_FORMAT) * p_sys->info.channels;
  250.     p_data->i_dts = p_data->i_pts =
  251.             1 + INT64_C(1000000) * p_sys->i_position / p_sys->info.sample_freq;
  252.     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_data->i_dts );
  253.     es_out_Send( p_demux->out, p_sys->p_es, p_data );
  254.     /* */
  255.     p_sys->i_position += i_ret;
  256.     return 1;
  257. }
  258. /*****************************************************************************
  259.  * Control:
  260.  *****************************************************************************/
  261. static int Control( demux_t *p_demux, int i_query, va_list args )
  262. {
  263.     demux_sys_t *p_sys = p_demux->p_sys;
  264.     double   f, *pf;
  265.     int64_t i64, *pi64;
  266.     bool *pb_bool;
  267.     switch( i_query )
  268.     {
  269.         case DEMUX_HAS_UNSUPPORTED_META:
  270.             pb_bool = (bool*)va_arg( args, bool* );
  271.             *pb_bool = true;
  272.             return VLC_SUCCESS;
  273.         case DEMUX_GET_LENGTH:
  274.             pi64 = (int64_t*)va_arg( args, int64_t * );
  275. #ifndef HAVE_MPC_MPCDEC_H
  276.             *pi64 = INT64_C(1000000) * p_sys->info.pcm_samples /
  277.                         p_sys->info.sample_freq;
  278. #else
  279.             *pi64 = INT64_C(1000000) * (p_sys->info.samples -
  280.                                         p_sys->info.beg_silence) /
  281.                 p_sys->info.sample_freq;
  282. #endif
  283.             return VLC_SUCCESS;
  284.         case DEMUX_GET_POSITION:
  285.             pf = (double*)va_arg( args, double * );
  286. #ifndef HAVE_MPC_MPCDEC_H
  287.             if( p_sys->info.pcm_samples > 0 )
  288.                 *pf = (double) p_sys->i_position /
  289.                       (double)p_sys->info.pcm_samples;
  290. #else
  291.             if( p_sys->info.samples - p_sys->info.beg_silence > 0)
  292.                 *pf = (double) p_sys->i_position /
  293.                       (double)(p_sys->info.samples - p_sys->info.beg_silence);
  294. #endif
  295.             else
  296.                 *pf = 0.0;
  297.             return VLC_SUCCESS;
  298.         case DEMUX_GET_TIME:
  299.             pi64 = (int64_t*)va_arg( args, int64_t * );
  300.             *pi64 = INT64_C(1000000) * p_sys->i_position /
  301.                         p_sys->info.sample_freq;
  302.             return VLC_SUCCESS;
  303.         case DEMUX_SET_POSITION:
  304.             f = (double)va_arg( args, double );
  305. #ifndef HAVE_MPC_MPCDEC_H
  306.             i64 = (int64_t)(f * p_sys->info.pcm_samples);
  307.             if( mpc_decoder_seek_sample( &p_sys->decoder, i64 ) )
  308. #else
  309.             i64 = (int64_t)(f * (p_sys->info.samples -
  310.                                  p_sys->info.beg_silence));
  311.             if( mpc_demux_seek_sample( p_sys->decoder, i64 ) == MPC_STATUS_OK )
  312. #endif
  313.             {
  314.                 p_sys->i_position = i64;
  315.                 return VLC_SUCCESS;
  316.             }
  317.             return VLC_EGENERIC;
  318.         case DEMUX_SET_TIME:
  319.             i64 = (int64_t)va_arg( args, int64_t );
  320. #ifndef HAVE_MPC_MPCDEC_H
  321.             if( mpc_decoder_seek_sample( &p_sys->decoder, i64 ) )
  322. #else
  323.              if( mpc_demux_seek_sample( p_sys->decoder, i64 ) == MPC_STATUS_OK )
  324. #endif
  325.             {
  326.                 p_sys->i_position = i64;
  327.                 return VLC_SUCCESS;
  328.             }
  329.             return VLC_EGENERIC;
  330.         default:
  331.             return VLC_EGENERIC;
  332.     }
  333. }
  334. #ifndef HAVE_MPC_MPCDEC_H
  335. static mpc_int32_t ReaderRead( void *p_private, void *dst, mpc_int32_t i_size )
  336. {
  337.     demux_t *p_demux = (demux_t*)p_private;
  338. #else
  339. static mpc_int32_t ReaderRead( mpc_reader *p_private, void *dst, mpc_int32_t i_size )
  340. {
  341.     demux_t *p_demux = (demux_t*)p_private->data;
  342. #endif
  343.     return stream_Read( p_demux->s, dst, i_size );
  344. }
  345. #ifndef HAVE_MPC_MPCDEC_H
  346. static mpc_bool_t ReaderSeek( void *p_private, mpc_int32_t i_offset )
  347. {
  348.     demux_t *p_demux = (demux_t*)p_private;
  349. #else
  350. static mpc_bool_t ReaderSeek( mpc_reader *p_private, mpc_int32_t i_offset )
  351. {
  352.     demux_t *p_demux = (demux_t*)p_private->data;
  353. #endif
  354.     return !stream_Seek( p_demux->s, i_offset );
  355. }
  356. #ifndef HAVE_MPC_MPCDEC_H
  357. static mpc_int32_t ReaderTell( void *p_private)
  358. {
  359.     demux_t *p_demux = (demux_t*)p_private;
  360. #else
  361. static mpc_int32_t ReaderTell( mpc_reader *p_private)
  362. {
  363.     demux_t *p_demux = (demux_t*)p_private->data;
  364. #endif
  365.     return stream_Tell( p_demux->s );
  366. }
  367. #ifndef HAVE_MPC_MPCDEC_H
  368. static mpc_int32_t ReaderGetSize( void *p_private )
  369. {
  370.     demux_t *p_demux = (demux_t*)p_private;
  371. #else
  372. static mpc_int32_t ReaderGetSize( mpc_reader *p_private )
  373. {
  374.     demux_t *p_demux = (demux_t*)p_private->data;
  375. #endif
  376.     return stream_Size( p_demux->s );
  377. }
  378. #ifndef HAVE_MPC_MPCDEC_H
  379. static mpc_bool_t ReaderCanSeek( void *p_private )
  380. {
  381.     demux_t *p_demux = (demux_t*)p_private;
  382. #else
  383. static mpc_bool_t ReaderCanSeek( mpc_reader *p_private )
  384. {
  385.     demux_t *p_demux = (demux_t*)p_private->data;
  386. #endif
  387.     bool b_canseek;
  388.     stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
  389.     return b_canseek;
  390. }