+static const int hdr2samplerate[] = { 48000, 96000, 44100, 32000 };
+static const int hdr2samplesize[] = { 16, 20, 24, 16 };
+static const int hdr2layout[] = {
+ HB_INPUT_CH_LAYOUT_MONO, HB_INPUT_CH_LAYOUT_STEREO,
+ HB_INPUT_CH_LAYOUT_2F1R, HB_INPUT_CH_LAYOUT_2F2R,
+ HB_INPUT_CH_LAYOUT_3F2R, HB_INPUT_CH_LAYOUT_4F2R,
+ HB_INPUT_CH_LAYOUT_STEREO, HB_INPUT_CH_LAYOUT_STEREO,
+};
+
+static void lpcmInfo( hb_work_object_t *w, hb_buffer_t *in )
+{
+ hb_work_private_t * pv = w->private_data;
+
+ /*
+ * LPCM packets have a 7 byte header (the substream id is stripped off
+ * before we get here so it's numbered -1 below)::
+ * byte -1 Substream id
+ * byte 0 Number of frames that begin in this packet
+ * (last frame may finish in next packet)
+ * byte 1,2 offset to first frame that begins in this packet (not including hdr)
+ * byte 3:
+ * bits 0-4 continuity counter (increments modulo 20)
+ * bit 5 reserved
+ * bit 6 audio mute on/off
+ * bit 7 audio emphasis on/off
+ * byte 4:
+ * bits 0-2 #channels - 1 (e.g., stereo = 1)
+ * bit 3 reserved
+ * bits 4-5 sample rate (0=48K,1=96K,2=44.1K,3=32K)
+ * bits 6-7 bits per sample (0=16 bit, 1=20 bit, 2=24 bit)
+ * byte 5 Dynamic range control (0x80 = off)
+ *
+ * The audio is viewed as "frames" of 150 90KHz ticks each (80 samples @ 48KHz).
+ * The frames are laid down continuously without regard to MPEG packet
+ * boundaries. E.g., for 48KHz stereo, the first packet will contain 6
+ * frames plus the start of the 7th, the second packet will contain the
+ * end of the 7th, 8-13 & the start of 14, etc. The frame structure is
+ * important because the PTS on the packet gives the time of the first
+ * frame that starts in the packet *NOT* the time of the first sample
+ * in the packet. Also samples get split across packet boundaries
+ * so we can't assume that we can consume all the data in one packet
+ * on every call to the work routine.
+ */
+ pv->offset = ( ( in->data[1] << 8 ) | in->data[2] ) + 2;
+ if ( pv->offset >= HB_DVD_READ_BUFFER_SIZE )
+ {
+ hb_log( "declpcm: illegal frame offset %d", pv->offset );
+ pv->offset = 2; /*XXX*/
+ }
+ pv->samplerate = hdr2samplerate[ ( in->data[4] >> 4 ) & 0x3 ];
+ pv->nchannels = ( in->data[4] & 7 ) + 1;
+ pv->sample_size = hdr2samplesize[in->data[4] >> 6];
+
+ /*
+ * PCM frames have a constant duration (150 90KHz ticks).
+ * We need to convert that to the amount of data expected. It's the
+ * duration divided by the sample rate (to get #samples) times the number
+ * of channels times the bits per sample divided by 8 to get bytes.
+ * (we have to compute in bits because 20 bit samples are not an integral
+ * number of bytes). We do all the multiplies first then the divides to
+ * avoid truncation errors.
+ */
+ pv->duration = in->data[0] * 150;
+ pv->count = ( pv->duration * pv->nchannels * pv->samplerate ) / 90000;
+ pv->size = ( pv->count * pv->sample_size ) / 8;
+
+ pv->next_pts = in->start;
+}
+
+static int declpcmInit( hb_work_object_t * w, hb_job_t * job )