[vlc-commits] codecs: lpcm: add WiDi LPCM

Francois Cartegnie git at videolan.org
Sat Apr 12 20:38:03 CEST 2014


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Apr 10 19:54:21 2014 +0200| [69adf3b6954f157b9566a52b66b0f2e63a496dcd] | committer: Francois Cartegnie

codecs: lpcm: add WiDi LPCM

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=69adf3b6954f157b9566a52b66b0f2e63a496dcd
---

 include/vlc_fourcc.h |    1 +
 modules/codec/lpcm.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/include/vlc_fourcc.h b/include/vlc_fourcc.h
index 8aaabd8..5ce8538 100644
--- a/include/vlc_fourcc.h
+++ b/include/vlc_fourcc.h
@@ -366,6 +366,7 @@
 #define VLC_CODEC_DVD_LPCM                   VLC_FOURCC('l','p','c','m')
 #define VLC_CODEC_DVDA_LPCM                  VLC_FOURCC('a','p','c','m')
 #define VLC_CODEC_BD_LPCM                    VLC_FOURCC('b','p','c','m')
+#define VLC_CODEC_WIDI_LPCM                  VLC_FOURCC('w','p','c','m')
 #define VLC_CODEC_SDDS                       VLC_FOURCC('s','d','d','s')
 #define VLC_CODEC_MIDI                       VLC_FOURCC('M','I','D','I')
 #define VLC_CODEC_RALF                       VLC_FOURCC('R','A','L','F')
diff --git a/modules/codec/lpcm.c b/modules/codec/lpcm.c
index 24c8555..e3dad87 100644
--- a/modules/codec/lpcm.c
+++ b/modules/codec/lpcm.c
@@ -142,17 +142,30 @@ struct encoder_sys_t
  * - frequency (4 bits)
  * - bits per sample (2 bits)
  * - unknown (6 bits)
+ *
+ * LPCM WIDI header
+ * refers http://www.dvdforum.org/images/Guideline1394V10R0_20020911.pdf
+  * - sub stream id (8 bits) = 0xa0
+ * - frame header count (8 bits) = 0x06
+ * [ 0b0000000 (7 bits)
+ * - audio emphasis (1 bit) ] (8 bits)
+ * [ qz word length (2 bits) 0x00 == 16bits
+ * - sampling freq (3 bits) 0b001 == 44.1K, 0b010 == 48K Hz
+ * - channels count(3 bits) ] (8 bits) 0b000 == dual mono, 0b001 == stereo
+ * follows: LPCM data (15360 bits/1920 bytes)
  */
 
 #define LPCM_VOB_HEADER_LEN (6)
 #define LPCM_AOB_HEADER_LEN (11)
 #define LPCM_BD_HEADER_LEN (4)
+#define LPCM_WIDI_HEADER_LEN (4)
 
 enum
 {
     LPCM_VOB,
     LPCM_AOB,
     LPCM_BD,
+    LPCM_WIDI,
 };
 
 typedef struct
@@ -190,7 +203,11 @@ static int BdHeader( decoder_sys_t *p_sys,
                      unsigned *pi_bits,
                      const uint8_t *p_header );
 static void BdExtract( block_t *, block_t *, unsigned, unsigned, unsigned, unsigned );
-
+/* */
+static int WidiHeader( unsigned *pi_rate,
+                       unsigned *pi_channels, unsigned *pi_original_channels,
+                       unsigned *pi_bits,
+                       const uint8_t *p_header );
 
 /*****************************************************************************
  * OpenCommon:
@@ -219,6 +236,11 @@ static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
         i_type = LPCM_BD;
         i_header_size = LPCM_BD_HEADER_LEN;
         break;
+    /* WIDI LPCM */
+    case VLC_CODEC_WIDI_LPCM:
+        i_type = LPCM_WIDI;
+        i_header_size = LPCM_WIDI_HEADER_LEN;
+        break;
     default:
         return VLC_EGENERIC;
     }
@@ -247,6 +269,9 @@ static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
         case LPCM_AOB:
             p_dec->fmt_out.i_codec = VLC_CODEC_DVDA_LPCM;
             break;
+        case LPCM_WIDI:
+            p_dec->fmt_out.i_codec = VLC_CODEC_WIDI_LPCM;
+            break;
         default:
             assert(0);
         case LPCM_BD:
@@ -342,6 +367,10 @@ static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
         i_ret = BdHeader( p_sys, &i_rate, &i_channels, &i_channels_padding, &i_original_channels, &i_bits,
                           p_block->p_buffer );
         break;
+    case LPCM_WIDI:
+        i_ret = WidiHeader( &i_rate, &i_channels, &i_original_channels, &i_bits,
+                            p_block->p_buffer );
+        break;
     default:
         abort();
     }
@@ -414,6 +443,7 @@ static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
 
         switch( p_sys->i_type )
         {
+        case LPCM_WIDI:
         case LPCM_VOB:
             VobExtract( p_aout_buffer, p_block, i_bits );
             break;
@@ -972,6 +1002,38 @@ static int BdHeader( decoder_sys_t *p_sys,
     return 0;
 }
 
+static int WidiHeader( unsigned *pi_rate,
+                       unsigned *pi_channels, unsigned *pi_original_channels,
+                       unsigned *pi_bits,
+                       const uint8_t *p_header )
+{
+    if ( p_header[0] != 0xa0 || p_header[1] != 0x06 )
+        return -1;
+
+    switch( ( p_header[3] & 0x38 ) >> 3 )
+    {
+    case 0b001:
+        *pi_rate = 44100;
+        break;
+    case 0b010:
+        *pi_rate = 48000;
+        break;
+    default:
+        return -1;
+    }
+
+    if( p_header[3] >> 6 != 0 )
+        return -1;
+    else
+        *pi_bits = 16;
+
+    *pi_channels = (p_header[3] & 0x7) + 1;
+
+    *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
+
+    return 0;
+}
+
 static void VobExtract( block_t *p_aout_buffer, block_t *p_block,
                         unsigned i_bits )
 {



More information about the vlc-commits mailing list