[xiph-commits] r12394 - in trunk/xiph-qt: CAVorbis/src OggExport/src
arek at svn.xiph.org
arek at svn.xiph.org
Mon Jan 29 17:21:27 PST 2007
Author: arek
Date: 2007-01-29 17:21:22 -0800 (Mon, 29 Jan 2007)
New Revision: 12394
Modified:
trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.cpp
trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.h
trunk/xiph-qt/OggExport/src/OggExport.c
trunk/xiph-qt/OggExport/src/exporter_types.h
trunk/xiph-qt/OggExport/src/stream_audio.c
Log:
Added UI and configuration handling to Vorbis encoder, plus improved support for audio streams in exporter.
Modified: trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.cpp
===================================================================
--- trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.cpp 2007-01-29 22:37:46 UTC (rev 12393)
+++ trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.cpp 2007-01-30 01:21:22 UTC (rev 12394)
@@ -44,10 +44,6 @@
#include "debug.h"
-#if !defined(NO_ACS)
-#define NO_ACS 1
-#endif /* defined(NO_ACS) */
-
#if !defined(NO_ADV_PROPS)
#define NO_ADV_PROPS 1
#endif /* defined(NO_ADV_PROPS) */
@@ -57,9 +53,19 @@
(x)->mFormatFlags, (x)->mBytesPerPacket, (x)->mFramesPerPacket, (x)->mBytesPerPacket, \
(x)->mChannelsPerFrame, (x)->mBitsPerChannel
+AudioChannelLayoutTag CAVorbisEncoder::gOutChannelLayouts[kVorbisEncoderOutChannelLayouts] = {
+ kAudioChannelLayoutTag_Mono,
+ kAudioChannelLayoutTag_Stereo,
+ //kAudioChannelLayoutTag_ITU_2_1, // there's no tag for [L, C, R] layout!! :(
+ kAudioChannelLayoutTag_Quadraphonic,
+ kAudioChannelLayoutTag_MPEG_5_0_C,
+ kAudioChannelLayoutTag_MPEG_5_1_C,
+};
+
CAVorbisEncoder::CAVorbisEncoder() :
mCookie(NULL), mCookieSize(0), mCompressionInitialized(false), mEOSHit(false),
- last_granulepos(0), last_packetno(0), mVorbisFPList(), mProducedPList()
+ last_granulepos(0), last_packetno(0), mVorbisFPList(), mProducedPList(),
+ mCfgMode(kVorbisEncoderModeQuality), mCfgQuality(0.4), mCfgBitrate(128), mCfgDict(NULL)
{
CAStreamBasicDescription theInputFormat1(kAudioStreamAnyRate, kAudioFormatLinearPCM,
0, 1, 0, 0, 32, kAudioFormatFlagsNativeFloatPacked);
@@ -109,6 +115,9 @@
vorbis_info_clear(&mV_vi);
}
+
+ if (mCfgDict != NULL)
+ CFRelease(mCfgDict);
}
void CAVorbisEncoder::Initialize(const AudioStreamBasicDescription* inInputFormat,
@@ -171,18 +180,39 @@
{
/*
- case kAudioCodecPropertyInputChannelLayout :
case kAudioCodecPropertyOutputChannelLayout :
// by default a codec doesn't support channel layouts.
CODEC_THROW(kAudioCodecIllegalOperationError);
break;
case kAudioCodecPropertyAvailableInputChannelLayouts :
- case kAudioCodecPropertyAvailableOutputChannelLayouts :
- // by default a codec doesn't support channel layouts.
- CODEC_THROW(kAudioCodecIllegalOperationError);
- break;
*/
+ case kAudioCodecPropertyInputChannelLayout:
+ if (ioPropertyDataSize >= sizeof(AudioChannelLayout)) {
+ fill_channel_layout(mInputFormat.mChannelsPerFrame, reinterpret_cast<AudioChannelLayout*>(outPropertyData));
+ } else {
+ CODEC_THROW(kAudioCodecBadPropertySizeError);
+ }
+ break;
+
+ case kAudioCodecPropertyOutputChannelLayout:
+ if (ioPropertyDataSize >= sizeof(AudioChannelLayout)) {
+ fill_channel_layout(mOutputFormat.mChannelsPerFrame, reinterpret_cast<AudioChannelLayout*>(outPropertyData));
+ } else {
+ CODEC_THROW(kAudioCodecBadPropertySizeError);
+ }
+ break;
+
+ case kAudioCodecPropertyAvailableOutputChannelLayouts:
+ if (ioPropertyDataSize == sizeof(AudioChannelLayoutTag) * kVorbisEncoderOutChannelLayouts) {
+ for (int i = 0; i < kVorbisEncoderOutChannelLayouts; i++) {
+ (reinterpret_cast<AudioChannelLayoutTag*>(outPropertyData))[i] = gOutChannelLayouts[i];
+ }
+ } else {
+ CODEC_THROW(kAudioCodecBadPropertySizeError);
+ }
+ break;
+
case kAudioCodecPropertyAvailableNumberChannels:
if(ioPropertyDataSize == sizeof(UInt32) * 1) {
(reinterpret_cast<UInt32*>(outPropertyData))[0] = 0xffffffff;
@@ -193,8 +223,8 @@
case kAudioCodecPropertyAvailableBitRateRange:
if (ioPropertyDataSize == sizeof(AudioValueRange) * 1) {
- (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMinimum = 1.0;
- (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 480.0;
+ (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMinimum = 8.0;
+ (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 384.0;
} else {
CODEC_THROW(kAudioCodecBadPropertySizeError);
}
@@ -240,7 +270,7 @@
case kAudioCodecPropertyAvailableInputSampleRates:
if (ioPropertyDataSize == sizeof(AudioValueRange)) {
(reinterpret_cast<AudioValueRange*>(outPropertyData))->mMinimum = 0.0;
- (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 0.0;
+ (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 200000.0;
} else {
CODEC_THROW(kAudioCodecBadPropertySizeError);
}
@@ -249,23 +279,22 @@
case kAudioCodecPropertyAvailableOutputSampleRates:
if (ioPropertyDataSize == sizeof(AudioValueRange)) {
(reinterpret_cast<AudioValueRange*>(outPropertyData))->mMinimum = 0.0;
- (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 0.0;
+ (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 200000.0;
} else {
CODEC_THROW(kAudioCodecBadPropertySizeError);
}
break;
-#if !defined(NO_ACS) || NO_ACS == 0
case kAudioCodecPropertySettings:
if (ioPropertyDataSize == sizeof(CFDictionaryRef)) {
- BuildSettings(outPropertyData);
+ if (!BuildSettings(outPropertyData))
+ CODEC_THROW(kAudioCodecUnspecifiedError);
} else {
CODEC_THROW(kAudioCodecBadPropertySizeError);
}
break;
-#endif
case kAudioCodecPropertyRequiresPacketDescription:
@@ -294,6 +323,8 @@
} else {
*reinterpret_cast<UInt32*>(outPropertyData) = 0;
}
+ dbg_printf("[ VE] . [%08lx] :: GetProperty('%4.4s') = %ld\n", (UInt32) this, reinterpret_cast<char*> (&inPropertyID),
+ *reinterpret_cast<UInt32*>(outPropertyData));
}
else
{
@@ -384,17 +415,23 @@
switch(inPropertyID)
{
/*
- case kAudioCodecPropertyInputChannelLayout :
- case kAudioCodecPropertyOutputChannelLayout :
- // by default a codec doesn't support channel layouts.
- CODEC_THROW(kAudioCodecIllegalOperationError);
- break;
case kAudioCodecPropertyAvailableInputChannelLayouts :
- case kAudioCodecPropertyAvailableOutputChannelLayouts :
// by default a codec doesn't support channel layouts.
CODEC_THROW(kAudioCodecIllegalOperationError);
break;
*/
+
+ case kAudioCodecPropertyOutputChannelLayout:
+ case kAudioCodecPropertyInputChannelLayout:
+ outPropertyDataSize = sizeof(AudioChannelLayout);
+ outWritable = false;
+ break;
+
+ case kAudioCodecPropertyAvailableOutputChannelLayouts:
+ outPropertyDataSize = sizeof(AudioChannelLayoutTag) * kVorbisEncoderOutChannelLayouts;
+ outWritable = false;
+ break;
+
case kAudioCodecPropertyAvailableNumberChannels:
outPropertyDataSize = sizeof(UInt32) * 1; // [0xffffffff - any number]
outWritable = false;
@@ -420,12 +457,10 @@
outWritable = false;
break;
-#if !defined(NO_ACS) || NO_ACS == 0
case kAudioCodecPropertySettings:
outPropertyDataSize = sizeof(CFDictionaryRef);
outWritable = true;
break;
-#endif
case kAudioCodecPropertyRequiresPacketDescription:
@@ -477,15 +512,14 @@
dbg_printf("[ VE] >> [%08lx] :: SetProperty('%4.4s')\n", (UInt32) this, reinterpret_cast<char*> (&inPropertyID));
switch(inPropertyID) {
-#if !defined(NO_ACS) || NO_ACS == 0
case kAudioCodecPropertySettings:
if (inPropertyDataSize == sizeof(CFDictionaryRef)) {
- ApplySettings(inPropertyData);
+ if (inPropertyData != NULL)
+ ApplySettings(*reinterpret_cast<const CFDictionaryRef*>(inPropertyData));
} else {
CODEC_THROW(kAudioCodecBadPropertySizeError);
}
break;
-#endif
default:
ACBaseCodec::SetProperty(inPropertyID, inPropertyDataSize, inPropertyData);
@@ -514,12 +548,12 @@
if (!mIsInitialized) {
// check to make sure the input format is legal
if ((inInputFormat.mFormatID != kAudioFormatLinearPCM) ||
+ (inInputFormat.mSampleRate > 200000.0) ||
!(((inInputFormat.mFormatFlags == kAudioFormatFlagsNativeFloatPacked) &&
(inInputFormat.mBitsPerChannel == 32)) ||
((inInputFormat.mFormatFlags == (kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked)) &&
(inInputFormat.mBitsPerChannel == 16))))
{
- dbg_printf("CAVorbisEncoder::SetFormats: only supports either 16 bit native endian signed integer or 32 bit native endian Core Audio floats for input\n");
CODEC_THROW(kAudioCodecUnsupportedFormatError);
}
@@ -534,13 +568,19 @@
{
if (!mIsInitialized) {
// check to make sure the output format is legal
- if (inOutputFormat.mFormatID != kAudioFormatXiphVorbis) {
- dbg_printf("CAVorbisEncoder::SetFormats: only supports Xiph Vorbis for output\n");
+ if (inOutputFormat.mFormatID != kAudioFormatXiphVorbis ||
+ inOutputFormat.mSampleRate > 200000.0) {
CODEC_THROW(kAudioCodecUnsupportedFormatError);
}
// tell our base class about the new format
XCACodec::SetCurrentOutputFormat(inOutputFormat);
+
+ // adjust the default config parameters
+ mCfgBitrate = BitrateMid();
+ if (mOutputFormat.mSampleRate < 8000.0 || mOutputFormat.mSampleRate > 50000.0)
+ mCfgMode = kVorbisEncoderModeQuality;
+ dbg_printf("[ VE] of [%08lx] :: InitializeCompressionSettings() = br:%ld, m:%d\n", (UInt32) this, mCfgBitrate, mCfgMode);
} else {
CODEC_THROW(kAudioCodecStateError);
}
@@ -600,210 +640,6 @@
dbg_printf("[ VE] <.. [%08lx] :: FixFormats()\n", (UInt32) this);
}
-
-Boolean CAVorbisEncoder::BuildSettings(void *outSettingsDict)
-{
- const char *buffer = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
- "<plist version=\"1.0\">"
- "<dict>"
- " <key>name</key>"
- " <string>Xiph Vorbis Encoder</string>"
- " <key>parameters</key>"
- " <array>"
- " <dict>"
- " <key>available values</key>"
- " <array>"
- " <string>Variable Bit Rate (target quality)</string>"
- " <string>Average Bit Rate</string>"
- " <string>Variable Bit Rate (target bit rate)</string>"
- " </array>"
- " <key>current value</key>"
- " <integer>0</integer>"
- " <key>hint</key>"
- " <integer>5</integer>"
- " <key>key</key>"
- " <string>Target Format</string>"
- " <key>name</key>"
- " <string>Bit Rate Format</string>"
- " <key>summary</key>"
- " <string>Vorbis encoding bit rate management mode</string>"
- " <key>value type</key>"
- " <integer>10</integer>"
- " </dict>"
- " <dict>"
- " <key>available values</key>"
- " <array>"
- " <string>16</string>"
- " <string>20</string>"
- " <string>24</string>"
- " <string>28</string>"
- " <string>32</string>"
- " <string>40</string>"
- " <string>48</string>"
- " <string>56</string>"
- " <string>64</string>"
- " <string>80</string>"
- " <string>96</string>"
- " <string>112</string>"
- " <string>128</string>"
- " <string>160</string>"
- " <string>192</string>"
- " <string>224</string>"
- " <string>256</string>"
- " <string>320</string>"
- " </array>"
- " <key>current value</key>"
- " <integer>12</integer>"
- " <key>hint</key>"
- " <integer>4</integer>"
- " <key>key</key>"
- " <string>Bit Rate</string>"
- " <key>limited values</key>"
- " <array>"
- " <string>16</string>"
- " <string>20</string>"
- " <string>24</string>"
- " <string>28</string>"
- " <string>32</string>"
- " <string>40</string>"
- " <string>48</string>"
- " <string>56</string>"
- " <string>64</string>"
- " <string>80</string>"
- " <string>96</string>"
- " <string>112</string>"
- " <string>128</string>"
- " <string>160</string>"
- " <string>192</string>"
- " <string>224</string>"
- " <string>256</string>"
- " <string>320</string>"
- " </array>"
- " <key>name</key>"
- " <string>Target Bit Rate</string>"
- " <key>summary</key>"
- " <string>The bit rate of the Vorbis bitstream produced by the encoder</string>"
- " <key>unit</key>"
- " <string>kbps</string>"
- " <key>value type</key>"
- " <integer>10</integer>"
- " </dict>"
- " <dict>"
- " <key>available values</key>"
- " <array>"
- " <string>Recommended</string>"
- " <string>8.000</string>"
- " <string>11.025</string>"
- " <string>12.000</string>"
- " <string>16.000</string>"
- " <string>22.050</string>"
- " <string>24.000</string>"
- " <string>32.000</string>"
- " <string>44.100</string>"
- " <string>48.000</string>"
- " <string>52.000</string>"
- " </array>"
- " <key>current value</key>"
- " <integer>8</integer>"
- " <key>hint</key>"
- " <integer>6</integer>"
- " <key>key</key>"
- " <string>Sample Rate</string>"
- " <key>limited values</key>"
- " <array>"
- " <string>Recommended</string>"
- " <string>32.000</string>"
- " <string>44.100</string>"
- " </array>"
- " <key>name</key>"
- " <string>Sample Rate</string>"
- " <key>summary</key>"
- " <string>The sample rate of the Vorbis bitstream produced by the encoder</string>"
- " <key>unit</key>"
- " <string>kHz</string>"
- " <key>value type</key>"
- " <integer>10</integer>"
- " </dict>"
- " <dict>"
- " <key>available values</key>"
- " <array>"
- " <string>None</string>"
- " <string>Bit Rate</string>"
- " <string>Sample Rate</string>"
- " </array>"
- " <key>current value</key>"
- " <integer>1</integer>"
- " <key>hint</key>"
- " <integer>13</integer>"
- " <key>key</key>"
- " <string>Precedence</string>"
- " <key>name</key>"
- " <string>Precedence</string>"
- " <key>summary</key>"
- " <string>If either the bit rate or sample rate is allowed to override the other setting</string>"
- " <key>value type</key>"
- " <integer>10</integer>"
- " </dict>"
- " <dict>"
- " <key>available values</key>"
- " <array>"
- " <string>Good</string>"
- " <string>Better</string>"
- " <string>Best</string>"
- " </array>"
- " <key>current value</key>"
- " <integer>1</integer>"
- " <key>hint</key>"
- " <integer>1</integer>"
- " <key>key</key>"
- " <string>Quality</string>"
- " <key>name</key>"
- " <string>Quality</string>"
- " <key>summary</key>"
- " <string>The quality of the encoded Vorbis bitstream</string>"
- " <key>value type</key>"
- " <integer>10</integer>"
- " </dict>"
- " <dict>"
- " <key>available values</key>"
- " <array>"
- " <string>Mono</string>"
- " <string>Stereo</string>"
- " <string>2.0 (2.1?!)</string>"
- " <string>Quadraphonic</string>"
- " <string>5.0</string>"
- " <string>5.1</string>"
- " </array>"
- " <key>current value</key>"
- " <integer>1</integer>"
- " <key>hint</key>"
- " <integer>5</integer>"
- " <key>key</key>"
- " <string>Channel Configuration</string>"
- " <key>limited values</key>"
- " <array>"
- " <string>Stereo</string>"
- " </array>"
- " <key>name</key>"
- " <string>Channel Configuration</string>"
- " <key>summary</key>"
- " <string>The channel layout of the Vorbis bitstream produced by the encoder</string>"
- " <key>value type</key>"
- " <integer>10</integer>"
- " </dict>"
- " </array>"
- "</dict>"
- "</plist>";
- CFDataRef data = CFDataCreate(NULL, (UInt8 *) buffer, strlen(buffer));
- CFDictionaryRef dict = (CFDictionaryRef) CFPropertyListCreateFromXMLData(NULL, data, kCFPropertyListImmutable, NULL);
- if (dict != NULL) {
- *reinterpret_cast<CFDictionaryRef*>(outSettingsDict) = dict;
- return true;
- }
- return false;
-}
-
void CAVorbisEncoder::InitializeCompressionSettings()
{
int ret = 0;
@@ -825,10 +661,35 @@
vorbis_info_init(&mV_vi);
- ret = vorbis_encode_init_vbr(&mV_vi, mOutputFormat.mChannelsPerFrame, lround(mOutputFormat.mSampleRate), 0.4);
+ UInt32 sample_rate = lround(mOutputFormat.mSampleRate);
- if (ret)
+ if (mCfgMode == kVorbisEncoderModeQuality) {
+ ret = vorbis_encode_init_vbr(&mV_vi, mOutputFormat.mChannelsPerFrame, sample_rate, mCfgQuality);
+ } else {
+ UInt32 total_bitrate = mCfgBitrate * 1000;
+ if (mOutputFormat.mChannelsPerFrame > 2)
+ total_bitrate *= mOutputFormat.mChannelsPerFrame;
+
+ dbg_printf("[ VE] .? [%08lx] :: InitializeCompressionSettings() = br:%ld\n", (UInt32) this, total_bitrate);
+
+ if (mCfgMode == kVorbisEncoderModeAverage) {
+ ret = vorbis_encode_init(&mV_vi, mOutputFormat.mChannelsPerFrame, sample_rate, -1, total_bitrate, -1);
+ } else if (mCfgMode == kVorbisEncoderModeQualityByBitrate) {
+ ret = vorbis_encode_setup_managed(&mV_vi, mOutputFormat.mChannelsPerFrame, sample_rate, -1, total_bitrate, -1);
+ if (!ret)
+ ret = vorbis_encode_ctl(&mV_vi, OV_ECTL_RATEMANAGE2_SET, NULL);
+ if (!ret)
+ ret = vorbis_encode_setup_init(&mV_vi);
+ }
+ if (ret)
+ mCfgBitrate = 128;
+ }
+
+ if (ret) {
+ vorbis_info_clear(&mV_vi);
+ dbg_printf("[ VE] <!! [%08lx] :: InitializeCompressionSettings() = %ld\n", (UInt32) this, ret);
CODEC_THROW(kAudioCodecUnspecifiedError);
+ }
vorbis_comment_init(&mV_vc);
vorbis_comment_add_tag(&mV_vc, "ENCODER", "XiphQT, CAVorbisEncoder.cpp $Rev$");
@@ -920,7 +781,6 @@
if (!mIsInitialized)
CODEC_THROW(kAudioCodecStateError);
- UInt32 frames = 0;
UInt32 fout = 0; //frames produced
UInt32 bout = 0; //bytes produced
UInt32 bspace = ioOutputDataByteSize;
@@ -1037,3 +897,413 @@
(UInt32) this, ioNumberPackets, ioOutputDataByteSize, theAnswer);
return theAnswer;
}
+
+/* ======================== Settings ======================= */
+Boolean CAVorbisEncoder::BuildSettings(void *outSettingsDict)
+{
+ Boolean ret = false;
+ SInt32 n, ln;
+ CFNumberRef cf_n;
+ CFMutableDictionaryRef sd;
+ CFMutableDictionaryRef eltd;
+ CFMutableArrayRef params;
+
+ if (mCfgDict == NULL) {
+ sd = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ if (sd == NULL)
+ return ret;
+ CFDictionaryAddValue(sd, CFSTR(kAudioSettings_TopLevelKey), CFSTR("Xiph Vorbis Encoder"));
+ }
+
+ params = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ {
+ eltd = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingKey), CFSTR("Encoding Mode"));
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingName), CFSTR("Encoding Mode"));
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Summary), CFSTR("Vorbis encoding mode."));
+ n = kAudioSettingsFlags_ExpertParameter | kAudioSettingsFlags_MetaParameter;
+ cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Hint), cf_n);
+ CFRelease(cf_n);
+ n = 0;
+ ln = 3;
+ if (mOutputFormat.mSampleRate >= 8000.0 && mOutputFormat.mSampleRate <= 50000.0) {
+ if (mCfgMode == kVorbisEncoderModeAverage)
+ n = 1;
+ else if (mCfgMode == kVorbisEncoderModeQualityByBitrate)
+ n = 2;
+ } else {
+ ln = 1;
+ }
+ cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_CurrentValue), cf_n);
+ CFRelease(cf_n);
+ n = kCFNumberLongType;
+ cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_ValueType), cf_n);
+ CFRelease(cf_n);
+
+ CFStringRef values[4] = {CFSTR("Target Quality"),
+ CFSTR("Average Bit Rate"),
+ CFSTR("Target Bit Rate Quality"),
+ CFSTR("Managed Bit Rate")};
+ CFArrayRef varr = CFArrayCreate(NULL, reinterpret_cast<const void**>(&values), 4, &kCFTypeArrayCallBacks);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_AvailableValues), varr);
+ CFRelease(varr);
+
+ varr = CFArrayCreate(NULL, reinterpret_cast<const void**>(&values), ln, &kCFTypeArrayCallBacks);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_LimitedValues), varr);
+ CFRelease(varr);
+
+ CFArrayAppendValue(params, eltd);
+ CFRelease(eltd);
+ }
+
+ if (mCfgMode == kVorbisEncoderModeQuality) {
+ eltd = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingKey), CFSTR("Encoding Quality"));
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingName), CFSTR("Encoding Quality"));
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Summary), CFSTR("Vorbis encoding quality."));
+ n = 0; // no flags - basic parameter
+ cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Hint), cf_n);
+ CFRelease(cf_n);
+
+ n = lroundf(mCfgQuality * 10.0) + 1;
+ if (n < 0)
+ n = 0;
+ else if (n > 11)
+ n = 11;
+ cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_CurrentValue), cf_n);
+ CFRelease(cf_n);
+
+ n = kCFNumberLongType;
+ cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_ValueType), cf_n);
+ CFRelease(cf_n);
+
+ CFNumberRef values[12];
+ for (UInt32 i = 0; i < 12; i++) {
+ n = i - 1;
+ values[i] = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ }
+ CFArrayRef varr = CFArrayCreate(NULL, reinterpret_cast<const void**>(&values), 12, &kCFTypeArrayCallBacks);
+ for (UInt32 i = 0; i < 12; i++) {
+ CFRelease(values[i]);
+ }
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_AvailableValues), varr);
+ CFRelease(varr);
+
+ CFArrayAppendValue(params, eltd);
+ CFRelease(eltd);
+ } else {
+ eltd = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingKey), CFSTR("Target Bitrate"));
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingName), CFSTR("Target Bitrate"));
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Summary), CFSTR("Target bitrate."));
+ n = 0; // no flags - basic parameter
+ cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Hint), cf_n);
+ CFRelease(cf_n);
+
+ n = ibrn(mCfgBitrate, kVorbisEncoderBitrateSeriesBase);
+ if (n < 0)
+ n = 0;
+ else if (n >= kVorbisEncoderBitrateSeriesLength)
+ n = kVorbisEncoderBitrateSeriesLength - 1;
+ cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_CurrentValue), cf_n);
+ CFRelease(cf_n);
+
+ n = kCFNumberLongType;
+ cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_ValueType), cf_n);
+ CFRelease(cf_n);
+
+ CFNumberRef values[kVorbisEncoderBitrateSeriesLength];
+ SInt32 brs_min = ibrn(BitrateMin(), kVorbisEncoderBitrateSeriesBase);
+ SInt32 brs_max = ibrn(BitrateMax(), kVorbisEncoderBitrateSeriesBase) - 1;
+ if (brs_max >= kVorbisEncoderBitrateSeriesLength)
+ brs_max = kVorbisEncoderBitrateSeriesLength - 1;
+ if (brs_max < brs_min) {
+ CFRelease(eltd);
+ CFRelease(params);
+ return false;
+ }
+
+ for (UInt32 i = 0; i < kVorbisEncoderBitrateSeriesLength; i++) {
+ n = brn(i, kVorbisEncoderBitrateSeriesBase);
+ values[i] = CFNumberCreate(NULL, kCFNumberLongType, &n);
+ }
+ CFArrayRef varr = CFArrayCreate(NULL, reinterpret_cast<const void**>(&values), kVorbisEncoderBitrateSeriesLength, &kCFTypeArrayCallBacks);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_AvailableValues), varr);
+ CFRelease(varr);
+
+ if (brs_min > 0 || brs_max < kVorbisEncoderBitrateSeriesLength - 1) {
+ CFNumberRef *limited = &values[brs_min];
+ brs_max = brs_max + 1 - brs_min;
+ if (brs_max > 0) {
+ varr = CFArrayCreate(NULL, reinterpret_cast<const void**>(limited), brs_max, &kCFTypeArrayCallBacks);
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_LimitedValues), varr);
+ CFRelease(varr);
+ }
+ }
+ for (UInt32 i = 0; i < kVorbisEncoderBitrateSeriesLength; i++) {
+ CFRelease(values[i]);
+ }
+
+ CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Unit), mOutputFormat.mChannelsPerFrame > 2 ? CFSTR("kbps/chan.") : CFSTR("kbps"));
+
+ CFArrayAppendValue(params, eltd);
+ CFRelease(eltd);
+ }
+
+ CFDictionarySetValue(sd, CFSTR(kAudioSettings_Parameters), params);
+ CFRelease(params);
+
+ *reinterpret_cast<CFDictionaryRef*>(outSettingsDict) = sd;
+ ret = true;
+
+ return ret;
+}
+
+Boolean CAVorbisEncoder::ApplySettings(const CFDictionaryRef sd)
+{
+ Boolean ret = false;
+ CFArrayRef params = NULL;
+ CFStringRef name = NULL;
+ CFIndex i, cf_l;
+
+ dbg_printf("[ VE] >> [%08lx] :: ApplySettings()\n", (UInt32) this);
+
+ name = (CFStringRef) CFDictionaryGetValue(sd, CFSTR(kAudioSettings_TopLevelKey));
+ if (name == NULL || CFStringCompare(name, CFSTR("Xiph Vorbis Encoder"), 0) != kCFCompareEqualTo)
+ return ret;
+
+ params = (CFArrayRef) CFDictionaryGetValue(sd, CFSTR(kAudioSettings_Parameters));
+ if (params == NULL)
+ return ret;
+
+ cf_l = CFArrayGetCount(params);
+ for (i = 0; i < cf_l; i++) {
+ CFDictionaryRef eltd = (CFDictionaryRef) CFArrayGetValueAtIndex(params, i);
+ CFStringRef key = (CFStringRef) CFDictionaryGetValue(eltd, CFSTR(kAudioSettings_SettingKey));
+ CFArrayRef available;
+ CFIndex current;
+ CFNumberRef nval;
+
+ if (key == NULL)
+ continue;
+
+ nval = (CFNumberRef) CFDictionaryGetValue(eltd, CFSTR(kAudioSettings_CurrentValue));
+ available = (CFArrayRef) CFDictionaryGetValue(eltd, CFSTR(kAudioSettings_AvailableValues));
+
+ if (nval == NULL || available == NULL)
+ continue;
+
+ if (!CFNumberGetValue(nval, kCFNumberLongType, ¤t))
+ continue;
+
+ if (CFStringCompare(key, CFSTR("Encoding Mode"), 0) == kCFCompareEqualTo) {
+ if (current == 0)
+ mCfgMode = kVorbisEncoderModeQuality;
+ else if (current == 1)
+ mCfgMode = kVorbisEncoderModeAverage;
+ else if (current == 2)
+ mCfgMode = kVorbisEncoderModeQualityByBitrate;
+ else
+ return ret;
+ dbg_printf("[ VE] M [%08lx] :: ApplySettings() :: %d\n", (UInt32) this, mCfgMode);
+ } else if (CFStringCompare(key, CFSTR("Encoding Quality"), 0) == kCFCompareEqualTo) {
+ nval = (CFNumberRef) CFArrayGetValueAtIndex(available, current);
+ SInt32 q = 4;
+ CFNumberGetValue(nval, kCFNumberLongType, &q);
+ if (q < -1 || q > 10)
+ continue;
+ mCfgQuality = (float) q / 10.0;
+ dbg_printf("[ VE] Q [%08lx] :: ApplySettings() :: %1.1f\n", (UInt32) this, mCfgQuality);
+ } else if (CFStringCompare(key, CFSTR("Target Bitrate"), 0) == kCFCompareEqualTo) {
+ nval = (CFNumberRef) CFArrayGetValueAtIndex(available, current);
+ SInt32 br = 4;
+ CFNumberGetValue(nval, kCFNumberLongType, &br);
+ if (br < BitrateMin())
+ br = BitrateMin();
+ else if (br > BitrateMax())
+ br = BitrateMax();
+ mCfgBitrate = br;
+ dbg_printf("[ VE] B [%08lx] :: ApplySettings() :: %ld\n", (UInt32) this, mCfgBitrate);
+ }
+ }
+
+ if (mOutputFormat.mSampleRate < 8000.0 || mOutputFormat.mSampleRate > 50000.0)
+ mCfgMode = kVorbisEncoderModeQuality;
+ dbg_printf("[ VE] !M [%08lx] :: ApplySettings() :: %d\n", (UInt32) this, mCfgMode);
+
+ ret = true;
+ dbg_printf("[ VE] < [%08lx] :: ApplySettings() = %d\n", (UInt32) this, ret);
+ return ret;
+}
+
+
+UInt32 CAVorbisEncoder::ibrn(UInt32 br, UInt32 bs)
+{
+ UInt32 n = -3; // number of bits - 3
+ UInt32 bn = (br - 1) >> bs;
+ UInt32 _br = bn;
+
+ while (bn) {
+ n++;
+ bn >>= 1;
+ };
+
+ if (n < 0)
+ return 0;
+
+ return (n << 2) + ((_br >> n) & 0x03) + 1;
+}
+
+void CAVorbisEncoder::fill_channel_layout(UInt32 nch, AudioChannelLayout *acl)
+{
+ acl->mChannelBitmap = 0;
+ acl->mNumberChannelDescriptions = 0;
+ switch (nch) {
+ case 1:
+ acl->mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
+ break;
+ case 2:
+ acl->mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
+ break;
+ case 3:
+ /* ITU_2_1 used a.t.m, but 3-channel layout shouldn't be
+ accessible, as it's not the proper layout for vorbis */
+ acl->mChannelLayoutTag = kAudioChannelLayoutTag_ITU_2_1;
+ break;
+ case 4:
+ acl->mChannelLayoutTag = kAudioChannelLayoutTag_Quadraphonic;
+ break;
+ case 5:
+ acl->mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_0_C;
+ break;
+ case 6:
+ acl->mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_1_C;
+ break;
+ default:
+ acl->mChannelLayoutTag = kAudioChannelLayoutTag_DiscreteInOrder | nch;
+ break;
+ }
+}
+
+
+/*
+ * Vorbis bitrate limits depend on modes (sample rate + channel
+ * (un)coupling). The values in the following methods are taken from
+ * the current libvorbis sources, and may need to be changed if they
+ * change in libvorbis.
+ */
+
+SInt32 CAVorbisEncoder::BitrateMin()
+{
+ SInt32 br = -1;
+
+ if (mOutputFormat.mChannelsPerFrame == 2) {
+ if (mOutputFormat.mSampleRate < 9000.0)
+ br = 12;
+ else if (mOutputFormat.mSampleRate < 15000.0)
+ br = 16;
+ else if (mOutputFormat.mSampleRate < 19000.0)
+ br = 24;
+ else if (mOutputFormat.mSampleRate < 26000.0)
+ br = 30;
+ else if (mOutputFormat.mSampleRate < 40000.0)
+ br = 36;
+ else if (mOutputFormat.mSampleRate < 50000.0)
+ br = 45;
+ } else {
+ if (mOutputFormat.mSampleRate < 9000.0)
+ br = 8;
+ else if (mOutputFormat.mSampleRate < 15000.0)
+ br = 12;
+ else if (mOutputFormat.mSampleRate < 19000.0)
+ br = 16;
+ else if (mOutputFormat.mSampleRate < 26000.0)
+ br = 16;
+ else if (mOutputFormat.mSampleRate < 40000.0)
+ br = 30;
+ else if (mOutputFormat.mSampleRate < 50000.0)
+ br = 32;
+ }
+
+ return br;
+}
+
+SInt32 CAVorbisEncoder::BitrateMax()
+{
+ SInt32 br = 0;
+
+ if (mOutputFormat.mChannelsPerFrame == 2) {
+ if (mOutputFormat.mSampleRate < 9000.0)
+ br = 64;
+ else if (mOutputFormat.mSampleRate < 15000.0)
+ br = 88;
+ else if (mOutputFormat.mSampleRate < 19000.0)
+ br = 192;
+ else if (mOutputFormat.mSampleRate < 26000.0)
+ br = 192;
+ else if (mOutputFormat.mSampleRate < 40000.0)
+ br = 380;
+ else if (mOutputFormat.mSampleRate < 50000.0)
+ br = 500;
+ } else {
+ if (mOutputFormat.mSampleRate < 9000.0)
+ br = 42;
+ else if (mOutputFormat.mSampleRate < 15000.0)
+ br = 50;
+ else if (mOutputFormat.mSampleRate < 19000.0)
+ br = 100;
+ else if (mOutputFormat.mSampleRate < 26000.0)
+ br = 90;
+ else if (mOutputFormat.mSampleRate < 40000.0)
+ br = 190;
+ else if (mOutputFormat.mSampleRate < 50000.0)
+ br = 240;
+ }
+
+ return br;
+}
+
+SInt32 CAVorbisEncoder::BitrateMid()
+{
+ SInt32 br = 128;
+
+ if (mOutputFormat.mChannelsPerFrame == 2) {
+ if (mOutputFormat.mSampleRate < 9000.0)
+ br = 32;
+ else if (mOutputFormat.mSampleRate < 15000.0)
+ br = 48;
+ else if (mOutputFormat.mSampleRate < 19000.0)
+ br = 86;
+ else if (mOutputFormat.mSampleRate < 26000.0)
+ br = 86;
+ else if (mOutputFormat.mSampleRate < 40000.0)
+ br = 128;
+ else if (mOutputFormat.mSampleRate < 50000.0)
+ br = 128;
+ } else {
+ if (mOutputFormat.mSampleRate < 9000.0)
+ br = 20;
+ else if (mOutputFormat.mSampleRate < 15000.0)
+ br = 24;
+ else if (mOutputFormat.mSampleRate < 19000.0)
+ br = 48;
+ else if (mOutputFormat.mSampleRate < 26000.0)
+ br = 48;
+ else if (mOutputFormat.mSampleRate < 40000.0)
+ br = 96;
+ else if (mOutputFormat.mSampleRate < 50000.0)
+ br = 96;
+ }
+
+ return br;
+}
Modified: trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.h
===================================================================
--- trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.h 2007-01-29 22:37:46 UTC (rev 12393)
+++ trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.h 2007-01-30 01:21:22 UTC (rev 12394)
@@ -89,8 +89,19 @@
virtual void FixFormats();
+ SInt32 BitrateMin();
+ SInt32 BitrateMax();
+ SInt32 BitrateMid();
+
+ /* bitrate-series generator and inverse generator functions */
+ static UInt32 brn(UInt32 n, UInt32 bs) { return (4 + n % 4) << ((n >> 2) + bs); };
+ static UInt32 ibrn(UInt32 br, UInt32 bs);
+
+ static void fill_channel_layout(UInt32 nch, AudioChannelLayout *acl);
+
private:
Boolean BuildSettings(void *outSettingsDict);
+ Boolean ApplySettings(CFDictionaryRef sd);
protected:
Byte* mCookie;
@@ -136,8 +147,27 @@
/* Just a funny number, and only roughly valid for the 'Xiph (Ogg-Framed) Vorbis'. */
kVorbisFormatMaxBytesPerPacket = 255 * 255,
- kVorbisEncoderBufferSize = 256 * 1024
+ kVorbisEncoderBufferSize = 256 * 1024,
+
+ kVorbisEncoderOutChannelLayouts = 5,
+
+ kVorbisEncoderBitrateSeriesLength = 23,
+ kVorbisEncoderBitrateSeriesBase = 1,
};
+
+ static AudioChannelLayoutTag gOutChannelLayouts[kVorbisEncoderOutChannelLayouts];
+
+ /* settings */
+ enum VorbisEncoderMode {
+ kVorbisEncoderModeQuality = 0,
+ kVorbisEncoderModeAverage,
+ kVorbisEncoderModeQualityByBitrate,
+ };
+ VorbisEncoderMode mCfgMode;
+ float mCfgQuality; // [-0.1; 1.0] quality range
+ SInt32 mCfgBitrate; // in kbits
+
+ CFMutableDictionaryRef mCfgDict;
};
#endif /* __CAVorbisEncoder_h__ */
Modified: trunk/xiph-qt/OggExport/src/OggExport.c
===================================================================
--- trunk/xiph-qt/OggExport/src/OggExport.c 2007-01-29 22:37:46 UTC (rev 12393)
+++ trunk/xiph-qt/OggExport/src/OggExport.c 2007-01-30 01:21:22 UTC (rev 12394)
@@ -128,10 +128,16 @@
static ComponentResult mux_streams(OggExportGlobalsPtr globals, DataHandler data_h);
static ComponentResult _setup_std_video(OggExportGlobalsPtr globals, ComponentInstance stdVideo);
+static ComponentResult _setup_std_audio(OggExportGlobalsPtr globals, ComponentInstance stdAudio);
static ComponentResult _get_std_video_config(OggExportGlobalsPtr globals, ComponentInstance stdVideo);
+static ComponentResult _get_std_audio_config(OggExportGlobalsPtr globals, ComponentInstance stdAudio);
static ComponentResult _video_settings_to_ac(OggExportGlobalsPtr globals, QTAtomContainer *settings);
+static ComponentResult _audio_settings_to_ac(OggExportGlobalsPtr globals, QTAtomContainer *settings);
static ComponentResult _ac_to_video_settings(OggExportGlobalsPtr globals, QTAtomContainer settings);
+static ComponentResult _ac_to_audio_settings(OggExportGlobalsPtr globals, QTAtomContainer settings);
+static ComponentResult _preconfig_stdaudio(ComponentInstance stdAudio);
+
static ComponentResult _movie_fps(Movie theMovie, Fixed *fps);
@@ -181,10 +187,16 @@
globals->set_v_custom = NULL;
globals->set_v_ci = NULL;
- globals->set_a_quality = codecNormalQuality;
- globals->set_a_bitrate = 0;
- globals->set_a_samplerate = 0;
+ globals->set_a_rquality = 0x40; //!kRenderQuality_Medium;
+ globals->set_a_settings = NULL;
+ globals->set_a_custom = NULL;
+ globals->set_a_ci = NULL;
+ memset(&globals->set_a_asbd, 0, sizeof(AudioStreamBasicDescription));
+ globals->set_a_asbd.mFormatID = kAudioFormatXiphVorbis;
+ globals->set_a_asbd.mChannelsPerFrame = 6;
+
+
globals->setdlg_a_allow = true;
globals->setdlg_v_allow = true;
@@ -226,6 +238,15 @@
if (globals->set_v_settings)
QTDisposeAtomContainer(globals->set_v_settings);
+ if (globals->set_a_ci)
+ CloseComponent(globals->set_a_ci);
+
+ if (globals->set_a_custom)
+ CFRelease(globals->set_a_custom);
+
+ if (globals->set_a_settings)
+ QTDisposeAtomContainer(globals->set_a_settings);
+
DisposePtr((Ptr) globals);
}
@@ -301,13 +322,19 @@
break;
default:
- err = kQTPropertyNotSupportedErr;
+ //err = kQTPropertyNotSupportedErr;
+ err = QTSetComponentProperty(globals->quickTimeMovieExporter, inPropClass,
+ inPropID, inPropValueSize, inPropValueAddress);
+
break;
}
break;
default:
- err = kQTPropertyNotSupportedErr;
+ //err = kQTPropertyNotSupportedErr;
+ err = QTSetComponentProperty(globals->quickTimeMovieExporter, inPropClass,
+ inPropID, inPropValueSize, inPropValueAddress);
+
break;
}
@@ -384,7 +411,7 @@
dbg_printf("[ OE] >> [%08lx] :: ToDataRef(%d, %ld, %ld)\n", (UInt32) globals, onlyThisTrack != NULL, startTime, duration);
- // TODO: loop for all tracks
+ // TODO: loop for all tracks...?
if (globals->set_v_disable != 1) {
err = MovieExportNewGetDataAndPropertiesProcs(globals->quickTimeMovieExporter, VideoMediaType, &scale, theMovie,
@@ -570,7 +597,6 @@
err = SCRequestSequenceSettings(stdVideo);
if (!err) {
- /* TODO: get config from the stdComp and store it */
if (globals->set_v_settings) {
QTDisposeAtomContainer(globals->set_v_settings);
globals->set_v_settings = NULL;
@@ -582,7 +608,8 @@
}
}
- //CloseComponent(stdVideo);
+ if (globals->set_v_ci == NULL)
+ CloseComponent(stdVideo);
if (ph != NULL)
DisposeHandle((Handle) ph);
@@ -592,6 +619,116 @@
return err;
}
+ComponentResult ConfigAndShowStdAudioDlg(OggExportGlobalsPtr globals, WindowRef window)
+{
+ ComponentResult err = noErr;
+ ComponentInstance stdAudio = globals->set_a_ci;
+ SCExtendedProcs xProcs;
+
+ dbg_printf("[ OE] >> [%08lx] :: ConfigAndShowStdAudioDlg() [%08lx, %08lx]\n", (UInt32) globals, (UInt32) stdAudio, (UInt32) globals->set_a_settings);
+
+ if (stdAudio == NULL) {
+ err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &stdAudio);
+ dbg_printf("[ OE] !a [%08lx] :: ConfigAndShowStdAudioDlg() = %ld [%08lx]\n", (UInt32) globals, err, (UInt32) stdAudio);
+ }
+
+ if (!err) {
+ memset(&xProcs, 0, sizeof(xProcs));
+ strcpy((char*)xProcs.customName + 1, "Select Output Format");
+ xProcs.customName[0] = (unsigned char) strlen((char*) xProcs.customName + 1);
+ (void) QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_ExtendedProcs,
+ sizeof(xProcs), &xProcs);
+
+ if (globals->set_a_settings == NULL) {
+ err = _setup_std_audio(globals, stdAudio);
+ dbg_printf("[ OE] ?' [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+ }
+
+ if (!err && globals->setdlg_movie != NULL) {
+ SoundDescriptionHandle sdh = (SoundDescriptionHandle) NewHandle(0);
+ Media media;
+ Track track = globals->setdlg_track;
+ if (track == NULL)
+ track = GetMovieIndTrackType(globals->setdlg_movie, 1, AudioMediaCharacteristic,
+ movieTrackCharacteristic | movieTrackEnabledOnly);
+ if (track != NULL)
+ media = GetTrackMedia(track);
+
+ if (media != NULL)
+ GetMediaSampleDescription(media, 1, (SampleDescriptionHandle) sdh);
+
+ if (GetHandleSize((Handle) sdh) > 0) {
+ /*
+ SoundDescriptionV2Handle sd2h;
+ QTSoundDescriptionConvert(kQTSoundDescriptionKind_Movie_AnyVersion,
+ (SoundDescriptionHandle) sdh,
+ kQTSoundDescriptionKind_Movie_Version2,
+ &sdh);
+ */
+ err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_InputSoundDescription,
+ sizeof(SoundDescriptionHandle), &sdh);
+ dbg_printf("[ OE] sd [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+ }
+ DisposeHandle((Handle) sdh);
+ } else {
+ /*
+ AudioStreamBasicDescription asbd = { 44100.0, kAudioFormatLinearPCM, kAudioFormatFlagsNativeFloatPacked, 24, 1, 24, 6, 32, 0 };
+
+ err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_InputBasicDescription,
+ sizeof(AudioStreamBasicDescription), &asbd);
+ */
+ err = _preconfig_stdaudio(stdAudio);
+ dbg_printf("[ OE] bd [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+ }
+
+ if (globals->set_a_settings != NULL) {
+ err = SCSetSettingsFromAtomContainer(stdAudio, globals->set_a_settings);
+ dbg_printf("[ OE] ?\" [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+ }
+
+ if (!err) {
+ OSType formats[1] = { kAudioFormatXiphVorbis };
+ err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_ClientRestrictedCompressionFormatList,
+ sizeof(OSType) * 1, formats);
+ dbg_printf("[ OE] fl [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+ }
+
+ if (!err) {
+ QTAtomContainer std_a_settings = NULL;
+ err = SCGetSettingsAsAtomContainer(stdAudio, &std_a_settings);
+ dbg_printf("[ OE] ?S [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+ if (!err) {
+ err = SCSetSettingsFromAtomContainer(stdAudio, std_a_settings);
+ dbg_printf("[ OE] !S [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+ }
+ }
+
+ if (!err)
+ err = SCRequestImageSettings(stdAudio);
+
+ if (!err) {
+ if (globals->set_a_settings) {
+ QTDisposeAtomContainer(globals->set_a_settings);
+ globals->set_a_settings = NULL;
+ }
+ err = SCGetSettingsAsAtomContainer(stdAudio, &globals->set_a_settings);
+ if (err && globals->set_a_settings) {
+ QTDisposeAtomContainer(globals->set_a_settings);
+ globals->set_a_settings = NULL;
+ }
+ }
+
+ if (globals->set_a_ci == NULL)
+ CloseComponent(stdAudio);
+ }
+
+ return err;
+}
+
#if USE_NIB_FILE
static pascal OSStatus SettingsWindowEventHandler(EventHandlerCallRef inHandler, EventRef inEvent, void *inUserData)
{
@@ -644,6 +781,14 @@
//globals->set_v_settings = NULL;
}
+ if (globals->set_a_ci != NULL) {
+ /* result = */ _get_std_audio_config(globals, globals->set_a_ci);
+ } else if (globals->set_a_settings != NULL) {
+ /* result = */ _ac_to_audio_settings(globals, globals->set_a_settings);
+ //QTDisposeAtomContainer(globals->set_v_settings);
+ //globals->set_v_settings = NULL;
+ }
+
QuitAppModalLoopForWindow(window);
result = noErr;
break;
@@ -662,26 +807,10 @@
break;
case 'OEca': /* O(gg)E(xport)c(onfigure)a(udio) */
- {
- SCExtendedProcs xProcs;
- ComponentInstance stdAudio;
+ result = ConfigAndShowStdAudioDlg(globals, window);
+ if (result == userCanceledErr || result == scUserCancelled)
+ result = noErr;
- result = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &stdAudio);
- if (result == noErr) {
- memset(&xProcs, 0, sizeof(xProcs));
- strcpy((char*)xProcs.customName + 1, "Select Output Format");
- xProcs.customName[0] = (unsigned char) strlen((char*) xProcs.customName + 1);
- (void) QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
- kQTSCAudioPropertyID_ExtendedProcs,
- sizeof(xProcs), &xProcs);
-
- result = SCRequestImageSettings(stdAudio);
- if (result == userCanceledErr)
- result = noErr; // User cancelling is ok.
- CloseComponent(stdAudio);
- }
- }
-
break;
case 'OEea': /* O(gg)E(xport)e(nable)a(udio) */
@@ -936,6 +1065,30 @@
goto bail;
}
+ if (globals->set_a_disable == 0) {
+ QTAtomContainer as = NULL;
+ err = noErr;
+ if (globals->set_a_settings != NULL) {
+ as = globals->set_a_settings;
+ } else {
+ err = QTNewAtomContainer(&as);
+ if (!err)
+ err = _audio_settings_to_ac(globals, &as);
+ }
+
+ if (!err) {
+ dbg_printf("[ OE] aAC [%08lx] :: GetSettingsAsAtomContainer() = %ld %ld\n", (UInt32) globals, err, GetHandleSize(as));
+
+ err = QTInsertChildren(ac, kParentAtomIsContainer, as);
+
+ if (globals->set_a_settings == NULL)
+ QTDisposeAtomContainer(as);
+ }
+
+ if (err)
+ goto bail;
+ }
+
bail:
if (err && ac) {
QTDisposeAtomContainer(ac);
@@ -1001,6 +1154,24 @@
goto bail;
}
+ atom = QTFindChildByID(settings, kParentAtomIsContainer, kQTSettingsSound, 1, NULL);
+ if (atom) {
+ if (globals->set_a_settings) {
+ QTDisposeAtomContainer(globals->set_a_settings);
+ globals->set_a_settings = NULL;
+ }
+ err = QTCopyAtom(settings, atom, &globals->set_a_settings);
+ if (err)
+ goto bail;
+ err = _ac_to_audio_settings(globals, globals->set_a_settings);
+
+ //QTDisposeAtomContainer(globals->set_a_settings);
+ //globals->set_a_settings = NULL;
+
+ if (err)
+ goto bail;
+ }
+
bail:
dbg_printf("[ OE] < [%08lx] :: SetSettingsFromAtomContainer() = %d\n", (UInt32) globals, err);
return err;
@@ -1051,55 +1222,36 @@
static OSErr ConfigureQuickTimeMovieExporter(OggExportGlobalsPtr globals)
{
- ComponentInstance stdComp = NULL;
- QTAtomContainer movieExporterSettings = NULL;
+ QTAtomContainer settings = NULL;
OSErr err;
dbg_printf("[ OE] >> [%08lx] :: ConfigureQuickTimeMovieExporter()\n", (UInt32) globals);
- /* TODO: make this function do something */
+ err = MovieExportGetSettingsAsAtomContainer(globals->self, &settings);
+ dbg_printf("[ OE] gO [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
+ if (!err) {
+ /* quicktime movie exporter seems to have problems with 0.0/recommended sample rates in output -
+ removing all the audio atoms for now */
+ QTAtom atom = QTFindChildByID(settings, kParentAtomIsContainer, kQTSettingsSound, 1, NULL);
+ if (atom) {
+ QTRemoveAtom(settings, atom);
+ }
- /*
- // Open the Standard Compression component
- err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &stdAudioCompression);
- if (err)
- goto bail;
+ err = MovieExportSetSettingsFromAtomContainer(globals->quickTimeMovieExporter, settings);
+ dbg_printf("[ OE] sE [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
- // Get the settings atom
- err = SCGetSettingsAsAtomContainer(stdAudioCompression, &movieExporterSettings);
- if (err)
- goto bail;
-
- // Set the compression settings for the QT Movie Exporter
- //err = MovieExportSetSettingsFromAtomContainer(globals->quickTimeMovieExporter, movieExporterSettings);
- */
-
- /*
- if (globals->set_v_settings) {
- err = MovieExportSetSettingsFromAtomContainer(globals->quickTimeMovieExporter, globals->set_v_settings);
- dbg_printf("[ OE] =S [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
- } else {
- err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubType, &stdComp);
if (!err) {
+ err = QTSetComponentProperty(globals->quickTimeMovieExporter, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_RenderQuality,
+ sizeof(UInt32), &globals->set_a_rquality);
+ dbg_printf("[ OE] Rq [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld [%08lx]\n", (UInt32) globals, err, (UInt32) globals->set_a_rquality);
+ err = noErr;
}
}
- */
- err = MovieExportGetSettingsAsAtomContainer(globals->self, &movieExporterSettings);
- dbg_printf("[ OE] gO [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
- if (!err) {
- err = MovieExportSetSettingsFromAtomContainer(globals->quickTimeMovieExporter, movieExporterSettings);
- dbg_printf("[ OE] sE [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
- }
+ if (settings)
+ DisposeHandle(settings);
-
- bail:
- if (stdComp)
- CloseComponent(stdComp);
-
- if (movieExporterSettings)
- DisposeHandle(movieExporterSettings);
-
dbg_printf("[ OE] < [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
return err;
}
@@ -1449,7 +1601,9 @@
if (!err) {
*(OSType *)*codec_types = kXiphComponentsManufacturer;
- err = SCSetInfo(stdVideo, scCodecManufacturerType, &codec_types);
+ HLock(codec_types);
+ err = SCSetInfo(stdVideo, scCodecManufacturerType, *codec_types);
+ HUnlock(codec_types);
}
DisposeHandle(codec_types);
@@ -1467,6 +1621,46 @@
return err;
}
+static ComponentResult _setup_std_audio(OggExportGlobalsPtr globals, ComponentInstance stdAudio)
+{
+ ComponentResult err = noErr;
+ /* isbd's mChannelsPerFrame should be set to the highest number of
+ channels supported by the supported audio encoder, and mSampleRate should be non-zero */
+ AudioStreamBasicDescription isbd = { 44100.0, kAudioFormatLinearPCM, kAudioFormatFlagsNativeFloatPacked, 24, 1, 24, 6, 32, 0 };
+
+ dbg_printf("[ OE] >> [%08lx] :: _setup_std_audio()\n", (UInt32) globals);
+
+ /* Can't set output description (if it contains 0.0 samplerate?) without input format set :( */
+ err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_InputBasicDescription,
+ sizeof(isbd), &isbd);
+ dbg_printf("[ OE] i? [%08lx] :: _setup_std_audio() = %ld\n", (UInt32) globals, err);
+
+ if (!err) {
+ err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_BasicDescription,
+ sizeof(AudioStreamBasicDescription), &globals->set_a_asbd);
+ dbg_printf("[ OE] o! [%08lx] :: _setup_std_audio() = %ld\n", (UInt32) globals, err);
+ }
+
+ if (!err) {
+ err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_RenderQuality,
+ sizeof(UInt32), &globals->set_a_rquality);
+ dbg_printf("[ OE] rq [%08lx] :: _setup_std_audio() = %ld [%08lx]\n", (UInt32) globals, err, (UInt32) globals->set_a_rquality);
+ }
+
+ if (!err && globals->set_a_custom != NULL) {
+ err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_CodecSpecificSettingsArray,
+ sizeof(CFArrayRef), &globals->set_a_custom);
+ dbg_printf("[ OE] cs [%08lx] :: _setup_std_audio() = %ld\n", (UInt32) globals, err);
+ }
+
+ dbg_printf("[ OE] < [%08lx] :: _setup_std_audio() = %ld [%08lx]\n", (UInt32) globals, err, (UInt32) stdAudio);
+ return err;
+}
+
static ComponentResult _get_std_video_config(OggExportGlobalsPtr globals, ComponentInstance stdVideo)
{
ComponentResult err = noErr;
@@ -1506,6 +1700,53 @@
return err;
}
+static ComponentResult _get_std_audio_config(OggExportGlobalsPtr globals, ComponentInstance stdAudio)
+{
+ ComponentResult err = noErr;
+ Boolean tmpbool = false;
+
+ err = QTGetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_BasicDescription,
+ sizeof(AudioStreamBasicDescription),
+ &globals->set_a_asbd, NULL);
+
+ if (!err) {
+ err = QTGetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_SampleRateIsRecommended,
+ sizeof(Boolean),
+ &tmpbool, NULL);
+ if (!err && tmpbool)
+ globals->set_a_asbd.mSampleRate = 0.0;
+ dbg_printf("[ OE] rec [%08lx] :: _get_std_audio_config() = %ld, %d\n", (UInt32) globals, err, tmpbool);
+ }
+
+ if (!err) {
+ err = QTGetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_RenderQuality,
+ sizeof(UInt32),
+ &globals->set_a_rquality, NULL);
+ }
+
+ if (!err) {
+ if (globals->set_a_custom != NULL) {
+ CFRelease(globals->set_a_custom);
+ globals->set_a_custom = NULL;
+ }
+ err = QTGetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_CodecSpecificSettingsArray,
+ sizeof(CFArrayRef),
+ &globals->set_a_custom, NULL);
+ if (err && globals->set_a_custom != NULL) {
+ CFRelease(globals->set_a_custom);
+ globals->set_a_custom = NULL;
+ } else if (!err) {
+ CFRetain(globals->set_a_custom);
+ }
+ }
+
+ return err;
+}
+
static ComponentResult _video_settings_to_ac(OggExportGlobalsPtr globals, QTAtomContainer *settings)
{
ComponentResult err = noErr;
@@ -1528,6 +1769,29 @@
return err;
}
+static ComponentResult _audio_settings_to_ac(OggExportGlobalsPtr globals, QTAtomContainer *settings)
+{
+ ComponentResult err = noErr;
+ ComponentInstance stdAudio = NULL;
+
+ dbg_printf("[ OE] >> [%08lx] :: _audio_settings_to_ac()\n", (UInt32) globals);
+
+ err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &stdAudio);
+
+ if (!err) {
+ err = _setup_std_audio(globals, stdAudio);
+ dbg_printf("[ OE] .? [%08lx] :: _audio_settings_to_ac() = %ld\n", (UInt32) globals, err);
+
+ if (!err)
+ err = SCGetSettingsAsAtomContainer(stdAudio, settings);
+
+ CloseComponent(stdAudio);
+ }
+
+ dbg_printf("[ OE] < [%08lx] :: _audio_settings_to_ac() = %d [%ld]\n", (UInt32) globals, err, GetHandleSize(*settings));
+ return err;
+}
+
static ComponentResult _ac_to_video_settings(OggExportGlobalsPtr globals, QTAtomContainer settings)
{
ComponentResult err = noErr;
@@ -1551,6 +1815,45 @@
return err;
}
+static ComponentResult _ac_to_audio_settings(OggExportGlobalsPtr globals, QTAtomContainer settings)
+{
+ ComponentResult err = noErr;
+ ComponentInstance stdAudio = NULL;
+
+ dbg_printf("[ OE] >> [%08lx] :: _ac_to_audio_settings() [%ld]\n", (UInt32) globals, GetHandleSize(settings));
+
+ err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &stdAudio);
+
+ if (!err)
+ err = _preconfig_stdaudio(stdAudio);
+
+ if (!err) {
+ err = SCSetSettingsFromAtomContainer(stdAudio, settings);
+
+ if (!err)
+ err = _get_std_audio_config(globals, stdAudio);
+
+ CloseComponent(stdAudio);
+ }
+
+ dbg_printf("[ OE] < [%08lx] :: _ac_to_audio_settings() = %ld\n", (UInt32) globals, err);
+ return err;
+}
+
+static ComponentResult _preconfig_stdaudio(ComponentInstance stdAudio)
+{
+ ComponentResult err = noErr;
+ /* Can't set output description (if it contains 0.0 samplerate?) without input format set :( */
+ AudioStreamBasicDescription isbd = { 44100.0, kAudioFormatLinearPCM, kAudioFormatFlagsNativeFloatPacked, 24, 1, 24, 6, 32, 0 };
+
+ err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_InputBasicDescription,
+ sizeof(isbd), &isbd);
+
+ dbg_printf("[ OE] = [%08lx] :: _preconfig_stdaudio() = %ld\n", (UInt32) -1, err);
+ return err;
+}
+
static ComponentResult _movie_fps(Movie theMovie, Fixed *fps)
{
ComponentResult err = noErr;
Modified: trunk/xiph-qt/OggExport/src/exporter_types.h
===================================================================
--- trunk/xiph-qt/OggExport/src/exporter_types.h 2007-01-29 22:37:46 UTC (rev 12393)
+++ trunk/xiph-qt/OggExport/src/exporter_types.h 2007-01-30 01:21:22 UTC (rev 12394)
@@ -136,9 +136,11 @@
Handle set_v_custom;
ComponentInstance set_v_ci;
- CodecQ set_a_quality;
- UInt32 set_a_bitrate;
- Float64 set_a_samplerate;
+ CodecQ set_a_rquality; /**< processing chain's render quality */
+ AudioStreamBasicDescription set_a_asbd; /**< audio codec's target output format settings */
+ QTAtomContainer set_a_settings; /**< all audio codec's settings */
+ CFArrayRef set_a_custom; /**< specific codec-only settings */
+ ComponentInstance set_a_ci;
/* settings dialog vars */
Boolean setdlg_a_allow;
Modified: trunk/xiph-qt/OggExport/src/stream_audio.c
===================================================================
--- trunk/xiph-qt/OggExport/src/stream_audio.c 2007-01-29 22:37:46 UTC (rev 12393)
+++ trunk/xiph-qt/OggExport/src/stream_audio.c 2007-01-30 01:21:22 UTC (rev 12394)
@@ -37,6 +37,9 @@
#include "debug.h"
+extern ComponentResult _audio_settings_to_ac(OggExportGlobalsPtr globals, QTAtomContainer *settings);
+
+
static ComponentResult
_flush_ogg(StreamInfoPtr si, DataHandler data_h, wide *offset)
{
@@ -114,7 +117,7 @@
StreamInfoPtr si = (StreamInfoPtr) inRefCon;
ComponentResult err = noErr;
- dbg_printf("[ OE] >> [%08lx] :: _InputDataProc__audio(%ld)\n",
+ dbg_printf("[ aOE] >> [%08lx] :: _InputDataProc__audio(%ld)\n",
(UInt32) -1, *ioNumberDataPackets);
*ioNumberDataPackets = 0;
@@ -138,7 +141,7 @@
err = InvokeMovieExportGetDataUPP(si->refCon, &si->gdp,
si->getDataProc);
- dbg_printf("[ OE] < [%08lx] :: _InputDataProc__audio() = %ld; "
+ dbg_printf("[ aOE] < [%08lx] :: _InputDataProc__audio() = %ld; "
"%ld, %ld, %ld, %ld, %ld)\n",
(UInt32) -1, err, *ioNumberDataPackets, si->gdp.dataSize,
si->gdp.requestedTime, si->gdp.actualTime, ioData->mNumberBuffers);
@@ -172,7 +175,7 @@
si->gdp.requestedTime = si->gdp.actualTime = 0;
}
- dbg_printf("[ OE] < [%08lx] :: _InputDataProc__audio(%ld, "
+ dbg_printf("[ aOE] < [%08lx] :: _InputDataProc__audio(%ld, "
"%ld, %ld, %ld, %ld, %d) = %ld\n",
(UInt32) -1, *ioNumberDataPackets, si->gdp.dataSize,
si->gdp.requestedTime, si->gdp.actualTime, ioData->mNumberBuffers,
@@ -332,7 +335,7 @@
if (!err) {
sd = (SoundDescriptionV2Ptr) *sdh;
- dbg_printf("[ OE] i [%08lx] :: configure_stream__audio() = %ld, '%4.4s' ('%4.4s', %d, %d, '%4.4s', [%ld, %ld, %lf] [%ld, %ld, %ld, %ld])\n",
+ dbg_printf("[ aOE] i [%08lx] :: configure_stream__audio() = %ld, '%4.4s' ('%4.4s', %d, %d, '%4.4s', [%ld, %ld, %lf] [%ld, %ld, %ld, %ld])\n",
(UInt32) globals, err, (char *) &si->gdp.descType,
(char *) &sd->dataFormat, sd->version, sd->revlevel, (char *) &sd->vendor,
sd->numAudioChannels, sd->constBitsPerChannel, sd->audioSampleRate,
@@ -359,14 +362,14 @@
err = QTSoundDescriptionGetPropertyInfo(sdh, kQTPropertyClass_SoundDescription,
kQTSoundDescriptionPropertyID_AudioChannelLayout,
NULL, &acl_size, NULL);
- dbg_printf("[ OE] cl [%08lx] :: configure_stream__audio() = %ld, %ld\n",
+ dbg_printf("[ aOE] cl [%08lx] :: configure_stream__audio() = %ld, %ld\n",
(UInt32) globals, err, acl_size);
if (!err) {
acl = (AudioChannelLayout *) calloc(1, acl_size);
err = QTSoundDescriptionGetProperty(sdh, kQTPropertyClass_SoundDescription,
kQTSoundDescriptionPropertyID_AudioChannelLayout,
acl_size, acl, NULL);
- dbg_printf("[ OE] CL [%08lx] :: configure_stream__audio() = %ld, {0x%08lx, %ld, %ld}\n",
+ dbg_printf("[ aOE] CL [%08lx] :: configure_stream__audio() = %ld, {0x%08lx, %ld, %ld}\n",
(UInt32) globals, err, acl->mChannelLayoutTag,
acl->mChannelBitmap, acl->mNumberChannelDescriptions);
} else {
@@ -376,6 +379,7 @@
DisposeHandle((Handle) sdh);
+#if 0
if (!acl) {
acl_size = sizeof(AudioChannelLayout);
acl = (AudioChannelLayout *) calloc(1, acl_size);
@@ -385,20 +389,21 @@
acl->mChannelBitmap = 0;
acl->mNumberChannelDescriptions = 0;
}
+#endif
err = QTSetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio, kQTSCAudioPropertyID_InputBasicDescription,
sizeof(si->si_a.qte_out_asbd), &si->si_a.qte_out_asbd);
- dbg_printf("[ OE] iD [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
+ dbg_printf("[ aOE] iD [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
{
AudioStreamBasicDescription *asbd = &si->si_a.qte_out_asbd;
- dbg_printf("[ OE] iD [%08lx] :: configure_stream__audio() = %ld, {%lf, '%4.4s', %04lx, %ld, %ld, %ld, %ld, %ld}\n", (UInt32) globals, err,
+ dbg_printf("[ aOE] iD [%08lx] :: configure_stream__audio() = %ld, {%lf, '%4.4s', %04lx, %ld, %ld, %ld, %ld, %ld}\n", (UInt32) globals, err,
asbd->mSampleRate, (char *) &asbd->mFormatID, asbd->mFormatFlags, asbd->mBytesPerPacket, asbd->mFramesPerPacket,
asbd->mBytesPerFrame, asbd->mChannelsPerFrame, asbd->mBitsPerChannel);
}
- if (!err) {
+ if (!err && acl != NULL && false) {
err = QTSetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio, kQTSCAudioPropertyID_InputChannelLayout,
acl_size, acl);
- dbg_printf("[ OE] iL [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
+ dbg_printf("[ aOE] iL [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
if (err)
err = noErr;
}
@@ -406,18 +411,33 @@
}
if (!err) {
- /* TODO: this config should be taken from saved settings or user
- * dialog (efectively, that's saved settings as well)
- */
- AudioStreamBasicDescription asbd = {si->si_a.qte_out_asbd.mSampleRate,
- kAudioFormatXiphVorbis, 0, 0, 0, 0,
- si->si_a.qte_out_asbd.mChannelsPerFrame, 0};
+ AudioStreamBasicDescription asbd = {globals->set_a_asbd.mSampleRate, globals->set_a_asbd.mFormatID,
+ globals->set_a_asbd.mFormatFlags, globals->set_a_asbd.mBytesPerPacket,
+ globals->set_a_asbd.mFramesPerPacket, globals->set_a_asbd.mBytesPerFrame,
+ //si->si_a.qte_out_asbd.mChannelsPerFrame,
+ globals->set_a_asbd.mChannelsPerFrame,
+ 0};
+
err = QTSetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio,
kQTSCAudioPropertyID_BasicDescription,
sizeof(asbd), &asbd);
- dbg_printf("[ OE] iO [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
+ dbg_printf("[ aOE] iO [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
if (!err) {
+ err = QTSetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_RenderQuality,
+ sizeof(UInt32), &globals->set_a_rquality);
+ dbg_printf("[ aOE] rq [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
+ }
+
+ if (!err && globals->set_a_custom != NULL) {
+ err = QTSetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_CodecSpecificSettingsArray,
+ sizeof(CFArrayRef), &globals->set_a_custom);
+ dbg_printf("[ aOE] cs [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
+ }
+
+ if (!err) {
err = QTGetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio,
kQTSCAudioPropertyID_BasicDescription,
sizeof(si->si_a.stda_asbd), &si->si_a.stda_asbd, NULL);
@@ -425,7 +445,7 @@
if (!err) {
if (si->si_a.stda_asbd.mBytesPerPacket) {
- si->si_a.max_packet_size = asbd.mBytesPerPacket;
+ si->si_a.max_packet_size = si->si_a.stda_asbd.mBytesPerPacket;
} else {
err = QTGetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio,
kQTSCAudioPropertyID_MaximumOutputPacketSize,
@@ -433,7 +453,7 @@
&si->si_a.max_packet_size, NULL);
}
}
- dbg_printf("[ OE] xp [%08lx] :: configure_stream__audio() (%ld)\n", (UInt32) globals, si->si_a.max_packet_size);
+ dbg_printf("[ aOE] xp [%08lx] :: configure_stream__audio() (%ld)\n", (UInt32) globals, si->si_a.max_packet_size);
}
if (acl) {
@@ -460,7 +480,7 @@
UInt32 max_page_duration = (UInt32) (max_duration *
si->si_a.stda_asbd.mSampleRate);
- dbg_printf("[ OE] >> [%08lx] :: fill_page__audio(%lf)\n",
+ dbg_printf("[ aOE] >> [%08lx] :: fill_page__audio(%lf)\n",
(UInt32) globals, max_duration);
if (ogg_stream_pageout(&si->os, &si->og) > 0) {
@@ -514,7 +534,7 @@
err = SCAudioFillBuffer(si->si_a.stdAudio, _InputDataProc__audio,
(void *) si, (UInt32 *) &pull_packets,
abl, aspds);
- dbg_printf("[ OE] . [%08lx] :: fill_page__audio(): "
+ dbg_printf("[ aOE] . [%08lx] :: fill_page__audio(): "
"SCAudioFillBuffer(%ld) = %ld, eos: %d\n",
(UInt32) globals, pull_packets, err,
pull_packets == 0 &&
@@ -540,7 +560,7 @@
si->acc_packets++;
si->acc_duration += si->si_a.op_duration;
result = ogg_stream_packetin(&si->os, &si->si_a.op);
- dbg_printf("[ OE] _i [%08lx] :: fill_page__audio(): "
+ dbg_printf("[ aOE] _i [%08lx] :: fill_page__audio(): "
"ogg_stream_packetin(%lld, %ld, %lld) = %d\n",
(UInt32) globals, si->si_a.op.packetno,
si->si_a.op.bytes, si->si_a.op.granulepos,
@@ -563,7 +583,7 @@
si->si_a.op.packet = (UInt8 *) abl->mBuffers[0].mData +
aspds[i].mStartOffset;
result = ogg_stream_packetin(&si->os, &si->si_a.op);
- dbg_printf("[ OE] i [%08lx] :: fill_page__audio(): "
+ dbg_printf("[ aOE] i [%08lx] :: fill_page__audio(): "
"ogg_stream_packetin(%lld, %ld, %lld) = %d\n",
(UInt32) globals, si->si_a.op.packetno,
si->si_a.op.bytes, si->si_a.op.granulepos,
@@ -600,7 +620,7 @@
}
}
- dbg_printf("[ OE] < [%08lx] :: fill_page__audio() = %ld (%ld, %lf)\n",
+ dbg_printf("[ aOE] < [%08lx] :: fill_page__audio() = %ld (%ld, %lf)\n",
(UInt32) globals, err, si->og_ts_sec, si->og_ts_subsec);
return err;
}
More information about the commits
mailing list