Ticket #5900: audioencoding-fixes-jya13.patch
File audioencoding-fixes-jya13.patch, 91.8 KB (added by , 15 years ago) |
---|
-
mythplugins/mythmusic/mythmusic/main.cpp
diff -Naur --exclude=.svn a/mythplugins/mythmusic/mythmusic/main.cpp c/mythplugins/mythmusic/mythmusic/main.cpp
a c 378 378 REG_KEY("Music", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 379 379 REG_KEY("Music", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 380 380 REG_KEY("Music", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 381 REG_KEY("Music", "TOGGLEUPMIX","Toggle upmixer", "Ctrl+U"); 381 382 REG_KEY("Music", "CYCLEVIS", "Cycle visualizer mode", "6"); 382 383 REG_KEY("Music", "BLANKSCR", "Blank screen", "5"); 383 384 REG_KEY("Music", "THMBUP", "Increase rating", "9"); -
mythplugins/mythmusic/mythmusic/musicplayer.cpp
diff -Naur --exclude=.svn a/mythplugins/mythmusic/mythmusic/musicplayer.cpp c/mythplugins/mythmusic/mythmusic/musicplayer.cpp
a c 347 347 348 348 void MusicPlayer::openOutputDevice(void) 349 349 { 350 QString adevice ;350 QString adevice, pdevice; 351 351 352 352 if (gContext->GetSetting("MusicAudioDevice") == "default") 353 353 adevice = gContext->GetSetting("AudioOutputDevice"); 354 354 else 355 355 adevice = gContext->GetSetting("MusicAudioDevice"); 356 356 357 if (!gContext->GetNumSetting("MythAC3Upmix", 0)) 358 pdevice = "default"; 359 else 360 pdevice = gContext->GetSetting("PassThruOutputDevice"); 361 357 362 // TODO: Error checking that device is opened correctly! 358 m_output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100,363 m_output = AudioOutput::OpenAudio(adevice, pdevice, 16, 2, 44100, 359 364 AUDIOOUTPUT_MUSIC, true, false); 360 365 m_output->setBufferSize(256 * 1024); 361 366 m_output->SetBlocking(false); -
mythplugins/mythmusic/mythmusic/playbackbox.cpp
diff -Naur --exclude=.svn a/mythplugins/mythmusic/mythmusic/playbackbox.cpp c/mythplugins/mythmusic/mythmusic/playbackbox.cpp
a c 358 358 changeSpeed(true); 359 359 else if (action == "MUTE") 360 360 toggleMute(); 361 else if (action == "TOGGLEUPMIX") 362 toggleUpmix(); 361 363 else if (action == "MENU" && visualizer_status != 2) 362 364 { 363 365 menufilters = false; … … 1178 1180 } 1179 1181 } 1180 1182 1183 void PlaybackBoxMusic::toggleUpmix() 1184 { 1185 if (gPlayer->getOutput()) 1186 gPlayer->getOutput()->ToggleUpmix(); 1187 } 1188 1189 1181 1190 void PlaybackBoxMusic::showProgressBar() 1182 1191 { 1183 1192 if (progress_bar) -
mythplugins/mythmusic/mythmusic/playbackbox.h
diff -Naur --exclude=.svn a/mythplugins/mythmusic/mythmusic/playbackbox.h c/mythplugins/mythmusic/mythmusic/playbackbox.h
a c 69 69 void changeVolume(bool up_or_down); 70 70 void changeSpeed(bool up_or_down); 71 71 void toggleMute(); 72 void toggleUpmix(); 72 73 void resetTimer(); 73 74 void hideVolume(){showVolume(false);} 74 75 void showVolume(bool on_or_off); -
mythtv/libs/libmyth/audiooutput.cpp
diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutput.cpp c/mythtv/libs/libmyth/audiooutput.cpp
a c 36 36 int audio_bits, 37 37 int audio_channels, int audio_samplerate, 38 38 AudioOutputSource source, 39 bool set_initial_vol, bool audio_passthru )39 bool set_initial_vol, bool audio_passthru, bool AC3upmix) 40 40 { 41 41 if (passthru_device.isEmpty() || passthru_device.lower() == "default") 42 42 passthru_device = main_device; … … 47 47 return new AudioOutputALSA(main_device.remove(0, 5), 48 48 passthru_device.remove(0, 5), audio_bits, 49 49 audio_channels, audio_samplerate, source, 50 set_initial_vol, audio_passthru );50 set_initial_vol, audio_passthru, AC3upmix); 51 51 #else 52 52 VERBOSE(VB_IMPORTANT, "Audio output device is set to an ALSA device " 53 53 "but ALSA support is not compiled in!"); -
mythtv/libs/libmyth/audiooutput.h
diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutput.h c/mythtv/libs/libmyth/audiooutput.h
a c 22 22 int audio_bits, 23 23 int audio_channels, int audio_samplerate, 24 24 AudioOutputSource source, 25 bool set_initial_vol, bool audio_passthru );25 bool set_initial_vol, bool audio_passthru, bool AC3upmix=false); 26 26 27 27 AudioOutput() : 28 28 VolumeBase(), OutputListeners(), 29 lastError(QString::null), lastWarn(QString::null) {} 29 isAC3upmix(false), 30 lastError(QString::null), lastWarn(QString::null) { }; 30 31 31 32 virtual ~AudioOutput() { }; 32 33 … … 39 40 40 41 virtual void SetStretchFactor(float factor); 41 42 virtual float GetStretchFactor(void) { return 1.0f; } 43 virtual bool ToggleUpmix(void) = 0; 44 bool isAC3upmix; 42 45 43 46 // do AddSamples calls block? 44 47 virtual void SetBlocking(bool blocking) = 0; -
mythtv/libs/libmyth/audiooutputalsa.cpp
diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputalsa.cpp c/mythtv/libs/libmyth/audiooutputalsa.cpp
a c 8 8 9 9 #include "mythcontext.h" 10 10 #include "audiooutputalsa.h" 11 #include "audiooutputdigitalencoder.h" 11 12 12 13 #define LOC QString("ALSA: ") 13 14 #define LOC_WARN QString("ALSA, Warning: ") … … 17 18 QString laudio_main_device, QString laudio_passthru_device, 18 19 int laudio_bits, int laudio_channels, 19 20 int laudio_samplerate, AudioOutputSource lsource, 20 bool lset_initial_vol, bool laudio_passthru) : 21 bool lset_initial_vol, bool laudio_passthru, 22 bool AC3upmix) : 21 23 AudioOutputBase(laudio_main_device, laudio_passthru_device, 22 24 laudio_bits, laudio_channels, 23 25 laudio_samplerate, lsource, 24 lset_initial_vol, laudio_passthru), 26 lset_initial_vol, laudio_passthru, 27 AC3upmix), 25 28 pcm_handle(NULL), numbadioctls(0), 26 29 killAudioLock(false), mixer_handle(NULL), 27 30 mixer_control(QString::null), volume_range_multiplier(1.0f), … … 35 38 AudioOutputALSA::~AudioOutputALSA() 36 39 { 37 40 KillAudio(); 41 if (isAC3upmix) 42 SetIECStatus(true); 43 } 44 45 void AudioOutputALSA::SetIECStatus(bool audio) { 46 47 snd_ctl_t *ctl; 48 const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT); 49 int spdif_index = -1; 50 snd_ctl_elem_list_t *clist; 51 snd_ctl_elem_id_t *cid; 52 snd_ctl_elem_value_t *cval; 53 snd_aes_iec958_t iec958; 54 int cidx, controls; 55 56 VERBOSE(VB_AUDIO, QString("Setting IEC958 status: %1") 57 .arg(audio ? "audio" : "non-audio")); 58 59 int err; 60 if ((err = snd_ctl_open(&ctl, "default", 0)) < 0) 61 { 62 Error(QString("AudioOutputALSA::SetIECStatus: snd_ctl_open(default): %1") 63 .arg(snd_strerror(err))); 64 return; 65 } 66 snd_ctl_elem_list_alloca(&clist); 67 snd_ctl_elem_list(ctl, clist); 68 snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist)); 69 snd_ctl_elem_list(ctl, clist); 70 controls = snd_ctl_elem_list_get_used(clist); 71 for (cidx = 0; cidx < controls; cidx++) 72 { 73 if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str)) 74 if (spdif_index < 0 || 75 snd_ctl_elem_list_get_index(clist, cidx) == (uint)spdif_index) 76 break; 77 } 78 79 if (cidx >= controls) 80 return; 81 82 snd_ctl_elem_id_alloca(&cid); 83 snd_ctl_elem_list_get_id(clist, cidx, cid); 84 snd_ctl_elem_value_alloca(&cval); 85 snd_ctl_elem_value_set_id(cval, cid); 86 snd_ctl_elem_read(ctl,cval); 87 snd_ctl_elem_value_get_iec958(cval, &iec958); 88 89 if (!audio) 90 iec958.status[0] |= IEC958_AES0_NONAUDIO; 91 else 92 iec958.status[0] &= ~IEC958_AES0_NONAUDIO; 93 94 snd_ctl_elem_value_set_iec958(cval, &iec958); 95 snd_ctl_elem_write(ctl, cval); 96 38 97 } 39 98 40 99 bool AudioOutputALSA::OpenDevice() … … 42 101 snd_pcm_format_t format; 43 102 unsigned int buffer_time, period_time; 44 103 int err; 104 QString real_device; 45 105 46 106 if (pcm_handle != NULL) 47 107 CloseDevice(); … … 49 109 pcm_handle = NULL; 50 110 numbadioctls = 0; 51 111 52 QString real_device = (audio_passthru) ? 53 audio_passthru_device : audio_main_device; 112 if (!isAC3upmix) { 113 real_device = (audio_passthru) ? 114 audio_passthru_device : audio_main_device; 115 } 116 else 117 if (audio_passthru || audio_enc) 118 { 119 real_device = audio_passthru_device; 120 SetIECStatus(false); 121 } 122 else 123 { 124 real_device = audio_main_device; 125 SetIECStatus(true); 126 } 54 127 55 128 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 56 129 .arg(real_device)); … … 148 221 } 149 222 150 223 224 void AudioOutputALSA::reorder_6ch_ac3(void *buf, unsigned int len) { 225 unsigned short *src = (unsigned short *)buf; 226 unsigned short tmp; 227 unsigned int samples = len >> 1; 228 229 for (uint i = 0; i < samples; i += 6) { 230 tmp = src[i+1]; 231 src[i+1] = src[i+2]; 232 src[i+2] = src[i+3]; 233 src[i+3] = src[i+4]; 234 src[i+4] = tmp; 235 } 236 } 237 151 238 void AudioOutputALSA::WriteAudio(unsigned char *aubuf, int size) 152 239 { 153 240 unsigned char *tmpbuf; … … 159 246 VERBOSE(VB_IMPORTANT, QString("WriteAudio() called with pcm_handle == NULL!")); 160 247 return; 161 248 } 162 249 250 // Re-Order channels mapping if analog output is used and source is AC3 multi-channels 251 if (isAC3upmix && !audio_passthru 252 && audio_codec && (audio_codec->codec_id == CODEC_ID_AC3) 253 && (source_audio_channels > 2)) { 254 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 255 QString("WriteAudio: Re-ordering audio channels %1 bytes (%2 frames)") 256 .arg(size).arg(frames)); 257 reorder_6ch_ac3(aubuf, size); 258 } 163 259 tmpbuf = aubuf; 164 260 165 261 VERBOSE(VB_AUDIO|VB_TIMESTAMP, -
mythtv/libs/libmyth/audiooutputalsa.h
diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputalsa.h c/mythtv/libs/libmyth/audiooutputalsa.h
a c 20 20 int laudio_bits, 21 21 int laudio_channels, int laudio_samplerate, 22 22 AudioOutputSource source, 23 bool set_initial_vol, bool laudio_passthru); 23 bool set_initial_vol, bool laudio_passthru, 24 bool AC3upmix = false); 24 25 virtual ~AudioOutputALSA(); 25 26 26 27 // Volume control … … 37 38 virtual inline int getBufferedOnSoundcard(void); 38 39 39 40 private: 41 void SetIECStatus(bool audio); 40 42 inline int SetParameters(snd_pcm_t *handle, 41 43 snd_pcm_format_t format, unsigned int channels, 42 44 unsigned int rate, unsigned int buffer_time, … … 49 51 void CloseMixer(void); 50 52 void SetupMixer(void); 51 53 void GetVolumeRange(snd_mixer_elem_t *elem); 54 void reorder_6ch_ac3(void *buf, unsigned int len); 52 55 53 56 private: 54 57 snd_pcm_t *pcm_handle; -
mythtv/libs/libmyth/audiooutputbase.cpp
diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputbase.cpp c/mythtv/libs/libmyth/audiooutputbase.cpp
a c 27 27 QString laudio_main_device, QString laudio_passthru_device, 28 28 int /*laudio_bits*/, int /*laudio_channels*/, 29 29 int /*laudio_samplerate*/, AudioOutputSource lsource, 30 bool lset_initial_vol, bool /*laudio_passthru*/) : 30 bool lset_initial_vol, bool /*laudio_passthru*/, 31 bool AC3upmix) : 31 32 32 33 effdsp(0), effdspstretched(0), 33 34 audio_channels(-1), audio_bytes_per_sample(0), … … 37 38 38 39 audio_main_device(QDeepCopy<QString>(laudio_main_device)), 39 40 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 40 audio_passthru(false), audio_stretchfactor(1.0f), 41 audio_passthru(false), audio_enc(false), 42 audio_reenc(false), audio_stretchfactor(1.0f), 41 43 42 44 audio_codec(NULL), 43 45 source(lsource), killaudio(false), … … 54 56 pSoundStretch(NULL), 55 57 encoder(NULL), 56 58 upmixer(NULL), 59 57 60 source_audio_channels(-1), 61 source_audio_samplerate(0), 58 62 source_audio_bytes_per_sample(0), 59 63 needs_upmix(false), 60 64 surround_mode(FreeSurround::SurroundModePassive), 65 old_audio_stretchfactor(1.0), 61 66 62 67 blocking(false), 63 68 … … 84 89 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 85 90 memset(audiobuffer, 0, sizeof(char) * AUDBUFSIZE); 86 91 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 92 orig_config_channels = configured_audio_channels; 93 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 94 src_quality = gContext->GetNumSetting("SRCQuality", 3); 95 isAC3upmix = AC3upmix; 87 96 88 97 // You need to call Reconfigure from your concrete class. 89 98 // Reconfigure(laudio_bits, laudio_channels, … … 110 119 void AudioOutputBase::SetStretchFactorLocked(float laudio_stretchfactor) 111 120 { 112 121 effdspstretched = (int)((float)effdsp / laudio_stretchfactor); 113 if ( audio_stretchfactor != laudio_stretchfactor)122 if ((audio_stretchfactor != laudio_stretchfactor) || !pSoundStretch) 114 123 { 115 124 audio_stretchfactor = laudio_stretchfactor; 116 125 if (pSoundStretch) … … 124 133 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 125 134 .arg(audio_stretchfactor)); 126 135 pSoundStretch = new soundtouch::SoundTouch(); 127 if (audio_codec) 128 { 129 if (!encoder) 136 if (!isAC3upmix) { 137 if (audio_codec) 130 138 { 131 VERBOSE(VB_AUDIO, LOC + 132 QString("Creating Encoder for codec %1 origfs %2") 133 .arg(audio_codec->codec_id) 134 .arg(audio_codec->frame_size)); 135 136 encoder = new AudioOutputDigitalEncoder(); 137 if (!encoder->Init(audio_codec->codec_id, 138 audio_codec->bit_rate, 139 audio_codec->sample_rate, 140 audio_codec->channels 141 )) 139 if (!encoder) 142 140 { 143 // eeks144 delete encoder;145 encoder = NULL;146 141 VERBOSE(VB_AUDIO, LOC + 147 QString("Failed to Create Encoder")); 142 QString("Creating Encoder for codec %1 origfs %2") 143 .arg(audio_codec->codec_id) 144 .arg(audio_codec->frame_size)); 145 146 encoder = new AudioOutputDigitalEncoder(isAC3upmix); 147 if (!encoder->Init(audio_codec->codec_id, 148 audio_codec->bit_rate, 149 audio_codec->sample_rate, 150 audio_codec->channels 151 )) 152 { 153 // eeks 154 delete encoder; 155 encoder = NULL; 156 VERBOSE(VB_AUDIO, LOC + 157 QString("Failed to Create Encoder")); 158 } 148 159 } 149 160 } 150 } 151 if (audio_codec && encoder) 152 { 153 pSoundStretch->setSampleRate(audio_codec->sample_rate); 154 pSoundStretch->setChannels(audio_codec->channels); 155 } 156 else 157 { 161 if (audio_codec && encoder) 162 { 163 pSoundStretch->setSampleRate(audio_codec->sample_rate); 164 pSoundStretch->setChannels(audio_codec->channels); 165 } 166 else 167 { 168 pSoundStretch->setSampleRate(audio_samplerate); 169 pSoundStretch->setChannels(audio_channels); 170 } 171 } else { 158 172 pSoundStretch->setSampleRate(audio_samplerate); 159 pSoundStretch->setChannels(audio_channels); 173 pSoundStretch->setChannels(upmixer ? 174 configured_audio_channels : source_audio_channels); 160 175 } 161 162 176 pSoundStretch->setTempo(audio_stretchfactor); 163 177 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); 164 178 165 179 // dont need these with only tempo change 166 180 //pSoundStretch->setPitch(1.0); 167 181 //pSoundStretch->setRate(1.0); 168 169 182 //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true); 170 183 //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false); 171 184 } … … 184 197 return audio_stretchfactor; 185 198 } 186 199 200 bool AudioOutputBase::ToggleUpmix(void) 201 { 202 if (orig_config_channels == 2 || audio_passthru) 203 return false; 204 if (configured_audio_channels == 6) 205 configured_audio_channels = 2; 206 else 207 configured_audio_channels = 6; 208 209 Reconfigure(audio_bits, source_audio_channels, 210 source_audio_samplerate, audio_passthru); 211 return (configured_audio_channels == 6); 212 } 213 187 214 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 188 215 int laudio_samplerate, bool laudio_passthru, 189 216 void *laudio_codec) … … 194 221 int cchannels = 0; 195 222 int lsource_audio_channels = laudio_channels; 196 223 bool lneeds_upmix = false; 224 bool laudio_reenc = false; 197 225 198 if (laudio_codec) 199 { 200 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 201 laudio_bits = 16; 202 laudio_channels = 2; 203 lsource_audio_channels = laudio_channels; 204 laudio_samplerate = 48000; 205 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 206 } 226 if (!isAC3upmix) { 227 if (laudio_codec) 228 { 229 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 230 laudio_bits = 16; 231 laudio_channels = 2; 232 lsource_audio_channels = laudio_channels; 233 laudio_samplerate = 48000; 234 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 235 } 207 236 208 if (audio_codec)209 {210 codec_id = audio_codec->codec_id;211 cchannels = ((AVCodecContext*)audio_codec)->channels;212 }237 if (audio_codec) 238 { 239 codec_id = audio_codec->codec_id; 240 cchannels = ((AVCodecContext*)audio_codec)->channels; 241 } 213 242 214 if ((configured_audio_channels == 6) && 215 !(laudio_codec || audio_codec)) 216 { 217 laudio_channels = configured_audio_channels; 218 lneeds_upmix = true; 219 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 243 if ((configured_audio_channels == 6) && 244 !(laudio_codec || audio_codec)) 245 { 246 laudio_channels = configured_audio_channels; 247 lneeds_upmix = true; 248 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 249 } 250 } else { //AC3 Upmix 251 // Are we perhaps reencoding a (previously) timestretched bitstream? 252 if (laudio_channels > 2 && !laudio_passthru) 253 laudio_reenc = true; 254 255 // Enough channels? Upmix if not 256 if (laudio_channels < configured_audio_channels && !laudio_passthru) 257 { 258 laudio_channels = configured_audio_channels; 259 lneeds_upmix = true; 260 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 261 } 262 if (laudio_codec) 263 audio_codec = (AVCodecContext*)laudio_codec; 220 264 } 221 265 222 266 ClearError(); 223 267 bool general_deps = (laudio_bits == audio_bits && 224 268 laudio_channels == audio_channels && 225 269 laudio_samplerate == audio_samplerate && !need_resampler && 226 270 laudio_passthru == audio_passthru && 227 271 lneeds_upmix == needs_upmix && 228 lcodec_id == codec_id && lcchannels == cchannels); 272 (isAC3upmix ? (laudio_reenc == audio_reenc) : (lcodec_id == codec_id && lcchannels == cchannels)) 273 ); 229 274 bool upmix_deps = 230 275 (lsource_audio_channels == source_audio_channels); 231 276 if (general_deps && upmix_deps) … … 256 301 audio_channels = laudio_channels; 257 302 source_audio_channels = lsource_audio_channels; 258 303 audio_bits = laudio_bits; 259 audio_samplerate = laudio_samplerate; 260 audio_codec = (AVCodecContext*)laudio_codec; 304 if (!isAC3upmix) { 305 audio_samplerate = laudio_samplerate; 306 audio_codec = (AVCodecContext*)laudio_codec; 307 } else { 308 source_audio_samplerate = audio_samplerate = laudio_samplerate; 309 audio_reenc = laudio_reenc; 310 } 261 311 audio_passthru = laudio_passthru; 262 312 needs_upmix = lneeds_upmix; 263 313 … … 268 318 Error("AudioOutput only supports 8 or 16bit audio."); 269 319 return; 270 320 } 271 audio_bytes_per_sample = audio_channels * audio_bits / 8;272 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;273 321 274 322 need_resampler = false; 275 323 killaudio = false; … … 279 327 280 328 numlowbuffer = 0; 281 329 330 if (!isAC3upmix) { 331 audio_bytes_per_sample = audio_channels * audio_bits / 8; 332 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 333 } else { 334 // Encode to AC-3 if not passing thru, there's more than 2 channels 335 // and we're allowed to passthru AC-3 336 // This won't reencode timestretched 2ch AC-3 but there's no point doing so 337 if (!audio_passthru && audio_channels > 2 && allow_ac3_passthru) 338 { 339 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); 340 int srate = src_quality == 0 ? audio_samplerate : 48000; 341 encoder = new AudioOutputDigitalEncoder(); 342 if (!encoder->Init(CODEC_ID_AC3, 448000, srate, 343 audio_channels, audio_reenc)) 344 { 345 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 346 delete encoder; 347 encoder = NULL; 348 } 349 350 audio_enc = true; 351 } 352 353 if(audio_passthru || audio_enc) 354 // AC-3 output - soundcard expects a 2ch 48k stream 355 audio_channels = 2; 356 357 audio_bytes_per_sample = audio_channels * audio_bits / 8; 358 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 359 360 // Always resample to 48k - many cards can't do anything else 361 // and ALSA will do it with linear interpolation (yuk) if we don't anyway 362 if (src_quality != 0 && audio_samplerate != 48000) 363 { 364 int error; 365 audio_samplerate = 48000; 366 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2") 367 .arg(laudio_samplerate).arg(audio_samplerate)); 368 src_ctx = src_new(3-src_quality, audio_channels, &error); 369 if (error) 370 { 371 Error(QString("Error creating resampler, the error was: %1") 372 .arg(src_strerror(error)) ); 373 pthread_mutex_unlock(&avsync_lock); 374 pthread_mutex_unlock(&audio_buflock); 375 src_ctx = NULL; 376 return; 377 } 378 src_data.src_ratio = (double) audio_samplerate / laudio_samplerate; 379 src_data.data_in = src_in; 380 src_data.data_out = src_out; 381 src_data.output_frames = 16384*6; 382 need_resampler = true; 383 } 384 } 282 385 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 283 386 .arg(audio_main_device).arg(audio_channels) 284 387 .arg(source_audio_channels).arg(audio_samplerate)); … … 314 417 current_seconds = -1; 315 418 source_bitrate = -1; 316 419 420 if (!isAC3upmix) { 317 421 // NOTE: this won't do anything as above samplerate vars are set equal 318 422 // Check if we need the resampler 319 423 if (audio_samplerate != laudio_samplerate) … … 336 440 src_data.output_frames = 16384*6; 337 441 need_resampler = true; 338 442 } 339 443 } 340 444 if (needs_upmix) 341 445 { 342 446 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); … … 348 452 upmixer = new FreeSurround( 349 453 audio_samplerate, 350 454 source == AUDIOOUTPUT_VIDEO, 351 (FreeSurround::SurroundMode)surround_mode );455 (FreeSurround::SurroundMode)surround_mode,isAC3upmix); 352 456 353 457 VERBOSE(VB_AUDIO, LOC + 354 458 QString("create upmixer done with surround mode %1") … … 357 461 358 462 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 359 463 .arg(audio_stretchfactor)); 360 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 361 .arg((audio_codec) ? 362 codec_id_string(audio_codec->codec_id) : "not set")); 363 364 if (redo_stretch) 365 { 366 float laudio_stretchfactor = audio_stretchfactor; 367 delete pSoundStretch; 368 pSoundStretch = NULL; 369 audio_stretchfactor = 0.0f; 370 SetStretchFactorLocked(laudio_stretchfactor); 371 } 372 else 373 { 374 SetStretchFactorLocked(audio_stretchfactor); 375 if (pSoundStretch) 464 if (!isAC3upmix) { 465 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 466 .arg((audio_codec) ? 467 codec_id_string(audio_codec->codec_id) : "not set")); 468 469 if (redo_stretch) 470 { 471 delete pSoundStretch; 472 pSoundStretch = NULL; 473 SetStretchFactorLocked(audio_stretchfactor); 474 } 475 else 376 476 { 377 // if its passthru then we need to reencode378 if ( audio_codec)477 SetStretchFactorLocked(audio_stretchfactor); 478 if (pSoundStretch) 379 479 { 380 if (!encoder) 480 // if its passthru then we need to reencode 481 if (audio_codec) 381 482 { 382 VERBOSE(VB_AUDIO, LOC + 383 QString("Creating Encoder for codec %1") 384 .arg(audio_codec->codec_id)); 385 386 encoder = new AudioOutputDigitalEncoder(); 387 if (!encoder->Init(audio_codec->codec_id, 388 audio_codec->bit_rate, 389 audio_codec->sample_rate, 390 audio_codec->channels 391 )) 483 if (!encoder) 392 484 { 393 // eeks 394 delete encoder; 395 encoder = NULL; 396 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder"); 485 VERBOSE(VB_AUDIO, LOC + 486 QString("Creating Encoder for codec %1") 487 .arg(audio_codec->codec_id)); 488 489 encoder = new AudioOutputDigitalEncoder(isAC3upmix); 490 if (!encoder->Init(audio_codec->codec_id, 491 audio_codec->bit_rate, 492 audio_codec->sample_rate, 493 audio_codec->channels 494 )) 495 { 496 // eeks 497 delete encoder; 498 encoder = NULL; 499 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder"); 500 } 397 501 } 398 502 } 399 }400 if (audio_codec && encoder)401 {402 pSoundStretch->setSampleRate(audio_codec->sample_rate);403 pSoundStretch->setChannels(audio_codec->channels);404 }405 else406 {407 pSoundStretch->setSampleRate(audio_samplerate);408 pSoundStretch->setChannels(audio_channels);503 if (audio_codec && encoder) 504 { 505 pSoundStretch->setSampleRate(audio_codec->sample_rate); 506 pSoundStretch->setChannels(audio_codec->channels); 507 } 508 else 509 { 510 pSoundStretch->setSampleRate(audio_samplerate); 511 pSoundStretch->setChannels(audio_channels); 512 } 409 513 } 410 514 } 515 } else { 516 SetStretchFactorLocked(old_audio_stretchfactor); 411 517 } 412 413 518 // Setup visualisations, zero the visualisations buffers 414 519 prepareVisuals(); 415 520 … … 456 561 killaudio = true; 457 562 StopOutputThread(); 458 563 564 if (isAC3upmix) 565 pthread_mutex_lock(&audio_buflock); 566 459 567 // Close resampler? 460 if (src_ctx) 568 if (src_ctx) { 461 569 src_delete(src_ctx); 570 if (isAC3upmix) 571 src_ctx = NULL; 572 } 462 573 need_resampler = false; 463 574 464 575 // close sound stretcher … … 466 577 { 467 578 delete pSoundStretch; 468 579 pSoundStretch = NULL; 580 if (isAC3upmix) { 581 old_audio_stretchfactor = audio_stretchfactor; 582 audio_stretchfactor = 1.0; 583 } 469 584 } 470 585 471 586 if (encoder) … … 480 595 upmixer = NULL; 481 596 } 482 597 needs_upmix = false; 598 if (isAC3upmix) 599 audio_enc = false; 483 600 484 601 CloseDevice(); 485 602 603 if (isAC3upmix) 604 pthread_mutex_unlock(&audio_buflock); 486 605 killAudioLock.unlock(); 487 606 } 488 607 … … 642 761 // include algorithmic latencies 643 762 if (pSoundStretch) 644 763 { 645 // add the effect of any unused but processed samples, 646 // AC3 reencode does this 647 totalbuffer += (int)(pSoundStretch->numSamples() * 648 audio_bytes_per_sample); 764 if (!isAC3upmix) { 765 // add the effect of any unused but processed samples, 766 // AC3 reencode does this 767 totalbuffer += (int)(pSoundStretch->numSamples() * 768 audio_bytes_per_sample); 769 } 649 770 // add the effect of unprocessed samples in time stretch algo 650 771 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 651 772 audio_bytes_per_sample) / audio_stretchfactor); … … 656 777 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 657 778 } 658 779 780 if (isAC3upmix && encoder) 781 totalbuffer += encoder->Buffered(); 782 659 783 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 660 784 (audio_bytes_per_sample * effdspstretched)); 661 785 … … 709 833 return false; // would overflow 710 834 } 711 835 836 if (isAC3upmix) 837 pthread_mutex_lock(&audio_buflock); 838 712 839 // resample input if necessary 713 840 if (need_resampler && src_ctx) 714 841 { … … 742 869 _AddSamples(buffers, false, samples, timecode); 743 870 } 744 871 872 if (isAC3upmix) 873 pthread_mutex_unlock(&audio_buflock); 874 745 875 return true; 746 876 } 747 877 … … 753 883 int abps = (encoder) ? 754 884 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 755 885 int len = samples * abps; 886 887 if (isAC3upmix) { 888 // Give original samples to mythmusic visualisation 889 dispatchVisual((unsigned char *)buffer, len, timecode, 890 source_audio_channels, audio_bits); 891 } 756 892 757 893 // Check we have enough space to write the data 758 894 if (need_resampler && src_ctx) … … 777 913 return false; // would overflow 778 914 } 779 915 916 if (isAC3upmix) 917 pthread_mutex_lock(&audio_buflock); 918 780 919 // resample input if necessary 781 920 if (need_resampler && src_ctx) 782 921 { … … 805 944 _AddSamples(buffer, true, samples, timecode); 806 945 } 807 946 947 if (isAC3upmix) 948 pthread_mutex_unlock(&audio_buflock); 949 808 950 return true; 809 951 } 810 952 … … 837 979 { 838 980 int error = src_reset(src_ctx); 839 981 if (error) 982 { 840 983 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 841 984 "Error occured while resetting resampler: %1") 842 985 .arg(src_strerror(error))); 986 if (isAC3upmix) 987 src_ctx = NULL; 988 } 843 989 } 844 990 } 845 991 } … … 849 995 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 850 996 long long timecode) 851 997 { 852 pthread_mutex_lock(&audio_buflock); 998 if (!isAC3upmix) 999 pthread_mutex_lock(&audio_buflock); 853 1000 854 1001 int len; // = samples * audio_bytes_per_sample; 855 1002 int audio_bytes = audio_bits / 8; … … 868 1015 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode) 869 1016 .arg(needs_upmix)); 870 1017 1018 if (isAC3upmix) 1019 len = WaitForFreeSpace(samples); 1020 871 1021 if (upmixer && needs_upmix) 872 1022 { 873 1023 int out_samples = 0; 874 1024 int step = (interleaved)?source_audio_channels:1; 875 len = WaitForFreeSpace(samples); // test 1025 1026 if (!isAC3upmix) { 1027 org_waud = waud; 1028 len = WaitForFreeSpace(samples); 1029 } 876 1030 for (int itemp = 0; itemp < samples; ) 877 1031 { 878 1032 // just in case it does a processing cycle, release the lock 879 1033 // to allow the output loop to do output 880 pthread_mutex_unlock(&audio_buflock); 1034 if (!isAC3upmix) 1035 pthread_mutex_unlock(&audio_buflock); 881 1036 if (audio_bytes == 2) 882 1037 { 883 1038 itemp += upmixer->putSamples( … … 894 1049 source_audio_channels, 895 1050 (interleaved) ? 0 : samples); 896 1051 } 897 pthread_mutex_lock(&audio_buflock); 1052 if (!isAC3upmix) 1053 pthread_mutex_lock(&audio_buflock); 898 1054 899 1055 int copy_samples = upmixer->numSamples(); 900 1056 if (copy_samples) … … 928 1084 } 929 1085 else 930 1086 { 931 len = WaitForFreeSpace(samples);932 1087 if (!isAC3upmix) 1088 len = WaitForFreeSpace(samples); 933 1089 if (interleaved) 934 1090 { 935 1091 char *mybuf = (char*)buffer; … … 965 1121 } 966 1122 } 967 1123 1124 if (!isAC3upmix) { 968 1125 if (samples > 0) 969 1126 { 970 1127 if (pSoundStretch) … … 1022 1179 continue; 1023 1180 1024 1181 //len = WaitForFreeSpace(amount); 1025 c har *ob = encoder->GetOutBuff();1182 const char *ob = encoder->GetOutBuff(); 1026 1183 if (amount >= bdiff) 1027 1184 { 1028 1185 memcpy(audiobuffer + org_waud, ob, bdiff); … … 1035 1192 1036 1193 bdiff = AUDBUFSIZE - amount; 1037 1194 org_waud += amount; 1195 if (org_waud >= AUDBUFSIZE) 1196 { 1197 VERBOSE(VB_IMPORTANT, QString("org_waud >= kAudioRingBufferSize %1 %2").arg(org_waud).arg(amount)); 1198 org_waud -= AUDBUFSIZE; 1199 } 1038 1200 } 1039 1201 } 1040 1202 else … … 1064 1226 org_waud += nSamples * audio_bytes_per_sample; 1065 1227 nSamplesToEnd -= nSamples; 1066 1228 } 1229 if (org_waud >= AUDBUFSIZE) 1230 { 1231 VERBOSE(VB_IMPORTANT, QString("org_waud >= kAudioRingBufferSize %1 %2 %3").arg(org_waud).arg(nSamples).arg(audio_bytes_per_sample)); 1232 org_waud -= AUDBUFSIZE; 1233 } 1067 1234 1068 1235 newLen += nSamples * audio_bytes_per_sample; 1069 1236 len -= nSamples * audio_bytes_per_sample; … … 1096 1263 } 1097 1264 1098 1265 pthread_mutex_unlock(&audio_buflock); 1266 } else { 1267 if (samples <= 0) 1268 return; 1269 1270 if (pSoundStretch) 1271 { 1272 // does not change the timecode, only the number of samples 1273 // back to orig pos 1274 org_waud = waud; 1275 int bdiff = AUDBUFSIZE - org_waud; 1276 int nSamplesToEnd = bdiff/abps; 1277 if (bdiff < len) 1278 { 1279 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 1280 (audiobuffer + 1281 org_waud), nSamplesToEnd); 1282 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 1283 (len - bdiff) / abps); 1284 } 1285 else 1286 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 1287 (audiobuffer + org_waud), 1288 len / abps); 1289 1290 int nSamples = pSoundStretch->numSamples(); 1291 len = WaitForFreeSpace(nSamples); 1292 1293 while ((nSamples = pSoundStretch->numSamples())) 1294 { 1295 if (nSamples > nSamplesToEnd) 1296 nSamples = nSamplesToEnd; 1297 1298 nSamples = pSoundStretch->receiveSamples( 1299 (soundtouch::SAMPLETYPE*) 1300 (audiobuffer + org_waud), nSamples 1301 ); 1302 1303 if (nSamples == nSamplesToEnd) { 1304 org_waud = 0; 1305 nSamplesToEnd = AUDBUFSIZE/abps; 1306 } 1307 else { 1308 org_waud += nSamples * abps; 1309 nSamplesToEnd -= nSamples; 1310 } 1311 1312 } 1313 1314 } 1315 1316 // Encode to AC-3? 1317 if (encoder) 1318 { 1319 1320 org_waud = waud; 1321 int bdiff = AUDBUFSIZE - org_waud; 1322 int to_get = 0; 1323 1324 if (bdiff < len) 1325 { 1326 encoder->EncodeUpmix(audiobuffer + org_waud, bdiff); 1327 to_get = encoder->EncodeUpmix(audiobuffer, len - bdiff); 1328 } 1329 else 1330 to_get = encoder->EncodeUpmix(audiobuffer + org_waud, len); 1331 1332 if (to_get > 0) 1333 { 1334 1335 if (to_get >= bdiff) 1336 { 1337 encoder->GetFrames(audiobuffer + org_waud, bdiff); 1338 to_get -= bdiff; 1339 org_waud = 0; 1340 } 1341 if (to_get > 0) 1342 encoder->GetFrames(audiobuffer + org_waud, to_get); 1343 1344 org_waud += to_get; 1345 1346 } 1347 1348 } 1349 1350 waud = org_waud; 1351 lastaudiolen = audiolen(false); 1352 1353 if (timecode < 0) 1354 // mythmusic doesn't give timestamps.. 1355 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1356 1357 samples_buffered += samples; 1358 1359 /* we want the time at the end -- but the file format stores 1360 time at the start of the chunk. */ 1361 // even with timestretch, timecode is still calculated from original 1362 // sample count 1363 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 1364 } // End AC3 upmiz 1099 1365 } 1100 1366 1101 1367 void AudioOutputBase::Status() -
mythtv/libs/libmyth/audiooutputbase.h
diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputbase.h c/mythtv/libs/libmyth/audiooutputbase.h
a c 41 41 int laudio_bits, 42 42 int laudio_channels, int laudio_samplerate, 43 43 AudioOutputSource lsource, 44 bool lset_initial_vol, bool laudio_passthru); 44 bool lset_initial_vol, bool laudio_passthru, 45 bool AC3upmix = false); 45 46 virtual ~AudioOutputBase(); 46 47 47 48 // reconfigure sound out for new params … … 59 60 60 61 virtual void SetStretchFactor(float factor); 61 62 virtual float GetStretchFactor(void); 63 virtual bool ToggleUpmix(void); 62 64 63 65 virtual void Reset(void); 64 66 … … 139 141 QString audio_passthru_device; 140 142 141 143 bool audio_passthru; 144 bool audio_enc; 145 bool audio_reenc; 142 146 143 147 float audio_stretchfactor; 144 148 AVCodecContext *audio_codec; … … 151 155 bool buffer_output_data_for_use; // used by AudioOutputNULL 152 156 153 157 int configured_audio_channels; 158 int orig_config_channels; 159 int src_quality; 160 int source_audio_channels; 154 161 155 162 private: 156 163 // resampler … … 166 173 AudioOutputDigitalEncoder *encoder; 167 174 FreeSurround *upmixer; 168 175 169 int source_audio_ channels;176 int source_audio_samplerate; 170 177 int source_audio_bytes_per_sample; 171 178 bool needs_upmix; 172 179 int surround_mode; 180 bool allow_ac3_passthru; 181 float old_audio_stretchfactor; 173 182 174 183 bool blocking; // do AddSamples calls block? 175 184 -
mythtv/libs/libmyth/audiooutputdigitalencoder.cpp
diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputdigitalencoder.cpp c/mythtv/libs/libmyth/audiooutputdigitalencoder.cpp
a c 27 27 28 28 AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) : 29 29 av_context(NULL), 30 outbuf(NULL),31 outbuf_size(0),32 30 frame_buffer(NULL), 33 one_frame_bytes(0) 31 one_frame_bytes(0), 32 outbuflen(0), 33 inbuflen(0), 34 reorder(true), 35 isAC3upmix(false) 36 { 37 } 38 39 AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(bool AC3upmix) : 40 av_context(NULL), 41 frame_buffer(NULL), 42 one_frame_bytes(0), 43 outbuflen(0), 44 inbuflen(0), 45 reorder(true), 46 isAC3upmix(AC3upmix) 34 47 { 35 48 } 36 49 … … 48 61 av_context = NULL; 49 62 } 50 63 51 if (outbuf) 52 { 53 delete [] outbuf; 54 outbuf = NULL; 55 outbuf_size = 0; 56 } 57 58 if (frame_buffer) 64 if (!isAC3upmix && frame_buffer) 59 65 { 60 66 delete [] frame_buffer; 61 67 frame_buffer = NULL; … … 65 71 66 72 //CODEC_ID_AC3 67 73 bool AudioOutputDigitalEncoder::Init( 68 CodecID codec_id, int bitrate, int samplerate, int channels )74 CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding) 69 75 { 70 76 AVCodec *codec; 71 77 int ret; 72 78 73 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 ")79 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 re=%5") 74 80 .arg(codec_id_string(codec_id)) 75 81 .arg(bitrate) 76 82 .arg(samplerate) 77 .arg(channels)); 78 83 .arg(channels) 84 .arg(reencoding)); 85 86 reorder = !reencoding; 87 88 // We need to do this when called from mythmusic 89 if (isAC3upmix) { 90 avcodec_init(); 91 avcodec_register_all(); 92 } 79 93 //codec = avcodec_find_encoder(codec_id); 80 94 // always AC3 as there is no DTS encoder at the moment 2005/1/9 81 95 codec = avcodec_find_encoder(CODEC_ID_AC3); … … 105 119 audio_bytes_per_sample = bytes_per_frame; 106 120 one_frame_bytes = bytes_per_frame * av_context->frame_size; 107 121 108 outbuf_size = 16384; // ok for AC3 but DTS?109 outbuf = new char [outbuf_size];110 122 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 111 123 .arg(av_context->frame_size) 112 124 .arg(bytes_per_frame) … … 256 268 257 269 } AESHeader; 258 270 271 void reorder_6ch_ac3(void *buf, unsigned int len) { 272 unsigned short *src = (unsigned short *)buf; 273 unsigned short tmp; 274 unsigned int samples = len >> 1; 275 276 for (uint i = 0; i < samples; i += 6) { 277 tmp = src[i+4]; 278 src[i+4] = src[i+3]; 279 src[i+3] = src[i+2]; 280 src[i+2] = src[i+1]; 281 src[i+1] = tmp; 282 } 283 } 284 259 285 static int encode_frame( 260 286 bool dts, 261 287 unsigned char *data, 262 size_t &len )288 size_t &len, bool AC3upmix) 263 289 { 264 size_t enc_len ;290 size_t enc_len = len; 265 291 int flags, sample_rate, bit_rate; 266 292 267 293 // we don't do any length/crc validation of the AC3 frame here; presumably … … 272 298 // ignore, and if so, may as well just assume that it will ignore 273 299 // anything with a bad CRC... 274 300 275 uint nr_samples = 0, block_len; 301 uint nr_samples = 0, block_len = 0; 302 276 303 if (dts) 277 304 { 278 305 enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate); … … 293 320 #endif 294 321 } 295 322 296 if ( enc_len == 0 || enc_len > len)323 if (!AC3upmix && (enc_len == 0 || enc_len > len)) 297 324 { 298 325 int l = len; 299 326 len = 0; … … 352 379 data[6] = (enc_len << 3) & 0xFF; 353 380 data[7] = (enc_len >> 5) & 0xFF; 354 381 memset(data + 8 + enc_len, 0, block_len - 8 - enc_len); 355 len = block_len; 382 if (!AC3upmix) 383 len = block_len; 356 384 357 385 return enc_len; 358 386 } … … 365 393 366 394 // put data in the correct spot for encode frame 367 395 outsize = avcodec_encode_audio( 368 av_context, ((uchar*)outbuf) + 8, outbuf_size- 8, buff);396 av_context, ((uchar*)outbuf) + 8, OUTBUFSIZE - 8, buff); 369 397 370 398 size_t tmpsize = outsize; 371 399 372 400 outsize = MAX_AC3_FRAME_SIZE; 373 401 encsize = encode_frame( 374 402 /*av_context->codec_id==CODEC_ID_DTS*/ false, 375 (unsigned char*)outbuf, outsize );403 (unsigned char*)outbuf, outsize, false); 376 404 377 405 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 378 406 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") … … 380 408 381 409 return outsize; 382 410 } 411 412 size_t AudioOutputDigitalEncoder::EncodeUpmix(void *buf, int len) 413 { 414 size_t outsize = 0; 415 416 int fs = FrameSize(); 417 memcpy(inbuf+inbuflen, buf, len); 418 inbuflen += len; 419 int frames = inbuflen / fs; 420 421 while (frames--) 422 { 423 if (reorder) 424 reorder_6ch_ac3(inbuf, fs); 425 426 // put data in the correct spot for encode frame 427 outsize = avcodec_encode_audio( 428 av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf); 429 430 encode_frame( 431 /*av_context->codec_id==CODEC_ID_DTS*/ false, 432 (unsigned char*)outbuf + outbuflen, outsize, true 433 ); 434 435 outbuflen += MAX_AC3_FRAME_SIZE; 436 inbuflen -= fs; 437 memmove(inbuf, inbuf+fs, inbuflen); 438 } 439 440 return outbuflen; 441 } 442 443 void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen) 444 { 445 int len = (maxlen < outbuflen ? maxlen : outbuflen); 446 memcpy(ptr, outbuf, len); 447 outbuflen -= len; 448 memmove(outbuf, outbuf+len, outbuflen); 449 } -
mythtv/libs/libmyth/audiooutputdigitalencoder.h
diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputdigitalencoder.h c/mythtv/libs/libmyth/audiooutputdigitalencoder.h
a c 5 5 #include "libavcodec/avcodec.h" 6 6 }; 7 7 8 #define INBUFSIZE 131072 9 #define OUTBUFSIZE 98304 10 8 11 class AudioOutputDigitalEncoder 9 12 { 10 13 public: 11 14 AudioOutputDigitalEncoder(void); 15 AudioOutputDigitalEncoder(bool AC3upmix); 12 16 ~AudioOutputDigitalEncoder(); 13 17 14 bool Init(CodecID codec_id, int bitrate, int samplerate, int channels); 18 bool Init(CodecID codec_id, int bitrate, int samplerate, 19 int channels, bool reencoding = false); 15 20 void Dispose(void); 16 21 size_t Encode(short * buff); 17 22 18 23 inline char *GetFrameBuffer(void); 19 24 size_t FrameSize(void) const { return one_frame_bytes; } 20 char *GetOutBuff(void) const { return outbuf; } 25 const char *GetOutBuff(void) const { return outbuf; } 26 //AC3 upmix 27 size_t EncodeUpmix(void *buf, int len); 28 void GetFrames(void *ptr, int maxlen); 29 int Buffered(void) const { return inbuflen; } 21 30 22 31 public: 23 32 size_t audio_bytes_per_sample; 24 33 25 34 private: 26 35 AVCodecContext *av_context; 27 char *outbuf; 28 int outbuf_size; 36 char outbuf[OUTBUFSIZE]; 29 37 char *frame_buffer; 30 38 size_t one_frame_bytes; 39 // AC3 upmix 40 char inbuf[INBUFSIZE]; 41 int outbuflen; 42 int inbuflen; 43 bool reorder; 44 bool isAC3upmix; 31 45 }; 32 46 33 47 inline char *AudioOutputDigitalEncoder::GetFrameBuffer(void) -
mythtv/libs/libmythfreesurround/el_processor.cpp
diff -Naur --exclude=.svn a/mythtv/libs/libmythfreesurround/el_processor.cpp c/mythtv/libs/libmythfreesurround/el_processor.cpp
a c 40 40 41 41 const float PI = 3.141592654; 42 42 const float epsilon = 0.000001; 43 const float center_level_upmix = 0.5*sqrt(0.5); 43 44 //const float center_level = 0.5*sqrt(0.5); // gain of the center channel 44 45 //const float center_level = sqrt(0.5); // gain of the center channel 45 46 const float center_level = 1.0; // gain of the center channel … … 57 58 public: 58 59 // create an instance of the decoder 59 60 // blocksize is fixed over the lifetime of this object for performance reasons 60 decoder_impl(unsigned blocksize=8192): N(blocksize), halfN(blocksize/2) {61 decoder_impl(unsigned blocksize=8192, bool AC3upmix=false): N(blocksize), halfN(blocksize/2), isAC3upmix(AC3upmix) { 61 62 #ifdef USE_FFTW3 62 63 // create FFTW buffers 63 64 lt = (float*)fftwf_malloc(sizeof(float)*N); … … 99 100 filter[c].resize(N); 100 101 } 101 102 // DC component of filters is always 0 102 for (unsigned c=0;c<5;c++) 103 { 104 filter[c][0] = 0.0; 105 filter[c][1] = 0.0; 106 filter[c][halfN] = 0.0; 107 } 108 sample_rate(48000); 109 // generate the window function (square root of hann, b/c it is applied before and after the transform) 110 wnd.resize(N); 111 // dft normalization included in the window for zero cost scaling 112 // also add a gain factor of *2 due to processing gain in algo (see center_level) 113 surround_gain(1.0); 103 if (!isAC3upmix) { 104 for (unsigned c=0;c<5;c++) 105 { 106 filter[c][0] = 0.0; 107 filter[c][1] = 0.0; 108 filter[c][halfN] = 0.0; 109 } 110 sample_rate(48000); 111 // generate the window function (square root of hann, b/c it is applied before and after the transform) 112 wnd.resize(N); 113 // dft normalization included in the window for zero cost scaling 114 // also add a gain factor of *2 due to processing gain in algo (see center_level) 115 surround_gain(1.0); 116 } else { 117 sample_rate(48000); 118 // generate the window function (square root of hann, b/c it is applied before and after the transform) 119 wnd.resize(N); 120 for (unsigned k=0;k<N;k++) 121 wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N); 122 } 114 123 current_buf = 0; 115 124 // set the default coefficients 116 125 surround_coefficients(0.8165,0.5774); … … 192 201 // set lfe filter params 193 202 void sample_rate(unsigned int srate) { 194 203 // lfe filter is just straight through band limited 195 unsigned int cutoff = (250*N)/srate; 196 for (unsigned f=0;f<=halfN;f++) { 197 if ((f>=2) && (f<cutoff)) 198 filter[5][f] = 1.0; 199 else 200 filter[5][f] = 0.0; 204 unsigned int cutoff; 205 if (!isAC3upmix) { 206 cutoff = (250*N)/srate; 207 for (unsigned f=0;f<=halfN;f++) { 208 if ((f>=2) && (f<cutoff)) 209 filter[5][f] = 1.0; 210 else 211 filter[5][f] = 0.0; 212 } 213 } else { 214 cutoff = (30*N)/srate; 215 for (unsigned f=0;f<=halfN;f++) { 216 if (f<cutoff) 217 filter[5][f] = 0.5*sqrt(0.5); 218 else 219 filter[5][f] = 0.0; 220 } 201 221 } 202 222 } 203 223 … … 237 257 } 238 258 239 259 private: 260 bool isAC3upmix; 240 261 // polar <-> cartesian coodinates conversion 241 262 static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); } 242 263 static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); } … … 290 311 291 312 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 292 313 // but dont do DC or N/2 component 293 for (unsigned f=2;f<halfN;f++) { 314 unsigned start_f = isAC3upmix ? 0:2; 315 for (unsigned f=start_f;f<halfN;f++) { 294 316 // get left/right amplitudes/phases 295 317 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]); 296 318 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]); … … 357 379 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 358 380 float volume[5] = { 359 381 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 360 front * center_level*((1-abs(xfs[f])) * (1-center_width)), // center382 front * (isAC3upmix ? center_level_upmix : center_level) *((1-abs(xfs[f])) * (1-center_width)), // center 361 383 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 362 384 back * surround_level * left, // left surround 363 385 back * surround_level * right // right surround … … 402 424 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 403 425 float volume[5] = { 404 426 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 405 front * center_level*((1-abs(xfs[f])) * (1-center_width)),// center427 front * (isAC3upmix ? center_level_upmix : center_level) *((1-abs(xfs[f])) * (1-center_width)), // center 406 428 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 407 429 back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))), // left surround 408 430 back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2))) // right surround … … 613 635 614 636 // implementation of the shell class 615 637 616 fsurround_decoder::fsurround_decoder(unsigned blocksize ): impl(new decoder_impl(blocksize)) { }638 fsurround_decoder::fsurround_decoder(unsigned blocksize, bool AC3upmix): impl(new decoder_impl(blocksize,AC3upmix)) { } 617 639 618 640 fsurround_decoder::~fsurround_decoder() { delete impl; } 619 641 -
mythtv/libs/libmythfreesurround/el_processor.h
diff -Naur --exclude=.svn a/mythtv/libs/libmythfreesurround/el_processor.h c/mythtv/libs/libmythfreesurround/el_processor.h
a c 24 24 public: 25 25 // create an instance of the decoder 26 26 // blocksize is fixed over the lifetime of this object for performance reasons 27 fsurround_decoder(unsigned blocksize=8192);27 fsurround_decoder(unsigned blocksize=8192, bool AC3upmix=false); 28 28 // destructor 29 29 ~fsurround_decoder(); 30 30 … … 51 51 void gain(float gain); 52 52 53 53 // set the phase shifting mode for decoding 54 // 0 = (+0 °,+0°) - music mode55 // 1 = (+0 °,+180°) - PowerDVD compatibility56 // 2 = (+180 °,+0°) - BeSweet compatibility57 // 3 = (-90 °,+90°) - This seems to work. I just don't know why.54 // 0 = (+0,+0) - music mode 55 // 1 = (+0,+180) - PowerDVD compatibility 56 // 2 = (+180,+0) - BeSweet compatibility 57 // 3 = (-90,+90) - This seems to work. I just don't know why. 58 58 void phase_mode(unsigned mode); 59 59 60 60 // override the steering mode … … 71 71 72 72 private: 73 73 class decoder_impl *impl; // private implementation (details hidden) 74 bool isAC3upmix; 74 75 }; 75 76 76 77 -
mythtv/libs/libmythfreesurround/freesurround.cpp
diff -Naur --exclude=.svn a/mythtv/libs/libmythfreesurround/freesurround.cpp c/mythtv/libs/libmythfreesurround/freesurround.cpp
a c 163 163 164 164 // construction methods 165 165 void *new_decoder() { return new fsurround_decoder(block_size); } 166 void *new_decoder_upmix() { return new fsurround_decoder(block_size,true); } 166 167 void *new_buffers() { return new buffers(block_size/2); } 167 168 void *new_int16buffers() { return new int16buffers(block_size/2); } 168 169 169 170 object_pool dp(&new_decoder); 171 object_pool dp_upmix(&new_decoder_upmix); 170 172 //object_pool bp(&new_buffers); 171 173 object_pool bp16(&new_int16buffers); 172 174 … … 175 177 int channel_select = -1; 176 178 #endif 177 179 178 FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode ) :180 FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode, bool AC3upmix) : 179 181 srate(srate), 180 182 open_(false), 181 183 initialized_(false), … … 185 187 in_count(0), 186 188 out_count(0), 187 189 processed(true), 188 surround_mode(smode) 190 surround_mode(smode), 191 isAC3upmix(AC3upmix) 189 192 { 190 193 VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode)); 191 194 if (moviemode) 192 195 { 193 196 params.phasemode = 1; 194 params.center_width = 0; 195 params.gain = 1.0; 197 if (!isAC3upmix) { 198 params.center_width = 0; 199 params.gain = 1.0; 200 } else { 201 params.center_width = 25; 202 params.dimension = 0.5; 203 } 196 204 } 197 205 else 198 206 { 199 params.center_width = 70; 200 // for 50, gain should be about 1.9, c/lr about 2.7 201 // for 70, gain should be about 3.1, c/lr about 1.5 202 params.gain = 3.1; 207 if (!isAC3upmix) { 208 params.center_width = 70; 209 // for 50, gain should be about 1.9, c/lr about 2.7 210 // for 70, gain should be about 3.1, c/lr about 1.5 211 params.gain = 3.1; 212 } else { 213 params.center_width = 65; 214 params.dimension = 0.3; 215 } 203 216 } 204 217 switch (surround_mode) 205 218 { … … 235 248 decoder->phase_mode(params.phasemode); 236 249 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 237 250 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0); 238 decoder->gain(params.gain); 251 if (!isAC3upmix) 252 decoder->gain(params.gain); 239 253 } 240 254 } 241 255 … … 654 668 { 655 669 if (decoder) 656 670 { 657 // actually these params need only be set when they change... but it doesn't hurt658 #if 0659 decoder->steering_mode(params.steering);660 decoder->phase_mode(params.phasemode);661 decoder->surround_coefficients(params.coeff_a, params.coeff_b);662 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);663 #endif664 // decode the bufs->block665 //decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0);666 //decoder->decode(output,params.center_width/100.0,params.dimension/100.0);667 671 decoder->decode(params.center_width/100.0,params.dimension/100.0); 668 672 } 669 673 } … … 693 697 { 694 698 if (!decoder) 695 699 { 696 decoder = (fsurround_decoder*)dp.acquire((void*)1); 700 if (!isAC3upmix) 701 decoder = (fsurround_decoder*)dp.acquire((void*)1); 702 else 703 decoder = (fsurround_decoder*)dp_upmix.acquire((void*)1); 697 704 decoder->flush(); 698 705 //if (bufs) 699 706 // bufs->clear(); … … 708 715 { 709 716 if (decoder) 710 717 { 711 dp.release(this); 718 if (!isAC3upmix) 719 dp.release(this); 720 else 721 dp_upmix.release(this); 712 722 decoder = 0; 713 723 } 714 724 } -
mythtv/libs/libmythfreesurround/freesurround.h
diff -Naur --exclude=.svn a/mythtv/libs/libmythfreesurround/freesurround.h c/mythtv/libs/libmythfreesurround/freesurround.h
a c 31 31 SurroundModeActiveLinear 32 32 } SurroundMode; 33 33 public: 34 FreeSurround(uint srate, bool moviemode, SurroundMode mode );34 FreeSurround(uint srate, bool moviemode, SurroundMode mode, bool AC3upmix=false); 35 35 ~FreeSurround(); 36 36 37 37 // put samples in buffer, returns number of samples used … … 88 88 bool processed; // whether processing is enabled or not for latency calc 89 89 int processed_size; // amount processed 90 90 SurroundMode surround_mode; // 1 of 3 surround modes supported 91 bool isAC3upmix; 91 92 92 93 }; 93 94 -
mythtv/libs/libmythsamplerate/samplerate.c
diff -Naur --exclude=.svn a/mythtv/libs/libmythsamplerate/samplerate.c c/mythtv/libs/libmythsamplerate/samplerate.c
a c 428 428 429 429 error = src_process (src_state, src_data) ; 430 430 431 src_ state = src_delete (src_state) ;431 src_delete (src_state) ; 432 432 433 433 return error ; 434 434 } /* src_simple */ … … 452 452 { len -- ; 453 453 454 454 scaled_value = in [len] * (8.0 * 0x10000000) ; 455 if ( CPU_CLIPS_POSITIVE == 0 &&scaled_value >= (1.0 * 0x7FFFFFFF))455 if (scaled_value >= (1.0 * 0x7FFFFFFF)) 456 456 { out [len] = 32767 ; 457 457 continue ; 458 458 } ; 459 if ( CPU_CLIPS_NEGATIVE == 0 &&scaled_value <= (-8.0 * 0x10000000))459 if (scaled_value <= (-8.0 * 0x10000000)) 460 460 { out [len] = -32768 ; 461 461 continue ; 462 462 } ; -
mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp c/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
a c 769 769 770 770 no_audio_in = false; 771 771 772 bool isAC3upmix = gContext->GetNumSetting("MythAC3Upmix",0); 773 // If previously AC3 upmixer was different than current state, delete AudioOutput 774 if (audioOutput && (audioOutput->isAC3upmix != isAC3upmix)) 775 { 776 delete audioOutput; 777 audioOutput = NULL; 778 } 779 772 780 if (!audioOutput && !using_null_videoout) 773 781 { 774 782 bool setVolume = gContext->GetNumSetting("MythControlsVolume", 1); … … 777 785 audio_bits, audio_channels, 778 786 audio_samplerate, 779 787 AUDIOOUTPUT_VIDEO, 780 setVolume, audio_passthru );788 setVolume, audio_passthru, isAC3upmix); 781 789 if (!audioOutput) 782 790 errMsg = QObject::tr("Unable to create AudioOutput."); 783 791 else … … 806 814 audioOutput->Reconfigure(audio_bits, audio_channels, 807 815 audio_samplerate, audio_passthru, 808 816 audio_codec); 817 if (audioOutput->isAC3upmix && audio_passthru) 818 audio_channels = 2; 809 819 errMsg = audioOutput->GetError(); 810 820 if (!errMsg.isEmpty()) 811 821 audioOutput->SetStretchFactor(audio_stretchfactor); -
mythtv/libs/libmythtv/avformatdecoder.cpp
diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/avformatdecoder.cpp c/mythtv/libs/libmythtv/avformatdecoder.cpp
a c 411 411 audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]), 412 412 allow_ac3_passthru(false), allow_dts_passthru(false), 413 413 disable_passthru(false), max_channels(2), 414 dummy_frame(NULL),414 last_ac3_channels(0), dummy_frame(NULL), 415 415 // DVD 416 416 lastdvdtitle(-1), 417 417 decodeStillFrame(false), … … 429 429 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 430 430 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 431 431 max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2); 432 isAC3upmix = gContext->GetNumSetting("MythAC3Upmix", 0); 432 433 433 434 audioIn.sample_size = -32; // force SetupAudioStream to run once 434 435 itv = GetNVP()->GetInteractiveTV(); … … 2829 2830 { 2830 2831 int idx = atracks[i].av_stream_index; 2831 2832 AVCodecContext *codec_ctx = ic->streams[idx]->codec; 2832 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&2833 !disable_passthru &&2834 (codec_ctx->codec_id == CODEC_ID_AC3));2835 bool do_dts_passthru = (allow_dts_passthru && !transcoding &&2836 !disable_passthru &&2837 (codec_ctx->codec_id == CODEC_ID_DTS));2838 2833 AudioInfo item(codec_ctx->codec_id, 2839 2834 codec_ctx->sample_rate, codec_ctx->channels, 2840 do_ac3_passthru || do_dts_passthru);2835 DoPassThrough(codec_ctx)); 2841 2836 VERBOSE(VB_AUDIO, LOC + " * " + item.toString()); 2842 2837 } 2843 2838 #endif … … 2971 2966 bool AvFormatDecoder::GetFrame(int onlyvideo) 2972 2967 { 2973 2968 AVPacket *pkt = NULL; 2969 AC3HeaderInfo hdr; 2974 2970 int len; 2975 2971 unsigned char *ptr; 2976 2972 int data_size = 0; … … 3157 3153 pts = 0; 3158 3154 3159 3155 AVStream *curstream = ic->streams[pkt->stream_index]; 3156 AVCodecContext *ctx = curstream->codec; 3160 3157 3161 3158 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3162 3159 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 3163 3160 3164 3161 if (ringBuffer->isDVD() && 3165 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3162 ctx->codec_type == CODEC_TYPE_VIDEO) 3166 3163 { 3167 3164 MpegPreProcessPkt(curstream, pkt); 3168 3165 … … 3190 3187 3191 3188 if (!d->HasMPEG2Dec()) 3192 3189 { 3193 int current_width = c urstream->codec->width;3190 int current_width = ctx->width; 3194 3191 int video_width = GetNVP()->GetVideoSize().width(); 3195 3192 if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput()) 3196 3193 { … … 3231 3228 } 3232 3229 3233 3230 if (storevideoframes && 3234 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3231 ctx->codec_type == CODEC_TYPE_VIDEO) 3235 3232 { 3236 3233 av_dup_packet(pkt); 3237 3234 storedPackets.append(pkt); … … 3239 3236 continue; 3240 3237 } 3241 3238 3242 if (len > 0 && c urstream->codec->codec_type == CODEC_TYPE_VIDEO &&3239 if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO && 3243 3240 pkt->stream_index == selectedVideoIndex) 3244 3241 { 3245 AVCodecContext *context = curstream->codec;3246 3242 3247 if (c ontext->codec_id == CODEC_ID_MPEG1VIDEO ||3248 c ontext->codec_id == CODEC_ID_MPEG2VIDEO ||3249 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||3250 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD)3243 if (ctx->codec_id == CODEC_ID_MPEG1VIDEO || 3244 ctx->codec_id == CODEC_ID_MPEG2VIDEO || 3245 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC || 3246 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD) 3251 3247 { 3252 3248 if (!ringBuffer->isDVD()) 3253 3249 MpegPreProcessPkt(curstream, pkt); 3254 3250 } 3255 else if (c ontext->codec_id == CODEC_ID_H264)3251 else if (ctx->codec_id == CODEC_ID_H264) 3256 3252 { 3257 3253 H264PreProcessPkt(curstream, pkt); 3258 3254 } … … 3298 3294 } 3299 3295 3300 3296 if (len > 0 && 3301 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3302 c urstream->codec->codec_id == CODEC_ID_MPEG2VBI)3297 ctx->codec_type == CODEC_TYPE_DATA && 3298 ctx->codec_id == CODEC_ID_MPEG2VBI) 3303 3299 { 3304 3300 ProcessVBIDataPacket(curstream, pkt); 3305 3301 … … 3308 3304 } 3309 3305 3310 3306 if (len > 0 && 3311 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3312 c urstream->codec->codec_id == CODEC_ID_DVB_VBI)3307 ctx->codec_type == CODEC_TYPE_DATA && 3308 ctx->codec_id == CODEC_ID_DVB_VBI) 3313 3309 { 3314 3310 ProcessDVBDataPacket(curstream, pkt); 3315 3311 … … 3318 3314 } 3319 3315 3320 3316 if (len > 0 && 3321 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3322 c urstream->codec->codec_id == CODEC_ID_DSMCC_B)3317 ctx->codec_type == CODEC_TYPE_DATA && 3318 ctx->codec_id == CODEC_ID_DSMCC_B) 3323 3319 { 3324 3320 ProcessDSMCCPacket(curstream, pkt); 3325 3321 … … 3339 3335 } 3340 3336 3341 3337 // we don't care about other data streams 3342 if (c urstream->codec->codec_type == CODEC_TYPE_DATA)3338 if (ctx->codec_type == CODEC_TYPE_DATA) 3343 3339 { 3344 3340 av_free_packet(pkt); 3345 3341 continue; 3346 3342 } 3347 3343 3348 if (!c urstream->codec->codec)3344 if (!ctx->codec) 3349 3345 { 3350 3346 VERBOSE(VB_PLAYBACK, LOC + 3351 3347 QString("No codec for stream index %1, type(%2) id(%3:%4)") 3352 3348 .arg(pkt->stream_index) 3353 .arg(codec_type_string(c urstream->codec->codec_type))3354 .arg(codec_id_string(c urstream->codec->codec_id))3355 .arg(c urstream->codec->codec_id));3349 .arg(codec_type_string(ctx->codec_type)) 3350 .arg(codec_id_string(ctx->codec_id)) 3351 .arg(ctx->codec_id)); 3356 3352 av_free_packet(pkt); 3357 3353 continue; 3358 3354 } … … 3361 3357 have_err = false; 3362 3358 3363 3359 avcodeclock.lock(); 3364 int ctype = c urstream->codec->codec_type;3360 int ctype = ctx->codec_type; 3365 3361 int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; 3366 3362 int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; 3367 3363 int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; … … 3386 3382 3387 3383 // detect switches between stereo and dual languages 3388 3384 bool wasDual = audSubIdx != -1; 3389 bool isDual = c urstream->codec->avcodec_dual_language;3385 bool isDual = ctx->avcodec_dual_language; 3390 3386 if ((wasDual && !isDual) || (!wasDual && isDual)) 3391 3387 { 3392 3388 SetupAudioStreamSubIndexes(audIdx); 3393 3389 reselectAudioTrack = true; 3394 3390 } 3395 3391 3396 bool do_ac3_passthru =3397 (allow_ac3_passthru && !transcoding &&3398 (curstream->codec->codec_id == CODEC_ID_AC3));3399 bool do_dts_passthru =3400 (allow_dts_passthru && !transcoding &&3401 (curstream->codec->codec_id == CODEC_ID_DTS));3402 bool using_passthru = do_ac3_passthru || do_dts_passthru;3403 3404 3392 // detect channels on streams that need 3405 3393 // to be decoded before we can know this 3406 3394 bool already_decoded = false; 3407 if (!c urstream->codec->channels)3395 if (!ctx->channels) 3408 3396 { 3409 3397 QMutexLocker locker(&avcodeclock); 3410 3398 VERBOSE(VB_IMPORTANT, LOC + 3411 3399 QString("Setting channels to %1") 3412 3400 .arg(audioOut.channels)); 3413 3401 3414 if ( using_passthru)3402 if (DoPassThrough(ctx)) 3415 3403 { 3416 3404 // for passthru let it select the max number 3417 3405 // of channels 3418 c urstream->codec->channels = 0;3419 c urstream->codec->request_channels = 0;3406 ctx->channels = 0; 3407 ctx->request_channels = 0; 3420 3408 } 3421 3409 else 3422 3410 { 3423 c urstream->codec->channels = audioOut.channels;3424 c urstream->codec->request_channels =3411 ctx->channels = audioOut.channels; 3412 ctx->request_channels = 3425 3413 audioOut.channels; 3426 3414 } 3427 3415 ret = avcodec_decode_audio( 3428 c urstream->codec, audioSamples,3416 ctx, audioSamples, 3429 3417 &data_size, ptr, len); 3430 3418 already_decoded = true; 3431 3419 3432 reselectAudioTrack |= curstream->codec->channels; 3420 reselectAudioTrack |= ctx->channels; 3421 } 3422 3423 if (isAC3upmix && ctx->codec_id == CODEC_ID_AC3 && 3424 !ff_ac3_parse_header(ptr, &hdr)) 3425 { 3426 if (hdr.channels != last_ac3_channels) 3427 { 3428 last_ac3_channels = ctx->channels = hdr.channels; 3429 SetupAudioStream(); 3430 } 3433 3431 } 3434 3432 3435 3433 if (reselectAudioTrack) … … 3445 3443 .av_stream_index; 3446 3444 audSubIdx = selectedTrack[kTrackTypeAudio] 3447 3445 .av_substream_index; 3446 ctx = curstream->codec; 3448 3447 } 3449 3448 3450 3449 if ((onlyvideo > 0) || (pkt->stream_index != audIdx)) … … 3476 3475 if (audioOut.do_passthru) 3477 3476 { 3478 3477 data_size = pkt->size; 3479 bool dts = CODEC_ID_DTS == c urstream->codec->codec_id;3478 bool dts = CODEC_ID_DTS == ctx->codec_id; 3480 3479 ret = encode_frame(dts, ptr, len, 3481 3480 audioSamples, data_size); 3482 3481 } 3483 3482 else 3484 3483 { 3485 AVCodecContext *ctx = curstream->codec;3486 3487 3484 if ((ctx->channels == 0) || 3488 3485 (ctx->channels > audioOut.channels)) 3489 3486 { … … 3492 3489 3493 3490 if (!already_decoded) 3494 3491 { 3495 curstream->codec->request_channels = 3496 audioOut.channels; 3492 ctx->request_channels = audioOut.channels; 3497 3493 ret = avcodec_decode_audio( 3498 3494 ctx, audioSamples, &data_size, ptr, len); 3499 3495 } … … 3510 3506 audIdx = -1; 3511 3507 AutoSelectAudioTrack(); 3512 3508 data_size = 0; 3509 ctx = curstream->codec; 3513 3510 } 3514 3511 } 3515 3512 avcodeclock.unlock(); … … 3527 3524 3528 3525 // calc for next frame 3529 3526 lastapts += (long long)((double)(data_size * 1000) / 3530 (curstream->codec->channels * 2) / 3531 curstream->codec->sample_rate); 3527 (ctx->channels * 2) / ctx->sample_rate); 3532 3528 3533 3529 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, 3534 3530 LOC + QString("audio timecode %1 %2 %3 %4") … … 3588 3584 continue; 3589 3585 } 3590 3586 3591 AVCodecContext *context = curstream->codec;3592 3587 AVFrame mpa_pic; 3593 3588 bzero(&mpa_pic, sizeof(AVFrame)); 3594 3589 … … 3603 3598 // HACK 3604 3599 while (!gotpicture && count < 5) 3605 3600 { 3606 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3601 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3607 3602 &gotpicture, ptr, len); 3608 3603 count++; 3609 3604 } 3610 3605 } 3611 3606 else 3612 3607 { 3613 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3608 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3614 3609 &gotpicture, ptr, len); 3615 3610 } 3616 3611 } 3617 3612 else 3618 3613 { 3619 ret = avcodec_decode_video(c ontext, &mpa_pic,3614 ret = avcodec_decode_video(ctx, &mpa_pic, 3620 3615 &gotpicture, ptr, len); 3621 3616 // Reparse it to not drop the DVD still frame 3622 3617 if (decodeStillFrame) 3623 ret = avcodec_decode_video(c ontext, &mpa_pic,3618 ret = avcodec_decode_video(ctx, &mpa_pic, 3624 3619 &gotpicture, ptr, len); 3625 3620 } 3626 3621 avcodeclock.unlock(); … … 3687 3682 3688 3683 img_convert(&tmppicture, PIX_FMT_YUV420P, 3689 3684 (AVPicture *)&mpa_pic, 3690 c ontext->pix_fmt,3691 c ontext->width,3692 c ontext->height);3685 ctx->pix_fmt, 3686 ctx->width, 3687 ctx->height); 3693 3688 3694 3689 if (xf) 3695 3690 { … … 3712 3707 (temppts + 10000 > lastvpts || temppts < 0)) 3713 3708 { 3714 3709 temppts = lastvpts; 3715 temppts += (long long)(1000 * av_q2d(c ontext->time_base));3710 temppts += (long long)(1000 * av_q2d(ctx->time_base)); 3716 3711 // MPEG2 frames can be repeated, update pts accordingly 3717 3712 temppts += (long long)(mpa_pic.repeat_pict * 500 3718 * av_q2d(c urstream->codec->time_base));3713 * av_q2d(ctx->time_base)); 3719 3714 } 3720 3715 3721 3716 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + … … 3751 3746 picframe->frameNumber = framesPlayed; 3752 3747 GetNVP()->ReleaseNextVideoFrame(picframe, temppts); 3753 3748 if (d->HasMPEG2Dec() && mpa_pic.data[3]) 3754 c ontext->release_buffer(context, &mpa_pic);3749 ctx->release_buffer(ctx, &mpa_pic); 3755 3750 3756 3751 decoded_video_frame = picframe; 3757 3752 gotvideo = 1; … … 3810 3805 } 3811 3806 default: 3812 3807 { 3813 AVCodecContext *enc = curstream->codec;3814 3808 VERBOSE(VB_IMPORTANT, LOC_ERR + 3815 3809 QString("Decoding - id(%1) type(%2)") 3816 .arg(codec_id_string( enc->codec_id))3817 .arg(codec_type_string( enc->codec_type)));3810 .arg(codec_id_string(ctx->codec_id)) 3811 .arg(codec_type_string(ctx->codec_type))); 3818 3812 have_err = true; 3819 3813 break; 3820 3814 } … … 3959 3953 } 3960 3954 } 3961 3955 3956 bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx) 3957 { 3958 bool do_ac3_passthru = 3959 (allow_ac3_passthru && !transcoding && 3960 (ctx->codec_id == CODEC_ID_AC3)); 3961 bool do_dts_passthru = 3962 (allow_dts_passthru && !transcoding && 3963 (ctx->codec_id == CODEC_ID_DTS)); 3964 bool using_passthru = do_ac3_passthru || do_dts_passthru; 3965 3966 if (!isAC3upmix) 3967 return using_passthru; 3968 3969 bool passthru = false; 3970 3971 if (ctx->codec_id == CODEC_ID_AC3) 3972 passthru = allow_ac3_passthru && 3973 ctx->channels >= (int)max_channels; 3974 else if (ctx->codec_id == CODEC_ID_DTS) 3975 passthru = allow_dts_passthru; 3976 3977 passthru &= !transcoding && !disable_passthru; 3978 // Don't know any cards that support spdif clocked at < 44100 3979 // Some US cable transmissions have 2ch 32k AC-3 streams 3980 passthru &= ctx->sample_rate >= 44100; 3981 3982 return passthru; 3983 } 3984 3962 3985 /** \fn AvFormatDecoder::SetupAudioStream(void) 3963 3986 * \brief Reinitializes audio if it needs to be reinitialized. 3964 3987 * … … 3984 4007 assert(curstream); 3985 4008 assert(curstream->codec); 3986 4009 codec_ctx = curstream->codec; 3987 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3988 (codec_ctx->codec_id == CODEC_ID_AC3)); 3989 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3990 (codec_ctx->codec_id == CODEC_ID_DTS)); 3991 using_passthru = do_ac3_passthru || do_dts_passthru; 3992 info = AudioInfo(codec_ctx->codec_id, 3993 codec_ctx->sample_rate, codec_ctx->channels, 3994 using_passthru && !disable_passthru); 4010 using_passthru = DoPassThrough(codec_ctx); 4011 if (!isAC3upmix) 4012 info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, codec_ctx->channels, using_passthru && !disable_passthru); 4013 else 4014 info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, 4015 codec_ctx->channels, using_passthru); 3995 4016 } 3996 4017 3997 4018 if (info == audioIn) … … 4002 4023 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4003 4024 4004 4025 audioOut = audioIn = info; 4026 if (!isAC3upmix) { 4005 4027 if (using_passthru) 4006 4028 { 4007 4029 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card … … 4058 4080 4059 4081 // allow the audio stuff to reencode 4060 4082 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 4083 } else { 4084 4085 if (!using_passthru && audioOut.channels > (int)max_channels) 4086 { 4087 audioOut.channels = (int)max_channels; 4088 audioOut.sample_size = audioOut.channels * 2; 4089 codec_ctx->channels = audioOut.channels; 4090 } 4091 4092 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4093 QString("\n\t\t\tfrom %1 to %2") 4094 .arg(old_in.toString()).arg(audioOut.toString())); 4095 4096 if (audioOut.sample_rate > 0) 4097 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4098 4099 GetNVP()->SetAudioCodec(codec_ctx); 4100 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 4101 audioOut.sample_rate, 4102 audioOut.do_passthru); 4103 4104 } 4061 4105 QString errMsg = GetNVP()->ReinitAudio(); 4062 4106 bool audiook = errMsg.isEmpty(); 4063 4107 -
mythtv/libs/libmythtv/avformatdecoder.h
diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/avformatdecoder.h c/mythtv/libs/libmythtv/avformatdecoder.h
a c 183 183 void InitVideoCodec(AVStream *stream, AVCodecContext *enc, 184 184 bool selectedStream = false); 185 185 186 /// Preprocess a packet, setting the video parms if ne ssesary.186 /// Preprocess a packet, setting the video parms if necessary. 187 187 void MpegPreProcessPkt(AVStream *stream, AVPacket *pkt); 188 188 void H264PreProcessPkt(AVStream *stream, AVPacket *pkt); 189 189 … … 196 196 197 197 void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames); 198 198 199 bool DoPassThrough(const AVCodecContext *ctx); 199 200 bool SetupAudioStream(void); 200 201 void SetupAudioStreamSubIndexes(int streamIndex); 201 202 void RemoveAudioStreams(); … … 264 265 bool allow_dts_passthru; 265 266 bool disable_passthru; 266 267 uint max_channels; 268 uint last_ac3_channels; 269 bool isAC3upmix; 267 270 268 271 VideoFrame *dummy_frame; 269 272 -
mythtv/libs/libmythtv/tv_play.cpp
diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/tv_play.cpp c/mythtv/libs/libmythtv/tv_play.cpp
a c 348 348 REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 349 349 REG_KEY("TV Playback", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 350 350 REG_KEY("TV Playback", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 351 REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U"); 351 352 REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture mode", 352 353 "V"); 353 354 REG_KEY("TV Playback", "TOGGLEPIPWINDOW", "Toggle active PiP window", "B"); … … 480 481 Teletext F2,F3,F4,F5,F6,F7,F8 481 482 ITV F2,F3,F4,F5,F6,F7,F12 482 483 483 Playback: Ctrl-B,Ctrl-G,Ctrl-Y 484 Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U 484 485 */ 485 486 } 486 487 … … 2710 2711 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2711 2712 action == "STRETCHINC" || action == "STRETCHDEC" || 2712 2713 action == "MUTE" || action == "TOGGLEASPECT" || 2713 action == "TOGGLEFILL" )2714 action == "TOGGLEFILL" || action == "TOGGLEUPMIX") 2714 2715 { 2715 2716 passThru = 1; 2716 2717 handled = false; … … 2765 2766 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2766 2767 action == "STRETCHINC" || action == "STRETCHDEC" || 2767 2768 action == "MUTE" || action == "PAUSE" || 2768 action == "CLEAROSD" )2769 action == "CLEAROSD" || action == "TOGGLEUPMIX") 2769 2770 { 2770 2771 passThru = 1; 2771 2772 handled = false; … … 3070 3071 ChangeTimeStretch(0); // just display 3071 3072 else if (action == "TOGGLESTRETCH") 3072 3073 ToggleTimeStretch(); 3074 else if (action == "TOGGLEUPMIX") 3075 ToggleUpmix(); 3073 3076 else if (action == "CYCLECOMMSKIPMODE") { 3074 3077 SetAutoCommercialSkip((enum commSkipMode) 3075 3078 ((autoCommercialSkip + 1) % CommSkipModes)); … … 6054 6057 } 6055 6058 } 6056 6059 6060 void TV::ToggleUpmix() 6061 { 6062 AudioOutput *aud = nvp->getAudioOutput(); 6063 if (!aud) 6064 return; 6065 QString text; 6066 if(!aud->isAC3upmix) { 6067 text = tr("Upmixer disabled !"); 6068 } else { 6069 if (aud->ToggleUpmix()) 6070 text = tr("Upmixer On"); 6071 else 6072 text = tr("Upmixer Off"); 6073 } 6074 6075 if (GetOSD() && !browsemode) 6076 GetOSD()->SetSettingsText(text, 5); 6077 } 6078 6079 6057 6080 // dir in 10ms jumps 6058 6081 void TV::ChangeAudioSync(int dir, bool allowEdit) 6059 6082 { … … 7302 7325 7303 7326 ChangeTimeStretch(0, !floatRead); // just display 7304 7327 } 7328 else if (action == "TOGGLEUPMIX") 7329 ToggleUpmix(); 7305 7330 else if (action.left(11) == "SELECTSCAN_") 7306 7331 activenvp->SetScanType((FrameScanType) action.right(1).toInt()); 7307 7332 else if (action.left(15) == "TOGGLEAUDIOSYNC") … … 7550 7575 (speedX100 == 150) ? 1 : 0, NULL, 7551 7576 "STRETCHGROUP"); 7552 7577 7578 if(nvp && nvp->getAudioOutput()->isAC3upmix) 7579 item = new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX"); 7580 7553 7581 // add scan mode override settings to menu 7554 7582 FrameScanType scan_type = kScan_Ignore; 7555 7583 bool scan_type_locked = false; -
mythtv/libs/libmythtv/tv_play.h
diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/tv_play.h c/mythtv/libs/libmythtv/tv_play.h
a c 314 314 void ChangeSpeed(int direction); 315 315 void ToggleTimeStretch(void); 316 316 void ChangeTimeStretch(int dir, bool allowEdit = true); 317 void ToggleUpmix(void); 317 318 void ChangeAudioSync(int dir, bool allowEdit = true); 318 319 float StopFFRew(void); 319 320 void ChangeFFRew(int direction); -
mythtv/programs/mythfrontend/globalsettings.cpp
diff -Naur --exclude=.svn a/mythtv/programs/mythfrontend/globalsettings.cpp c/mythtv/programs/mythfrontend/globalsettings.cpp
a c 116 116 return gc; 117 117 } 118 118 119 static HostCheckBox *AC3Upmix() 120 { 121 HostCheckBox *gc = new HostCheckBox("MythAC3Upmix"); 122 gc->setLabel(QObject::tr("AC3 audio upmixer")); 123 gc->setValue(false); 124 gc->setHelpText(QObject::tr("Enable AC3 upmixer and digital software volume control.")); 125 return gc; 126 } 127 128 static HostComboBox *SRCQuality() 129 { 130 HostComboBox *gc = new HostComboBox("SRCQuality", false); 131 gc->setLabel(QObject::tr("Sample Rate Conversion")); 132 gc->addSelection(QObject::tr("Best"), "3", true); // default 133 gc->addSelection(QObject::tr("Medium"), "2"); 134 gc->addSelection(QObject::tr("Fastest"), "1"); 135 gc->addSelection(QObject::tr("Disabled"), "0"); 136 gc->setHelpText( 137 QObject::tr( 138 "Set the quality of audio sample rate conversion. " 139 "This only affects non 48000Hz PCM audio. " 140 "All three options offer a worst-case SNR of 97dB. " 141 "'Best' at a bandwidth of 97%. " 142 "'Medium' at a bandwidth of 90%. " 143 "'Fastest' at a bandwidth of 80%. " 144 "Set 'Disabled' only if you know what you are doing.")); 145 return gc; 146 } 147 119 148 static HostComboBox *PassThroughOutputDevice() 120 149 { 121 150 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3284 3313 return gs; 3285 3314 } 3286 3315 3316 class AC3UpmixSettings : public TriggeredConfigurationGroup 3317 { 3318 public: 3319 AC3UpmixSettings(Setting *checkbox, ConfigurationGroup *group) : 3320 TriggeredConfigurationGroup(false, false, false, false) 3321 { 3322 setTrigger(checkbox); 3323 3324 addTarget("1", group); 3325 addTarget("0", new VerticalConfigurationGroup(false,false)); 3326 } 3327 }; 3328 3287 3329 class AudioSettings : public TriggeredConfigurationGroup 3288 3330 { 3289 3331 public: … … 3296 3338 addChild(AudioOutputDevice()); 3297 3339 addChild(PassThroughOutputDevice()); 3298 3340 3299 3300 3341 // General boolean settings 3342 VerticalConfigurationGroup *vgrp0 = 3301 3343 new VerticalConfigurationGroup(false, false, true, true); 3302 3303 3344 vgrp0->addChild(AC3PassThrough()); 3345 vgrp0->addChild(DTSPassThrough()); 3304 3346 3305 3347 HorizontalConfigurationGroup *agrp = 3306 3348 new HorizontalConfigurationGroup(false, false, true, true); 3307 agrp->addChild(MaxAudioChannels()); 3308 agrp->addChild(AudioUpmixType()); 3309 addChild(agrp); 3349 agrp->addChild(MaxAudioChannels()); 3350 agrp->addChild(AudioUpmixType()); 3351 addChild(agrp); 3352 3353 HorizontalConfigurationGroup *agrp1 = 3354 new HorizontalConfigurationGroup(false, false, true, true); 3355 3356 VerticalConfigurationGroup *agrp1v1 = 3357 new VerticalConfigurationGroup(false, false, true, true); 3358 3359 Setting* ac3upmix = AC3Upmix(); 3360 agrp1v1->addChild(ac3upmix); 3361 agrp1->addChild(agrp1v1); 3362 3363 VerticalConfigurationGroup *agrp1v2 = 3364 new VerticalConfigurationGroup(false, false, true, true); 3365 3366 agrp1v2->addChild(SRCQuality()); 3367 3368 AC3UpmixSettings *sub1 = 3369 new AC3UpmixSettings(ac3upmix, agrp1v2); 3370 agrp1->addChild(sub1); 3371 addChild(agrp1); 3310 3372 3311 3373 VerticalConfigurationGroup *vgrp1 = 3312 3374 new VerticalConfigurationGroup(false, false, true, true); -
mythtv/programs/mythtranscode/transcode.cpp
diff -Naur --exclude=.svn a/mythtv/programs/mythtranscode/transcode.cpp c/mythtv/programs/mythtranscode/transcode.cpp
a c 218 218 // Do nothing 219 219 return MUTE_OFF; 220 220 } 221 virtual bool ToggleUpmix(void) 222 { 223 // Do nothing 224 return false; 225 } 221 226 222 227 // These are pure virtual in AudioOutput, but we don't need them here 223 228 virtual void bufferOutputData(bool){ return; }