OSDN Git Service

50a5a128de76f8dbf7844aa5a6fe12401537f847
[handbrake-jp/handbrake-jp.git] / libhb / declpcm.c
1 /* $Id: declpcm.c,v 1.8 2005/11/04 14:44:01 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.fr/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8
9 struct hb_work_private_s
10 {
11     hb_job_t    *job;
12     uint32_t    size;       /* frame size in bytes */
13     uint32_t    count;      /* frame size in samples */
14     uint32_t    pos;        /* buffer offset for next input data */
15
16     int64_t     next_pts;   /* pts for next output frame */
17     int64_t     sequence;
18
19     /* the following is frame info for the frame we're currently accumulating */
20     uint64_t    duration;   /* frame duratin (in 90KHz ticks) */
21     uint32_t    offset;     /* where in buf frame starts */
22     uint32_t    samplerate; /* sample rate in bits/sec */
23     uint8_t     nchannels;
24     uint8_t     sample_size; /* bits per sample */
25
26     uint8_t     frame[HB_DVD_READ_BUFFER_SIZE*2];
27 };
28
29 static hb_buffer_t * Decode( hb_work_object_t * w );
30 static int  declpcmInit( hb_work_object_t *, hb_job_t * );
31 static int  declpcmWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
32 static void declpcmClose( hb_work_object_t * );
33 static int  declpcmBSInfo( hb_work_object_t *, const hb_buffer_t *,
34                            hb_work_info_t * );
35
36 hb_work_object_t hb_declpcm =
37 {
38     WORK_DECLPCM,
39     "LPCM decoder",
40     declpcmInit,
41     declpcmWork,
42     declpcmClose,
43     0,
44     declpcmBSInfo
45 };
46
47 static const int hdr2samplerate[] = { 48000, 96000, 44100, 32000 };
48 static const int hdr2samplesize[] = { 16, 20, 24, 16 };
49 static const int hdr2layout[] = {
50         HB_INPUT_CH_LAYOUT_MONO,   HB_INPUT_CH_LAYOUT_STEREO,
51         HB_INPUT_CH_LAYOUT_2F1R,   HB_INPUT_CH_LAYOUT_2F2R,
52         HB_INPUT_CH_LAYOUT_3F2R,   HB_INPUT_CH_LAYOUT_4F2R,
53         HB_INPUT_CH_LAYOUT_STEREO, HB_INPUT_CH_LAYOUT_STEREO,
54 };
55
56 static void lpcmInfo( hb_work_object_t *w, hb_buffer_t *in )
57 {
58     hb_work_private_t * pv = w->private_data;
59
60     /*
61      * LPCM packets have a 7 byte header (the substream id is stripped off
62      * before we get here so it's numbered -1 below)::
63      * byte -1  Substream id
64      * byte 0   Number of frames that begin in this packet
65      *          (last frame may finish in next packet)
66      * byte 1,2 offset to first frame that begins in this packet (not including hdr)
67      * byte 3:
68      *   bits 0-4  continuity counter (increments modulo 20)
69      *   bit   5   reserved
70      *   bit   6   audio mute on/off
71      *   bit   7   audio emphasis on/off
72      * byte 4:
73      *   bits 0-2  #channels - 1 (e.g., stereo = 1)
74      *   bit   3   reserved
75      *   bits 4-5  sample rate (0=48K,1=96K,2=44.1K,3=32K)
76      *   bits 6-7  bits per sample (0=16 bit, 1=20 bit, 2=24 bit)
77      * byte 5   Dynamic range control (0x80 = off)
78      *
79      * The audio is viewed as "frames" of 150 90KHz ticks each (80 samples @ 48KHz).
80      * The frames are laid down continuously without regard to MPEG packet
81      * boundaries. E.g., for 48KHz stereo, the first packet will contain 6
82      * frames plus the start of the 7th, the second packet will contain the
83      * end of the 7th, 8-13 & the start of 14, etc. The frame structure is
84      * important because the PTS on the packet gives the time of the first
85      * frame that starts in the packet *NOT* the time of the first sample 
86      * in the packet. Also samples get split across packet boundaries
87      * so we can't assume that we can consume all the data in one packet
88      * on every call to the work routine.
89      */
90     pv->offset = ( ( in->data[1] << 8 ) | in->data[2] ) + 2;
91     if ( pv->offset >= HB_DVD_READ_BUFFER_SIZE )
92     {
93         hb_log( "declpcm: illegal frame offset %d", pv->offset );
94         pv->offset = 2; /*XXX*/
95     }
96     pv->samplerate = hdr2samplerate[ ( in->data[4] >> 4 ) & 0x3 ];
97     pv->nchannels  = ( in->data[4] & 7 ) + 1;
98     pv->sample_size = hdr2samplesize[in->data[4] >> 6];
99
100     /*
101      * PCM frames have a constant duration (150 90KHz ticks).
102      * We need to convert that to the amount of data expected.  It's the
103      * duration divided by the sample rate (to get #samples) times the number
104      * of channels times the bits per sample divided by 8 to get bytes.
105      * (we have to compute in bits because 20 bit samples are not an integral
106      * number of bytes). We do all the multiplies first then the divides to
107      * avoid truncation errors. 
108      */
109     pv->duration = in->data[0] * 150;
110     pv->count = ( pv->duration * pv->nchannels * pv->samplerate ) / 90000;
111     pv->size = ( pv->count * pv->sample_size ) / 8;
112
113     pv->next_pts = in->start;
114 }
115
116 static int declpcmInit( hb_work_object_t * w, hb_job_t * job )
117 {
118     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
119     w->private_data = pv;
120     pv->job   = job;
121     return 0;
122 }
123
124 /* 
125  * Convert DVD encapsulated LPCM to floating point PCM audio buffers.
126  * The amount of audio in a PCM frame is always <= the amount that will fit
127  * in a DVD block (2048 bytes) but the standard doesn't require that the audio
128  * frames line up with the DVD frames. Since audio frame boundaries are unrelated
129  * to DVD PES boundaries, this routine has to reconstruct then extract the audio
130  * frames. Because of the arbitrary alignment, it can output zero, one or two buf's.
131  */
132 static int declpcmWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
133                  hb_buffer_t ** buf_out )
134 {
135     hb_work_private_t * pv = w->private_data;
136     hb_buffer_t *in = *buf_in;
137     hb_buffer_t *buf = NULL;
138
139     if ( in->size <= 0 )
140     {
141         /* EOF on input stream - send it downstream & say that we're done */
142         *buf_out = in;
143         *buf_in = NULL;
144         return HB_WORK_DONE;
145     }
146
147     pv->sequence = in->sequence;
148
149     /* if we have a frame to finish, add enough data from this buf to finish it */
150     if ( pv->size )
151     {
152         memcpy( pv->frame + pv->pos, in->data + 6, pv->size - pv->pos );
153         buf = Decode( w );
154     }
155     *buf_out = buf;
156
157     /* save the (rest of) data from this buf in our frame buffer */
158     lpcmInfo( w, in );
159     int off = pv->offset;
160     int amt = in->size - off;
161     pv->pos = amt;
162     memcpy( pv->frame, in->data + off, amt );
163     if ( amt >= pv->size )
164     {
165         if ( buf )
166         {
167             buf->next = Decode( w );
168         }
169         else
170         {
171             *buf_out = Decode( w );
172         }
173         pv->size = 0;
174     }
175     return HB_WORK_OK;
176 }
177
178 static hb_buffer_t *Decode( hb_work_object_t *w )
179 {
180     hb_work_private_t *pv = w->private_data;
181     hb_buffer_t *out = hb_buffer_init( pv->count * sizeof( float ) );
182  
183     out->start  = pv->next_pts;
184     pv->next_pts += pv->duration;
185     out->stop = pv->next_pts;
186
187     uint8_t *frm = pv->frame;
188     float *odat = (float *)out->data;
189     int count = pv->count;
190
191     switch( pv->sample_size )
192     {
193         case 16: // 2 byte, big endian, signed (the right shift sign extends)
194             while ( --count >= 0 )
195             {
196                 *odat++ = ( (int)( frm[0] << 24 ) >> 16 ) | frm[1];
197                 frm += 2;
198             }
199             break;
200         case 20:
201             // 20 bit big endian signed (5 bytes for 2 samples = 2.5 bytes/sample
202             // so we do two samples per iteration).
203             count /= 2;
204             while ( --count >= 0 )
205             {
206                 *odat++ = (float)( ( (int)( frm[0] << 24 ) >> 12 ) |
207                                    ( frm[1] << 4 ) | ( frm[2] >> 4 ) ) / 16.;
208                 *odat++ = (float)( ( (int)( frm[2] << 28 ) >> 16 ) |
209                                    ( frm[3] << 8 ) | frm[4] ) / 16.;
210                 frm += 5;
211             }
212             break;
213         case 24:
214             // This format is bizarre. It's 24 bit samples but some confused
215             // individual apparently thought they would be easier to interpret
216             // as 16 bits if they were scrambled in the following way:
217             // Things are stored in 4 sample (12 byte) chunks. Each chunk has
218             // 4 samples containing the two top bytes of the actual samples in
219             // 16 bit big-endian order followed by the four least significant bytes
220             // of each sample.
221             count /= 4; // the loop has to work in 4 sample chunks
222             while ( --count >= 0 )
223             {
224                 *odat++ = (float)( ( (int)( frm[0] << 24 ) >> 8 ) |
225                             ( frm[1] << 8 ) | frm[8] ) / 256.;
226                 *odat++ = (float)( ( (int)( frm[2] << 24 ) >> 8 ) |
227                             ( frm[3] << 8 ) | frm[9] ) / 256.;
228                 *odat++ = (float)( ( (int)( frm[4] << 24 ) >> 8 ) |
229                             ( frm[5] << 8 ) | frm[10] ) / 256.;
230                 *odat++ = (float)( ( (int)( frm[6] << 24 ) >> 8 ) |
231                             ( frm[7] << 8 ) | frm[11] ) / 256.;
232                 frm += 12;
233             }
234             break;
235     }
236     return out;
237 }
238
239 static void declpcmClose( hb_work_object_t * w )
240 {
241     if ( w->private_data )
242     {
243         free( w->private_data );
244         w->private_data = 0;
245     }
246 }
247
248 static int declpcmBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
249                           hb_work_info_t *info )
250 {
251     int nchannels  = ( b->data[4] & 7 ) + 1;
252     int sample_size = hdr2samplesize[b->data[4] >> 6];
253
254     int rate = hdr2samplerate[ ( b->data[4] >> 4 ) & 0x3 ];
255     int bitrate = rate * sample_size * nchannels;
256
257     memset( info, 0, sizeof(*info) );
258
259     info->name = "LPCM";
260     info->rate = rate;
261     info->rate_base = 1;
262     info->bitrate = bitrate;
263     info->flags = ( b->data[3] << 16 ) | ( b->data[4] << 8 ) | b->data[5];
264     info->channel_layout = hdr2layout[nchannels - 1];
265
266     return 1;
267 }