root/branches/perian-1.1/FFissionCodec/FFissionCodec.cpp

Revision 887, 4.4 kB (checked in by astrange, 6 months ago)

Merge trunk to 1.1 branch.

Line 
1 /*
2  *  FFissionCodec.cpp
3  *
4  *  Copyright (c) 2006  David Conrad
5  *
6  *  This program is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License as published by the Free Software Foundation;
9  *  version 2.1 of the License.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 extern "C" {
23 #include "avcodec.h"
24 }
25 #include "FFissionCodec.h"
26
27 extern "C" void init_FFmpeg();
28
29 FFissionCodec::FFissionCodec(UInt32 inInputBufferByteSize) : ACSimpleCodec(inInputBufferByteSize)
30 {
31         init_FFmpeg();
32        
33         avContext = avcodec_alloc_context();
34         avCodec = NULL;
35 }
36
37 FFissionCodec::~FFissionCodec()
38 {
39         if (avContext) {
40                 if (avCodec) {
41                         avcodec_close(avContext);
42                 }
43                
44                 av_free(avContext);
45         }
46 }
47
48 void FFissionCodec::Initialize(const AudioStreamBasicDescription* inInputFormat,
49                                                            const AudioStreamBasicDescription* inOutputFormat,
50                                                            const void* inMagicCookie, UInt32 inMagicCookieByteSize)
51 {
52         //      use the given arguments, if necessary
53         if (inInputFormat != NULL)
54         {
55                 SetCurrentInputFormat(*inInputFormat);
56         }
57        
58         if (inOutputFormat != NULL)
59         {
60                 SetCurrentOutputFormat(*inOutputFormat);
61         }
62        
63         //      make sure the sample rate and number of channels match between the input format and the output format
64        
65         if ((mInputFormat.mSampleRate != mOutputFormat.mSampleRate) ||
66                 (mInputFormat.mChannelsPerFrame != mOutputFormat.mChannelsPerFrame))
67         {
68                 CODEC_THROW(kAudioCodecUnsupportedFormatError);
69         }
70        
71         ACSimpleCodec::Initialize(inInputFormat, inOutputFormat, inMagicCookie, inMagicCookieByteSize);
72 }
73
74 void FFissionCodec::GetPropertyInfo(AudioCodecPropertyID inPropertyID, UInt32& outPropertyDataSize, bool& outWritable) {
75         switch(inPropertyID)
76         {
77                 case kAudioCodecPropertyMaximumPacketByteSize:
78                         outPropertyDataSize = sizeof(UInt32);
79                         outWritable = false;
80                         break;
81                        
82                 case kAudioCodecPropertyHasVariablePacketByteSizes:
83                         outPropertyDataSize = sizeof(UInt32);
84                         outWritable = false;
85                         break;
86                        
87                 case kAudioCodecPropertyPacketFrameSize:
88                         outPropertyDataSize = sizeof(UInt32);
89                         outWritable = false;
90                         break;
91                        
92                 default:
93                         ACSimpleCodec::GetPropertyInfo(inPropertyID, outPropertyDataSize, outWritable);
94                         break;
95         }
96 }
97
98 void FFissionCodec::GetProperty(AudioCodecPropertyID inPropertyID, UInt32& ioPropertyDataSize, void* outPropertyData)
99 {
100         switch(inPropertyID) {
101                 case kAudioCodecPropertyManufacturerCFString:
102                         if (ioPropertyDataSize != sizeof(CFStringRef))
103                                 CODEC_THROW(kAudioCodecBadPropertySizeError);
104                         break;
105                        
106                 case kAudioCodecPropertyMaximumPacketByteSize:
107                 case kAudioCodecPropertyRequiresPacketDescription:
108                 case kAudioCodecPropertyHasVariablePacketByteSizes:
109                 case kAudioCodecPropertyPacketFrameSize:
110                         if(ioPropertyDataSize != sizeof(UInt32))
111                                 CODEC_THROW(kAudioCodecBadPropertySizeError);
112                         break;
113         }
114        
115         switch (inPropertyID) {
116                 case kAudioCodecPropertyManufacturerCFString:
117                         CFStringRef name = CFCopyLocalizedStringFromTableInBundle(CFSTR("Perian Project"), CFSTR("CodecNames"), GetCodecBundle(), CFSTR(""));
118                         *(CFStringRef*)outPropertyData = name;
119                         break;
120                        
121                 case kAudioCodecPropertyMaximumPacketByteSize:
122                         if (avContext)
123                                 *reinterpret_cast<UInt32*>(outPropertyData) = avContext->block_align;
124                         else
125                                 *reinterpret_cast<UInt32*>(outPropertyData) = mInputFormat.mBytesPerPacket;
126                         break;
127                        
128                 case kAudioCodecPropertyRequiresPacketDescription:
129                         *reinterpret_cast<UInt32*>(outPropertyData) = false;
130                         break;
131                        
132                 case kAudioCodecPropertyHasVariablePacketByteSizes:
133                         *reinterpret_cast<UInt32*>(outPropertyData) = false;
134                         break;
135                        
136                 case kAudioCodecPropertyPacketFrameSize:
137                         if (avContext && avContext->frame_size)
138                                 *reinterpret_cast<UInt32*>(outPropertyData) = avContext->frame_size;
139                         else if (mInputFormat.mFramesPerPacket)
140                                 *reinterpret_cast<UInt32*>(outPropertyData) = mInputFormat.mFramesPerPacket;
141                         else
142                                 // not perfect but returning 0 can crash on intel
143                                 *reinterpret_cast<UInt32*>(outPropertyData) = 1;
144                         break;
145                        
146                 default:
147                         ACSimpleCodec::GetProperty(inPropertyID, ioPropertyDataSize, outPropertyData);
148         }
149 }
Note: See TracBrowser for help on using the browser.