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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * aes3.c: aes3 decoder/packetizer module
  3.  *****************************************************************************
  4.  * Copyright (C) 2008 the VideoLAN team
  5.  * $Id: 986fa787cd5923c81e965d47fa8e3980c96a0bee $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@videolan.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. /*****************************************************************************
  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_codec.h>
  32. #include <vlc_aout.h>
  33. #include <assert.h>
  34. /*****************************************************************************
  35.  * Module descriptor
  36.  *****************************************************************************/
  37. static int  OpenDecoder   ( vlc_object_t * );
  38. static int  OpenPacketizer( vlc_object_t * );
  39. static void Close         ( vlc_object_t * );
  40. vlc_module_begin ()
  41.     set_category( CAT_INPUT )
  42.     set_subcategory( SUBCAT_INPUT_ACODEC )
  43.     set_description( N_("AES3/SMPTE 302M audio decoder") )
  44.     set_capability( "decoder", 100 )
  45.     set_callbacks( OpenDecoder, Close )
  46.     add_submodule ()
  47.     set_description( N_("AES3/SMPTE 302M audio packetizer") )
  48.     set_capability( "packetizer", 100 )
  49.     set_callbacks( OpenPacketizer, Close )
  50. vlc_module_end ()
  51. /*****************************************************************************
  52.  * decoder_sys_t : aes3 decoder descriptor
  53.  *****************************************************************************/
  54. struct decoder_sys_t
  55. {
  56.     /*
  57.      * Output properties
  58.      */
  59.     audio_date_t end_date;
  60. };
  61. #define AES3_HEADER_LEN 4
  62. /*****************************************************************************
  63.  * Local prototypes
  64.  *****************************************************************************/
  65. static int Open( decoder_t *p_dec, bool b_packetizer );
  66. static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
  67.                        block_t **pp_block, bool b_packetizer );
  68. static inline uint8_t Reverse8( int n )
  69. {
  70.     n = ((n >> 1) & 0x55) | ((n << 1) & 0xaa);
  71.     n = ((n >> 2) & 0x33) | ((n << 2) & 0xcc);
  72.     n = ((n >> 4) & 0x0f) | ((n << 4) & 0xf0);
  73.     return n;
  74. }
  75. /*****************************************************************************
  76.  * OpenDecoder:
  77.  *****************************************************************************/
  78. static int OpenDecoder( vlc_object_t *p_this )
  79. {
  80.     decoder_t *p_dec = (decoder_t*)p_this;
  81.     return Open( p_dec, false );
  82. }
  83. /*****************************************************************************
  84.  * OpenPacketizer:
  85.  *****************************************************************************/
  86. static int OpenPacketizer( vlc_object_t *p_this )
  87. {
  88.     decoder_t *p_dec = (decoder_t*)p_this;
  89.     return Open( p_dec, true );
  90. }
  91. /*****************************************************************************
  92.  * Close : aes3 decoder destruction
  93.  *****************************************************************************/
  94. static void Close( vlc_object_t *p_this )
  95. {
  96.     decoder_t *p_dec = (decoder_t*)p_this;
  97.     free( p_dec->p_sys );
  98. }
  99. /*****************************************************************************
  100.  * Decode: decodes an aes3 frame.
  101.  ****************************************************************************
  102.  * Beware, this function must be fed with complete frames (PES packet).
  103.  *****************************************************************************/
  104. static aout_buffer_t *Decode( decoder_t *p_dec, block_t **pp_block )
  105. {
  106.     decoder_sys_t *p_sys = p_dec->p_sys;
  107.     block_t       *p_block;
  108.     aout_buffer_t *p_aout_buffer;
  109.     int            i_frame_length, i_bits;
  110.     p_block = Parse( p_dec, &i_frame_length, &i_bits, pp_block, false );
  111.     if( !p_block )
  112.         return NULL;
  113.     p_aout_buffer = decoder_NewAudioBuffer( p_dec, i_frame_length );
  114.     if( p_aout_buffer == NULL )
  115.         goto exit;
  116.     p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
  117.     p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_frame_length );
  118.     p_block->i_buffer -= AES3_HEADER_LEN;
  119.     p_block->p_buffer += AES3_HEADER_LEN;
  120.     if( i_bits == 24 )
  121.     {
  122.         uint8_t *p_out = p_aout_buffer->p_buffer;
  123.         while( p_block->i_buffer / 7 )
  124.         {
  125.             p_out[0] = Reverse8( p_block->p_buffer[0] );
  126.             p_out[1] = Reverse8( p_block->p_buffer[1] );
  127.             p_out[2] = Reverse8( p_block->p_buffer[2] );
  128.             p_out[3] = (Reverse8( p_block->p_buffer[3] ) >> 4) | ( (Reverse8( p_block->p_buffer[4] ) << 4) & 0xf0 );
  129.             p_out[4] = (Reverse8( p_block->p_buffer[4] ) >> 4) | ( (Reverse8( p_block->p_buffer[5] ) << 4) & 0xf0 );
  130.             p_out[5] = (Reverse8( p_block->p_buffer[5] ) >> 4) | ( (Reverse8( p_block->p_buffer[6] ) << 4) & 0xf0 );
  131.             p_block->i_buffer -= 7;
  132.             p_block->p_buffer += 7;
  133.             p_out += 6;
  134.         }
  135.     }
  136.     else if( i_bits == 20 )
  137.     {
  138.         uint8_t *p_out = p_aout_buffer->p_buffer;
  139.         while( p_block->i_buffer / 6 )
  140.         {
  141.             p_out[0] =                                            ( (Reverse8( p_block->p_buffer[0] ) << 4) & 0xf0 );
  142.             p_out[1] = ( Reverse8( p_block->p_buffer[0]) >> 4 ) | ( (Reverse8( p_block->p_buffer[1]) << 4 ) & 0xf0 );
  143.             p_out[2] = ( Reverse8( p_block->p_buffer[1]) >> 4 ) | ( (Reverse8( p_block->p_buffer[2]) << 4 ) & 0xf0 );
  144.             p_out[3] =                                            ( (Reverse8( p_block->p_buffer[3] ) << 4) & 0xf0 );
  145.             p_out[4] = ( Reverse8( p_block->p_buffer[3]) >> 4 ) | ( (Reverse8( p_block->p_buffer[4]) << 4 ) & 0xf0 );
  146.             p_out[5] = ( Reverse8( p_block->p_buffer[4]) >> 4 ) | ( (Reverse8( p_block->p_buffer[5]) << 4 ) & 0xf0 );
  147.             p_block->i_buffer -= 6;
  148.             p_block->p_buffer += 6;
  149.             p_out += 6;
  150.         }
  151.     }
  152.     else
  153.     {
  154.         uint8_t *p_out = p_aout_buffer->p_buffer;
  155.         assert( i_bits == 16 );
  156.         while( p_block->i_buffer / 5 )
  157.         {
  158.             p_out[0] = Reverse8( p_block->p_buffer[0] );
  159.             p_out[1] = Reverse8( p_block->p_buffer[1] );
  160.             p_out[2] = (Reverse8( p_block->p_buffer[2] ) >> 4) | ( (Reverse8( p_block->p_buffer[3] ) << 4) & 0xf0 );
  161.             p_out[3] = (Reverse8( p_block->p_buffer[3] ) >> 4) | ( (Reverse8( p_block->p_buffer[4] ) << 4) & 0xf0 );
  162.             p_block->i_buffer -= 5;
  163.             p_block->p_buffer += 5;
  164.             p_out += 4;
  165.         }
  166.     }
  167. exit:
  168.     block_Release( p_block );
  169.     return p_aout_buffer;
  170. }
  171. /*****************************************************************************
  172.  * Packetize: packetizes an aes3 frame.
  173.  ****************************************************************************
  174.  * Beware, this function must be fed with complete frames (PES packet).
  175.  *****************************************************************************/
  176. static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
  177. {
  178.     decoder_sys_t *p_sys = p_dec->p_sys;
  179.     block_t       *p_block;
  180.     int           i_frame_length, i_bits;
  181.     p_block = Parse( p_dec, &i_frame_length, &i_bits, pp_block, true );
  182.     if( !p_block )
  183.         return NULL;
  184.     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
  185.     p_block->i_length = aout_DateIncrement( &p_sys->end_date, i_frame_length ) - p_block->i_pts;
  186.     /* Just pass on the incoming frame */
  187.     return p_block;
  188. }
  189. /*****************************************************************************
  190.  *
  191.  ****************************************************************************/
  192. static int Open( decoder_t *p_dec, bool b_packetizer )
  193. {
  194.     decoder_sys_t *p_sys;
  195.     if( p_dec->fmt_in.i_codec != VLC_FOURCC('a','e','s','3') )
  196.         return VLC_EGENERIC;
  197.     /* Allocate the memory needed to store the decoder's structure */
  198.     p_dec->p_sys = p_sys = malloc( sizeof(decoder_sys_t) );
  199.     if( !p_sys )
  200.         return VLC_EGENERIC;
  201.     /* Misc init */
  202.     aout_DateInit( &p_sys->end_date, 48000 );
  203.     aout_DateSet( &p_sys->end_date, 0 );
  204.     /* Set output properties */
  205.     p_dec->fmt_out.i_cat = AUDIO_ES;
  206.     p_dec->fmt_out.audio.i_rate = 48000;
  207.     /* Set callback */
  208.     if( b_packetizer )
  209.     {
  210.         p_dec->fmt_out.i_codec = VLC_FOURCC('a','e','s','3');
  211.         p_dec->pf_decode_audio = NULL;
  212.         p_dec->pf_packetize    = Packetize;
  213.     }
  214.     else
  215.     {
  216.         p_dec->pf_decode_audio = Decode;
  217.         p_dec->pf_packetize    = NULL;
  218.     }
  219.     return VLC_SUCCESS;
  220. }
  221. static const unsigned int pi_original_channels[4] = {
  222.     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
  223.     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  224.         AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
  225.     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  226.         AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
  227.         AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
  228.     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  229.         AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
  230.         AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
  231.         AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
  232. };
  233. static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
  234.                        block_t **pp_block, bool b_packetizer )
  235. {
  236.     decoder_sys_t *p_sys = p_dec->p_sys;
  237.     block_t       *p_block;
  238.     uint32_t h;
  239.     unsigned int i_size;
  240.     int i_channels;
  241.     int i_id;
  242.     int i_bits;
  243.     if( !pp_block || !*pp_block ) return NULL;
  244.     p_block = *pp_block;
  245.     *pp_block = NULL; /* So the packet doesn't get re-sent */
  246.     /* Date management */
  247.     if( p_block->i_pts > 0 &&
  248.         p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
  249.     {
  250.         aout_DateSet( &p_sys->end_date, p_block->i_pts );
  251.     }
  252.     if( !aout_DateGet( &p_sys->end_date ) )
  253.     {
  254.         /* We've just started the stream, wait for the first PTS. */
  255.         block_Release( p_block );
  256.         return NULL;
  257.     }
  258.     if( p_block->i_buffer <= AES3_HEADER_LEN )
  259.     {
  260.         msg_Err(p_dec, "frame is too short");
  261.         block_Release( p_block );
  262.         return NULL;
  263.     }
  264.     /*
  265.      * AES3 header :
  266.      * size:            16
  267.      * number channels   2
  268.      * channel_id        8
  269.      * bits per samples  2
  270.      * alignments        4
  271.      */
  272.     h = GetDWBE( p_block->p_buffer );
  273.     i_size = (h >> 16) & 0xffff;
  274.     i_channels = 2 + 2*( (h >> 14) & 0x03 );
  275.     i_id = (h >> 6) & 0xff;
  276.     i_bits = 16 + 4*( (h >> 4)&0x03 );
  277.     if( AES3_HEADER_LEN + i_size != p_block->i_buffer || i_bits > 24 )
  278.     {
  279.         msg_Err(p_dec, "frame has invalid header");
  280.         block_Release( p_block );
  281.         return NULL;
  282.     }
  283.     /* Set output properties */
  284.     if( b_packetizer )
  285.     {
  286.         p_dec->fmt_out.audio.i_bitspersample = i_bits;
  287.     }
  288.     else
  289.     {
  290.         p_dec->fmt_out.i_codec = i_bits == 16 ? VLC_FOURCC('s','1','6','l') : VLC_FOURCC('s','2','4','l');
  291.         p_dec->fmt_out.audio.i_bitspersample = i_bits == 16 ? 16 : 24;
  292.     }
  293.     p_dec->fmt_out.audio.i_channels = i_channels;
  294.     p_dec->fmt_out.audio.i_original_channels = pi_original_channels[i_channels/2-1];
  295.     p_dec->fmt_out.audio.i_physical_channels = pi_original_channels[i_channels/2-1] & AOUT_CHAN_PHYSMASK;
  296.     *pi_frame_length = (p_block->i_buffer - AES3_HEADER_LEN) / ( (4+i_bits) * i_channels / 8 );
  297.     *pi_bits = i_bits;
  298.     return p_block;
  299. }