Ticket #5900: audioencoding-fixes-vdpau-jya7.patch
File audioencoding-fixes-vdpau-jya7.patch, 91.0 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 17 17 QString laudio_main_device, QString laudio_passthru_device, 18 18 int laudio_bits, int laudio_channels, 19 19 int laudio_samplerate, AudioOutputSource lsource, 20 bool lset_initial_vol, bool laudio_passthru) : 20 bool lset_initial_vol, bool laudio_passthru, 21 bool AC3upmix) : 21 22 AudioOutputBase(laudio_main_device, laudio_passthru_device, 22 23 laudio_bits, laudio_channels, 23 24 laudio_samplerate, lsource, 24 lset_initial_vol, laudio_passthru), 25 lset_initial_vol, laudio_passthru, 26 AC3upmix), 25 27 pcm_handle(NULL), numbadioctls(0), 26 28 killAudioLock(false), mixer_handle(NULL), 27 29 mixer_control(QString::null), volume_range_multiplier(1.0f), … … 35 37 AudioOutputALSA::~AudioOutputALSA() 36 38 { 37 39 KillAudio(); 40 if (isAC3upmix) 41 SetIECStatus(true); 42 } 43 44 void AudioOutputALSA::SetIECStatus(bool audio) { 45 46 snd_ctl_t *ctl; 47 const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT); 48 int spdif_index = -1; 49 snd_ctl_elem_list_t *clist; 50 snd_ctl_elem_id_t *cid; 51 snd_ctl_elem_value_t *cval; 52 snd_aes_iec958_t iec958; 53 int cidx, controls; 54 55 VERBOSE(VB_AUDIO, QString("Setting IEC958 status: %1") 56 .arg(audio ? "audio" : "non-audio")); 57 58 snd_ctl_open(&ctl, "default", 0); 59 snd_ctl_elem_list_alloca(&clist); 60 snd_ctl_elem_list(ctl, clist); 61 snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist)); 62 snd_ctl_elem_list(ctl, clist); 63 controls = snd_ctl_elem_list_get_used(clist); 64 for (cidx = 0; cidx < controls; cidx++) 65 { 66 if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str)) 67 if (spdif_index < 0 || 68 snd_ctl_elem_list_get_index(clist, cidx) == (uint)spdif_index) 69 break; 70 } 71 72 if (cidx >= controls) 73 return; 74 75 snd_ctl_elem_id_alloca(&cid); 76 snd_ctl_elem_list_get_id(clist, cidx, cid); 77 snd_ctl_elem_value_alloca(&cval); 78 snd_ctl_elem_value_set_id(cval, cid); 79 snd_ctl_elem_read(ctl,cval); 80 snd_ctl_elem_value_get_iec958(cval, &iec958); 81 82 if (!audio) 83 iec958.status[0] |= IEC958_AES0_NONAUDIO; 84 else 85 iec958.status[0] &= ~IEC958_AES0_NONAUDIO; 86 87 snd_ctl_elem_value_set_iec958(cval, &iec958); 88 snd_ctl_elem_write(ctl, cval); 89 38 90 } 39 91 40 92 bool AudioOutputALSA::OpenDevice() … … 42 94 snd_pcm_format_t format; 43 95 unsigned int buffer_time, period_time; 44 96 int err; 97 QString real_device; 45 98 46 99 if (pcm_handle != NULL) 47 100 CloseDevice(); … … 49 102 pcm_handle = NULL; 50 103 numbadioctls = 0; 51 104 52 QString real_device = (audio_passthru) ? 53 audio_passthru_device : audio_main_device; 105 if (!isAC3upmix) { 106 real_device = (audio_passthru) ? 107 audio_passthru_device : audio_main_device; 108 } 109 else 110 if (audio_passthru || audio_enc) 111 { 112 real_device = audio_passthru_device; 113 SetIECStatus(false); 114 } 115 else 116 { 117 real_device = audio_main_device; 118 SetIECStatus(true); 119 } 54 120 55 121 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 56 122 .arg(real_device)); -
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, -
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 } 220 262 } 221 263 222 264 ClearError(); 223 265 bool general_deps = (laudio_bits == audio_bits && 224 266 laudio_channels == audio_channels && 225 267 laudio_samplerate == audio_samplerate && !need_resampler && 226 268 laudio_passthru == audio_passthru && 227 269 lneeds_upmix == needs_upmix && 228 lcodec_id == codec_id && lcchannels == cchannels); 270 (isAC3upmix ? (laudio_reenc == audio_reenc) : (lcodec_id == codec_id && lcchannels == cchannels)) 271 ); 229 272 bool upmix_deps = 230 273 (lsource_audio_channels == source_audio_channels); 231 274 if (general_deps && upmix_deps) … … 256 299 audio_channels = laudio_channels; 257 300 source_audio_channels = lsource_audio_channels; 258 301 audio_bits = laudio_bits; 259 audio_samplerate = laudio_samplerate; 260 audio_codec = (AVCodecContext*)laudio_codec; 302 if (!isAC3upmix) { 303 audio_samplerate = laudio_samplerate; 304 audio_codec = (AVCodecContext*)laudio_codec; 305 } else { 306 source_audio_samplerate = audio_samplerate = laudio_samplerate; 307 audio_reenc = laudio_reenc; 308 } 261 309 audio_passthru = laudio_passthru; 262 310 needs_upmix = lneeds_upmix; 263 311 … … 268 316 Error("AudioOutput only supports 8 or 16bit audio."); 269 317 return; 270 318 } 271 audio_bytes_per_sample = audio_channels * audio_bits / 8;272 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;273 319 274 320 need_resampler = false; 275 321 killaudio = false; … … 279 325 280 326 numlowbuffer = 0; 281 327 328 if (!isAC3upmix) { 329 audio_bytes_per_sample = audio_channels * audio_bits / 8; 330 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 331 } else { 332 // Encode to AC-3 if not passing thru, there's more than 2 channels 333 // and we're allowed to passthru AC-3 334 // This won't reencode timestretched 2ch AC-3 but there's no point doing so 335 if (!audio_passthru && audio_channels > 2 && allow_ac3_passthru) 336 { 337 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); 338 int srate = src_quality == 0 ? audio_samplerate : 48000; 339 encoder = new AudioOutputDigitalEncoder(); 340 if (!encoder->Init(CODEC_ID_AC3, 448000, srate, 341 audio_channels, audio_reenc)) 342 { 343 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 344 delete encoder; 345 encoder = NULL; 346 } 347 348 audio_enc = true; 349 } 350 351 if(audio_passthru || audio_enc) 352 // AC-3 output - soundcard expects a 2ch 48k stream 353 audio_channels = 2; 354 355 audio_bytes_per_sample = audio_channels * audio_bits / 8; 356 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 357 358 // Always resample to 48k - many cards can't do anything else 359 // and ALSA will do it with linear interpolation (yuk) if we don't anyway 360 if (src_quality != 0 && audio_samplerate != 48000) 361 { 362 int error; 363 audio_samplerate = 48000; 364 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2") 365 .arg(laudio_samplerate).arg(audio_samplerate)); 366 src_ctx = src_new(3-src_quality, audio_channels, &error); 367 if (error) 368 { 369 Error(QString("Error creating resampler, the error was: %1") 370 .arg(src_strerror(error)) ); 371 pthread_mutex_unlock(&avsync_lock); 372 pthread_mutex_unlock(&audio_buflock); 373 src_ctx = NULL; 374 return; 375 } 376 src_data.src_ratio = (double) audio_samplerate / laudio_samplerate; 377 src_data.data_in = src_in; 378 src_data.data_out = src_out; 379 src_data.output_frames = 16384*6; 380 need_resampler = true; 381 } 382 } 282 383 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 283 384 .arg(audio_main_device).arg(audio_channels) 284 385 .arg(source_audio_channels).arg(audio_samplerate)); … … 314 415 current_seconds = -1; 315 416 source_bitrate = -1; 316 417 418 if (!isAC3upmix) { 317 419 // NOTE: this won't do anything as above samplerate vars are set equal 318 420 // Check if we need the resampler 319 421 if (audio_samplerate != laudio_samplerate) … … 336 438 src_data.output_frames = 16384*6; 337 439 need_resampler = true; 338 440 } 339 441 } 340 442 if (needs_upmix) 341 443 { 342 444 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); … … 348 450 upmixer = new FreeSurround( 349 451 audio_samplerate, 350 452 source == AUDIOOUTPUT_VIDEO, 351 (FreeSurround::SurroundMode)surround_mode );453 (FreeSurround::SurroundMode)surround_mode,isAC3upmix); 352 454 353 455 VERBOSE(VB_AUDIO, LOC + 354 456 QString("create upmixer done with surround mode %1") … … 357 459 358 460 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 359 461 .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) 462 if (!isAC3upmix) { 463 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 464 .arg((audio_codec) ? 465 codec_id_string(audio_codec->codec_id) : "not set")); 466 467 if (redo_stretch) 468 { 469 delete pSoundStretch; 470 pSoundStretch = NULL; 471 SetStretchFactorLocked(audio_stretchfactor); 472 } 473 else 376 474 { 377 // if its passthru then we need to reencode378 if ( audio_codec)475 SetStretchFactorLocked(audio_stretchfactor); 476 if (pSoundStretch) 379 477 { 380 if (!encoder) 478 // if its passthru then we need to reencode 479 if (audio_codec) 381 480 { 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 )) 481 if (!encoder) 392 482 { 393 // eeks 394 delete encoder; 395 encoder = NULL; 396 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder"); 483 VERBOSE(VB_AUDIO, LOC + 484 QString("Creating Encoder for codec %1") 485 .arg(audio_codec->codec_id)); 486 487 encoder = new AudioOutputDigitalEncoder(isAC3upmix); 488 if (!encoder->Init(audio_codec->codec_id, 489 audio_codec->bit_rate, 490 audio_codec->sample_rate, 491 audio_codec->channels 492 )) 493 { 494 // eeks 495 delete encoder; 496 encoder = NULL; 497 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder"); 498 } 397 499 } 398 500 } 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);501 if (audio_codec && encoder) 502 { 503 pSoundStretch->setSampleRate(audio_codec->sample_rate); 504 pSoundStretch->setChannels(audio_codec->channels); 505 } 506 else 507 { 508 pSoundStretch->setSampleRate(audio_samplerate); 509 pSoundStretch->setChannels(audio_channels); 510 } 409 511 } 410 512 } 513 } else { 514 SetStretchFactorLocked(old_audio_stretchfactor); 411 515 } 412 413 516 // Setup visualisations, zero the visualisations buffers 414 517 prepareVisuals(); 415 518 … … 456 559 killaudio = true; 457 560 StopOutputThread(); 458 561 562 if (isAC3upmix) 563 pthread_mutex_lock(&audio_buflock); 564 459 565 // Close resampler? 460 if (src_ctx) 566 if (src_ctx) { 461 567 src_delete(src_ctx); 568 if (isAC3upmix) 569 src_ctx = NULL; 570 } 462 571 need_resampler = false; 463 572 464 573 // close sound stretcher … … 466 575 { 467 576 delete pSoundStretch; 468 577 pSoundStretch = NULL; 578 if (isAC3upmix) { 579 old_audio_stretchfactor = audio_stretchfactor; 580 audio_stretchfactor = 1.0; 581 } 469 582 } 470 583 471 584 if (encoder) … … 480 593 upmixer = NULL; 481 594 } 482 595 needs_upmix = false; 596 if (isAC3upmix) 597 audio_enc = false; 483 598 484 599 CloseDevice(); 485 600 601 if (isAC3upmix) 602 pthread_mutex_unlock(&audio_buflock); 486 603 killAudioLock.unlock(); 487 604 } 488 605 … … 642 759 // include algorithmic latencies 643 760 if (pSoundStretch) 644 761 { 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); 762 if (!isAC3upmix) { 763 // add the effect of any unused but processed samples, 764 // AC3 reencode does this 765 totalbuffer += (int)(pSoundStretch->numSamples() * 766 audio_bytes_per_sample); 767 } 649 768 // add the effect of unprocessed samples in time stretch algo 650 769 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 651 770 audio_bytes_per_sample) / audio_stretchfactor); … … 656 775 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 657 776 } 658 777 778 if (isAC3upmix && encoder) 779 totalbuffer += encoder->Buffered(); 780 659 781 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 660 782 (audio_bytes_per_sample * effdspstretched)); 661 783 … … 709 831 return false; // would overflow 710 832 } 711 833 834 if (isAC3upmix) 835 pthread_mutex_lock(&audio_buflock); 836 712 837 // resample input if necessary 713 838 if (need_resampler && src_ctx) 714 839 { … … 742 867 _AddSamples(buffers, false, samples, timecode); 743 868 } 744 869 870 if (isAC3upmix) 871 pthread_mutex_unlock(&audio_buflock); 872 745 873 return true; 746 874 } 747 875 … … 753 881 int abps = (encoder) ? 754 882 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 755 883 int len = samples * abps; 884 885 if (isAC3upmix) { 886 // Give original samples to mythmusic visualisation 887 dispatchVisual((unsigned char *)buffer, len, timecode, 888 source_audio_channels, audio_bits); 889 } 756 890 757 891 // Check we have enough space to write the data 758 892 if (need_resampler && src_ctx) … … 777 911 return false; // would overflow 778 912 } 779 913 914 if (isAC3upmix) 915 pthread_mutex_lock(&audio_buflock); 916 780 917 // resample input if necessary 781 918 if (need_resampler && src_ctx) 782 919 { … … 805 942 _AddSamples(buffer, true, samples, timecode); 806 943 } 807 944 945 if (isAC3upmix) 946 pthread_mutex_unlock(&audio_buflock); 947 808 948 return true; 809 949 } 810 950 … … 837 977 { 838 978 int error = src_reset(src_ctx); 839 979 if (error) 980 { 840 981 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 841 982 "Error occured while resetting resampler: %1") 842 983 .arg(src_strerror(error))); 984 if (isAC3upmix) 985 src_ctx = NULL; 986 } 843 987 } 844 988 } 845 989 } … … 849 993 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 850 994 long long timecode) 851 995 { 852 pthread_mutex_lock(&audio_buflock); 996 if (!isAC3upmix) 997 pthread_mutex_lock(&audio_buflock); 853 998 854 999 int len; // = samples * audio_bytes_per_sample; 855 1000 int audio_bytes = audio_bits / 8; … … 868 1013 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode) 869 1014 .arg(needs_upmix)); 870 1015 1016 if (isAC3upmix) 1017 len = WaitForFreeSpace(samples); 1018 871 1019 if (upmixer && needs_upmix) 872 1020 { 873 1021 int out_samples = 0; 874 1022 int step = (interleaved)?source_audio_channels:1; 875 len = WaitForFreeSpace(samples); // test 1023 1024 if (!isAC3upmix) { 1025 org_waud = waud; 1026 len = WaitForFreeSpace(samples); 1027 } 876 1028 for (int itemp = 0; itemp < samples; ) 877 1029 { 878 1030 // just in case it does a processing cycle, release the lock 879 1031 // to allow the output loop to do output 880 pthread_mutex_unlock(&audio_buflock); 1032 if (!isAC3upmix) 1033 pthread_mutex_unlock(&audio_buflock); 881 1034 if (audio_bytes == 2) 882 1035 { 883 1036 itemp += upmixer->putSamples( … … 894 1047 source_audio_channels, 895 1048 (interleaved) ? 0 : samples); 896 1049 } 897 pthread_mutex_lock(&audio_buflock); 1050 if (!isAC3upmix) 1051 pthread_mutex_lock(&audio_buflock); 898 1052 899 1053 int copy_samples = upmixer->numSamples(); 900 1054 if (copy_samples) … … 928 1082 } 929 1083 else 930 1084 { 931 len = WaitForFreeSpace(samples);932 1085 if (!isAC3upmix) 1086 len = WaitForFreeSpace(samples); 933 1087 if (interleaved) 934 1088 { 935 1089 char *mybuf = (char*)buffer; … … 965 1119 } 966 1120 } 967 1121 1122 if (!isAC3upmix) { 968 1123 if (samples > 0) 969 1124 { 970 1125 if (pSoundStretch) … … 1022 1177 continue; 1023 1178 1024 1179 //len = WaitForFreeSpace(amount); 1025 c har *ob = encoder->GetOutBuff();1180 const char *ob = encoder->GetOutBuff(); 1026 1181 if (amount >= bdiff) 1027 1182 { 1028 1183 memcpy(audiobuffer + org_waud, ob, bdiff); … … 1035 1190 1036 1191 bdiff = AUDBUFSIZE - amount; 1037 1192 org_waud += amount; 1193 if (org_waud >= AUDBUFSIZE) 1194 { 1195 VERBOSE(VB_IMPORTANT, QString("org_waud >= kAudioRingBufferSize %1 %2").arg(org_waud).arg(amount)); 1196 org_waud -= AUDBUFSIZE; 1197 } 1038 1198 } 1039 1199 } 1040 1200 else … … 1064 1224 org_waud += nSamples * audio_bytes_per_sample; 1065 1225 nSamplesToEnd -= nSamples; 1066 1226 } 1227 if (org_waud >= AUDBUFSIZE) 1228 { 1229 VERBOSE(VB_IMPORTANT, QString("org_waud >= kAudioRingBufferSize %1 %2 %3").arg(org_waud).arg(nSamples).arg(audio_bytes_per_sample)); 1230 org_waud -= AUDBUFSIZE; 1231 } 1067 1232 1068 1233 newLen += nSamples * audio_bytes_per_sample; 1069 1234 len -= nSamples * audio_bytes_per_sample; … … 1096 1261 } 1097 1262 1098 1263 pthread_mutex_unlock(&audio_buflock); 1264 } else { 1265 if (samples <= 0) 1266 return; 1267 1268 if (pSoundStretch) 1269 { 1270 // does not change the timecode, only the number of samples 1271 // back to orig pos 1272 org_waud = waud; 1273 int bdiff = AUDBUFSIZE - org_waud; 1274 int nSamplesToEnd = bdiff/abps; 1275 if (bdiff < len) 1276 { 1277 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 1278 (audiobuffer + 1279 org_waud), nSamplesToEnd); 1280 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 1281 (len - bdiff) / abps); 1282 } 1283 else 1284 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 1285 (audiobuffer + org_waud), 1286 len / abps); 1287 1288 int nSamples = pSoundStretch->numSamples(); 1289 len = WaitForFreeSpace(nSamples); 1290 1291 while ((nSamples = pSoundStretch->numSamples())) 1292 { 1293 if (nSamples > nSamplesToEnd) 1294 nSamples = nSamplesToEnd; 1295 1296 nSamples = pSoundStretch->receiveSamples( 1297 (soundtouch::SAMPLETYPE*) 1298 (audiobuffer + org_waud), nSamples 1299 ); 1300 1301 if (nSamples == nSamplesToEnd) { 1302 org_waud = 0; 1303 nSamplesToEnd = AUDBUFSIZE/abps; 1304 } 1305 else { 1306 org_waud += nSamples * abps; 1307 nSamplesToEnd -= nSamples; 1308 } 1309 1310 } 1311 1312 } 1313 1314 // Encode to AC-3? 1315 if (encoder) 1316 { 1317 1318 org_waud = waud; 1319 int bdiff = AUDBUFSIZE - org_waud; 1320 int to_get = 0; 1321 1322 if (bdiff < len) 1323 { 1324 encoder->EncodeUpmix(audiobuffer + org_waud, bdiff); 1325 to_get = encoder->EncodeUpmix(audiobuffer, len - bdiff); 1326 } 1327 else 1328 to_get = encoder->EncodeUpmix(audiobuffer + org_waud, len); 1329 1330 if (to_get > 0) 1331 { 1332 1333 if (to_get >= bdiff) 1334 { 1335 encoder->GetFrames(audiobuffer + org_waud, bdiff); 1336 to_get -= bdiff; 1337 org_waud = 0; 1338 } 1339 if (to_get > 0) 1340 encoder->GetFrames(audiobuffer + org_waud, to_get); 1341 1342 org_waud += to_get; 1343 1344 } 1345 1346 } 1347 1348 waud = org_waud; 1349 lastaudiolen = audiolen(false); 1350 1351 if (timecode < 0) 1352 // mythmusic doesn't give timestamps.. 1353 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1354 1355 samples_buffered += samples; 1356 1357 /* we want the time at the end -- but the file format stores 1358 time at the start of the chunk. */ 1359 // even with timestretch, timecode is still calculated from original 1360 // sample count 1361 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 1362 } // End AC3 upmiz 1099 1363 } 1100 1364 1101 1365 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; 154 160 155 161 private: 156 162 // resampler … … 167 173 FreeSurround *upmixer; 168 174 169 175 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); … … 4943 4953 } 4944 4954 } 4945 4955 4956 bool NuppelVideoPlayer::ToggleUpmix() 4957 { 4958 if (audioOutput) 4959 return audioOutput->ToggleUpmix(); 4960 return false; 4961 } 4962 4946 4963 void NuppelVideoPlayer::Zoom(ZoomDirection direction) 4947 4964 { 4948 4965 if (videoOutput) -
mythtv/libs/libmythtv/NuppelVideoPlayer.h
diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/NuppelVideoPlayer.h c/mythtv/libs/libmythtv/NuppelVideoPlayer.h
a c 175 175 // Toggle Sets 176 176 void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle); 177 177 void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle); 178 bool ToggleUpmix(void); 178 179 179 180 // Gets 180 181 QSize GetVideoBufferSize(void) const { return video_dim; } -
mythtv/libs/libmythtv/avformatdecoder.cpp
diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/avformatdecoder.cpp c/mythtv/libs/libmythtv/avformatdecoder.cpp
a c 427 427 audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]), 428 428 allow_ac3_passthru(false), allow_dts_passthru(false), 429 429 disable_passthru(false), max_channels(2), 430 dummy_frame(NULL),430 last_ac3_channels(0), dummy_frame(NULL), 431 431 // DVD 432 432 lastdvdtitle(-1), 433 433 decodeStillFrame(false), … … 445 445 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 446 446 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 447 447 max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2); 448 isAC3upmix = gContext->GetNumSetting("MythAC3Upmix", 0); 448 449 449 450 audioIn.sample_size = -32; // force SetupAudioStream to run once 450 451 itv = GetNVP()->GetInteractiveTV(); … … 2946 2947 { 2947 2948 int idx = atracks[i].av_stream_index; 2948 2949 AVCodecContext *codec_ctx = ic->streams[idx]->codec; 2949 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&2950 !disable_passthru &&2951 (codec_ctx->codec_id == CODEC_ID_AC3));2952 bool do_dts_passthru = (allow_dts_passthru && !transcoding &&2953 !disable_passthru &&2954 (codec_ctx->codec_id == CODEC_ID_DTS));2955 2950 AudioInfo item(codec_ctx->codec_id, 2956 2951 codec_ctx->sample_rate, codec_ctx->channels, 2957 do_ac3_passthru || do_dts_passthru);2952 DoPassThrough(codec_ctx)); 2958 2953 VERBOSE(VB_AUDIO, LOC + " * " + item.toString()); 2959 2954 } 2960 2955 #endif … … 3088 3083 bool AvFormatDecoder::GetFrame(int onlyvideo) 3089 3084 { 3090 3085 AVPacket *pkt = NULL; 3086 AC3HeaderInfo hdr; 3091 3087 int len; 3092 3088 unsigned char *ptr; 3093 3089 int data_size = 0; … … 3274 3270 pts = 0; 3275 3271 3276 3272 AVStream *curstream = ic->streams[pkt->stream_index]; 3273 AVCodecContext *ctx = curstream->codec; 3277 3274 3278 3275 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3279 3276 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 3280 3277 3281 3278 if (ringBuffer->isDVD() && 3282 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3279 ctx->codec_type == CODEC_TYPE_VIDEO) 3283 3280 { 3284 3281 MpegPreProcessPkt(curstream, pkt); 3285 3282 … … 3307 3304 3308 3305 if (!d->HasMPEG2Dec()) 3309 3306 { 3310 int current_width = c urstream->codec->width;3307 int current_width = ctx->width; 3311 3308 int video_width = GetNVP()->GetVideoSize().width(); 3312 3309 if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput()) 3313 3310 { … … 3348 3345 } 3349 3346 3350 3347 if (storevideoframes && 3351 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3348 ctx->codec_type == CODEC_TYPE_VIDEO) 3352 3349 { 3353 3350 av_dup_packet(pkt); 3354 3351 storedPackets.append(pkt); … … 3356 3353 continue; 3357 3354 } 3358 3355 3359 if (len > 0 && c urstream->codec->codec_type == CODEC_TYPE_VIDEO &&3356 if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO && 3360 3357 pkt->stream_index == selectedVideoIndex) 3361 3358 { 3362 AVCodecContext *context = curstream->codec;3363 3359 3364 if (c ontext->codec_id == CODEC_ID_MPEG1VIDEO ||3365 c ontext->codec_id == CODEC_ID_MPEG2VIDEO ||3366 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||3367 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||3368 c ontext->codec_id == CODEC_ID_MPEGVIDEO_VDPAU)3360 if (ctx->codec_id == CODEC_ID_MPEG1VIDEO || 3361 ctx->codec_id == CODEC_ID_MPEG2VIDEO || 3362 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC || 3363 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD || 3364 ctx->codec_id == CODEC_ID_MPEGVIDEO_VDPAU) 3369 3365 { 3370 3366 if (!ringBuffer->isDVD()) 3371 3367 MpegPreProcessPkt(curstream, pkt); 3372 3368 } 3373 else if (c ontext->codec_id == CODEC_ID_H264 ||3374 c ontext->codec_id == CODEC_ID_H264_VDPAU)3369 else if (ctx->codec_id == CODEC_ID_H264 || 3370 ctx->codec_id == CODEC_ID_H264_VDPAU) 3375 3371 { 3376 3372 H264PreProcessPkt(curstream, pkt); 3377 3373 } … … 3417 3413 } 3418 3414 3419 3415 if (len > 0 && 3420 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3421 c urstream->codec->codec_id == CODEC_ID_MPEG2VBI)3416 ctx->codec_type == CODEC_TYPE_DATA && 3417 ctx->codec_id == CODEC_ID_MPEG2VBI) 3422 3418 { 3423 3419 ProcessVBIDataPacket(curstream, pkt); 3424 3420 … … 3427 3423 } 3428 3424 3429 3425 if (len > 0 && 3430 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3431 c urstream->codec->codec_id == CODEC_ID_DVB_VBI)3426 ctx->codec_type == CODEC_TYPE_DATA && 3427 ctx->codec_id == CODEC_ID_DVB_VBI) 3432 3428 { 3433 3429 ProcessDVBDataPacket(curstream, pkt); 3434 3430 … … 3437 3433 } 3438 3434 3439 3435 if (len > 0 && 3440 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3441 c urstream->codec->codec_id == CODEC_ID_DSMCC_B)3436 ctx->codec_type == CODEC_TYPE_DATA && 3437 ctx->codec_id == CODEC_ID_DSMCC_B) 3442 3438 { 3443 3439 ProcessDSMCCPacket(curstream, pkt); 3444 3440 … … 3458 3454 } 3459 3455 3460 3456 // we don't care about other data streams 3461 if (c urstream->codec->codec_type == CODEC_TYPE_DATA)3457 if (ctx->codec_type == CODEC_TYPE_DATA) 3462 3458 { 3463 3459 av_free_packet(pkt); 3464 3460 continue; 3465 3461 } 3466 3462 3467 if (!c urstream->codec->codec)3463 if (!ctx->codec) 3468 3464 { 3469 3465 VERBOSE(VB_PLAYBACK, LOC + 3470 3466 QString("No codec for stream index %1, type(%2) id(%3:%4)") 3471 3467 .arg(pkt->stream_index) 3472 .arg(codec_type_string(c urstream->codec->codec_type))3473 .arg(codec_id_string(c urstream->codec->codec_id))3474 .arg(c urstream->codec->codec_id));3468 .arg(codec_type_string(ctx->codec_type)) 3469 .arg(codec_id_string(ctx->codec_id)) 3470 .arg(ctx->codec_id)); 3475 3471 av_free_packet(pkt); 3476 3472 continue; 3477 3473 } … … 3480 3476 have_err = false; 3481 3477 3482 3478 avcodeclock.lock(); 3483 int ctype = c urstream->codec->codec_type;3479 int ctype = ctx->codec_type; 3484 3480 int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; 3485 3481 int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; 3486 3482 int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; … … 3505 3501 3506 3502 // detect switches between stereo and dual languages 3507 3503 bool wasDual = audSubIdx != -1; 3508 bool isDual = c urstream->codec->avcodec_dual_language;3504 bool isDual = ctx->avcodec_dual_language; 3509 3505 if ((wasDual && !isDual) || (!wasDual && isDual)) 3510 3506 { 3511 3507 SetupAudioStreamSubIndexes(audIdx); 3512 3508 reselectAudioTrack = true; 3513 3509 } 3514 3510 3515 bool do_ac3_passthru =3516 (allow_ac3_passthru && !transcoding &&3517 (curstream->codec->codec_id == CODEC_ID_AC3));3518 bool do_dts_passthru =3519 (allow_dts_passthru && !transcoding &&3520 (curstream->codec->codec_id == CODEC_ID_DTS));3521 bool using_passthru = do_ac3_passthru || do_dts_passthru;3522 3523 3511 // detect channels on streams that need 3524 3512 // to be decoded before we can know this 3525 3513 bool already_decoded = false; 3526 if (!c urstream->codec->channels)3514 if (!ctx->channels) 3527 3515 { 3528 3516 QMutexLocker locker(&avcodeclock); 3529 3517 VERBOSE(VB_IMPORTANT, LOC + 3530 3518 QString("Setting channels to %1") 3531 3519 .arg(audioOut.channels)); 3532 3520 3533 if ( using_passthru)3521 if (DoPassThrough(ctx)) 3534 3522 { 3535 3523 // for passthru let it select the max number 3536 3524 // of channels 3537 c urstream->codec->channels = 0;3538 c urstream->codec->request_channels = 0;3525 ctx->channels = 0; 3526 ctx->request_channels = 0; 3539 3527 } 3540 3528 else 3541 3529 { 3542 c urstream->codec->channels = audioOut.channels;3543 c urstream->codec->request_channels =3530 ctx->channels = audioOut.channels; 3531 ctx->request_channels = 3544 3532 audioOut.channels; 3545 3533 } 3546 3534 ret = avcodec_decode_audio( 3547 c urstream->codec, audioSamples,3535 ctx, audioSamples, 3548 3536 &data_size, ptr, len); 3549 3537 already_decoded = true; 3550 3538 3551 reselectAudioTrack |= curstream->codec->channels; 3539 reselectAudioTrack |= ctx->channels; 3540 } 3541 3542 if (isAC3upmix && ctx->codec_id == CODEC_ID_AC3 && 3543 !ff_ac3_parse_header(ptr, &hdr)) 3544 { 3545 if (hdr.channels != last_ac3_channels) 3546 { 3547 last_ac3_channels = ctx->channels = hdr.channels; 3548 SetupAudioStream(); 3549 } 3552 3550 } 3553 3551 3554 3552 if (reselectAudioTrack) … … 3564 3562 .av_stream_index; 3565 3563 audSubIdx = selectedTrack[kTrackTypeAudio] 3566 3564 .av_substream_index; 3565 ctx = curstream->codec; 3567 3566 } 3568 3567 3569 3568 if ((onlyvideo > 0) || (pkt->stream_index != audIdx)) … … 3595 3594 if (audioOut.do_passthru) 3596 3595 { 3597 3596 data_size = pkt->size; 3598 bool dts = CODEC_ID_DTS == c urstream->codec->codec_id;3597 bool dts = CODEC_ID_DTS == ctx->codec_id; 3599 3598 ret = encode_frame(dts, ptr, len, 3600 3599 audioSamples, data_size); 3601 3600 } 3602 3601 else 3603 3602 { 3604 AVCodecContext *ctx = curstream->codec;3605 3606 3603 if ((ctx->channels == 0) || 3607 3604 (ctx->channels > audioOut.channels)) 3608 3605 { … … 3611 3608 3612 3609 if (!already_decoded) 3613 3610 { 3614 curstream->codec->request_channels = 3615 audioOut.channels; 3611 ctx->request_channels = audioOut.channels; 3616 3612 ret = avcodec_decode_audio( 3617 3613 ctx, audioSamples, &data_size, ptr, len); 3618 3614 } … … 3629 3625 audIdx = -1; 3630 3626 AutoSelectAudioTrack(); 3631 3627 data_size = 0; 3628 ctx = curstream->codec; 3632 3629 } 3633 3630 } 3634 3631 avcodeclock.unlock(); … … 3646 3643 3647 3644 // calc for next frame 3648 3645 lastapts += (long long)((double)(data_size * 1000) / 3649 (curstream->codec->channels * 2) / 3650 curstream->codec->sample_rate); 3646 (ctx->channels * 2) / ctx->sample_rate); 3651 3647 3652 3648 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, 3653 3649 LOC + QString("audio timecode %1 %2 %3 %4") … … 3707 3703 continue; 3708 3704 } 3709 3705 3710 AVCodecContext *context = curstream->codec;3711 3706 AVFrame mpa_pic; 3712 3707 bzero(&mpa_pic, sizeof(AVFrame)); 3713 3708 … … 3722 3717 // HACK 3723 3718 while (!gotpicture && count < 5) 3724 3719 { 3725 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3720 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3726 3721 &gotpicture, ptr, len); 3727 3722 count++; 3728 3723 } 3729 3724 } 3730 3725 else 3731 3726 { 3732 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3727 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3733 3728 &gotpicture, ptr, len); 3734 3729 } 3735 3730 } 3736 3731 else 3737 3732 { 3738 ret = avcodec_decode_video(c ontext, &mpa_pic,3733 ret = avcodec_decode_video(ctx, &mpa_pic, 3739 3734 &gotpicture, ptr, len); 3740 3735 // Reparse it to not drop the DVD still frame 3741 3736 if (decodeStillFrame) 3742 ret = avcodec_decode_video(c ontext, &mpa_pic,3737 ret = avcodec_decode_video(ctx, &mpa_pic, 3743 3738 &gotpicture, ptr, len); 3744 3739 } 3745 3740 avcodeclock.unlock(); … … 3806 3801 3807 3802 img_convert(&tmppicture, PIX_FMT_YUV420P, 3808 3803 (AVPicture *)&mpa_pic, 3809 c ontext->pix_fmt,3810 c ontext->width,3811 c ontext->height);3804 ctx->pix_fmt, 3805 ctx->width, 3806 ctx->height); 3812 3807 3813 3808 if (xf) 3814 3809 { … … 3831 3826 (temppts + 10000 > lastvpts || temppts < 0)) 3832 3827 { 3833 3828 temppts = lastvpts; 3834 temppts += (long long)(1000 * av_q2d(c ontext->time_base));3829 temppts += (long long)(1000 * av_q2d(ctx->time_base)); 3835 3830 // MPEG2 frames can be repeated, update pts accordingly 3836 3831 temppts += (long long)(mpa_pic.repeat_pict * 500 3837 * av_q2d(c urstream->codec->time_base));3832 * av_q2d(ctx->time_base)); 3838 3833 } 3839 3834 3840 3835 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + … … 3870 3865 picframe->frameNumber = framesPlayed; 3871 3866 GetNVP()->ReleaseNextVideoFrame(picframe, temppts); 3872 3867 if (d->HasMPEG2Dec() && mpa_pic.data[3]) 3873 c ontext->release_buffer(context, &mpa_pic);3868 ctx->release_buffer(ctx, &mpa_pic); 3874 3869 3875 3870 decoded_video_frame = picframe; 3876 3871 gotvideo = 1; … … 3929 3924 } 3930 3925 default: 3931 3926 { 3932 AVCodecContext *enc = curstream->codec;3933 3927 VERBOSE(VB_IMPORTANT, LOC_ERR + 3934 3928 QString("Decoding - id(%1) type(%2)") 3935 .arg(codec_id_string( enc->codec_id))3936 .arg(codec_type_string( enc->codec_type)));3929 .arg(codec_id_string(ctx->codec_id)) 3930 .arg(codec_type_string(ctx->codec_type))); 3937 3931 have_err = true; 3938 3932 break; 3939 3933 } … … 4082 4076 } 4083 4077 } 4084 4078 4079 bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx) 4080 { 4081 bool do_ac3_passthru = 4082 (allow_ac3_passthru && !transcoding && 4083 (ctx->codec_id == CODEC_ID_AC3)); 4084 bool do_dts_passthru = 4085 (allow_dts_passthru && !transcoding && 4086 (ctx->codec_id == CODEC_ID_DTS)); 4087 bool using_passthru = do_ac3_passthru || do_dts_passthru; 4088 4089 if (!isAC3upmix) 4090 return using_passthru; 4091 4092 bool passthru = false; 4093 4094 if (ctx->codec_id == CODEC_ID_AC3) 4095 passthru = allow_ac3_passthru && 4096 ctx->channels >= (int)max_channels; 4097 else if (ctx->codec_id == CODEC_ID_DTS) 4098 passthru = allow_dts_passthru; 4099 4100 passthru &= !transcoding && !disable_passthru; 4101 // Don't know any cards that support spdif clocked at < 44100 4102 // Some US cable transmissions have 2ch 32k AC-3 streams 4103 passthru &= ctx->sample_rate >= 44100; 4104 4105 return passthru; 4106 } 4107 4085 4108 /** \fn AvFormatDecoder::SetupAudioStream(void) 4086 4109 * \brief Reinitializes audio if it needs to be reinitialized. 4087 4110 * … … 4107 4130 assert(curstream); 4108 4131 assert(curstream->codec); 4109 4132 codec_ctx = curstream->codec; 4110 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 4111 (codec_ctx->codec_id == CODEC_ID_AC3)); 4112 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 4113 (codec_ctx->codec_id == CODEC_ID_DTS)); 4114 using_passthru = do_ac3_passthru || do_dts_passthru; 4115 info = AudioInfo(codec_ctx->codec_id, 4116 codec_ctx->sample_rate, codec_ctx->channels, 4117 using_passthru && !disable_passthru); 4133 using_passthru = DoPassThrough(codec_ctx); 4134 if (!isAC3upmix) 4135 info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, codec_ctx->channels, using_passthru && !disable_passthru); 4136 else 4137 info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, 4138 codec_ctx->channels, using_passthru); 4118 4139 } 4119 4140 4120 4141 if (info == audioIn) … … 4125 4146 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4126 4147 4127 4148 audioOut = audioIn = info; 4149 if (!isAC3upmix) { 4128 4150 if (using_passthru) 4129 4151 { 4130 4152 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card … … 4181 4203 4182 4204 // allow the audio stuff to reencode 4183 4205 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 4206 } else { 4207 4208 if (!using_passthru && audioOut.channels > (int)max_channels) 4209 { 4210 audioOut.channels = (int)max_channels; 4211 audioOut.sample_size = audioOut.channels * 2; 4212 codec_ctx->channels = audioOut.channels; 4213 } 4214 4215 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4216 QString("\n\t\t\tfrom %1 to %2") 4217 .arg(old_in.toString()).arg(audioOut.toString())); 4218 4219 if (audioOut.sample_rate > 0) 4220 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4221 4222 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 4223 audioOut.sample_rate, 4224 audioOut.do_passthru); 4225 4226 } 4184 4227 QString errMsg = GetNVP()->ReinitAudio(); 4185 4228 bool audiook = errMsg.isEmpty(); 4186 4229 -
mythtv/libs/libmythtv/avformatdecoder.h
diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/avformatdecoder.h c/mythtv/libs/libmythtv/avformatdecoder.h
a c 185 185 void InitVideoCodec(AVStream *stream, AVCodecContext *enc, 186 186 bool selectedStream = false); 187 187 188 /// Preprocess a packet, setting the video parms if ne ssesary.188 /// Preprocess a packet, setting the video parms if necessary. 189 189 void MpegPreProcessPkt(AVStream *stream, AVPacket *pkt); 190 190 void H264PreProcessPkt(AVStream *stream, AVPacket *pkt); 191 191 … … 198 198 199 199 void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames); 200 200 201 bool DoPassThrough(const AVCodecContext *ctx); 201 202 bool SetupAudioStream(void); 202 203 void SetupAudioStreamSubIndexes(int streamIndex); 203 204 void RemoveAudioStreams(); … … 266 267 bool allow_dts_passthru; 267 268 bool disable_passthru; 268 269 uint max_channels; 270 uint last_ac3_channels; 271 bool isAC3upmix; 269 272 270 273 VideoFrame *dummy_frame; 271 274 -
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 … … 2712 2713 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2713 2714 action == "STRETCHINC" || action == "STRETCHDEC" || 2714 2715 action == "MUTE" || action == "TOGGLEASPECT" || 2715 action == "TOGGLEFILL" )2716 action == "TOGGLEFILL" || action == "TOGGLEUPMIX") 2716 2717 { 2717 2718 passThru = 1; 2718 2719 handled = false; … … 2767 2768 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2768 2769 action == "STRETCHINC" || action == "STRETCHDEC" || 2769 2770 action == "MUTE" || action == "PAUSE" || 2770 action == "CLEAROSD" )2771 action == "CLEAROSD" || action == "TOGGLEUPMIX") 2771 2772 { 2772 2773 passThru = 1; 2773 2774 handled = false; … … 3072 3073 ChangeTimeStretch(0); // just display 3073 3074 else if (action == "TOGGLESTRETCH") 3074 3075 ToggleTimeStretch(); 3076 else if (action == "TOGGLEUPMIX") 3077 ToggleUpmix(); 3075 3078 else if (action == "CYCLECOMMSKIPMODE") { 3076 3079 SetAutoCommercialSkip((enum commSkipMode) 3077 3080 ((autoCommercialSkip + 1) % CommSkipModes)); … … 6056 6059 } 6057 6060 } 6058 6061 6062 void TV::ToggleUpmix() 6063 { 6064 AudioOutput *aud = nvp->getAudioOutput(); 6065 if (!aud) 6066 return; 6067 QString text; 6068 if(!aud->isAC3upmix) { 6069 text = tr("Upmixer disabled !"); 6070 } else { 6071 if (aud->ToggleUpmix()) 6072 text = tr("Upmixer On"); 6073 else 6074 text = tr("Upmixer Off"); 6075 } 6076 6077 if (GetOSD() && !browsemode) 6078 GetOSD()->SetSettingsText(text, 5); 6079 } 6080 6081 6059 6082 // dir in 10ms jumps 6060 6083 void TV::ChangeAudioSync(int dir, bool allowEdit) 6061 6084 { … … 7304 7327 7305 7328 ChangeTimeStretch(0, !floatRead); // just display 7306 7329 } 7330 else if (action == "TOGGLEUPMIX") 7331 ToggleUpmix(); 7307 7332 else if (action.left(11) == "SELECTSCAN_") 7308 7333 activenvp->SetScanType((FrameScanType) action.right(1).toInt()); 7309 7334 else if (action.left(15) == "TOGGLEAUDIOSYNC") … … 7552 7577 (speedX100 == 150) ? 1 : 0, NULL, 7553 7578 "STRETCHGROUP"); 7554 7579 7580 if(nvp && nvp->getAudioOutput()->isAC3upmix) 7581 item = new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX"); 7582 7555 7583 // add scan mode override settings to menu 7556 7584 FrameScanType scan_type = kScan_Ignore; 7557 7585 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; }