Ticket #1104: mythtv_ac3.30.patch
File mythtv_ac3.30.patch, 60.0 KB (added by , 18 years ago) |
---|
-
libs/libmyth/libmyth.pro
39 39 SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp 40 40 41 41 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ 42 INCLUDEPATH += ../libavutil 42 43 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui 43 44 DEPENDPATH += ../libmythupnp 45 DEPENDPATH += ../libavutil ../libavcodec 44 46 45 47 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION} 46 48 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION} 49 LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION} 47 50 48 51 isEmpty(QMAKE_EXTENSION_SHLIB) { 49 52 QMAKE_EXTENSION_SHLIB=so … … 192 195 use_hidesyms { 193 196 QMAKE_CXXFLAGS += -fvisibility=hidden 194 197 } 198 199 contains( CONFIG_LIBA52, yes ) { 200 LIBS += -la52 201 } -
libs/libmyth/audiooutput.h
31 31 virtual ~AudioOutput() { }; 32 32 33 33 // reconfigure sound out for new params 34 virtual void Reconfigure(int audio_bits, int audio_channels, 35 int audio_samplerate, bool audio_passthru) = 0; 34 virtual void Reconfigure(int audio_bits, 35 int audio_channels, 36 int audio_samplerate, 37 bool audio_passthru, 38 void* audio_codec = NULL 39 ) = 0; 36 40 37 41 virtual void SetStretchFactor(float factor); 38 42 … … 74 78 lastError = msg; 75 79 VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError); 76 80 } 81 void ClearError() 82 { lastError = QString::null; }; 77 83 78 84 void Warn(QString msg) 79 85 { -
libs/libmyth/audiooutputdx.h
35 35 /// END HACK HACK HACK HACK 36 36 37 37 virtual void Reset(void); 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, int audio_passthru); 38 virtual void Reconfigure(int audio_bits, 39 int audio_channels, 40 int audio_samplerate, 41 bool audio_passthru, 42 AudioCodecMode aom = AUDIOCODECMODE_NORMAL); 40 43 virtual void SetBlocking(bool blocking); 41 44 42 45 virtual bool AddSamples(char *buffer, int samples, long long timecode); -
libs/libmyth/audiooutputdx.cpp
130 130 // FIXME: kedl: not sure what else could be required here? 131 131 } 132 132 133 void AudioOutputDX::Reconfigure(int audio_bits, int audio_channels, 134 int audio_samplerate, int audio_passthru) 133 void AudioOutputDX::Reconfigure(int audio_bits, 134 int audio_channels, 135 int audio_samplerate, 136 int audio_passthru, 137 AudioCodecMode laom 138 ) 135 139 { 136 140 if (dsbuffer) 137 141 DestroyDSBuffer(); -
libs/libmyth/audiooutputbase.h
18 18 #include "samplerate.h" 19 19 #include "SoundTouch.h" 20 20 21 #define AUDBUFSIZE 768000 21 struct AVCodecContext; 22 class DigitalEncoder; 22 23 #define AUDIO_SRC_IN_SIZE 16384 23 24 #define AUDIO_SRC_OUT_SIZE (16384*6) 24 25 #define AUDIO_TMP_BUF_SIZE (16384*6) 25 26 27 //#define AUDBUFSIZE 768000 28 //divisible by 12,10,8,6,4,2 and around 1024000 29 //#define AUDBUFSIZE 1024080 30 #define AUDBUFSIZE 1536000 31 26 32 class AudioOutputBase : public AudioOutput 27 33 { 28 34 public: … … 35 41 virtual ~AudioOutputBase(); 36 42 37 43 // reconfigure sound out for new params 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, bool audio_passthru); 44 virtual void Reconfigure(int audio_bits, 45 int audio_channels, 46 int audio_samplerate, 47 bool audio_passthru, 48 void* audio_codec = NULL); 40 49 41 50 // do AddSamples calls block? 42 51 virtual void SetBlocking(bool blocking); … … 125 134 bool audio_passthru; 126 135 127 136 float audio_stretchfactor; 137 AVCodecContext *audio_codec; 128 138 AudioOutputSource source; 129 139 130 140 bool killaudio; … … 133 143 bool set_initial_vol; 134 144 bool buffer_output_data_for_use; // used by AudioOutputNULL 135 145 146 int configured_audio_channels; 147 136 148 private: 137 149 // resampler 138 150 bool need_resampler; … … 144 156 145 157 // timestretch 146 158 soundtouch::SoundTouch * pSoundStretch; 159 DigitalEncoder * encoder; 147 160 148 161 bool blocking; // do AddSamples calls block? 149 162 … … 160 173 161 174 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 162 175 'audiotime' and 'audiotime_updated' */ 163 intaudiotime; // timecode of audio leaving the soundcard (same units as176 long long audiotime; // timecode of audio leaving the soundcard (same units as 164 177 // timecodes) ... 165 178 struct timeval audiotime_updated; // ... which was last updated at this time 166 179 167 180 /* Audio circular buffer */ 168 181 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 169 182 int raud, waud; /* read and write positions */ 170 intaudbuf_timecode; /* timecode of audio most recently placed into183 long long audbuf_timecode; /* timecode of audio most recently placed into 171 184 buffer */ 172 185 173 186 int numlowbuffer; -
libs/libmyth/audiooutputbase.cpp
14 14 #include <qdeepcopy.h> 15 15 16 16 // MythTV headers 17 #include "config.h" 17 18 #include "audiooutputbase.h" 18 19 20 extern "C" { 21 #include "libavcodec/avcodec.h" 22 #ifdef ENABLE_AC3_DECODER 23 #include "libavcodec/parser.h" 24 #else 25 //#include "libavcodec/liba52/a52.h" 26 #include <a52dec/a52.h> 27 #endif 28 } 29 30 #if QT_VERSION < 0x030200 31 #define LONGLONGCONVERT (long) 32 #else 33 #define LONGLONGCONVERT 34 #endif 35 36 #define LOC QString("DEnc: "); 37 #define MAX_AC3_FRAME_SIZE 6144 38 class DigitalEncoder 39 { 40 public: 41 DigitalEncoder(); 42 ~DigitalEncoder(); 43 void Dispose(); 44 bool Init(CodecID codec_id, int bitrate, int samplerate, int channels); 45 size_t Encode(short * buff); 46 47 // if needed 48 char * GetFrameBuffer() 49 { 50 if (!frame_buffer && av_context) 51 { 52 frame_buffer = new char [one_frame_bytes]; 53 } 54 return frame_buffer; 55 } 56 size_t FrameSize() const { return one_frame_bytes; } 57 char * GetOutBuff() const { return outbuf; } 58 59 size_t audio_bytes_per_sample; 60 private: 61 AVCodecContext *av_context; 62 char * outbuf; 63 char * frame_buffer; 64 int outbuf_size; 65 size_t one_frame_bytes; 66 }; 67 68 DigitalEncoder::DigitalEncoder() 69 { 70 av_context = NULL; 71 outbuf = NULL; 72 outbuf_size = 0; 73 one_frame_bytes = 0; 74 frame_buffer = NULL; 75 } 76 77 DigitalEncoder::~DigitalEncoder() 78 { 79 Dispose(); 80 } 81 82 void DigitalEncoder::Dispose() 83 { 84 if (av_context) 85 { 86 avcodec_close(av_context); 87 av_free(av_context); 88 av_context = NULL; 89 } 90 if (outbuf) 91 { 92 delete [] outbuf; 93 outbuf = NULL; 94 outbuf_size = 0; 95 } 96 if (frame_buffer) 97 { 98 delete [] frame_buffer; 99 frame_buffer = NULL; 100 one_frame_bytes = 0; 101 } 102 } 103 104 //CODEC_ID_AC3 105 bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels) 106 { 107 AVCodec * codec; 108 int ret; 109 110 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4") 111 .arg(codec_id_string(codec_id)) 112 .arg(bitrate) 113 .arg(samplerate) 114 .arg(channels)); 115 //codec = avcodec_find_encoder(codec_id); 116 // always AC3 as there is no DTS encoder at the moment 2005/1/9 117 codec = avcodec_find_encoder(CODEC_ID_AC3); 118 if (!codec) 119 { 120 VERBOSE(VB_IMPORTANT,"Error: could not find codec"); 121 return false; 122 } 123 av_context = avcodec_alloc_context(); 124 av_context->bit_rate = bitrate; 125 av_context->sample_rate = samplerate; 126 av_context->channels = channels; 127 // open it */ 128 if ((ret = avcodec_open(av_context, codec)) < 0) 129 { 130 VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate"); 131 Dispose(); 132 return false; 133 } 134 135 size_t bytes_per_frame = av_context->channels * sizeof(short); 136 audio_bytes_per_sample = bytes_per_frame; 137 one_frame_bytes = bytes_per_frame * av_context->frame_size; 138 139 outbuf_size = 16384; // ok for AC3 but DTS? 140 outbuf = new char [outbuf_size]; 141 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 142 .arg(av_context->frame_size) 143 .arg(bytes_per_frame) 144 .arg(one_frame_bytes) 145 ); 146 147 return true; 148 } 149 150 static int DTS_SAMPLEFREQS[16] = 151 { 152 0, 8000, 16000, 32000, 64000, 128000, 11025, 22050, 153 44100, 88200, 176400, 12000, 24000, 48000, 96000, 192000 154 }; 155 156 static int DTS_BITRATES[30] = 157 { 158 32000, 56000, 64000, 96000, 112000, 128000, 159 192000, 224000, 256000, 320000, 384000, 448000, 160 512000, 576000, 640000, 768000, 896000, 1024000, 161 1152000, 1280000, 1344000, 1408000, 1411200, 1472000, 162 1536000, 1920000, 2048000, 3072000, 3840000, 4096000 163 }; 164 165 static int dts_decode_header(uint8_t *indata_ptr, int *rate, 166 int *nblks, int *sfreq) 167 { 168 uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) | 169 (indata_ptr[2] << 8) | (indata_ptr[3])); 170 171 if (id != 0x7ffe8001) 172 return -1; 173 174 int ftype = indata_ptr[4] >> 7; 175 176 int surp = (indata_ptr[4] >> 2) & 0x1f; 177 surp = (surp + 1) % 32; 178 179 *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2); 180 ++*nblks; 181 182 int fsize = (indata_ptr[5] & 0x03) << 12 | 183 (indata_ptr[6] << 4) | (indata_ptr[7] >> 4); 184 ++fsize; 185 186 *sfreq = (indata_ptr[8] >> 2) & 0x0f; 187 *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07); 188 189 if (ftype != 1) 190 { 191 VERBOSE(VB_IMPORTANT, LOC + 192 QString("DTS: Termination frames not handled (ftype %1)") 193 .arg(ftype)); 194 return -1; 195 } 196 197 if (*sfreq != 13) 198 { 199 VERBOSE(VB_IMPORTANT, LOC + 200 QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq)); 201 return -1; 202 } 203 204 if ((fsize > 8192) || (fsize < 96)) 205 { 206 VERBOSE(VB_IMPORTANT, LOC + 207 QString("DTS: fsize: %1 invalid").arg(fsize)); 208 return -1; 209 } 210 211 if (*nblks != 8 && *nblks != 16 && *nblks != 32 && 212 *nblks != 64 && *nblks != 128 && ftype == 1) 213 { 214 VERBOSE(VB_IMPORTANT, LOC + 215 QString("DTS: nblks %1 not valid for normal frame") 216 .arg(*nblks)); 217 return -1; 218 } 219 220 return fsize; 221 } 222 223 static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/, 224 int *sample_rate, int *bit_rate) 225 { 226 int nblks; 227 int rate; 228 int sfreq; 229 230 int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq); 231 if (fsize >= 0) 232 { 233 if (rate >= 0 && rate <= 29) 234 *bit_rate = DTS_BITRATES[rate]; 235 else 236 *bit_rate = 0; 237 if (sfreq >= 1 && sfreq <= 15) 238 *sample_rate = DTS_SAMPLEFREQS[sfreq]; 239 else 240 *sample_rate = 0; 241 } 242 return fsize; 243 } 244 245 // until there is an easy way to do this with ffmpeg 246 // get the code from libavcodec/parser.c made non static 247 extern "C" int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, 248 int *bit_rate, int *samples); 249 250 static int encode_frame( 251 bool dts, 252 unsigned char *data, 253 size_t &len) 254 { 255 size_t enc_len; 256 int flags, sample_rate, bit_rate; 257 258 // we don't do any length/crc validation of the AC3 frame here; presumably 259 // the receiver will have enough sense to do that. if someone has a 260 // receiver that doesn't, here would be a good place to put in a call 261 // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the 262 // packet is bad? we'd need to send something that the receiver would 263 // ignore, and if so, may as well just assume that it will ignore 264 // anything with a bad CRC... 265 266 uint nr_samples = 0, block_len; 267 if (dts) 268 { 269 enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate); 270 int rate, sfreq, nblks; 271 dts_decode_header(data+8, &rate, &nblks, &sfreq); 272 nr_samples = nblks * 32; 273 block_len = nr_samples * 2 * 2; 274 } 275 else 276 { 277 #ifdef ENABLE_AC3_DECODER 278 enc_len = ac3_sync(data+8, &flags, &sample_rate, &bit_rate, (int*)&block_len); 279 #else 280 enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate); 281 block_len = MAX_AC3_FRAME_SIZE; 282 #endif 283 } 284 285 if (enc_len == 0 || enc_len > len) 286 { 287 int l = len; 288 len = 0; 289 return l; 290 } 291 292 enc_len = min((uint)enc_len, block_len - 8); 293 294 //uint32_t x = *(uint32_t*)(data+8); 295 // in place swab 296 swab(data+8, data+8, enc_len); 297 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, 298 // QString("DigitalEncoder::Encode swab test %1 %2") 299 // .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16)); 300 301 // the following values come from libmpcodecs/ad_hwac3.c in mplayer. 302 // they form a valid IEC958 AC3 header. 303 data[0] = 0x72; 304 data[1] = 0xF8; 305 data[2] = 0x1F; 306 data[3] = 0x4E; 307 data[4] = 0x01; 308 if (dts) 309 { 310 switch(nr_samples) 311 { 312 case 512: 313 data[4] = 0x0B; /* DTS-1 (512-sample bursts) */ 314 break; 315 316 case 1024: 317 data[4] = 0x0C; /* DTS-2 (1024-sample bursts) */ 318 break; 319 320 case 2048: 321 data[4] = 0x0D; /* DTS-3 (2048-sample bursts) */ 322 break; 323 324 default: 325 VERBOSE(VB_IMPORTANT, LOC + 326 QString("DTS: %1-sample bursts not supported") 327 .arg(nr_samples)); 328 data[4] = 0x00; 329 break; 330 } 331 } 332 data[5] = 0x00; 333 data[6] = (enc_len << 3) & 0xFF; 334 data[7] = (enc_len >> 5) & 0xFF; 335 memset(data + 8 + enc_len, 0, block_len - 8 - enc_len); 336 len = block_len; 337 338 return enc_len; 339 } 340 341 // must have exactly 1 frames worth of data 342 size_t DigitalEncoder::Encode(short * buff) 343 { 344 int encsize = 0; 345 size_t outsize = 0; 346 347 // put data in the correct spot for encode frame 348 outsize = avcodec_encode_audio( 349 av_context, 350 ((uchar*)outbuf)+8, 351 outbuf_size-8, 352 buff); 353 size_t tmpsize = outsize; 354 355 outsize = MAX_AC3_FRAME_SIZE; 356 encsize = encode_frame( 357 //av_context->codec_id==CODEC_ID_DTS, 358 false, 359 (unsigned char*)outbuf, outsize); 360 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 361 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 362 .arg(tmpsize) 363 .arg(encsize) 364 .arg(outsize) 365 ); 366 367 return outsize; 368 } 369 #undef LOC 19 370 #define LOC QString("AO: ") 20 371 #define LOC_ERR QString("AO, ERROR: ") 21 372 … … 24 375 int /*laudio_bits*/, int /*laudio_channels*/, 25 376 int /*laudio_samplerate*/, AudioOutputSource lsource, 26 377 bool lset_initial_vol, bool /*laudio_passthru*/) : 27 28 378 effdsp(0), effdspstretched(0), 29 379 audio_channels(-1), audio_bytes_per_sample(0), 30 380 audio_bits(-1), audio_samplerate(-1), … … 35 385 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 36 386 audio_passthru(false), audio_stretchfactor(1.0f), 37 387 388 audio_codec(NULL), 38 389 source(lsource), killaudio(false), 39 390 40 391 pauseaudio(false), audio_actually_paused(false), … … 46 397 47 398 src_ctx(NULL), 48 399 49 pSoundStretch(NULL), blocking(false), 400 pSoundStretch(NULL), 401 encoder(NULL), 402 blocking(false), 50 403 51 404 lastaudiolen(0), samples_buffered(0), 52 405 audiotime(0), … … 61 414 pthread_cond_init(&audio_bufsig, NULL); 62 415 63 416 output_audio = 0; // TODO FIXME Not POSIX compatible! 417 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 64 418 65 419 bzero(&src_data, sizeof(SRC_DATA)); 66 420 bzero(src_in, sizeof(float) * AUDIO_SRC_IN_SIZE); … … 108 462 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 109 463 .arg(audio_stretchfactor)); 110 464 pSoundStretch = new soundtouch::SoundTouch(); 111 pSoundStretch->setSampleRate(audio_samplerate); 112 pSoundStretch->setChannels(audio_channels); 465 if (audio_codec) 466 { 467 if (!encoder) 468 { 469 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 470 encoder = new DigitalEncoder(); 471 if (!encoder->Init(audio_codec->codec_id, 472 audio_codec->bit_rate, 473 audio_codec->sample_rate, 474 audio_codec->channels 475 )) 476 { 477 // eeks 478 delete encoder; 479 encoder = NULL; 480 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 481 } 482 } 483 } 484 if (encoder) 485 { 486 pSoundStretch->setSampleRate(audio_codec->sample_rate); 487 pSoundStretch->setChannels(audio_codec->channels); 488 } 489 else 490 { 491 pSoundStretch->setSampleRate(audio_samplerate); 492 pSoundStretch->setChannels(audio_channels); 493 } 113 494 114 495 pSoundStretch->setTempo(audio_stretchfactor); 115 496 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 132 513 } 133 514 134 515 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 135 int laudio_samplerate, bool laudio_passthru) 516 int laudio_samplerate, bool laudio_passthru, 517 void* laudio_codec) 136 518 { 519 int codec_id = CODEC_ID_NONE; 520 int lcodec_id = CODEC_ID_NONE; 521 int lcchannels = 0; 522 int cchannels = 0; 523 if (laudio_codec) 524 { 525 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 526 laudio_bits = 16; 527 laudio_channels = 2; 528 laudio_samplerate = 48000; 529 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 530 } 531 if (audio_codec) 532 { 533 codec_id = audio_codec->codec_id; 534 cchannels = ((AVCodecContext*)audio_codec)->channels; 535 } 536 ClearError(); 137 537 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 138 laudio_samplerate == audio_samplerate && 139 laudio_passthru == audio_passthru && !need_resampler) 538 laudio_samplerate == audio_samplerate && !need_resampler && 539 laudio_passthru == audio_passthru && 540 lcodec_id == codec_id && lcchannels == cchannels) 140 541 return; 141 542 142 543 KillAudio(); … … 148 549 waud = raud = 0; 149 550 audio_actually_paused = false; 150 551 552 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 151 553 audio_channels = laudio_channels; 152 554 audio_bits = laudio_bits; 153 555 audio_samplerate = laudio_samplerate; 556 audio_codec = (AVCodecContext*)laudio_codec; 154 557 audio_passthru = laudio_passthru; 155 558 if (audio_bits != 8 && audio_bits != 16) 156 559 { … … 169 572 170 573 numlowbuffer = 0; 171 574 575 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3") 576 .arg(audio_main_device).arg(audio_channels).arg(audio_samplerate)); 577 172 578 // Actually do the device specific open call 173 579 if (!OpenDevice()) 174 580 { 175 581 VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure"); 176 582 pthread_mutex_unlock(&avsync_lock); 177 583 pthread_mutex_unlock(&audio_buflock); 584 if (GetError().isEmpty()) 585 Error("Aborting reconfigure"); 586 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 178 587 return; 179 588 } 180 589 … … 197 606 current_seconds = -1; 198 607 source_bitrate = -1; 199 608 609 // NOTE: this wont do anything as above samplerate vars are set equal 200 610 // Check if we need the resampler 201 611 if (audio_samplerate != laudio_samplerate) 202 612 { … … 221 631 222 632 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 223 633 .arg(audio_stretchfactor)); 634 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 635 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 224 636 225 SetStretchFactorLocked(audio_stretchfactor); 226 if (pSoundStretch) 637 if (redo_stretch) 227 638 { 228 pSoundStretch->setSampleRate(audio_samplerate); 229 pSoundStretch->setChannels(audio_channels); 639 float laudio_stretchfactor = audio_stretchfactor; 640 delete pSoundStretch; 641 pSoundStretch = NULL; 642 audio_stretchfactor = 0.0; 643 SetStretchFactorLocked(laudio_stretchfactor); 230 644 } 645 else 646 { 647 SetStretchFactorLocked(audio_stretchfactor); 648 if (pSoundStretch) 649 { 650 // if its passthru then we need to reencode 651 if (audio_codec) 652 { 653 if (!encoder) 654 { 655 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 656 encoder = new DigitalEncoder(); 657 if (!encoder->Init(audio_codec->codec_id, 658 audio_codec->bit_rate, 659 audio_codec->sample_rate, 660 audio_codec->channels 661 )) 662 { 663 // eeks 664 delete encoder; 665 encoder = NULL; 666 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 667 } 668 } 669 } 670 if (encoder) 671 { 672 pSoundStretch->setSampleRate(audio_codec->sample_rate); 673 pSoundStretch->setChannels(audio_codec->channels); 674 } 675 else 676 { 677 pSoundStretch->setSampleRate(audio_samplerate); 678 pSoundStretch->setChannels(audio_channels); 679 } 680 } 681 } 231 682 232 683 // Setup visualisations, zero the visualisations buffers 233 684 prepareVisuals(); … … 273 724 pSoundStretch = NULL; 274 725 } 275 726 727 if (encoder) 728 { 729 delete encoder; 730 encoder = NULL; 731 } 732 276 733 CloseDevice(); 277 734 278 735 killAudioLock.unlock(); … … 286 743 287 744 void AudioOutputBase::Pause(bool paused) 288 745 { 746 VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused)); 289 747 pauseaudio = paused; 290 748 audio_actually_paused = false; 291 749 } … … 368 826 The reason is that computing 'audiotime' requires acquiring the audio 369 827 lock, which the video thread should not do. So, we call 'SetAudioTime()' 370 828 from the audio thread, and then call this from the video thread. */ 371 intret;829 long long ret; 372 830 struct timeval now; 373 831 374 832 if (audiotime == 0) … … 380 838 381 839 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 382 840 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 383 ret = ( int)(ret * audio_stretchfactor);841 ret = (long long)(ret * audio_stretchfactor); 384 842 843 #if 1 844 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 845 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 846 .arg(now.tv_sec).arg(now.tv_usec) 847 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 848 .arg(ret) 849 .arg(audiotime) 850 .arg(audio_stretchfactor) 851 ); 852 #endif 853 385 854 ret += audiotime; 386 855 387 856 pthread_mutex_unlock(&avsync_lock); 388 return ret;857 return (int)ret; 389 858 } 390 859 391 860 void AudioOutputBase::SetAudiotime(void) … … 422 891 // include algorithmic latencies 423 892 if (pSoundStretch) 424 893 { 894 // add the effect of any unused but processed samples, AC3 reencode does this 895 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 425 896 // add the effect of unprocessed samples in time stretch algo 426 897 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 427 898 audio_bytes_per_sample) / audio_stretchfactor); 428 899 } 429 900 430 901 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 431 902 (audio_bytes_per_sample * effdspstretched)); 432 903 433 904 gettimeofday(&audiotime_updated, NULL); 905 #if 1 906 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 907 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 908 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 909 .arg(audiotime) 910 .arg(audbuf_timecode) 911 .arg(totalbuffer) 912 .arg(soundcard_buffer) 913 .arg(effdspstretched) 914 .arg(audio_bytes_per_sample) 915 .arg(audio_stretchfactor) 916 ); 917 #endif 434 918 435 919 pthread_mutex_unlock(&avsync_lock); 436 920 pthread_mutex_unlock(&audio_buflock); … … 498 982 // NOTE: This function is not threadsafe 499 983 500 984 int afree = audiofree(true); 501 int len = samples * audio_bytes_per_sample;985 int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 502 986 503 987 // Check we have enough space to write the data 504 988 if (need_resampler && src_ctx) … … 509 993 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString( 510 994 "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4") 511 995 .arg(len).arg(AUDBUFSIZE-afree).arg(afree) 512 .arg(timecode)); 513 996 .arg(LONGLONGCONVERT timecode)); 514 997 return false; // would overflow 515 998 } 516 999 … … 547 1030 548 1031 int AudioOutputBase::WaitForFreeSpace(int samples) 549 1032 { 550 int len = samples * audio_bytes_per_sample; 1033 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 1034 int len = samples * abps; 551 1035 int afree = audiofree(false); 552 1036 553 1037 while (len > afree) 554 1038 { 555 1039 if (blocking) 556 1040 { 557 VERBOSE(VB_AUDIO , LOC + "Waiting for free space");1041 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space"); 558 1042 // wait for more space 559 1043 pthread_cond_wait(&audio_bufsig, &audio_buflock); 560 1044 afree = audiofree(false); 561 1045 } 562 1046 else 563 1047 { 564 VERBOSE(VB_IMPORTANT, LOC_ERR + 565 "Audio buffer overflow, audio data lost!"); 566 samples = afree / audio_bytes_per_sample; 567 len = samples * audio_bytes_per_sample; 1048 VERBOSE(VB_IMPORTANT, LOC_ERR + 1049 QString("Audio buffer overflow, %1 audio samples lost!") 1050 .arg(samples-afree / abps)); 1051 samples = afree / abps; 1052 len = samples * abps; 568 1053 if (src_ctx) 569 1054 { 570 1055 int error = src_reset(src_ctx); … … 589 1074 590 1075 int afree = audiofree(false); 591 1076 592 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 593 LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 594 .arg(samples * audio_bytes_per_sample) 595 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 1077 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 1078 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1079 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5") 1080 .arg(samples) 1081 .arg(samples * abps) 1082 .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode)); 596 1083 597 1084 len = WaitForFreeSpace(samples); 598 1085 599 1086 if (interleaved) 600 1087 { 601 1088 char *mybuf = (char*)buffer; 1089 #if 0 1090 #ifdef ENABLE_AC3_DECODER 1091 if (audio_channels == 6) 1092 { 1093 // reorder samples from L:C:R:LL:LR:LFE to L:R:LL:LR:C:LFE 1094 int i; 1095 short * p = (short*)buffer; 1096 for(i=0;i<samples;i++,p+=6) 1097 { 1098 short x = p[1]; 1099 p[1] = p[2]; 1100 p[2] = p[3]; 1101 p[3] = p[4]; 1102 p[4] = x; 1103 } 1104 } 1105 #endif 1106 #endif 602 1107 int bdiff = AUDBUFSIZE - org_waud; 603 1108 if (bdiff < len) 604 1109 { … … 629 1134 630 1135 if (pSoundStretch) 631 1136 { 1137 632 1138 // does not change the timecode, only the number of samples 633 1139 // back to orig pos 634 1140 org_waud = waud; 635 1141 int bdiff = AUDBUFSIZE - org_waud; 636 int nSamplesToEnd = bdiff/a udio_bytes_per_sample;1142 int nSamplesToEnd = bdiff/abps; 637 1143 if (bdiff < len) 638 1144 { 639 1145 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 640 1146 org_waud), nSamplesToEnd); 641 1147 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 642 (len - bdiff) / a udio_bytes_per_sample);1148 (len - bdiff) / abps); 643 1149 } 644 1150 else 645 1151 { 646 1152 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 647 org_waud), len / a udio_bytes_per_sample);1153 org_waud), len / abps); 648 1154 } 649 1155 650 int newLen = 0; 651 int nSamples; 652 len = WaitForFreeSpace(pSoundStretch->numSamples() * 653 audio_bytes_per_sample); 654 do 1156 if (encoder) 655 1157 { 656 int samplesToGet = len/audio_bytes_per_sample; 657 if (samplesToGet > nSamplesToEnd) 1158 // pull out a packet's worth and reencode it until we dont have enough 1159 // for any more packets 1160 soundtouch::SAMPLETYPE* temp_buff = 1161 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 1162 size_t frameSize = encoder->FrameSize()/abps; 1163 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1164 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 1165 .arg(frameSize) 1166 .arg(encoder->FrameSize()) 1167 .arg(pSoundStretch->numSamples()) 1168 ); 1169 // process the same number of samples as it creates a full encoded buffer 1170 // just like before 1171 while (pSoundStretch->numSamples() >= frameSize) 658 1172 { 659 samplesToGet = nSamplesToEnd; 1173 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 1174 int amount = encoder->Encode(temp_buff); 1175 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1176 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 1177 .arg(amount) 1178 .arg(got) 1179 .arg(pSoundStretch->numSamples()) 1180 ); 1181 if (amount == 0) 1182 continue; 1183 //len = WaitForFreeSpace(amount); 1184 char * ob = encoder->GetOutBuff(); 1185 if (amount >= bdiff) 1186 { 1187 memcpy(audiobuffer + org_waud, ob, bdiff); 1188 ob += bdiff; 1189 amount -= bdiff; 1190 org_waud = 0; 1191 } 1192 if (amount > 0) 1193 memcpy(audiobuffer + org_waud, ob, amount); 1194 bdiff = AUDBUFSIZE - amount; 1195 org_waud += amount; 660 1196 } 661 662 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 663 (audiobuffer + org_waud), samplesToGet); 664 if (nSamples == nSamplesToEnd) 1197 } 1198 else 1199 { 1200 int newLen = 0; 1201 int nSamples; 1202 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1203 audio_bytes_per_sample); 1204 do 665 1205 { 666 org_waud = 0; 667 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 668 } 669 else 670 { 671 org_waud += nSamples * audio_bytes_per_sample; 672 nSamplesToEnd -= nSamples; 673 } 1206 int samplesToGet = len/audio_bytes_per_sample; 1207 if (samplesToGet > nSamplesToEnd) 1208 { 1209 samplesToGet = nSamplesToEnd; 1210 } 674 1211 675 newLen += nSamples * audio_bytes_per_sample; 676 len -= nSamples * audio_bytes_per_sample; 677 } while (nSamples > 0); 1212 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 1213 (audiobuffer + org_waud), samplesToGet); 1214 if (nSamples == nSamplesToEnd) 1215 { 1216 org_waud = 0; 1217 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1218 } 1219 else 1220 { 1221 org_waud += nSamples * audio_bytes_per_sample; 1222 nSamplesToEnd -= nSamples; 1223 } 1224 1225 newLen += nSamples * audio_bytes_per_sample; 1226 len -= nSamples * audio_bytes_per_sample; 1227 } while (nSamples > 0); 1228 } 678 1229 } 679 1230 680 1231 waud = org_waud; … … 750 1301 space_on_soundcard = getSpaceOnSoundcard(); 751 1302 752 1303 if (space_on_soundcard != last_space_on_soundcard) { 753 VERBOSE(VB_AUDIO , LOC + QString("%1 bytes free on soundcard")1304 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard") 754 1305 .arg(space_on_soundcard)); 755 1306 last_space_on_soundcard = space_on_soundcard; 756 1307 } … … 763 1314 WriteAudio(zeros, fragment_size); 764 1315 } else { 765 1316 // this should never happen now -dag 766 VERBOSE(VB_AUDIO , LOC +1317 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 767 1318 QString("waiting for space on soundcard " 768 1319 "to write zeros: have %1 need %2") 769 1320 .arg(space_on_soundcard).arg(fragment_size)); … … 799 1350 if (fragment_size > audiolen(true)) 800 1351 { 801 1352 if (audiolen(true) > 0) // only log if we're sending some audio 802 VERBOSE(VB_AUDIO , LOC +1353 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 803 1354 QString("audio waiting for buffer to fill: " 804 1355 "have %1 want %2") 805 1356 .arg(audiolen(true)).arg(fragment_size)); 806 1357 807 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1358 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 808 1359 pthread_mutex_lock(&audio_buflock); 809 1360 pthread_cond_broadcast(&audio_bufsig); 810 1361 pthread_mutex_unlock(&audio_buflock); … … 818 1369 if (fragment_size > space_on_soundcard) 819 1370 { 820 1371 if (space_on_soundcard != last_space_on_soundcard) { 821 VERBOSE(VB_AUDIO , LOC +1372 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 822 1373 QString("audio waiting for space on soundcard: " 823 1374 "have %1 need %2") 824 1375 .arg(space_on_soundcard).arg(fragment_size)); … … 880 1431 881 1432 /* update raud */ 882 1433 raud = (raud + fragment_size) % AUDBUFSIZE; 883 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1434 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 884 1435 pthread_cond_broadcast(&audio_bufsig); 885 1436 886 1437 written_size = fragment_size; -
libs/libmyth/audiooutputalsa.cpp
52 52 QString real_device = (audio_passthru) ? 53 53 audio_passthru_device : audio_main_device; 54 54 55 int index; 56 if ((index=real_device.find('|'))>=0) 57 { 58 if (audio_channels != 2) 59 real_device = real_device.mid(index+1); 60 else 61 real_device = real_device.left(index); 62 } 63 55 64 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 56 65 .arg(real_device)); 57 66 … … 89 98 } 90 99 else 91 100 { 92 fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 93 buffer_time = 500000; // .5 seconds 101 //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 102 //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits 103 fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30); 104 buffer_time = 100000; // .5 seconds 94 105 period_time = buffer_time / 4; // 4 interrupts per buffer 95 106 } 96 107 … … 162 173 163 174 tmpbuf = aubuf; 164 175 165 VERBOSE(VB_AUDIO , QString("WriteAudio: Preparing %1 bytes (%2 frames)")176 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 166 177 .arg(size).arg(frames)); 167 178 168 179 while (frames > 0) -
programs/mythfrontend/globalsettings.cpp
58 58 #endif 59 59 #ifdef USING_ALSA 60 60 gc->addSelection("ALSA:default", "ALSA:default"); 61 gc->addSelection("ALSA:analog", "ALSA:analog"); 62 gc->addSelection("ALSA:digital", "ALSA:digital"); 63 gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog"); 64 gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital"); 61 65 #endif 62 66 #ifdef USING_ARTS 63 67 gc->addSelection("ARTS:", "ARTS:"); … … 73 77 return gc; 74 78 } 75 79 80 static HostComboBox *MaxAudioChannels() 81 { 82 HostComboBox *gc = new HostComboBox("MaxChannels",false); 83 gc->setLabel(QObject::tr("Max Audio Channels")); 84 //gc->addSelection(QObject::tr("Mono"), "1"); 85 //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default 86 //gc->addSelection(QObject::tr("3 Channel: L C R"), "3"); 87 //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4"); 88 //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5"); 89 //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6"); 90 gc->addSelection(QObject::tr("Stereo"), "2", true); // default 91 gc->addSelection(QObject::tr("6 Channel"), "6"); 92 gc->setHelpText( 93 QObject::tr("Set the maximum number of audio channels to be decoded. " 94 "This is for multi-channel/surround audio playback.")); 95 return gc; 96 } 97 76 98 static HostComboBox *PassThroughOutputDevice() 77 99 { 78 100 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3103 3125 new VerticalConfigurationGroup(false, false, true, true); 3104 3126 vgrp0->addChild(AC3PassThrough()); 3105 3127 vgrp0->addChild(DTSPassThrough()); 3128 addChild(MaxAudioChannels()); 3106 3129 3107 3130 VerticalConfigurationGroup *vgrp1 = 3108 3131 new VerticalConfigurationGroup(false, false, true, true); -
programs/mythtranscode/transcode.cpp
55 55 56 56 // reconfigure sound out for new params 57 57 virtual void Reconfigure(int audio_bits, int audio_channels, 58 int audio_samplerate, bool audio_passthru) 58 int audio_samplerate, bool audio_passthru, 59 void * = NULL) 59 60 { 61 ClearError(); 60 62 (void)audio_samplerate; 61 63 (void)audio_passthru; 62 64 bits = audio_bits; 63 65 channels = audio_channels; 64 66 bytes_per_sample = bits * channels / 8; 67 if (channels>2) 68 Error("Invalid channel count"); 65 69 } 66 70 67 71 // dsprate is in 100 * samples/second -
programs/mythuitest/mythuitest.pro
6 6 TARGET = mythuitest 7 7 CONFIG += thread opengl 8 8 9 LIBS += -L../../libs/libavcodec -L../../libs/libavutil 10 LIBS += -lmythavcodec-$$LIBVERSION -lmythavutil-$$LIBVERSION 9 11 LIBS += $$EXTRA_LIBS 10 12 13 TARGETDEPS += ../../libs/libavcodec/libmythavcodec-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB} 14 TARGETDEPS += ../../libs/libavutil/libmythavutil-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB} 15 11 16 macx { 12 17 # Duplication of source with libmyth (e.g. oldsettings.cpp) 13 18 # means that the linker complains, so we have to ignore duplicates -
libs/libmythtv/avformatdecoder.h
259 259 bool allow_ac3_passthru; 260 260 bool allow_dts_passthru; 261 261 bool disable_passthru; 262 int max_channels; 262 263 263 264 AudioInfo audioIn; 264 265 AudioInfo audioOut; -
libs/libmythtv/avformatdecoder.cpp
52 52 #define MAX_AC3_FRAME_SIZE 6144 53 53 54 54 /** Set to zero to allow any number of AC3 channels. */ 55 #define MAXCHANNELSELECT 1 56 #if MAXCHANNELSELECT 57 #define MAX_OUTPUT_CHANNELS compiler error 58 #else 55 59 #define MAX_OUTPUT_CHANNELS 2 60 #endif 56 61 57 62 static int cc608_parity(uint8_t byte); 58 63 static int cc608_good_parity(const int *parity_table, uint16_t data); … … 417 422 418 423 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 419 424 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 425 max_channels = gContext->GetNumSetting("MaxChannels", 2); 420 426 421 427 audioIn.sample_size = -32; // force SetupAudioStream to run once 422 428 itv = GetNVP()->GetInteractiveTV(); … … 1579 1614 <<") type ("<<codec_type_string(enc->codec_type) 1580 1615 <<") already open, leaving it alone."); 1581 1616 } 1617 #if MAXCHANNELSELECT 1618 #if 0 1619 if (enc->cqp != max_channels) 1620 { 1621 VERBOSE(VB_IMPORTANT, LOC + QString("Setting maxchannels to %1, %2").arg(max_channels).arg(enc->cqp)); 1622 enc->cqp = max_channels; 1623 } 1624 #endif 1625 #endif 1582 1626 //assert(enc->codec_id); 1627 VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels)); 1583 1628 1629 #if !MAXCHANNELSELECT 1584 1630 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1585 1631 if (enc->codec_id == CODEC_ID_DTS) 1586 1632 { … … 1589 1635 // enc->bit_rate = what??; 1590 1636 } 1591 1637 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1638 #endif 1592 1639 1593 1640 bitrate += enc->bit_rate; 1594 1641 break; … … 3260 3315 if (!curstream->codec->channels) 3261 3316 { 3262 3317 QMutexLocker locker(&avcodeclock); 3318 #if MAXCHANNELSELECT 3319 VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels)); 3320 #if 0 3321 curstream->codec->cqp = max_channels; 3322 #endif 3323 curstream->codec->channels = audioOut.channels; 3324 #else 3263 3325 curstream->codec->channels = MAX_OUTPUT_CHANNELS; 3326 #endif 3264 3327 ret = avcodec_decode_audio( 3265 3328 curstream->codec, audioSamples, 3266 3329 &data_size, ptr, len); 3267 3330 3268 3331 reselectAudioTrack |= curstream->codec->channels; 3269 3332 } 3333 #if MAXCHANNELSELECT 3334 #if 0 3335 if (curstream->codec->cqp != max_channels) 3336 { 3337 VERBOSE(VB_IMPORTANT, LOC + QString("Setting maxchannels to %1, %2").arg(max_channels).arg(curstream->codec->cqp)); 3338 curstream->codec->cqp = max_channels; 3339 } 3340 #endif 3341 #endif 3270 3342 3271 3343 if (reselectAudioTrack) 3272 3344 { … … 3320 3392 { 3321 3393 AVCodecContext *ctx = curstream->codec; 3322 3394 3395 #if MAXCHANNELSELECT 3323 3396 if ((ctx->channels == 0) || 3397 (ctx->channels > audioOut.channels)) 3398 ctx->channels = audioOut.channels; 3399 #else 3400 if ((ctx->channels == 0) || 3324 3401 (ctx->channels > MAX_OUTPUT_CHANNELS)) 3325 3402 ctx->channels = MAX_OUTPUT_CHANNELS; 3403 #endif 3326 3404 3327 3405 ret = avcodec_decode_audio( 3328 3406 ctx, audioSamples, &data_size, ptr, len); … … 3675 3753 3676 3754 void AvFormatDecoder::SetDisablePassThrough(bool disable) 3677 3755 { 3756 #if MAXCHANNELSELECT 3757 // can only disable never reenable as once tiemstretch is on its on for the session 3758 if (disable_passthru) 3759 return; 3760 #endif 3678 3761 if (selectedTrack[kTrackTypeAudio].av_stream_index < 0) 3679 3762 { 3680 3763 disable_passthru = disable; 3681 3764 return; 3682 3765 } 3683 3766 3684 3767 if (disable != disable_passthru) 3685 3768 { 3686 3769 disable_passthru = disable; … … 3707 3790 AVCodecContext *codec_ctx = NULL; 3708 3791 AudioInfo old_in = audioIn; 3709 3792 AudioInfo old_out = audioOut; 3793 bool using_passthru = false; 3710 3794 3711 3795 if ((currentTrack[kTrackTypeAudio] >= 0) && 3712 3796 (selectedTrack[kTrackTypeAudio].av_stream_index <= … … 3716 3800 { 3717 3801 assert(curstream); 3718 3802 assert(curstream->codec); 3719 codec_ctx = curstream->codec; 3803 codec_ctx = curstream->codec; 3720 3804 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3721 !disable_passthru &&3722 3805 (codec_ctx->codec_id == CODEC_ID_AC3)); 3723 3806 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3724 !disable_passthru &&3725 3807 (codec_ctx->codec_id == CODEC_ID_DTS)); 3808 using_passthru = do_ac3_passthru || do_dts_passthru; 3726 3809 info = AudioInfo(codec_ctx->codec_id, 3727 3810 codec_ctx->sample_rate, codec_ctx->channels, 3728 do_ac3_passthru || do_dts_passthru);3811 using_passthru && !disable_passthru); 3729 3812 } 3730 3813 3731 3814 if (info == audioIn) 3732 3815 return false; // no change 3733 3816 3817 QString ptmsg = ""; 3818 if (using_passthru) 3819 { 3820 ptmsg = QString(" using passthru"); 3821 } 3734 3822 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 3735 3823 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 3736 3824 3737 3825 audioOut = audioIn = info; 3826 #if MAXCHANNELSELECT 3827 if (using_passthru) 3828 #else 3738 3829 if (audioIn.do_passthru) 3830 #endif 3739 3831 { 3740 3832 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 3741 audioOut.channels = 2; 3742 audioOut.sample_rate = 48000; 3743 audioOut.sample_size = 4; 3833 AudioInfo digInfo = audioOut; 3834 if (!disable_passthru) 3835 { 3836 digInfo.channels = 2; 3837 digInfo.sample_rate = 48000; 3838 digInfo.sample_size = 4; 3839 } 3840 if (audioOut.channels > max_channels) 3841 { 3842 audioOut.channels = max_channels; 3843 audioOut.sample_size = audioOut.channels * 2; 3844 codec_ctx->channels = audioOut.channels; 3845 } 3846 #if MAXCHANNELSELECT 3847 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 3848 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 3849 .arg(digInfo.toString()) 3850 .arg(old_in.toString()).arg(old_out.toString()) 3851 .arg(audioIn.toString()).arg(audioOut.toString())); 3852 3853 if (digInfo.sample_rate > 0) 3854 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 3855 3856 //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 3857 // audioOut.sample_rate); 3858 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 3859 digInfo.sample_rate, audioIn.do_passthru); 3860 // allow the audio stuff to reencode 3861 GetNVP()->SetAudioCodec(codec_ctx); 3862 GetNVP()->ReinitAudio(); 3863 return true; 3864 #endif 3744 3865 } 3866 #if MAXCHANNELSELECT 3745 3867 else 3746 3868 { 3869 if (audioOut.channels > max_channels) 3870 { 3871 audioOut.channels = max_channels; 3872 audioOut.sample_size = audioOut.channels * 2; 3873 codec_ctx->channels = audioOut.channels; 3874 } 3875 } 3876 bool audiook; 3877 #if 0 3878 do 3879 { 3880 #endif 3881 #else 3882 else 3883 { 3747 3884 if (audioOut.channels > MAX_OUTPUT_CHANNELS) 3748 3885 { 3749 3886 audioOut.channels = MAX_OUTPUT_CHANNELS; … … 3751 3888 codec_ctx->channels = MAX_OUTPUT_CHANNELS; 3752 3889 } 3753 3890 } 3891 #endif 3754 3892 3755 3893 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 3756 3894 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") … … 3763 3901 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 3764 3902 audioOut.sample_rate, 3765 3903 audioIn.do_passthru); 3766 GetNVP()->ReinitAudio(); 3904 // allow the audio stuff to reencode 3905 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 3906 QString errMsg = GetNVP()->ReinitAudio(); 3907 #if MAXCHANNELSELECT 3908 audiook = errMsg.isEmpty(); 3909 #if 0 3910 if (!audiook) 3911 { 3912 switch (audioOut.channels) 3913 { 3914 #if 0 3915 case 8: 3916 audioOut.channels = 6; 3917 break; 3918 #endif 3919 case 6: 3920 #if 0 3921 audioOut.channels = 5; 3922 break; 3923 case 5: 3924 audioOut.channels = 4; 3925 break; 3926 case 4: 3927 audioOut.channels = 3; 3928 break; 3929 case 3: 3930 #endif 3931 audioOut.channels = 2; 3932 break; 3933 #if 0 3934 case 2: 3935 audioOut.channels = 1; 3936 break; 3937 #endif 3938 default: 3939 // failed to reconfigure under any circumstances 3940 audiook = true; 3941 audioOut.channels = 0; 3942 break; 3943 } 3944 audioOut.sample_size = audioOut.channels * 2; 3945 codec_ctx->channels = audioOut.channels; 3946 } 3947 } while (!audiook); 3948 #endif 3949 #endif 3767 3950 3768 3951 return true; 3769 3952 } -
libs/libmythtv/NuppelVideoPlayer.h
127 127 void SetAudioInfo(const QString &main, const QString &passthru, uint rate); 128 128 void SetAudioParams(int bits, int channels, int samplerate, bool passthru); 129 129 void SetEffDsp(int dsprate); 130 void SetAudioCodec(void *ac); 130 131 131 132 // Sets 132 133 void SetParentWidget(QWidget *widget) { parentWidget = widget; } … … 681 682 int audio_bits; 682 683 int audio_samplerate; 683 684 float audio_stretchfactor; 685 void *audio_codec; 684 686 bool audio_passthru; 685 687 686 688 // Picture-in-Picture -
libs/libmythtv/NuppelVideoPlayer.cpp
206 206 audio_passthru_device(QString::null), 207 207 audio_channels(2), audio_bits(-1), 208 208 audio_samplerate(44100), audio_stretchfactor(1.0f), 209 audio_codec(NULL), 209 210 // Picture-in-Picture 210 211 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 211 212 // Preview window support … … 767 768 if (audioOutput) 768 769 { 769 770 audioOutput->Reconfigure(audio_bits, audio_channels, 770 audio_samplerate, audio_passthru); 771 audio_samplerate, audio_passthru, 772 audio_codec); 771 773 errMsg = audioOutput->GetError(); 772 774 if (!errMsg.isEmpty()) 773 775 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3607 3619 audio_passthru = passthru; 3608 3620 } 3609 3621 3622 void NuppelVideoPlayer::SetAudioCodec(void* ac) 3623 { 3624 audio_codec = ac; 3625 } 3626 3610 3627 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3611 3628 { 3612 3629 if (audioOutput) -
libs/libavcodec/liba52.c
134 134 } 135 135 } 136 136 137 static inline int16_t convert(int32_t i) 138 { 139 return av_clip_int16(i - 0x43c00000); 140 } 141 142 void float2s16_2 (float * _f, int16_t * s16) 143 { 144 int i; 145 int32_t * f = (int32_t *) _f; 146 147 for (i = 0; i < 256; i++) { 148 s16[2*i] = convert (f[i]); 149 s16[2*i+1] = convert (f[i+256]); 150 } 151 } 152 153 void float2s16_4 (float * _f, int16_t * s16) 154 { 155 int i; 156 int32_t * f = (int32_t *) _f; 157 158 for (i = 0; i < 256; i++) { 159 s16[4*i] = convert (f[i]); 160 s16[4*i+1] = convert (f[i+256]); 161 s16[4*i+2] = convert (f[i+512]); 162 s16[4*i+3] = convert (f[i+768]); 163 } 164 } 165 166 void float2s16_5 (float * _f, int16_t * s16) 167 { 168 int i; 169 int32_t * f = (int32_t *) _f; 170 171 for (i = 0; i < 256; i++) { 172 s16[5*i] = convert (f[i]); 173 s16[5*i+1] = convert (f[i+256]); 174 s16[5*i+2] = convert (f[i+512]); 175 s16[5*i+3] = convert (f[i+768]); 176 s16[5*i+4] = convert (f[i+1024]); 177 } 178 } 179 180 #define LIKEAC3DEC 1 181 int channels_multi (int flags) 182 { 183 if (flags & A52_LFE) 184 return 6; 185 else if (flags & 1) /* center channel */ 186 return 5; 187 else if ((flags & A52_CHANNEL_MASK) == A52_2F2R) 188 return 4; 189 else 190 return 2; 191 } 192 193 void float2s16_multi (float * _f, int16_t * s16, int flags) 194 { 195 int i; 196 int32_t * f = (int32_t *) _f; 197 198 switch (flags) { 199 case A52_MONO: 200 for (i = 0; i < 256; i++) { 201 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; 202 s16[5*i+4] = convert (f[i]); 203 } 204 break; 205 case A52_CHANNEL: 206 case A52_STEREO: 207 case A52_DOLBY: 208 float2s16_2 (_f, s16); 209 break; 210 case A52_3F: 211 for (i = 0; i < 256; i++) { 212 s16[5*i] = convert (f[i]); 213 s16[5*i+1] = convert (f[i+512]); 214 s16[5*i+2] = s16[5*i+3] = 0; 215 s16[5*i+4] = convert (f[i+256]); 216 } 217 break; 218 case A52_2F2R: 219 float2s16_4 (_f, s16); 220 break; 221 case A52_3F2R: 222 float2s16_5 (_f, s16); 223 break; 224 case A52_MONO | A52_LFE: 225 for (i = 0; i < 256; i++) { 226 #if LIKEAC3DEC 227 s16[6*i] = s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 228 s16[6*i+1] = convert (f[i+256]); 229 s16[6*i+5] = convert (f[i]); 230 #else 231 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; 232 s16[6*i+4] = convert (f[i+256]); 233 s16[6*i+5] = convert (f[i]); 234 #endif 235 } 236 break; 237 case A52_CHANNEL | A52_LFE: 238 case A52_STEREO | A52_LFE: 239 case A52_DOLBY | A52_LFE: 240 for (i = 0; i < 256; i++) { 241 #if LIKEAC3DEC 242 s16[6*i] = convert (f[i+256]); 243 s16[6*i+2] = convert (f[i+512]); 244 s16[6*i+1] = s16[6*i+3] = s16[6*i+4] = 0; 245 s16[6*i+5] = convert (f[i]); 246 #else 247 s16[6*i] = convert (f[i+256]); 248 s16[6*i+1] = convert (f[i+512]); 249 s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 250 s16[6*i+5] = convert (f[i]); 251 #endif 252 } 253 break; 254 case A52_3F | A52_LFE: 255 for (i = 0; i < 256; i++) { 256 #if LIKEAC3DEC 257 s16[6*i] = convert (f[i+256]); 258 s16[6*i+2] = convert (f[i+768]); 259 s16[6*i+3] = s16[6*i+4] = 0; 260 s16[6*i+1] = convert (f[i+512]); 261 s16[6*i+5] = convert (f[i]); 262 #else 263 s16[6*i] = convert (f[i+256]); 264 s16[6*i+1] = convert (f[i+768]); 265 s16[6*i+2] = s16[6*i+3] = 0; 266 s16[6*i+4] = convert (f[i+512]); 267 s16[6*i+5] = convert (f[i]); 268 #endif 269 } 270 break; 271 case A52_2F2R | A52_LFE: 272 for (i = 0; i < 256; i++) { 273 #if LIKEAC3DEC 274 s16[6*i] = convert (f[i+256]); 275 s16[6*i+1] = 0; 276 s16[6*i+2] = convert (f[i+512]); 277 s16[6*i+3] = convert (f[i+768]); 278 s16[6*i+4] = convert (f[i+1024]); 279 s16[6*i+5] = convert (f[i]); 280 #else 281 s16[6*i] = convert (f[i+256]); 282 s16[6*i+1] = convert (f[i+512]); 283 s16[6*i+2] = convert (f[i+768]); 284 s16[6*i+3] = convert (f[i+1024]); 285 s16[6*i+4] = 0; 286 s16[6*i+5] = convert (f[i]); 287 #endif 288 } 289 break; 290 case A52_3F2R | A52_LFE: 291 for (i = 0; i < 256; i++) { 292 #if LIKEAC3DEC 293 s16[6*i] = convert (f[i+256]); 294 s16[6*i+1] = convert (f[i+512]); 295 s16[6*i+2] = convert (f[i+768]); 296 s16[6*i+3] = convert (f[i+1024]); 297 s16[6*i+4] = convert (f[i+1280]); 298 s16[6*i+5] = convert (f[i]); 299 #else 300 s16[6*i] = convert (f[i+256]); 301 s16[6*i+1] = convert (f[i+768]); 302 s16[6*i+2] = convert (f[i+1024]); 303 s16[6*i+3] = convert (f[i+1280]); 304 s16[6*i+4] = convert (f[i+512]); 305 s16[6*i+5] = convert (f[i]); 306 #endif 307 } 308 break; 309 } 310 } 311 137 312 /**** end */ 138 313 139 314 #define HEADER_SIZE 7 … … 177 352 /* update codec info */ 178 353 avctx->sample_rate = sample_rate; 179 354 s->channels = ac3_channels[s->flags & 7]; 355 if (avctx->cqp >= 0) 356 avctx->channels = avctx->cqp; 180 357 if (s->flags & A52_LFE) 181 358 s->channels++; 182 359 if (avctx->channels == 0) … … 199 376 s->inbuf_ptr += len; 200 377 buf_size -= len; 201 378 } else { 379 int chans; 202 380 flags = s->flags; 203 381 if (avctx->channels == 1) 204 382 flags = A52_MONO; 205 else if (avctx->channels == 2) 206 flags = A52_STEREO; 383 else if (avctx->channels == 2) { 384 if (s->channels>2) 385 flags = A52_DOLBY; 386 else 387 flags = A52_STEREO; 388 } 207 389 else 208 390 flags |= A52_ADJUST_LEVEL; 209 391 level = 1; 392 chans = channels_multi(flags); 210 393 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 211 394 fail: 212 395 av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); … … 217 400 for (i = 0; i < 6; i++) { 218 401 if (s->a52_block(s->state)) 219 402 goto fail; 220 float _to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);403 float2s16_multi(s->samples, out_samples + i * 256 * chans, flags); 221 404 } 222 405 s->inbuf_ptr = s->inbuf; 223 406 s->frame_size = 0; -
libs/libavcodec/ac3_parser.c
84 84 return 0; 85 85 } 86 86 87 staticint ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,87 /*static*/ int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, 88 88 int *bit_rate, int *samples) 89 89 { 90 90 int err;