root/branches/perian-1.0/bitstream_info.c

Revision 603, 3.6 kB (checked in by gbooker, 1 year ago)

Seems this didn't work... Oh well.

Line 
1 /*
2  *  bitstream_info.c
3  *  Perian
4  *
5  *  Created by Graham Booker on 1/6/07.
6  *  Copyright 2007 Graham Booker. All rights reserved.
7  *
8  */
9
10 #include "bitstream_info.h"
11
12 #include <AudioToolbox/AudioToolbox.h>
13 #include <QuickTime/QuickTime.h>
14
15 static const int nfchans_tbl[8] = { 2, 1, 2, 3, 3, 4, 4, 5 };
16 static const int ac3_layout_no_lfe[8] = {
17         kAudioChannelLayoutTag_Stereo,
18         kAudioChannelLayoutTag_Mono,
19         kAudioChannelLayoutTag_Stereo,
20         kAudioChannelLayoutTag_ITU_3_0,
21         kAudioChannelLayoutTag_ITU_2_1,
22         kAudioChannelLayoutTag_ITU_3_1,
23         kAudioChannelLayoutTag_ITU_2_2,
24         kAudioChannelLayoutTag_ITU_3_2};
25
26 static const int ac3_layout_lfe[8] = {
27         kAudioChannelLayoutTag_DVD_4,
28         kAudioChannelLayoutTag_Mono,  //No layout for this, hopefully we never have it
29         kAudioChannelLayoutTag_DVD_4,
30         kAudioChannelLayoutTag_DVD_10,
31         kAudioChannelLayoutTag_DVD_5,
32         kAudioChannelLayoutTag_DVD_11,
33         kAudioChannelLayoutTag_DVD_6,
34         kAudioChannelLayoutTag_ITU_3_2_1};
35
36 static const uint16_t ac3_freqs[3] = { 48000, 44100, 32000 };
37
38 /* From: http://svn.mplayerhq.hu/ac3/ (LGPL)
39  * Synchronize to ac3 bitstream.
40  * This function searches for the syncword '0xb77'.
41  *
42  * @param buf Pointer to "probable" ac3 bitstream buffer
43  * @param buf_size Size of buffer
44  * @return Returns the position where syncword is found, -1 if no syncword is found
45  */
46 static int ac3_synchronize(uint8_t *buf, int buf_size)
47 {
48     int i;
49        
50     for (i = 0; i < buf_size - 1; i++)
51         if (buf[i] == 0x0b && buf[i + 1] == 0x77)
52             return i;
53        
54     return -1;
55 }
56
57 /* A lot of this was stolen from: http://svn.mplayerhq.hu/ac3/ (LGPL)
58  * Fill info from an ac3 stream
59  *
60  * @param asdb Pointer to the AudioStreamBasicDescription to fill
61  * @param acl Pointer to the AudioChannelLayout to fill
62  * @param buffer Pointer to the buffer data to scan
63  * @param buff_size Size of the buffer
64  * @return 1 if successfull, 0 otherwise
65  */
66
67 int parse_ac3_bitstream(AudioStreamBasicDescription *asbd, AudioChannelLayout *acl, uint8_t *buffer, int buff_size)
68 {
69         int offset = ac3_synchronize(buffer, buff_size);
70         int passthrough = 0;
71         if(offset == -1)
72                 return 0;
73        
74         if(buff_size < offset + 7)
75                 return 0;
76        
77         CFTypeRef pass = CFPreferencesCopyAppValue(CFSTR("attemptPassthrough"), CFSTR("com.cod3r.a52codec"));
78         if(pass != NULL)
79         {
80                 CFTypeID type = CFGetTypeID(pass);
81                 if(type == CFStringGetTypeID())
82                         passthrough = CFStringGetIntValue(pass);
83                 else if (type == CFNumberGetTypeID())
84                         CFNumberGetValue(pass, kCFNumberIntType, &passthrough);
85                 CFRelease(pass);
86         }
87        
88         uint8_t fscod_and_frmsizecod = buffer[offset + 4];
89        
90         uint8_t fscod = fscod_and_frmsizecod >> 6;
91         uint8_t frmsizecod = fscod_and_frmsizecod & 0x3f;
92         if(frmsizecod >= 38)
93                 return 0;
94        
95         uint8_t bsid = buffer[offset + 5] >> 3;
96         if(bsid >= 0x12)
97                 return 0;
98        
99         uint8_t acmod = buffer[offset + 6] >> 5;
100         uint8_t shift = 4;
101         if(acmod & 0x01 && acmod != 0x01)
102                 shift -= 2;
103         if(acmod & 0x04)
104                 shift -= 2;
105         if(acmod == 0x02)
106                 shift -= 2;
107         uint8_t lfe = (buffer[offset + 6] >> shift) & 0x01;
108        
109         /* This is a valid frame!!! */
110 //      uint8_t bitrate = ac3_bitratetab[frmsizecod >> 1];
111         int sample_rate = ac3_freqs[fscod];
112        
113         shift = 0;
114         if(bsid > 8)
115                 shift = bsid - 8;
116        
117         if(passthrough)
118         {
119                 if(acmod > 2)
120                         acmod = 0;
121                 lfe = 0;
122         }
123         /* Setup the AudioStreamBasicDescription and AudioChannelLayout */
124         memset(asbd, 0, sizeof(AudioStreamBasicDescription));
125         asbd->mSampleRate = sample_rate >> shift;
126         asbd->mFormatID = kAudioFormatAC3;
127         asbd->mFramesPerPacket = 1;
128         asbd->mChannelsPerFrame = nfchans_tbl[acmod] + lfe;
129        
130         memset(acl, 0, sizeof(AudioChannelLayout));
131         if(lfe)
132                 acl->mChannelLayoutTag = ac3_layout_lfe[acmod];
133         else
134                 acl->mChannelLayoutTag = ac3_layout_no_lfe[acmod];
135        
136         return 1;
137 }
Note: See TracBrowser for help on using the browser.