Ticket #1104: mythtv_ac3.22.patch
File mythtv_ac3.22.patch, 60.1 KB (added by , 17 years ago) |
---|
-
libs/libmyth/libmyth.pro
35 35 SOURCES += virtualkeyboard.cpp mythobservable.cpp mythsocket.cpp 36 36 37 37 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ 38 INCLUDEPATH += ../libavutil 38 39 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui 40 DEPENDPATH += ../libavutil ../libavcodec 39 41 40 42 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION} 41 43 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION} 44 LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION} 42 45 43 46 isEmpty(QMAKE_EXTENSION_SHLIB) { 44 47 QMAKE_EXTENSION_SHLIB=so -
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
16 16 // MythTV headers 17 17 #include "audiooutputbase.h" 18 18 19 extern "C" { 20 #include "libavcodec/avcodec.h" 21 #include "libavcodec/liba52/a52.h" 22 } 23 24 #if QT_VERSION < 0x030200 25 #define LONGLONGCONVERT (long) 26 #else 27 #define LONGLONGCONVERT 28 #endif 29 30 #define LOC QString("DEnc: "); 31 #define MAX_AC3_FRAME_SIZE 6144 32 class DigitalEncoder 33 { 34 public: 35 DigitalEncoder(); 36 ~DigitalEncoder(); 37 void Dispose(); 38 bool Init(CodecID codec_id, int bitrate, int samplerate, int channels); 39 size_t Encode(short * buff); 40 41 // if needed 42 char * GetFrameBuffer() 43 { 44 if (!frame_buffer && av_context) 45 { 46 frame_buffer = new char [one_frame_bytes]; 47 } 48 return frame_buffer; 49 } 50 size_t FrameSize() const { return one_frame_bytes; } 51 char * GetOutBuff() const { return outbuf; } 52 53 size_t audio_bytes_per_sample; 54 private: 55 AVCodecContext *av_context; 56 char * outbuf; 57 char * frame_buffer; 58 int outbuf_size; 59 size_t one_frame_bytes; 60 }; 61 62 DigitalEncoder::DigitalEncoder() 63 { 64 av_context = NULL; 65 outbuf = NULL; 66 outbuf_size = 0; 67 one_frame_bytes = 0; 68 frame_buffer = NULL; 69 } 70 71 DigitalEncoder::~DigitalEncoder() 72 { 73 Dispose(); 74 } 75 76 void DigitalEncoder::Dispose() 77 { 78 if (av_context) 79 { 80 avcodec_close(av_context); 81 av_free(av_context); 82 av_context = NULL; 83 } 84 if (outbuf) 85 { 86 delete [] outbuf; 87 outbuf = NULL; 88 outbuf_size = 0; 89 } 90 if (frame_buffer) 91 { 92 delete [] frame_buffer; 93 frame_buffer = NULL; 94 one_frame_bytes = 0; 95 } 96 } 97 98 //CODEC_ID_AC3 99 bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels) 100 { 101 AVCodec * codec; 102 int ret; 103 104 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4") 105 .arg(codec_id_string(codec_id)) 106 .arg(bitrate) 107 .arg(samplerate) 108 .arg(channels)); 109 //codec = avcodec_find_encoder(codec_id); 110 // always AC3 as there is no DTS encoder at the moment 2005/1/9 111 codec = avcodec_find_encoder(CODEC_ID_AC3); 112 if (!codec) 113 { 114 VERBOSE(VB_IMPORTANT,"Error: could not find codec"); 115 return false; 116 } 117 av_context = avcodec_alloc_context(); 118 av_context->bit_rate = bitrate; 119 av_context->sample_rate = samplerate; 120 av_context->channels = channels; 121 // open it */ 122 if ((ret = avcodec_open(av_context, codec)) < 0) 123 { 124 VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate"); 125 Dispose(); 126 return false; 127 } 128 129 size_t bytes_per_frame = av_context->channels * sizeof(short); 130 audio_bytes_per_sample = bytes_per_frame; 131 one_frame_bytes = bytes_per_frame * av_context->frame_size; 132 133 outbuf_size = 16384; // ok for AC3 but DTS? 134 outbuf = new char [outbuf_size]; 135 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 136 .arg(av_context->frame_size) 137 .arg(bytes_per_frame) 138 .arg(one_frame_bytes) 139 ); 140 141 return true; 142 } 143 144 static int DTS_SAMPLEFREQS[16] = 145 { 146 0, 8000, 16000, 32000, 64000, 128000, 11025, 22050, 147 44100, 88200, 176400, 12000, 24000, 48000, 96000, 192000 148 }; 149 150 static int DTS_BITRATES[30] = 151 { 152 32000, 56000, 64000, 96000, 112000, 128000, 153 192000, 224000, 256000, 320000, 384000, 448000, 154 512000, 576000, 640000, 768000, 896000, 1024000, 155 1152000, 1280000, 1344000, 1408000, 1411200, 1472000, 156 1536000, 1920000, 2048000, 3072000, 3840000, 4096000 157 }; 158 159 static int dts_decode_header(uint8_t *indata_ptr, int *rate, 160 int *nblks, int *sfreq) 161 { 162 uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) | 163 (indata_ptr[2] << 8) | (indata_ptr[3])); 164 165 if (id != 0x7ffe8001) 166 return -1; 167 168 int ftype = indata_ptr[4] >> 7; 169 170 int surp = (indata_ptr[4] >> 2) & 0x1f; 171 surp = (surp + 1) % 32; 172 173 *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2); 174 ++*nblks; 175 176 int fsize = (indata_ptr[5] & 0x03) << 12 | 177 (indata_ptr[6] << 4) | (indata_ptr[7] >> 4); 178 ++fsize; 179 180 *sfreq = (indata_ptr[8] >> 2) & 0x0f; 181 *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07); 182 183 if (ftype != 1) 184 { 185 VERBOSE(VB_IMPORTANT, LOC + 186 QString("DTS: Termination frames not handled (ftype %1)") 187 .arg(ftype)); 188 return -1; 189 } 190 191 if (*sfreq != 13) 192 { 193 VERBOSE(VB_IMPORTANT, LOC + 194 QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq)); 195 return -1; 196 } 197 198 if ((fsize > 8192) || (fsize < 96)) 199 { 200 VERBOSE(VB_IMPORTANT, LOC + 201 QString("DTS: fsize: %1 invalid").arg(fsize)); 202 return -1; 203 } 204 205 if (*nblks != 8 && *nblks != 16 && *nblks != 32 && 206 *nblks != 64 && *nblks != 128 && ftype == 1) 207 { 208 VERBOSE(VB_IMPORTANT, LOC + 209 QString("DTS: nblks %1 not valid for normal frame") 210 .arg(*nblks)); 211 return -1; 212 } 213 214 return fsize; 215 } 216 217 static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/, 218 int *sample_rate, int *bit_rate) 219 { 220 int nblks; 221 int rate; 222 int sfreq; 223 224 int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq); 225 if (fsize >= 0) 226 { 227 if (rate >= 0 && rate <= 29) 228 *bit_rate = DTS_BITRATES[rate]; 229 else 230 *bit_rate = 0; 231 if (sfreq >= 1 && sfreq <= 15) 232 *sample_rate = DTS_SAMPLEFREQS[sfreq]; 233 else 234 *sample_rate = 0; 235 } 236 return fsize; 237 } 238 239 static int encode_frame( 240 bool dts, 241 unsigned char *data, 242 size_t &len) 243 { 244 size_t enc_len; 245 int flags, sample_rate, bit_rate; 246 247 // we don't do any length/crc validation of the AC3 frame here; presumably 248 // the receiver will have enough sense to do that. if someone has a 249 // receiver that doesn't, here would be a good place to put in a call 250 // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the 251 // packet is bad? we'd need to send something that the receiver would 252 // ignore, and if so, may as well just assume that it will ignore 253 // anything with a bad CRC... 254 255 uint nr_samples = 0, block_len; 256 if (dts) 257 { 258 enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate); 259 int rate, sfreq, nblks; 260 dts_decode_header(data+8, &rate, &nblks, &sfreq); 261 nr_samples = nblks * 32; 262 block_len = nr_samples * 2 * 2; 263 } 264 else 265 { 266 enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate); 267 block_len = MAX_AC3_FRAME_SIZE; 268 } 269 270 if (enc_len == 0 || enc_len > len) 271 { 272 int l = len; 273 len = 0; 274 return l; 275 } 276 277 enc_len = min((uint)enc_len, block_len - 8); 278 279 //uint32_t x = *(uint32_t*)(data+8); 280 // in place swab 281 swab(data+8, data+8, enc_len); 282 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, 283 // QString("DigitalEncoder::Encode swab test %1 %2") 284 // .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16)); 285 286 // the following values come from libmpcodecs/ad_hwac3.c in mplayer. 287 // they form a valid IEC958 AC3 header. 288 data[0] = 0x72; 289 data[1] = 0xF8; 290 data[2] = 0x1F; 291 data[3] = 0x4E; 292 data[4] = 0x01; 293 if (dts) 294 { 295 switch(nr_samples) 296 { 297 case 512: 298 data[4] = 0x0B; /* DTS-1 (512-sample bursts) */ 299 break; 300 301 case 1024: 302 data[4] = 0x0C; /* DTS-2 (1024-sample bursts) */ 303 break; 304 305 case 2048: 306 data[4] = 0x0D; /* DTS-3 (2048-sample bursts) */ 307 break; 308 309 default: 310 VERBOSE(VB_IMPORTANT, LOC + 311 QString("DTS: %1-sample bursts not supported") 312 .arg(nr_samples)); 313 data[4] = 0x00; 314 break; 315 } 316 } 317 data[5] = 0x00; 318 data[6] = (enc_len << 3) & 0xFF; 319 data[7] = (enc_len >> 5) & 0xFF; 320 memset(data + 8 + enc_len, 0, block_len - 8 - enc_len); 321 len = block_len; 322 323 return enc_len; 324 } 325 326 // must have exactly 1 frames worth of data 327 size_t DigitalEncoder::Encode(short * buff) 328 { 329 int encsize = 0; 330 size_t outsize = 0; 331 332 // put data in the correct spot for encode frame 333 outsize = avcodec_encode_audio( 334 av_context, 335 ((uchar*)outbuf)+8, 336 outbuf_size-8, 337 buff); 338 size_t tmpsize = outsize; 339 340 outsize = MAX_AC3_FRAME_SIZE; 341 encsize = encode_frame( 342 //av_context->codec_id==CODEC_ID_DTS, 343 false, 344 (unsigned char*)outbuf, outsize); 345 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 346 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 347 .arg(tmpsize) 348 .arg(encsize) 349 .arg(outsize) 350 ); 351 352 return outsize; 353 } 354 #undef LOC 19 355 #define LOC QString("AO: ") 20 356 #define LOC_ERR QString("AO, ERROR: ") 21 357 … … 24 360 int /*laudio_bits*/, int /*laudio_channels*/, 25 361 int /*laudio_samplerate*/, AudioOutputSource lsource, 26 362 bool lset_initial_vol, bool /*laudio_passthru*/) : 27 28 363 effdsp(0), effdspstretched(0), 29 364 audio_channels(-1), audio_bytes_per_sample(0), 30 365 audio_bits(-1), audio_samplerate(-1), … … 35 370 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 36 371 audio_passthru(false), audio_stretchfactor(1.0f), 37 372 373 audio_codec(NULL), 38 374 source(lsource), killaudio(false), 39 375 40 376 pauseaudio(false), audio_actually_paused(false), … … 46 382 47 383 src_ctx(NULL), 48 384 49 pSoundStretch(NULL), blocking(false), 385 pSoundStretch(NULL), 386 encoder(NULL), 387 blocking(false), 50 388 51 389 lastaudiolen(0), samples_buffered(0), 52 390 audiotime(0), … … 61 399 pthread_cond_init(&audio_bufsig, NULL); 62 400 63 401 output_audio = 0; // TODO FIXME Not POSIX compatible! 402 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 64 403 65 404 bzero(&src_data, sizeof(SRC_DATA)); 66 405 bzero(src_in, sizeof(float) * AUDIO_SRC_IN_SIZE); … … 108 447 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 109 448 .arg(audio_stretchfactor)); 110 449 pSoundStretch = new soundtouch::SoundTouch(); 111 pSoundStretch->setSampleRate(audio_samplerate); 112 pSoundStretch->setChannels(audio_channels); 450 if (audio_codec) 451 { 452 if (!encoder) 453 { 454 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 455 encoder = new DigitalEncoder(); 456 if (!encoder->Init(audio_codec->codec_id, 457 audio_codec->bit_rate, 458 audio_codec->sample_rate, 459 audio_codec->channels 460 )) 461 { 462 // eeks 463 delete encoder; 464 encoder = NULL; 465 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 466 } 467 } 468 } 469 if (encoder) 470 { 471 pSoundStretch->setSampleRate(audio_codec->sample_rate); 472 pSoundStretch->setChannels(audio_codec->channels); 473 } 474 else 475 { 476 pSoundStretch->setSampleRate(audio_samplerate); 477 pSoundStretch->setChannels(audio_channels); 478 } 113 479 114 480 pSoundStretch->setTempo(audio_stretchfactor); 115 481 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 132 498 } 133 499 134 500 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 135 int laudio_samplerate, bool laudio_passthru) 501 int laudio_samplerate, bool laudio_passthru, 502 void* laudio_codec) 136 503 { 504 int codec_id = CODEC_ID_NONE; 505 int lcodec_id = CODEC_ID_NONE; 506 int lcchannels = 0; 507 int cchannels = 0; 508 if (laudio_codec) 509 { 510 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 511 laudio_bits = 16; 512 laudio_channels = 2; 513 laudio_samplerate = 48000; 514 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 515 } 516 if (audio_codec) 517 { 518 codec_id = audio_codec->codec_id; 519 cchannels = ((AVCodecContext*)audio_codec)->channels; 520 } 521 ClearError(); 137 522 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 138 laudio_samplerate == audio_samplerate && 139 laudio_passthru == audio_passthru && !need_resampler) 523 laudio_samplerate == audio_samplerate && !need_resampler && 524 laudio_passthru == audio_passthru && 525 lcodec_id == codec_id && lcchannels == cchannels) 140 526 return; 141 527 142 528 KillAudio(); … … 148 534 waud = raud = 0; 149 535 audio_actually_paused = false; 150 536 537 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 151 538 audio_channels = laudio_channels; 152 539 audio_bits = laudio_bits; 153 540 audio_samplerate = laudio_samplerate; 541 audio_codec = (AVCodecContext*)laudio_codec; 154 542 audio_passthru = laudio_passthru; 155 543 if (audio_bits != 8 && audio_bits != 16) 156 544 { … … 169 557 170 558 numlowbuffer = 0; 171 559 560 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3") 561 .arg(audio_main_device).arg(audio_channels).arg(audio_samplerate)); 562 172 563 // Actually do the device specific open call 173 564 if (!OpenDevice()) 174 565 { 175 566 VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure"); 176 567 pthread_mutex_unlock(&avsync_lock); 177 568 pthread_mutex_unlock(&audio_buflock); 569 if (GetError().isEmpty()) 570 Error("Aborting reconfigure"); 571 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 178 572 return; 179 573 } 180 574 … … 197 591 current_seconds = -1; 198 592 source_bitrate = -1; 199 593 594 // NOTE: this wont do anything as above samplerate vars are set equal 200 595 // Check if we need the resampler 201 596 if (audio_samplerate != laudio_samplerate) 202 597 { … … 221 616 222 617 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 223 618 .arg(audio_stretchfactor)); 619 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 620 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 224 621 225 SetStretchFactorLocked(audio_stretchfactor); 226 if (pSoundStretch) 622 if (redo_stretch) 227 623 { 228 pSoundStretch->setSampleRate(audio_samplerate); 229 pSoundStretch->setChannels(audio_channels); 624 float laudio_stretchfactor = audio_stretchfactor; 625 delete pSoundStretch; 626 pSoundStretch = NULL; 627 audio_stretchfactor = 0.0; 628 SetStretchFactorLocked(laudio_stretchfactor); 230 629 } 630 else 631 { 632 SetStretchFactorLocked(audio_stretchfactor); 633 if (pSoundStretch) 634 { 635 // if its passthru then we need to reencode 636 if (audio_codec) 637 { 638 if (!encoder) 639 { 640 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 641 encoder = new DigitalEncoder(); 642 if (!encoder->Init(audio_codec->codec_id, 643 audio_codec->bit_rate, 644 audio_codec->sample_rate, 645 audio_codec->channels 646 )) 647 { 648 // eeks 649 delete encoder; 650 encoder = NULL; 651 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 652 } 653 } 654 } 655 if (encoder) 656 { 657 pSoundStretch->setSampleRate(audio_codec->sample_rate); 658 pSoundStretch->setChannels(audio_codec->channels); 659 } 660 else 661 { 662 pSoundStretch->setSampleRate(audio_samplerate); 663 pSoundStretch->setChannels(audio_channels); 664 } 665 } 666 } 231 667 232 668 // Setup visualisations, zero the visualisations buffers 233 669 prepareVisuals(); … … 273 709 pSoundStretch = NULL; 274 710 } 275 711 712 if (encoder) 713 { 714 delete encoder; 715 encoder = NULL; 716 } 717 276 718 CloseDevice(); 277 719 278 720 killAudioLock.unlock(); … … 286 728 287 729 void AudioOutputBase::Pause(bool paused) 288 730 { 731 VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused)); 289 732 pauseaudio = paused; 290 733 audio_actually_paused = false; 291 734 } … … 368 811 The reason is that computing 'audiotime' requires acquiring the audio 369 812 lock, which the video thread should not do. So, we call 'SetAudioTime()' 370 813 from the audio thread, and then call this from the video thread. */ 371 intret;814 long long ret; 372 815 struct timeval now; 373 816 374 817 if (audiotime == 0) … … 380 823 381 824 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 382 825 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 383 ret = ( int)(ret * audio_stretchfactor);826 ret = (long long)(ret * audio_stretchfactor); 384 827 828 #if 1 829 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 830 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 831 .arg(now.tv_sec).arg(now.tv_usec) 832 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 833 .arg(ret) 834 .arg(audiotime) 835 .arg(audio_stretchfactor) 836 ); 837 #endif 838 385 839 ret += audiotime; 386 840 387 841 pthread_mutex_unlock(&avsync_lock); 388 return ret;842 return (int)ret; 389 843 } 390 844 391 845 void AudioOutputBase::SetAudiotime(void) … … 422 876 // include algorithmic latencies 423 877 if (pSoundStretch) 424 878 { 879 // add the effect of any unused but processed samples, AC3 reencode does this 880 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 425 881 // add the effect of unprocessed samples in time stretch algo 426 882 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 427 883 audio_bytes_per_sample) / audio_stretchfactor); 428 884 } 429 885 430 886 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 431 887 (audio_bytes_per_sample * effdspstretched)); 432 888 433 889 gettimeofday(&audiotime_updated, NULL); 890 #if 1 891 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 892 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 893 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 894 .arg(audiotime) 895 .arg(audbuf_timecode) 896 .arg(totalbuffer) 897 .arg(soundcard_buffer) 898 .arg(effdspstretched) 899 .arg(audio_bytes_per_sample) 900 .arg(audio_stretchfactor) 901 ); 902 #endif 434 903 435 904 pthread_mutex_unlock(&avsync_lock); 436 905 pthread_mutex_unlock(&audio_buflock); … … 498 970 // NOTE: This function is not threadsafe 499 971 500 972 int afree = audiofree(true); 501 int len = samples * audio_bytes_per_sample;973 int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 502 974 503 975 // Check we have enough space to write the data 504 976 if (need_resampler && src_ctx) … … 509 981 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString( 510 982 "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4") 511 983 .arg(len).arg(AUDBUFSIZE-afree).arg(afree) 512 .arg(timecode)); 513 984 .arg(LONGLONGCONVERT timecode)); 514 985 return false; // would overflow 515 986 } 516 987 … … 547 1018 548 1019 int AudioOutputBase::WaitForFreeSpace(int samples) 549 1020 { 550 int len = samples * audio_bytes_per_sample; 1021 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 1022 int len = samples * abps; 551 1023 int afree = audiofree(false); 552 1024 553 1025 while (len > afree) 554 1026 { 555 1027 if (blocking) 556 1028 { 557 VERBOSE(VB_AUDIO , LOC + "Waiting for free space");1029 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space"); 558 1030 // wait for more space 559 1031 pthread_cond_wait(&audio_bufsig, &audio_buflock); 560 1032 afree = audiofree(false); 561 1033 } 562 1034 else 563 1035 { 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; 1036 VERBOSE(VB_IMPORTANT, LOC_ERR + 1037 QString("Audio buffer overflow, %1 audio samples lost!") 1038 .arg(samples-afree / abps)); 1039 samples = afree / abps; 1040 len = samples * abps; 568 1041 if (src_ctx) 569 1042 { 570 1043 int error = src_reset(src_ctx); … … 589 1062 590 1063 int afree = audiofree(false); 591 1064 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)); 1065 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 1066 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1067 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5") 1068 .arg(samples) 1069 .arg(samples * abps) 1070 .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode)); 596 1071 597 1072 len = WaitForFreeSpace(samples); 598 1073 … … 629 1104 630 1105 if (pSoundStretch) 631 1106 { 1107 632 1108 // does not change the timecode, only the number of samples 633 1109 // back to orig pos 634 1110 org_waud = waud; 635 1111 int bdiff = AUDBUFSIZE - org_waud; 636 int nSamplesToEnd = bdiff/a udio_bytes_per_sample;1112 int nSamplesToEnd = bdiff/abps; 637 1113 if (bdiff < len) 638 1114 { 639 1115 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 640 1116 org_waud), nSamplesToEnd); 641 1117 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 642 (len - bdiff) / a udio_bytes_per_sample);1118 (len - bdiff) / abps); 643 1119 } 644 1120 else 645 1121 { 646 1122 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 647 org_waud), len / a udio_bytes_per_sample);1123 org_waud), len / abps); 648 1124 } 649 1125 650 int newLen = 0; 651 int nSamples; 652 len = WaitForFreeSpace(pSoundStretch->numSamples() * 653 audio_bytes_per_sample); 654 do 1126 if (encoder) 655 1127 { 656 int samplesToGet = len/audio_bytes_per_sample; 657 if (samplesToGet > nSamplesToEnd) 1128 // pull out a packet's worth and reencode it until we dont have enough 1129 // for any more packets 1130 soundtouch::SAMPLETYPE* temp_buff = 1131 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 1132 size_t frameSize = encoder->FrameSize()/abps; 1133 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1134 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 1135 .arg(frameSize) 1136 .arg(encoder->FrameSize()) 1137 .arg(pSoundStretch->numSamples()) 1138 ); 1139 // process the same number of samples as it creates a full encoded buffer 1140 // just like before 1141 while (pSoundStretch->numSamples() >= frameSize) 658 1142 { 659 samplesToGet = nSamplesToEnd; 1143 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 1144 int amount = encoder->Encode(temp_buff); 1145 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1146 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 1147 .arg(amount) 1148 .arg(got) 1149 .arg(pSoundStretch->numSamples()) 1150 ); 1151 if (amount == 0) 1152 continue; 1153 //len = WaitForFreeSpace(amount); 1154 char * ob = encoder->GetOutBuff(); 1155 if (amount >= bdiff) 1156 { 1157 memcpy(audiobuffer + org_waud, ob, bdiff); 1158 ob += bdiff; 1159 amount -= bdiff; 1160 org_waud = 0; 1161 } 1162 if (amount > 0) 1163 memcpy(audiobuffer + org_waud, ob, amount); 1164 bdiff = AUDBUFSIZE - amount; 1165 org_waud += amount; 660 1166 } 661 662 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 663 (audiobuffer + org_waud), samplesToGet); 664 if (nSamples == nSamplesToEnd) 1167 } 1168 else 1169 { 1170 int newLen = 0; 1171 int nSamples; 1172 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1173 audio_bytes_per_sample); 1174 do 665 1175 { 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 } 1176 int samplesToGet = len/audio_bytes_per_sample; 1177 if (samplesToGet > nSamplesToEnd) 1178 { 1179 samplesToGet = nSamplesToEnd; 1180 } 674 1181 675 newLen += nSamples * audio_bytes_per_sample; 676 len -= nSamples * audio_bytes_per_sample; 677 } while (nSamples > 0); 1182 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 1183 (audiobuffer + org_waud), samplesToGet); 1184 if (nSamples == nSamplesToEnd) 1185 { 1186 org_waud = 0; 1187 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1188 } 1189 else 1190 { 1191 org_waud += nSamples * audio_bytes_per_sample; 1192 nSamplesToEnd -= nSamples; 1193 } 1194 1195 newLen += nSamples * audio_bytes_per_sample; 1196 len -= nSamples * audio_bytes_per_sample; 1197 } while (nSamples > 0); 1198 } 678 1199 } 679 1200 680 1201 waud = org_waud; … … 750 1271 space_on_soundcard = getSpaceOnSoundcard(); 751 1272 752 1273 if (space_on_soundcard != last_space_on_soundcard) { 753 VERBOSE(VB_AUDIO , LOC + QString("%1 bytes free on soundcard")1274 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard") 754 1275 .arg(space_on_soundcard)); 755 1276 last_space_on_soundcard = space_on_soundcard; 756 1277 } … … 763 1284 WriteAudio(zeros, fragment_size); 764 1285 } else { 765 1286 // this should never happen now -dag 766 VERBOSE(VB_AUDIO , LOC +1287 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 767 1288 QString("waiting for space on soundcard " 768 1289 "to write zeros: have %1 need %2") 769 1290 .arg(space_on_soundcard).arg(fragment_size)); … … 799 1320 if (fragment_size > audiolen(true)) 800 1321 { 801 1322 if (audiolen(true) > 0) // only log if we're sending some audio 802 VERBOSE(VB_AUDIO , LOC +1323 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 803 1324 QString("audio waiting for buffer to fill: " 804 1325 "have %1 want %2") 805 1326 .arg(audiolen(true)).arg(fragment_size)); 806 1327 807 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1328 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 808 1329 pthread_mutex_lock(&audio_buflock); 809 1330 pthread_cond_broadcast(&audio_bufsig); 810 1331 pthread_mutex_unlock(&audio_buflock); … … 818 1339 if (fragment_size > space_on_soundcard) 819 1340 { 820 1341 if (space_on_soundcard != last_space_on_soundcard) { 821 VERBOSE(VB_AUDIO , LOC +1342 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 822 1343 QString("audio waiting for space on soundcard: " 823 1344 "have %1 need %2") 824 1345 .arg(space_on_soundcard).arg(fragment_size)); … … 880 1401 881 1402 /* update raud */ 882 1403 raud = (raud + fragment_size) % AUDBUFSIZE; 883 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1404 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 884 1405 pthread_cond_broadcast(&audio_bufsig); 885 1406 886 1407 written_size = fragment_size; -
libs/libmyth/audiooutputalsa.cpp
49 49 QString real_device = (audio_passthru) ? 50 50 audio_passthru_device : audio_main_device; 51 51 52 int index; 53 if ((index=real_device.find('|'))>=0) 54 { 55 if (audio_channels != 2) 56 real_device = real_device.mid(index+1); 57 else 58 real_device = real_device.left(index); 59 } 60 52 61 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 53 62 .arg(real_device)); 54 63 … … 86 95 } 87 96 else 88 97 { 89 fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 90 buffer_time = 500000; // .5 seconds 98 //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 99 //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits 100 fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30); 101 buffer_time = 100000; // .5 seconds 91 102 period_time = buffer_time / 4; // 4 interrupts per buffer 92 103 } 93 104 … … 159 170 160 171 tmpbuf = aubuf; 161 172 162 VERBOSE(VB_AUDIO , QString("WriteAudio: Preparing %1 bytes (%2 frames)")173 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 163 174 .arg(size).arg(frames)); 164 175 165 176 while (frames > 0) -
programs/mythfrontend/globalsettings.cpp
39 39 dev.setNameFilter("adsp*"); 40 40 gc->fillSelectionsFromDir(dev); 41 41 } 42 #ifdef USE_ALSA 43 gc->addSelection("ALSA:default", "ALSA:default"); 44 gc->addSelection("ALSA:analog", "ALSA:analog"); 45 gc->addSelection("ALSA:digital", "ALSA:digital"); 46 gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog"); 47 gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital"); 48 #endif 49 #ifdef USE_ARTS 50 gc->addSelection("ARTS:", "ARTS:"); 51 #endif 52 #ifdef USE_JACK 53 gc->addSelection("JACK:output", "JACK:output"); 54 #endif 55 gc->addSelection("NULL", "NULL"); 42 56 43 57 return gc; 44 58 } 45 59 60 static HostComboBox *MaxAudioChannels() 61 { 62 HostComboBox *gc = new HostComboBox("MaxChannels",false); 63 gc->setLabel(QObject::tr("Max Audio Channels")); 64 //gc->addSelection(QObject::tr("Mono"), "1"); 65 //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default 66 //gc->addSelection(QObject::tr("3 Channel: L C R"), "3"); 67 //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4"); 68 //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5"); 69 //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6"); 70 gc->addSelection(QObject::tr("Stereo"), "2", true); // default 71 gc->addSelection(QObject::tr("6 Channel"), "6"); 72 gc->setHelpText( 73 QObject::tr("Set the maximum number of audio channels to be decoded. " 74 "This is for multi-channel/surround audio playback.")); 75 return gc; 76 } 77 46 78 static HostComboBox *PassThroughOutputDevice() 47 79 { 48 80 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 2444 2476 #ifdef CONFIG_DTS 2445 2477 vgrp0->addChild(DTSPassThrough()); 2446 2478 #endif 2479 addChild(MaxAudioChannels()); 2447 2480 2448 2481 VerticalConfigurationGroup *vgrp1 = 2449 2482 new VerticalConfigurationGroup(false, false, true, true); -
programs/mythtranscode/transcode.cpp
49 49 50 50 // reconfigure sound out for new params 51 51 virtual void Reconfigure(int audio_bits, int audio_channels, 52 int audio_samplerate, bool audio_passthru) 52 int audio_samplerate, bool audio_passthru, 53 void * = NULL) 53 54 { 55 ClearError(); 54 56 (void)audio_samplerate; 55 57 (void)audio_passthru; 56 58 bits = audio_bits; 57 59 channels = audio_channels; 58 60 bytes_per_sample = bits * channels / 8; 61 if (channels>2) 62 Error("Invalid channel count"); 59 63 } 60 64 61 65 // dsprate is in 100 * samples/second -
programs/mythuitest/mythuitest.pro
1 1 INCLUDEPATH += ../../libs/libmythui ../../libs/libmyth 2 2 3 LIBS += -L../../libs/libmyth -L../../libs/libmythui 3 LIBS += -L../../libs/libmyth -L../../libs/libmythui -L../../libs/libavcodec -L../../libs/libavutil 4 4 5 5 include ( ../../config.mak ) 6 6 include ( ../../settings.pro ) … … 9 9 TARGET = mythuitest 10 10 CONFIG += thread opengl 11 11 12 LIBS += -lmythui-$$LIBVERSION -lmyth-$$LIBVERSION $$EXTRA_LIBS12 LIBS += -lmythui-$$LIBVERSION -lmyth-$$LIBVERSION -lmythavcodec-$$LIBVERSION -lmythavutil-$$LIBVERSION $$EXTRA_LIBS 13 13 14 14 isEmpty(QMAKE_EXTENSION_SHLIB) { 15 15 QMAKE_EXTENSION_SHLIB=so … … 19 19 } 20 20 TARGETDEPS += ../../libs/libmythui/libmythui-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB} 21 21 TARGETDEPS += ../../libs/libmyth/libmyth-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB} 22 TARGETDEPS += ../../libs/libavcodec/libmythavcodec-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB} 23 TARGETDEPS += ../../libs/libavutil/libmythavutil-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB} 22 24 23 25 macx { 24 26 # Duplication of source with libmyth (e.g. oldsettings.cpp) -
libs/libmythtv/avformatdecoder.h
247 247 bool allow_ac3_passthru; 248 248 bool allow_dts_passthru; 249 249 bool disable_passthru; 250 int max_channels; 250 251 251 252 AudioInfo audioIn; 252 253 AudioInfo audioOut; -
libs/libmythtv/avformatdecoder.cpp
47 47 #define MAX_AC3_FRAME_SIZE 6144 48 48 49 49 /** Set to zero to allow any number of AC3 channels. */ 50 #define MAXCHANNELSELECT 1 51 #if MAXCHANNELSELECT 52 #define MAX_OUTPUT_CHANNELS compiler error 53 #else 50 54 #define MAX_OUTPUT_CHANNELS 2 55 #endif 51 56 52 57 static int cc608_parity(uint8_t byte); 53 58 static int cc608_good_parity(const int *parity_table, uint16_t data); … … 309 314 #ifdef CONFIG_DTS 310 315 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 311 316 #endif 317 max_channels = gContext->GetNumSetting("MaxChannels", 2); 312 318 313 319 audioIn.sample_size = -32; // force SetupAudioStream to run once 314 320 itv = GetNVP()->GetInteractiveTV(); … … 457 463 framesPlayed = lastKey; 458 464 framesRead = lastKey; 459 465 466 VERBOSE(VB_PLAYBACK, QString("AvFormatDecoder::DoFastForward newframe %5 frame %1 fps %2 ts %3 disc %4 cur_dts %6 adj %7 newts %8 fsa %9") 467 .arg(desiredFrame) 468 .arg(fps) 469 .arg(ts) 470 .arg(discardFrames) 471 .arg(framesPlayed) 472 .arg(st->cur_dts) 473 .arg(adj_cur_dts) 474 .arg(newts) 475 .arg(frameseekadjust) 476 ); 477 460 478 int normalframes = desiredFrame - framesPlayed; 461 479 normalframes = max(normalframes, 0); 480 #if 0 481 if (!exactseeks) 482 normalframes = 0; 483 #endif 484 462 485 SeekReset(lastKey, normalframes, discardFrames, discardFrames); 463 486 464 487 if (discardFrames) … … 545 568 // Skip all the desired number of skipFrames 546 569 for (;skipFrames > 0 && !ateof; skipFrames--) 547 570 { 548 GetFrame(0);571 GetFrame(0); 549 572 if (decoded_video_frame) 550 573 GetNVP()->DiscardVideoFrame(decoded_video_frame); 551 574 } … … 812 854 // If we don't have a position map, set up ffmpeg for seeking 813 855 if (!recordingHasPositionMap) 814 856 { 857 const char *name = ic->av_class->item_name(ic); 815 858 VERBOSE(VB_PLAYBACK, LOC + 816 "Recording has no position -- using libavformat seeking.");859 QString("Recording has no position -- using libavformat seeking. %1").arg(name)); 817 860 int64_t dur = ic->duration / (int64_t)AV_TIME_BASE; 818 861 819 862 if (dur > 0) … … 1402 1448 <<") type ("<<codec_type_string(enc->codec_type) 1403 1449 <<") already open, leaving it alone."); 1404 1450 } 1451 #if MAXCHANNELSELECT 1452 if (enc->cqp != max_channels) 1453 { 1454 VERBOSE(VB_IMPORTANT, LOC + QString("Setting maxchannels to %1, %2").arg(max_channels).arg(enc->cqp)); 1455 enc->cqp = max_channels; 1456 } 1457 #endif 1405 1458 //assert(enc->codec_id); 1459 VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels)); 1406 1460 1461 #if 0 1407 1462 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1408 1463 if (enc->codec_id == CODEC_ID_DTS) 1409 1464 { … … 1412 1478 // enc->bit_rate = what??; 1413 1479 } 1414 1480 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1481 #endif 1415 1482 1416 1483 bitrate += enc->bit_rate; 1417 1484 break; … … 2975 3050 if (!curstream->codec->channels) 2976 3051 { 2977 3052 QMutexLocker locker(&avcodeclock); 3053 #if MAXCHANNELSELECT 3054 VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels)); 3055 curstream->codec->cqp = max_channels; 3056 curstream->codec->channels = audioOut.channels; 3057 #else 2978 3058 curstream->codec->channels = MAX_OUTPUT_CHANNELS; 3059 #endif 2979 3060 ret = avcodec_decode_audio( 2980 3061 curstream->codec, audioSamples, 2981 3062 &data_size, ptr, len); 2982 3063 2983 3064 reselectAudioTrack |= curstream->codec->channels; 2984 3065 } 3066 #if MAXCHANNELSELECT 3067 if (curstream->codec->cqp != max_channels) 3068 { 3069 VERBOSE(VB_IMPORTANT, LOC + QString("Setting maxchannels to %1, %2").arg(max_channels).arg(curstream->codec->cqp)); 3070 curstream->codec->cqp = max_channels; 3071 } 3072 #endif 2985 3073 2986 3074 if (reselectAudioTrack) 2987 3075 { … … 3035 3123 { 3036 3124 AVCodecContext *ctx = curstream->codec; 3037 3125 3126 #if MAXCHANNELSELECT 3038 3127 if ((ctx->channels == 0) || 3128 (ctx->channels > audioOut.channels)) 3129 ctx->channels = audioOut.channels; 3130 #else 3131 if ((ctx->channels == 0) || 3039 3132 (ctx->channels > MAX_OUTPUT_CHANNELS)) 3040 3133 ctx->channels = MAX_OUTPUT_CHANNELS; 3134 #endif 3041 3135 3042 3136 ret = avcodec_decode_audio( 3043 3137 ctx, audioSamples, &data_size, ptr, len); … … 3373 3467 3374 3468 void AvFormatDecoder::SetDisablePassThrough(bool disable) 3375 3469 { 3470 #if MAXCHANNELSELECT 3471 // can only disable never reenable as once tiemstretch is on its on for the session 3472 if (disable_passthru) 3473 return; 3474 #endif 3376 3475 if (selectedTrack[kTrackTypeAudio].av_stream_index < 0) 3377 3476 { 3378 3477 disable_passthru = disable; … … 3405 3504 AVCodecContext *codec_ctx = NULL; 3406 3505 AudioInfo old_in = audioIn; 3407 3506 AudioInfo old_out = audioOut; 3507 bool using_passthru = false; 3408 3508 3409 3509 if ((currentTrack[kTrackTypeAudio] >= 0) && 3410 3510 (selectedTrack[kTrackTypeAudio].av_stream_index <= … … 3414 3514 { 3415 3515 assert(curstream); 3416 3516 assert(curstream->codec); 3417 codec_ctx = curstream->codec; 3517 codec_ctx = curstream->codec; 3418 3518 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3419 !disable_passthru &&3420 3519 (codec_ctx->codec_id == CODEC_ID_AC3)); 3421 3520 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3422 !disable_passthru &&3423 3521 (codec_ctx->codec_id == CODEC_ID_DTS)); 3522 using_passthru = do_ac3_passthru || do_dts_passthru; 3424 3523 info = AudioInfo(codec_ctx->codec_id, 3425 3524 codec_ctx->sample_rate, codec_ctx->channels, 3426 do_ac3_passthru || do_dts_passthru);3525 using_passthru && !disable_passthru); 3427 3526 } 3428 3527 3429 3528 if (info == audioIn) 3430 3529 return false; // no change 3431 3530 3531 QString ptmsg = ""; 3532 if (using_passthru) 3533 { 3534 ptmsg = QString(" using passthru"); 3535 } 3432 3536 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 3433 3537 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 3434 3538 3435 3539 audioOut = audioIn = info; 3540 #if MAXCHANNELSELECT 3541 if (using_passthru) 3542 #else 3436 3543 if (audioIn.do_passthru) 3544 #endif 3437 3545 { 3438 3546 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 3439 audioOut.channels = 2; 3440 audioOut.sample_rate = 48000; 3441 audioOut.sample_size = 4; 3547 AudioInfo digInfo = audioOut; 3548 if (!disable_passthru) 3549 { 3550 digInfo.channels = 2; 3551 digInfo.sample_rate = 48000; 3552 digInfo.sample_size = 4; 3553 } 3554 if (audioOut.channels > max_channels) 3555 { 3556 audioOut.channels = max_channels; 3557 audioOut.sample_size = audioOut.channels * 2; 3558 codec_ctx->channels = audioOut.channels; 3559 } 3560 #if MAXCHANNELSELECT 3561 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 3562 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 3563 .arg(digInfo.toString()) 3564 .arg(old_in.toString()).arg(old_out.toString()) 3565 .arg(audioIn.toString()).arg(audioOut.toString())); 3566 3567 if (digInfo.sample_rate > 0) 3568 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 3569 3570 //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 3571 // audioOut.sample_rate); 3572 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 3573 digInfo.sample_rate, audioIn.do_passthru); 3574 // allow the audio stuff to reencode 3575 GetNVP()->SetAudioCodec(codec_ctx); 3576 GetNVP()->ReinitAudio(); 3577 return true; 3578 #endif 3442 3579 } 3580 #if MAXCHANNELSELECT 3443 3581 else 3444 3582 { 3583 if (audioOut.channels > max_channels) 3584 { 3585 audioOut.channels = max_channels; 3586 audioOut.sample_size = audioOut.channels * 2; 3587 codec_ctx->channels = audioOut.channels; 3588 } 3589 } 3590 bool audiook; 3591 #else 3592 else 3593 { 3445 3594 if (audioOut.channels > MAX_OUTPUT_CHANNELS) 3446 3595 { 3447 3596 audioOut.channels = MAX_OUTPUT_CHANNELS; … … 3449 3602 codec_ctx->channels = MAX_OUTPUT_CHANNELS; 3450 3603 } 3451 3604 } 3605 #endif 3452 3606 3453 3607 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 3454 3608 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") … … 3461 3615 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 3462 3616 audioOut.sample_rate, 3463 3617 audioIn.do_passthru); 3464 GetNVP()->ReinitAudio(); 3618 // allow the audio stuff to reencode 3619 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 3620 QString errMsg = GetNVP()->ReinitAudio(); 3621 #if MAXCHANNELSELECT 3622 audiook = errMsg.isEmpty(); 3623 #if 0 3624 if (!audiook) 3625 { 3626 switch (audioOut.channels) 3627 { 3628 #if 0 3629 case 8: 3630 audioOut.channels = 6; 3631 break; 3632 #endif 3633 case 6: 3634 #if 0 3635 audioOut.channels = 5; 3636 break; 3637 case 5: 3638 audioOut.channels = 4; 3639 break; 3640 case 4: 3641 audioOut.channels = 3; 3642 break; 3643 case 3: 3644 #endif 3645 audioOut.channels = 2; 3646 break; 3647 #if 0 3648 case 2: 3649 audioOut.channels = 1; 3650 break; 3651 #endif 3652 default: 3653 // failed to reconfigure under any circumstances 3654 audiook = true; 3655 audioOut.channels = 0; 3656 break; 3657 } 3658 audioOut.sample_size = audioOut.channels * 2; 3659 codec_ctx->channels = audioOut.channels; 3660 } 3661 } while (!audiook); 3662 #endif 3663 #endif 3465 3664 3466 3665 return true; 3467 3666 } -
libs/libmythtv/NuppelVideoPlayer.h
126 126 void SetAudioInfo(const QString &main, const QString &passthru, uint rate); 127 127 void SetAudioParams(int bits, int channels, int samplerate, bool passthru); 128 128 void SetEffDsp(int dsprate); 129 void SetAudioCodec(void *ac); 129 130 130 131 // Sets 131 132 void SetParentWidget(QWidget *widget) { parentWidget = widget; } … … 668 671 int audio_bits; 669 672 int audio_samplerate; 670 673 float audio_stretchfactor; 674 void *audio_codec; 671 675 bool audio_passthru; 672 676 673 677 // 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 … … 686 687 if (audioOutput) 687 688 { 688 689 audioOutput->Reconfigure(audio_bits, audio_channels, 689 audio_samplerate, audio_passthru); 690 audio_samplerate, audio_passthru, 691 audio_codec); 690 692 errMsg = audioOutput->GetError(); 691 693 if (!errMsg.isEmpty()) 692 694 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3474 3485 audio_passthru = passthru; 3475 3486 } 3476 3487 3488 void NuppelVideoPlayer::SetAudioCodec(void* ac) 3489 { 3490 audio_codec = ac; 3491 } 3492 3477 3493 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3478 3494 { 3479 3495 if (audioOutput) -
libs/libavcodec/a52dec.c
144 144 } 145 145 } 146 146 147 static inline int16_t convert (int32_t i) 148 { 149 if (i > 0x43c07fff) 150 return 32767; 151 else if (i < 0x43bf8000) 152 return -32768; 153 else 154 return i - 0x43c00000; 155 } 156 157 void float2s16_2 (float * _f, int16_t * s16) 158 { 159 int i; 160 int32_t * f = (int32_t *) _f; 161 162 for (i = 0; i < 256; i++) { 163 s16[2*i] = convert (f[i]); 164 s16[2*i+1] = convert (f[i+256]); 165 } 166 } 167 168 void float2s16_4 (float * _f, int16_t * s16) 169 { 170 int i; 171 int32_t * f = (int32_t *) _f; 172 173 for (i = 0; i < 256; i++) { 174 s16[4*i] = convert (f[i]); 175 s16[4*i+1] = convert (f[i+256]); 176 s16[4*i+2] = convert (f[i+512]); 177 s16[4*i+3] = convert (f[i+768]); 178 } 179 } 180 181 void float2s16_5 (float * _f, int16_t * s16) 182 { 183 int i; 184 int32_t * f = (int32_t *) _f; 185 186 for (i = 0; i < 256; i++) { 187 s16[5*i] = convert (f[i]); 188 s16[5*i+1] = convert (f[i+256]); 189 s16[5*i+2] = convert (f[i+512]); 190 s16[5*i+3] = convert (f[i+768]); 191 s16[5*i+4] = convert (f[i+1024]); 192 } 193 } 194 195 int channels_multi (int flags) 196 { 197 if (flags & A52_LFE) 198 return 6; 199 else if (flags & 1) /* center channel */ 200 return 5; 201 else if ((flags & A52_CHANNEL_MASK) == A52_2F2R) 202 return 4; 203 else 204 return 2; 205 } 206 207 void float2s16_multi (float * _f, int16_t * s16, int flags) 208 { 209 int i; 210 int32_t * f = (int32_t *) _f; 211 212 switch (flags) { 213 case A52_MONO: 214 for (i = 0; i < 256; i++) { 215 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; 216 s16[5*i+4] = convert (f[i]); 217 } 218 break; 219 case A52_CHANNEL: 220 case A52_STEREO: 221 case A52_DOLBY: 222 float2s16_2 (_f, s16); 223 break; 224 case A52_3F: 225 for (i = 0; i < 256; i++) { 226 s16[5*i] = convert (f[i]); 227 s16[5*i+1] = convert (f[i+512]); 228 s16[5*i+2] = s16[5*i+3] = 0; 229 s16[5*i+4] = convert (f[i+256]); 230 } 231 break; 232 case A52_2F2R: 233 float2s16_4 (_f, s16); 234 break; 235 case A52_3F2R: 236 float2s16_5 (_f, s16); 237 break; 238 case A52_MONO | A52_LFE: 239 for (i = 0; i < 256; i++) { 240 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; 241 s16[6*i+4] = convert (f[i+256]); 242 s16[6*i+5] = convert (f[i]); 243 } 244 break; 245 case A52_CHANNEL | A52_LFE: 246 case A52_STEREO | A52_LFE: 247 case A52_DOLBY | A52_LFE: 248 for (i = 0; i < 256; i++) { 249 s16[6*i] = convert (f[i+256]); 250 s16[6*i+1] = convert (f[i+512]); 251 s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 252 s16[6*i+5] = convert (f[i]); 253 } 254 break; 255 case A52_3F | A52_LFE: 256 for (i = 0; i < 256; i++) { 257 s16[6*i] = convert (f[i+256]); 258 s16[6*i+1] = convert (f[i+768]); 259 s16[6*i+2] = s16[6*i+3] = 0; 260 s16[6*i+4] = convert (f[i+512]); 261 s16[6*i+5] = convert (f[i]); 262 } 263 break; 264 case A52_2F2R | A52_LFE: 265 for (i = 0; i < 256; i++) { 266 s16[6*i] = convert (f[i+256]); 267 s16[6*i+1] = convert (f[i+512]); 268 s16[6*i+2] = convert (f[i+768]); 269 s16[6*i+3] = convert (f[i+1024]); 270 s16[6*i+4] = 0; 271 s16[6*i+5] = convert (f[i]); 272 } 273 break; 274 case A52_3F2R | A52_LFE: 275 for (i = 0; i < 256; i++) { 276 s16[6*i] = convert (f[i+256]); 277 s16[6*i+1] = convert (f[i+768]); 278 s16[6*i+2] = convert (f[i+1024]); 279 s16[6*i+3] = convert (f[i+1280]); 280 s16[6*i+4] = convert (f[i+512]); 281 s16[6*i+5] = convert (f[i]); 282 } 283 break; 284 } 285 } 286 287 147 288 /**** end */ 148 289 149 290 #define HEADER_SIZE 7 … … 187 329 /* update codec info */ 188 330 avctx->sample_rate = sample_rate; 189 331 s->channels = ac3_channels[s->flags & 7]; 332 if (avctx->cqp >= 0) 333 avctx->channels = avctx->cqp; 190 334 if (s->flags & A52_LFE) 191 335 s->channels++; 192 336 if (avctx->channels == 0) … … 209 353 s->inbuf_ptr += len; 210 354 buf_size -= len; 211 355 } else { 356 int chans; 212 357 flags = s->flags; 213 358 if (avctx->channels == 1) 214 359 flags = A52_MONO; 215 else if (avctx->channels == 2) 216 flags = A52_STEREO; 360 else if (avctx->channels == 2) { 361 if (s->channels>2) 362 flags = A52_DOLBY; 363 else 364 flags = A52_STEREO; 365 } 217 366 else 218 367 flags |= A52_ADJUST_LEVEL; 219 368 level = 1; 369 chans = channels_multi(flags); 220 370 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 221 371 fail: 222 372 av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); … … 227 377 for (i = 0; i < 6; i++) { 228 378 if (s->a52_block(s->state)) 229 379 goto fail; 380 float2s16_multi(s->samples, out_samples + i * 256 * chans, flags); 230 381 } 231 382 s->inbuf_ptr = s->inbuf; 232 383 s->frame_size = 0; 384 *data_size = 6 * chans * 256 * sizeof(int16_t); 233 385 break; 234 386 } 235 387 } -
libs/libavcodec/ac3enc.c
1338 1338 { 1339 1339 AC3EncodeContext *s = avctx->priv_data; 1340 1340 int16_t *samples = data; 1341 // expects L C R LS RS LFE 1342 // audio format is L R LS RS C LFE 1343 static int channel_index[6] = { 0, 4, 1, 2, 3, 5 }; 1344 /* 1345 * A52->Analog->AC3Enc 1346 * 1->0->0 1347 * 3->1->2 1348 * 4->2->3 1349 * 5->3->4 1350 * 2->4->1 1351 * 0->5->5 1352 */ 1341 1353 int i, j, k, v, ch; 1342 1354 int16_t input_samples[N]; 1343 1355 int32_t mdct_coef[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; … … 1358 1370 /* compute input samples */ 1359 1371 memcpy(input_samples, s->last_samples[ch], N/2 * sizeof(int16_t)); 1360 1372 sinc = s->nb_all_channels; 1361 sptr = samples + (sinc * (N/2) * i) + ch ;1373 sptr = samples + (sinc * (N/2) * i) + channel_index[ch]; 1362 1374 for(j=0;j<N/2;j++) { 1363 1375 v = *sptr; 1364 1376 input_samples[j + N/2] = v;