Ticket #1104: mythtv_ac3.12.patch
File mythtv_ac3.12.patch, 75.2 KB (added by , 20 years ago) |
---|
-
libs/libmyth/libmyth.pro
34 34 SOURCES += virtualkeyboard.cpp mythobservable.cpp 35 35 36 36 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. 37 INCLUDEPATH += ../libavutil .. 37 38 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch 39 DEPENDPATH += ../libavutil ../libavcodec 38 40 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
27 27 28 28 // reconfigure sound out for new params 29 29 virtual void Reconfigure(int audio_bits, 30 int audio_channels, int audio_samplerate) = 0; 30 int audio_channels, 31 int audio_samplerate, 32 void* audio_codec = NULL 33 ) = 0; 31 34 32 35 virtual void SetStretchFactor(float factor); 33 36 … … 65 68 protected: 66 69 void Error(QString msg) 67 70 { lastError = msg; VERBOSE(VB_IMPORTANT, lastError); }; 71 void ClearError() 72 { lastError = QString::null; }; 68 73 69 74 private: 70 75 QString lastError; -
libs/libmyth/audiooutputdx.h
21 21 22 22 virtual void Reset(void); 23 23 virtual void Reconfigure(int audio_bits, 24 int audio_channels, int audio_samplerate); 24 int audio_channels, 25 int audio_samplerate 26 AudioCodecMode aom = AUDIOCODECMODE_NORMAL); 25 27 virtual void SetBlocking(bool blocking); 26 28 27 29 virtual bool AddSamples(char *buffer, int samples, long long timecode); -
libs/libmyth/audiooutputdx.cpp
119 119 } 120 120 121 121 void AudioOutputDX::Reconfigure(int audio_bits, 122 int audio_channels, int audio_samplerate) 122 int audio_channels, 123 int audio_samplerate, 124 AudioCodecMode laom 125 ) 123 126 { 124 127 if (dsbuffer) 125 128 DestroyDSBuffer(); -
libs/libmyth/audiooutputbase.h
12 12 #include "samplerate.h" 13 13 #include "SoundTouch.h" 14 14 15 #define AUDBUFSIZE 768000 15 struct AVCodecContext; 16 class DigitalEncoder; 16 17 18 //#define AUDBUFSIZE 768000 19 //divisible by 12,10,8,6,4,2 and around 1024000 20 //#define AUDBUFSIZE 1024080 21 #define AUDBUFSIZE 1536000 22 17 23 class AudioOutputBase : public AudioOutput 18 24 { 19 25 public: … … 24 30 25 31 // reconfigure sound out for new params 26 32 virtual void Reconfigure(int audio_bits, 27 int audio_channels, int audio_samplerate); 33 int audio_channels, 34 int audio_samplerate, 35 void* audio_codec = NULL); 28 36 29 37 // do AddSamples calls block? 30 38 virtual void SetBlocking(bool blocking); … … 52 60 // Send output events showing current progress 53 61 virtual void Status(void); 54 62 55 QString GetError() { return lastError; };63 //QString GetError() { return lastError; }; 56 64 57 65 virtual void SetSourceBitrate(int rate); 58 66 … … 108 116 109 117 float audio_stretchfactor; 110 118 AudioOutputSource source; 119 AVCodecContext *audio_codec; 111 120 112 121 bool killaudio; 113 122 … … 116 125 bool buffer_output_data_for_use; // used by AudioOutputNULL 117 126 118 127 private: 119 QString lastError;128 //QString lastError; 120 129 121 130 // resampler 122 131 bool need_resampler; … … 127 136 128 137 // timestretch 129 138 soundtouch::SoundTouch * pSoundStretch; 139 DigitalEncoder * encoder; 130 140 131 141 bool blocking; // do AddSamples calls block? 132 142 … … 142 152 143 153 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 144 154 'audiotime' and 'audiotime_updated' */ 145 intaudiotime; // timecode of audio leaving the soundcard (same units as155 long long audiotime; // timecode of audio leaving the soundcard (same units as 146 156 // timecodes) ... 147 157 struct timeval audiotime_updated; // ... which was last updated at this time 148 158 149 159 /* Audio circular buffer */ 150 160 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 151 161 int raud, waud; /* read and write positions */ 152 intaudbuf_timecode; /* timecode of audio most recently placed into162 long long audbuf_timecode; /* timecode of audio most recently placed into 153 163 buffer */ 154 164 155 165 int numlowbuffer; -
libs/libmyth/audiooutputbase.cpp
12 12 #include <sys/time.h> 13 13 #include <unistd.h> 14 14 15 extern "C" { 16 #include "libavcodec/avcodec.h" 17 #include "libavcodec/liba52/a52.h" 18 } 15 19 20 #if QT_VERSION < 0x030200 21 #define LONGLONGCONVERT (long) 22 #else 23 #define LONGLONGCONVERT 24 #endif 25 26 #define LOC QString("DEnc: "); 27 #define MAX_AC3_FRAME_SIZE 6144 28 class DigitalEncoder 29 { 30 public: 31 DigitalEncoder(); 32 ~DigitalEncoder(); 33 void Dispose(); 34 bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels); 35 size_t Encode(short * buff); 36 37 // if needed 38 char * GetFrameBuffer() 39 { 40 if (!frame_buffer && av_context) 41 { 42 frame_buffer = new char [one_frame_bytes]; 43 } 44 return frame_buffer; 45 } 46 size_t FrameSize() const { return one_frame_bytes; } 47 char * GetOutBuff() const { return outbuf; } 48 49 size_t audio_bytes_per_sample; 50 private: 51 AVCodecContext *av_context; 52 char * outbuf; 53 char * frame_buffer; 54 int outbuf_size; 55 size_t one_frame_bytes; 56 }; 57 58 DigitalEncoder::DigitalEncoder() 59 { 60 av_context = NULL; 61 outbuf = NULL; 62 outbuf_size = 0; 63 one_frame_bytes = 0; 64 frame_buffer = NULL; 65 } 66 67 DigitalEncoder::~DigitalEncoder() 68 { 69 Dispose(); 70 } 71 72 void DigitalEncoder::Dispose() 73 { 74 if (av_context) 75 { 76 avcodec_close(av_context); 77 av_free(av_context); 78 av_context = NULL; 79 } 80 if (outbuf) 81 { 82 delete [] outbuf; 83 outbuf = NULL; 84 outbuf_size = 0; 85 } 86 if (frame_buffer) 87 { 88 delete [] frame_buffer; 89 frame_buffer = NULL; 90 one_frame_bytes = 0; 91 } 92 } 93 94 //CODEC_ID_AC3 95 bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels) 96 { 97 AVCodec * codec; 98 int ret; 99 100 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4") 101 .arg(codec_id_string(codec_id)) 102 .arg(bitrate) 103 .arg(samplerate) 104 .arg(channels)); 105 //codec = avcodec_find_encoder(codec_id); 106 // always AC3 as there is no DTS encoder at the moment 2005/1/9 107 codec = avcodec_find_encoder(CODEC_ID_AC3); 108 if (!codec) 109 { 110 VERBOSE(VB_IMPORTANT,"Error: could not find codec"); 111 return false; 112 } 113 av_context = avcodec_alloc_context(); 114 av_context->bit_rate = bitrate; 115 av_context->sample_rate = samplerate; 116 av_context->channels = channels; 117 // open it */ 118 if ((ret = avcodec_open(av_context, codec)) < 0) 119 { 120 VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate"); 121 Dispose(); 122 return false; 123 } 124 125 size_t bytes_per_frame = av_context->channels * sizeof(short); 126 audio_bytes_per_sample = bytes_per_frame; 127 one_frame_bytes = bytes_per_frame * av_context->frame_size; 128 129 outbuf_size = 16384; // ok for AC3 but DTS? 130 outbuf = new char [outbuf_size]; 131 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 132 .arg(av_context->frame_size) 133 .arg(bytes_per_frame) 134 .arg(one_frame_bytes) 135 ); 136 137 return true; 138 } 139 140 static int DTS_SAMPLEFREQS[16] = 141 { 142 0, 8000, 16000, 32000, 64000, 128000, 11025, 22050, 143 44100, 88200, 176400, 12000, 24000, 48000, 96000, 192000 144 }; 145 146 static int DTS_BITRATES[30] = 147 { 148 32000, 56000, 64000, 96000, 112000, 128000, 149 192000, 224000, 256000, 320000, 384000, 448000, 150 512000, 576000, 640000, 768000, 896000, 1024000, 151 1152000, 1280000, 1344000, 1408000, 1411200, 1472000, 152 1536000, 1920000, 2048000, 3072000, 3840000, 4096000 153 }; 154 155 static int dts_decode_header(uint8_t *indata_ptr, int *rate, 156 int *nblks, int *sfreq) 157 { 158 uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) | 159 (indata_ptr[2] << 8) | (indata_ptr[3])); 160 161 if (id != 0x7ffe8001) 162 return -1; 163 164 int ftype = indata_ptr[4] >> 7; 165 166 int surp = (indata_ptr[4] >> 2) & 0x1f; 167 surp = (surp + 1) % 32; 168 169 *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2); 170 ++*nblks; 171 172 int fsize = (indata_ptr[5] & 0x03) << 12 | 173 (indata_ptr[6] << 4) | (indata_ptr[7] >> 4); 174 ++fsize; 175 176 *sfreq = (indata_ptr[8] >> 2) & 0x0f; 177 *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07); 178 179 if (ftype != 1) 180 { 181 VERBOSE(VB_IMPORTANT, LOC + 182 QString("DTS: Termination frames not handled (ftype %1)") 183 .arg(ftype)); 184 return -1; 185 } 186 187 if (*sfreq != 13) 188 { 189 VERBOSE(VB_IMPORTANT, LOC + 190 QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq)); 191 return -1; 192 } 193 194 if ((fsize > 8192) || (fsize < 96)) 195 { 196 VERBOSE(VB_IMPORTANT, LOC + 197 QString("DTS: fsize: %1 invalid").arg(fsize)); 198 return -1; 199 } 200 201 if (*nblks != 8 && *nblks != 16 && *nblks != 32 && 202 *nblks != 64 && *nblks != 128 && ftype == 1) 203 { 204 VERBOSE(VB_IMPORTANT, LOC + 205 QString("DTS: nblks %1 not valid for normal frame") 206 .arg(*nblks)); 207 return -1; 208 } 209 210 return fsize; 211 } 212 213 static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/, 214 int *sample_rate, int *bit_rate) 215 { 216 int nblks; 217 int rate; 218 int sfreq; 219 220 int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq); 221 if (fsize >= 0) 222 { 223 if (rate >= 0 && rate <= 29) 224 *bit_rate = DTS_BITRATES[rate]; 225 else 226 *bit_rate = 0; 227 if (sfreq >= 1 && sfreq <= 15) 228 *sample_rate = DTS_SAMPLEFREQS[sfreq]; 229 else 230 *sample_rate = 0; 231 } 232 return fsize; 233 } 234 235 static int encode_frame( 236 bool dts, 237 unsigned char *data, 238 size_t &len) 239 { 240 size_t enc_len; 241 int flags, sample_rate, bit_rate; 242 243 // we don't do any length/crc validation of the AC3 frame here; presumably 244 // the receiver will have enough sense to do that. if someone has a 245 // receiver that doesn't, here would be a good place to put in a call 246 // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the 247 // packet is bad? we'd need to send something that the receiver would 248 // ignore, and if so, may as well just assume that it will ignore 249 // anything with a bad CRC... 250 251 uint nr_samples = 0, block_len; 252 if (dts) 253 { 254 enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate); 255 int rate, sfreq, nblks; 256 dts_decode_header(data+8, &rate, &nblks, &sfreq); 257 nr_samples = nblks * 32; 258 block_len = nr_samples * 2 * 2; 259 } 260 else 261 { 262 enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate); 263 block_len = MAX_AC3_FRAME_SIZE; 264 } 265 266 if (enc_len == 0 || enc_len > len) 267 { 268 int l = len; 269 len = 0; 270 return l; 271 } 272 273 enc_len = min((uint)enc_len, block_len - 8); 274 275 //uint32_t x = *(uint32_t*)(data+8); 276 // in place swab 277 swab(data+8, data+8, enc_len); 278 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, 279 // QString("DigitalEncoder::Encode swab test %1 %2") 280 // .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16)); 281 282 // the following values come from libmpcodecs/ad_hwac3.c in mplayer. 283 // they form a valid IEC958 AC3 header. 284 data[0] = 0x72; 285 data[1] = 0xF8; 286 data[2] = 0x1F; 287 data[3] = 0x4E; 288 data[4] = 0x01; 289 if (dts) 290 { 291 switch(nr_samples) 292 { 293 case 512: 294 data[4] = 0x0B; /* DTS-1 (512-sample bursts) */ 295 break; 296 297 case 1024: 298 data[4] = 0x0C; /* DTS-2 (1024-sample bursts) */ 299 break; 300 301 case 2048: 302 data[4] = 0x0D; /* DTS-3 (2048-sample bursts) */ 303 break; 304 305 default: 306 VERBOSE(VB_IMPORTANT, LOC + 307 QString("DTS: %1-sample bursts not supported") 308 .arg(nr_samples)); 309 data[4] = 0x00; 310 break; 311 } 312 } 313 data[5] = 0x00; 314 data[6] = (enc_len << 3) & 0xFF; 315 data[7] = (enc_len >> 5) & 0xFF; 316 memset(data + 8 + enc_len, 0, block_len - 8 - enc_len); 317 len = block_len; 318 319 return enc_len; 320 } 321 322 // must have exactly 1 frames worth of data 323 size_t DigitalEncoder::Encode(short * buff) 324 { 325 int encsize = 0; 326 size_t outsize = 0; 327 328 // put data in the correct spot for encode frame 329 outsize = avcodec_encode_audio( 330 av_context, 331 ((uchar*)outbuf)+8, 332 outbuf_size-8, 333 buff); 334 size_t tmpsize = outsize; 335 336 outsize = MAX_AC3_FRAME_SIZE; 337 encsize = encode_frame( 338 //av_context->codec_id==CODEC_ID_DTS, 339 false, 340 (unsigned char*)outbuf, outsize); 341 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 342 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 343 .arg(tmpsize) 344 .arg(encsize) 345 .arg(outsize) 346 ); 347 348 return outsize; 349 } 350 #undef LOC 351 #define LOC QString("AO: ") 352 16 353 AudioOutputBase::AudioOutputBase(QString audiodevice, int, 17 354 int, int, 18 355 AudioOutputSource source, bool set_initial_vol) … … 29 366 current_seconds = -1; 30 367 source_bitrate = -1; 31 368 audio_stretchfactor = 1.0; 369 audio_codec = NULL; 32 370 pSoundStretch = NULL; 371 encoder = NULL; 33 372 blocking = false; 34 373 this->source = source; 35 374 this->set_initial_vol = set_initial_vol; … … 78 417 VERBOSE(VB_GENERAL, QString("Using time stretch %1") 79 418 .arg(audio_stretchfactor)); 80 419 pSoundStretch = new soundtouch::SoundTouch(); 81 pSoundStretch->setSampleRate(audio_samplerate); 82 pSoundStretch->setChannels(audio_channels); 420 if (audio_codec) 421 { 422 if (!encoder) 423 { 424 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 425 encoder = new DigitalEncoder(); 426 if (!encoder->Init(audio_codec->codec_id, 427 audio_codec->bit_rate, 428 audio_codec->sample_rate, 429 audio_codec->channels 430 )) 431 { 432 // eeks 433 delete encoder; 434 encoder = NULL; 435 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 436 } 437 } 438 } 439 if (encoder) 440 { 441 pSoundStretch->setSampleRate(audio_codec->sample_rate); 442 pSoundStretch->setChannels(audio_codec->channels); 443 } 444 else 445 { 446 pSoundStretch->setSampleRate(audio_samplerate); 447 pSoundStretch->setChannels(audio_channels); 448 } 83 449 84 450 pSoundStretch->setTempo(audio_stretchfactor); 85 451 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 102 468 } 103 469 104 470 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 105 int laudio_samplerate )471 int laudio_samplerate, void* laudio_codec) 106 472 { 473 int codec_id = CODEC_ID_NONE; 474 int lcodec_id = CODEC_ID_NONE; 475 if (laudio_codec) 476 { 477 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 478 laudio_bits = 16; 479 laudio_channels = 2; 480 laudio_samplerate = 48000; 481 } 482 if (audio_codec) 483 codec_id = audio_codec->codec_id; 484 ClearError(); 107 485 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 108 laudio_samplerate == audio_samplerate && !need_resampler) 486 laudio_samplerate == audio_samplerate && !need_resampler && 487 lcodec_id == codec_id) 109 488 return; 110 489 111 490 KillAudio(); … … 120 499 audio_channels = laudio_channels; 121 500 audio_bits = laudio_bits; 122 501 audio_samplerate = laudio_samplerate; 502 audio_codec = (AVCodecContext*)laudio_codec; 123 503 if (audio_bits != 8 && audio_bits != 16) 124 504 { 125 505 Error("AudioOutput only supports 8 or 16bit audio."); … … 135 515 136 516 numlowbuffer = 0; 137 517 138 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ")139 .arg(audiodevice) );518 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3") 519 .arg(audiodevice).arg(audio_channels).arg(audio_samplerate)); 140 520 141 521 // Actually do the device specific open call 142 522 if (!OpenDevice()) { 143 523 pthread_mutex_unlock(&avsync_lock); 144 524 pthread_mutex_unlock(&audio_buflock); 525 if (GetError().isEmpty()) 526 Error("Aborting reconfigure"); 145 527 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 146 528 return; 147 529 } … … 185 567 } 186 568 187 569 VERBOSE(VB_AUDIO, QString("Audio Stretch Factor: %1").arg(audio_stretchfactor)); 570 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 571 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 188 572 189 573 SetStretchFactorLocked(audio_stretchfactor); 190 574 if (pSoundStretch) 191 575 { 192 pSoundStretch->setSampleRate(audio_samplerate); 193 pSoundStretch->setChannels(audio_channels); 576 // if its passthru then we need to reencode 577 if (audio_codec) 578 { 579 if (!encoder) 580 { 581 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 582 encoder = new DigitalEncoder(); 583 if (!encoder->Init(audio_codec->codec_id, 584 audio_codec->bit_rate, 585 audio_codec->sample_rate, 586 audio_codec->channels 587 )) 588 { 589 // eeks 590 delete encoder; 591 encoder = NULL; 592 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 593 } 594 } 595 } 596 if (encoder) 597 { 598 pSoundStretch->setSampleRate(audio_codec->sample_rate); 599 pSoundStretch->setChannels(audio_codec->channels); 600 } 601 else 602 { 603 pSoundStretch->setSampleRate(audio_samplerate); 604 pSoundStretch->setChannels(audio_channels); 605 } 194 606 } 195 607 196 608 // Setup visualisations, zero the visualisations buffers … … 237 649 pSoundStretch = NULL; 238 650 } 239 651 652 if (encoder) 653 { 654 delete encoder; 655 encoder = NULL; 656 } 657 240 658 CloseDevice(); 241 659 242 660 killAudioLock.unlock(); … … 330 748 The reason is that computing 'audiotime' requires acquiring the audio 331 749 lock, which the video thread should not do. So, we call 'SetAudioTime()' 332 750 from the audio thread, and then call this from the video thread. */ 333 intret;751 long long ret; 334 752 struct timeval now; 335 753 336 754 if (audiotime == 0) … … 342 760 343 761 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 344 762 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 345 ret = ( int)(ret * audio_stretchfactor);763 ret = (long long)(ret * audio_stretchfactor); 346 764 765 #if 1 766 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 767 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 768 .arg(now.tv_sec).arg(now.tv_usec) 769 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 770 .arg(ret) 771 .arg(audiotime) 772 .arg(audio_stretchfactor) 773 ); 774 #endif 775 347 776 ret += audiotime; 348 777 349 778 pthread_mutex_unlock(&avsync_lock); 350 return ret;779 return (int)ret; 351 780 } 352 781 353 782 void AudioOutputBase::SetAudiotime(void) … … 384 813 // include algorithmic latencies 385 814 if (pSoundStretch) 386 815 { 816 // if encoder is active, then use its idea of audiobytes 817 //size_t abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 818 819 // add the effect of any unused but processed samples, AC3 reencode does this 820 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 387 821 // add the effect of unprocessed samples in time stretch algo 388 822 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 389 823 audio_bytes_per_sample) / audio_stretchfactor); 390 824 } 391 825 392 826 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 393 827 (audio_bytes_per_sample * effdspstretched)); 394 828 395 829 gettimeofday(&audiotime_updated, NULL); 830 #if 1 831 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 832 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 833 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 834 .arg(audiotime) 835 .arg(audbuf_timecode) 836 .arg(totalbuffer) 837 .arg(soundcard_buffer) 838 .arg(effdspstretched) 839 .arg(audio_bytes_per_sample) 840 .arg(audio_stretchfactor) 841 ); 842 #endif 396 843 397 844 pthread_mutex_unlock(&avsync_lock); 398 845 pthread_mutex_unlock(&audio_buflock); … … 452 899 // NOTE: This function is not threadsafe 453 900 454 901 int afree = audiofree(true); 455 int len = samples * audio_bytes_per_sample;902 int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 456 903 457 904 // Check we have enough space to write the data 458 905 if (need_resampler && src_ctx) 459 906 len = (int)ceilf(float(len) * src_data.src_ratio); 460 907 if ((len > afree) && !blocking) 908 { 909 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4") 910 .arg(len) 911 .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode)); 461 912 return false; // would overflow 913 } 462 914 463 915 // resample input if necessary 464 916 if (need_resampler && src_ctx) … … 492 944 493 945 int AudioOutputBase::WaitForFreeSpace(int samples) 494 946 { 495 int len = samples * audio_bytes_per_sample; 947 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 948 int len = samples * abps; 496 949 int afree = audiofree(false); 497 950 498 951 while (len > afree) 499 952 { 500 953 if (blocking) 501 954 { 502 VERBOSE(VB_AUDIO , "Waiting for free space");955 VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Waiting for free space"); 503 956 // wait for more space 504 957 pthread_cond_wait(&audio_bufsig, &audio_buflock); 505 958 afree = audiofree(false); 506 959 } 507 960 else 508 961 { 509 VERBOSE(VB_IMPORTANT, "Audio buffer overflow, audio data lost!"); 510 samples = afree / audio_bytes_per_sample; 511 len = samples * audio_bytes_per_sample; 962 VERBOSE(VB_IMPORTANT, 963 QString("Audio buffer overflow, %1 audio samples lost!") 964 .arg(samples-afree / abps)); 965 samples = afree / abps; 966 len = samples * abps; 512 967 if (src_ctx) 513 968 { 514 969 int error = src_reset(src_ctx); … … 533 988 534 989 int afree = audiofree(false); 535 990 536 VERBOSE(VB_AUDIO, QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 537 .arg(samples * audio_bytes_per_sample) 538 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 991 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 992 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5") 993 .arg(samples) 994 .arg(samples * abps) 995 .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode)); 539 996 540 997 len = WaitForFreeSpace(samples); 541 998 … … 572 1029 573 1030 if (pSoundStretch) 574 1031 { 1032 575 1033 // does not change the timecode, only the number of samples 576 1034 // back to orig pos 577 1035 org_waud = waud; 578 1036 int bdiff = AUDBUFSIZE - org_waud; 579 int nSamplesToEnd = bdiff/a udio_bytes_per_sample;1037 int nSamplesToEnd = bdiff/abps; 580 1038 if (bdiff < len) 581 1039 { 582 1040 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 583 1041 org_waud), nSamplesToEnd); 584 1042 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 585 (len - bdiff) / a udio_bytes_per_sample);1043 (len - bdiff) / abps); 586 1044 } 587 1045 else 588 1046 { 589 1047 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 590 org_waud), len / a udio_bytes_per_sample);1048 org_waud), len / abps); 591 1049 } 592 1050 593 int newLen = 0; 594 int nSamples; 595 len = WaitForFreeSpace(pSoundStretch->numSamples() * 596 audio_bytes_per_sample); 597 do 1051 if (encoder) 598 1052 { 599 int samplesToGet = len/audio_bytes_per_sample; 600 if (samplesToGet > nSamplesToEnd) 1053 // pull out a packet's worth and reencode it until we dont have enough 1054 // for any more packets 1055 soundtouch::SAMPLETYPE* temp_buff = 1056 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 1057 size_t frameSize = encoder->FrameSize()/abps; 1058 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1059 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 1060 .arg(frameSize) 1061 .arg(encoder->FrameSize()) 1062 .arg(pSoundStretch->numSamples()) 1063 ); 1064 // process the same number of samples as it creates a full encoded buffer 1065 // just like before 1066 while (pSoundStretch->numSamples() >= frameSize) 601 1067 { 602 samplesToGet = nSamplesToEnd; 1068 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 1069 int amount = encoder->Encode(temp_buff); 1070 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1071 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 1072 .arg(amount) 1073 .arg(got) 1074 .arg(pSoundStretch->numSamples()) 1075 ); 1076 if (amount == 0) 1077 continue; 1078 //len = WaitForFreeSpace(amount); 1079 char * ob = encoder->GetOutBuff(); 1080 if (amount >= bdiff) 1081 { 1082 memcpy(audiobuffer + org_waud, ob, bdiff); 1083 ob += bdiff; 1084 amount -= bdiff; 1085 org_waud = 0; 1086 } 1087 if (amount > 0) 1088 memcpy(audiobuffer + org_waud, ob, amount); 1089 bdiff = AUDBUFSIZE - amount; 1090 org_waud += amount; 603 1091 } 604 605 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 606 (audiobuffer + org_waud), samplesToGet); 607 if (nSamples == nSamplesToEnd) 1092 } 1093 else 1094 { 1095 int newLen = 0; 1096 int nSamples; 1097 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1098 audio_bytes_per_sample); 1099 do 608 1100 { 609 org_waud = 0; 610 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 611 } 612 else 613 { 614 org_waud += nSamples * audio_bytes_per_sample; 615 nSamplesToEnd -= nSamples; 616 } 1101 int samplesToGet = len/audio_bytes_per_sample; 1102 if (samplesToGet > nSamplesToEnd) 1103 { 1104 samplesToGet = nSamplesToEnd; 1105 } 617 1106 618 newLen += nSamples * audio_bytes_per_sample; 619 len -= nSamples * audio_bytes_per_sample; 620 } while (nSamples > 0); 1107 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 1108 (audiobuffer + org_waud), samplesToGet); 1109 if (nSamples == nSamplesToEnd) 1110 { 1111 org_waud = 0; 1112 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1113 } 1114 else 1115 { 1116 org_waud += nSamples * audio_bytes_per_sample; 1117 nSamplesToEnd -= nSamples; 1118 } 1119 1120 newLen += nSamples * audio_bytes_per_sample; 1121 len -= nSamples * audio_bytes_per_sample; 1122 } while (nSamples > 0); 1123 } 621 1124 } 622 1125 623 1126 waud = org_waud; … … 687 1190 space_on_soundcard = getSpaceOnSoundcard(); 688 1191 689 1192 if (space_on_soundcard != last_space_on_soundcard) { 690 VERBOSE(VB_AUDIO , QString("%1 bytes free on soundcard")1193 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("%1 bytes free on soundcard") 691 1194 .arg(space_on_soundcard)); 692 1195 last_space_on_soundcard = space_on_soundcard; 693 1196 } … … 700 1203 WriteAudio(zeros, fragment_size); 701 1204 } else { 702 1205 // this should never happen now -dag 703 VERBOSE(VB_AUDIO ,1206 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 704 1207 QString("waiting for space on soundcard " 705 1208 "to write zeros: have %1 need %2") 706 1209 .arg(space_on_soundcard).arg(fragment_size)); … … 736 1239 if (fragment_size > audiolen(true)) 737 1240 { 738 1241 if (audiolen(true) > 0) // only log if we're sending some audio 739 VERBOSE(VB_AUDIO ,1242 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 740 1243 QString("audio waiting for buffer to fill: " 741 1244 "have %1 want %2") 742 1245 .arg(audiolen(true)).arg(fragment_size)); 743 1246 744 VERBOSE(VB_AUDIO, "Broadcasting free space avail");1247 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail"); 745 1248 pthread_mutex_lock(&audio_buflock); 746 1249 pthread_cond_broadcast(&audio_bufsig); 747 1250 pthread_mutex_unlock(&audio_buflock); … … 755 1258 if (fragment_size > space_on_soundcard) 756 1259 { 757 1260 if (space_on_soundcard != last_space_on_soundcard) { 758 VERBOSE(VB_AUDIO ,1261 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 759 1262 QString("audio waiting for space on soundcard: " 760 1263 "have %1 need %2") 761 1264 .arg(space_on_soundcard).arg(fragment_size)); … … 817 1320 818 1321 /* update raud */ 819 1322 raud = (raud + fragment_size) % AUDBUFSIZE; 820 VERBOSE(VB_AUDIO, "Broadcasting free space avail");1323 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail"); 821 1324 pthread_cond_broadcast(&audio_bufsig); 822 1325 823 1326 written_size = fragment_size; -
libs/libmyth/audiooutputalsa.cpp
75 75 } 76 76 else 77 77 { 78 fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 78 //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 79 //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits 80 fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30); 79 81 buffer_time = 500000; // .5 seconds 80 82 period_time = buffer_time / 4; // 4 interrupts per buffer 81 83 } … … 148 150 149 151 tmpbuf = aubuf; 150 152 151 VERBOSE(VB_AUDIO , QString("WriteAudio: Preparing %1 bytes (%2 frames)")153 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 152 154 .arg(size).arg(frames)); 153 155 154 156 while (frames > 0) -
libs/libmythsoundtouch/TDStretch.cpp
96 96 97 97 pMidBuffer = NULL; 98 98 pRefMidBufferUnaligned = NULL; 99 midBufferLength = 0; 99 100 overlapLength = 0; 100 101 101 102 setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS); … … 108 109 109 110 TDStretch::~TDStretch() 110 111 { 111 delete[] pMidBuffer; 112 delete[] pRefMidBufferUnaligned; 112 if (midBufferLength) 113 { 114 delete[] pMidBuffer; 115 delete[] pRefMidBufferUnaligned; 116 midBufferLength = 0; 117 } 113 118 } 114 119 115 120 … … 196 201 197 202 void TDStretch::clearMidBuffer() 198 203 { 199 if (bMidBufferDirty )204 if (bMidBufferDirty && midBufferLength) 200 205 { 201 memset(pMidBuffer, 0, 2* sizeof(SAMPLETYPE) * overlapLength);206 memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength); 202 207 bMidBufferDirty = FALSE; 203 208 } 204 209 } … … 239 244 // Seeks for the optimal overlap-mixing position. 240 245 uint TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos) 241 246 { 247 #ifdef MULTICHANNEL 248 if (channels > 2) 249 { 250 // stereo sound 251 if (bQuickseek) 252 { 253 return seekBestOverlapPositionMultiQuick(refPos); 254 } 255 else 256 { 257 return seekBestOverlapPositionMulti(refPos); 258 } 259 } 260 else 261 #endif 242 262 if (channels == 2) 243 263 { 244 264 // stereo sound … … 272 292 // of 'ovlPos'. 273 293 inline void TDStretch::overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const 274 294 { 295 #ifdef MULTICHANNEL 296 if (channels > 2) 297 { 298 overlapMulti(output, input + channels * ovlPos); 299 } 300 else 301 #endif 275 302 if (channels == 2) 276 303 { 277 304 // stereo sound … … 291 318 // The best position is determined as the position where the two overlapped 292 319 // sample sequences are 'most alike', in terms of the highest cross-correlation 293 320 // value over the overlapping period 321 uint TDStretch::seekBestOverlapPositionMulti(const SAMPLETYPE *refPos) 322 { 323 uint bestOffs; 324 LONG_SAMPLETYPE bestCorr, corr; 325 uint i; 326 327 // Slopes the amplitudes of the 'midBuffer' samples 328 precalcCorrReference(); 329 330 bestCorr = INT_MIN; 331 bestOffs = 0; 332 333 // Scans for the best correlation value by testing each possible position 334 // over the permitted range. 335 for (i = 0; i < seekLength; i ++) 336 { 337 // Calculates correlation value for the mixing position corresponding 338 // to 'i' 339 corr = calcCrossCorrMulti(refPos + channels * i, pRefMidBuffer); 340 341 // Checks for the highest correlation value 342 if (corr > bestCorr) 343 { 344 bestCorr = corr; 345 bestOffs = i; 346 } 347 } 348 // clear cross correlation routine state if necessary (is so e.g. in MMX routines). 349 clearCrossCorrState(); 350 351 return bestOffs; 352 } 353 354 355 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the 356 // routine 357 // 358 // The best position is determined as the position where the two overlapped 359 // sample sequences are 'most alike', in terms of the highest cross-correlation 360 // value over the overlapping period 361 uint TDStretch::seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos) 362 { 363 uint j; 364 uint bestOffs; 365 LONG_SAMPLETYPE bestCorr, corr; 366 uint scanCount, corrOffset, tempOffset; 367 368 // Slopes the amplitude of the 'midBuffer' samples 369 precalcCorrReference(); 370 371 bestCorr = INT_MIN; 372 bestOffs = 0; 373 corrOffset = 0; 374 tempOffset = 0; 375 376 // Scans for the best correlation value using four-pass hierarchical search. 377 // 378 // The look-up table 'scans' has hierarchical position adjusting steps. 379 // In first pass the routine searhes for the highest correlation with 380 // relatively coarse steps, then rescans the neighbourhood of the highest 381 // correlation with better resolution and so on. 382 for (scanCount = 0;scanCount < 4; scanCount ++) 383 { 384 j = 0; 385 while (scanOffsets[scanCount][j]) 386 { 387 tempOffset = corrOffset + scanOffsets[scanCount][j]; 388 if (tempOffset >= seekLength) break; 389 390 // Calculates correlation value for the mixing position corresponding 391 // to 'tempOffset' 392 corr = calcCrossCorrMulti(refPos + channels * tempOffset, pRefMidBuffer); 393 394 // Checks for the highest correlation value 395 if (corr > bestCorr) 396 { 397 bestCorr = corr; 398 bestOffs = tempOffset; 399 } 400 j ++; 401 } 402 corrOffset = bestOffs; 403 } 404 // clear cross correlation routine state if necessary (is so e.g. in MMX routines). 405 clearCrossCorrState(); 406 407 return bestOffs; 408 } 409 410 411 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the 412 // routine 413 // 414 // The best position is determined as the position where the two overlapped 415 // sample sequences are 'most alike', in terms of the highest cross-correlation 416 // value over the overlapping period 294 417 uint TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos) 295 418 { 296 419 uint bestOffs; … … 512 635 void TDStretch::setChannels(uint numChannels) 513 636 { 514 637 if (channels == numChannels) return; 638 #ifdef MULTICHANNEL 639 assert(numChannels >= 1 && numChannels <= MULTICHANNEL); 640 #else 515 641 assert(numChannels == 1 || numChannels == 2); 642 #endif 516 643 517 644 channels = numChannels; 518 645 inputBuffer.setChannels(channels); … … 635 762 /// Set new overlap length parameter & reallocate RefMidBuffer if necessary. 636 763 void TDStretch::acceptNewOverlapLength(uint newOverlapLength) 637 764 { 638 uint prevOvl;765 //uint prevOvl; 639 766 640 prevOvl = overlapLength;767 //prevOvl = overlapLength; 641 768 overlapLength = newOverlapLength; 642 769 643 if (overlapLength > prevOvl) 770 //if (overlapLength > prevOvl) 771 if (overlapLength*channels > midBufferLength) 644 772 { 645 delete[] pMidBuffer; 646 delete[] pRefMidBufferUnaligned; 773 if (midBufferLength) 774 { 775 delete[] pMidBuffer; 776 delete[] pRefMidBufferUnaligned; 777 midBufferLength = 0; 778 } 647 779 648 pMidBuffer = new SAMPLETYPE[overlapLength * 2];780 pMidBuffer = new SAMPLETYPE[overlapLength * channels]; 649 781 bMidBufferDirty = TRUE; 650 782 clearMidBuffer(); 783 midBufferLength = overlapLength * channels; 651 784 652 pRefMidBufferUnaligned = new SAMPLETYPE[ 2* overlapLength + 16 / sizeof(SAMPLETYPE)];785 pRefMidBufferUnaligned = new SAMPLETYPE[channels * overlapLength + 16 / sizeof(SAMPLETYPE)]; 653 786 // ensure that 'pRefMidBuffer' is aligned to 16 byte boundary for efficiency 654 787 pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & -16); 655 788 } … … 718 851 719 852 #ifdef INTEGER_SAMPLES 720 853 854 #ifdef MULTICHANNEL 721 855 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation 722 856 // is faster to calculate 857 void TDStretch::precalcCorrReference() 858 { 859 int i,j; 860 int temp, temp2; 861 short *src = pMidBuffer; 862 short *dest = pRefMidBuffer; 863 864 for (i=0 ; i < (int)overlapLength ;i ++) 865 { 866 temp = i * (overlapLength - i); 867 868 for(j=0;j<channels;j++) 869 { 870 temp2 = (*src++ * temp) / slopingDivider; 871 *dest++ = (short)(temp2); 872 } 873 } 874 } 875 #endif 876 877 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation 878 // is faster to calculate 723 879 void TDStretch::precalcCorrReferenceStereo() 724 880 { 725 881 int i, cnt2; … … 772 928 } 773 929 } 774 930 931 #ifdef MULTICHANNEL 932 // Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo' 933 // version of the routine. 934 void TDStretch::overlapMulti(short *output, const short *input) const 935 { 936 int i,j; 937 short temp; 938 //uint cnt2; 939 const short *ip = input; 940 short *op = output; 941 const short *md = pMidBuffer; 775 942 943 for (i = 0; i < (int)overlapLength ; i ++) 944 { 945 temp = (short)(overlapLength - i); 946 for(j=0;j<channels;j++) 947 *op++ = (*ip++ * i + *md++ * temp ) / overlapLength; 948 } 949 } 950 #endif 951 952 776 953 /// Calculates overlap period length in samples. 777 954 /// Integer version rounds overlap length to closest power of 2 778 955 /// for a divide scaling operation. … … 824 1001 return corr; 825 1002 } 826 1003 1004 #ifdef MULTICHANNEL 1005 long TDStretch::calcCrossCorrMulti(const short *mixingPos, const short *compare) const 1006 { 1007 long corr; 1008 uint i; 1009 1010 corr = 0; 1011 for (i = channels; i < channels * overlapLength; i++) 1012 { 1013 corr += (mixingPos[i] * compare[i]) >> overlapDividerBits; 1014 } 1015 1016 return corr; 1017 } 1018 #endif 1019 827 1020 #endif // INTEGER_SAMPLES 828 1021 829 1022 ////////////////////////////////////////////////////////////////////////////// … … 931 1124 return corr; 932 1125 } 933 1126 934 #endif // FLOAT_SAMPLES 935 No newline at end of file 1127 #endif // FLOAT_SAMPLES -
libs/libmythsoundtouch/TDStretch.h
100 100 SAMPLETYPE *pMidBuffer; 101 101 SAMPLETYPE *pRefMidBuffer; 102 102 SAMPLETYPE *pRefMidBufferUnaligned; 103 uint midBufferLength; 103 104 uint overlapLength; 104 105 uint overlapDividerBits; 105 106 uint slopingDivider; … … 123 124 virtual void clearCrossCorrState(); 124 125 void calculateOverlapLength(uint overlapMs); 125 126 127 #ifdef MULTICHANNEL 128 virtual LONG_SAMPLETYPE calcCrossCorrMulti(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 129 #endif 126 130 virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 127 131 virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 128 132 133 #ifdef MULTICHANNEL 134 virtual uint seekBestOverlapPositionMulti(const SAMPLETYPE *refPos); 135 virtual uint seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos); 136 #endif 129 137 virtual uint seekBestOverlapPositionStereo(const SAMPLETYPE *refPos); 130 138 virtual uint seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos); 131 139 virtual uint seekBestOverlapPositionMono(const SAMPLETYPE *refPos); 132 140 virtual uint seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos); 133 141 uint seekBestOverlapPosition(const SAMPLETYPE *refPos); 134 142 143 #ifdef MULTICHANNEL 144 virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const; 145 #endif 135 146 virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const; 136 147 virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const; 137 148 138 149 void clearMidBuffer(); 139 150 void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const; 140 151 152 #ifdef MULTICHANNEL 153 void precalcCorrReference(); 154 #endif 141 155 void precalcCorrReferenceMono(); 142 156 void precalcCorrReferenceStereo(); 143 157 … … 225 239 class TDStretchMMX : public TDStretch 226 240 { 227 241 protected: 242 #ifdef MULTICHANNEL 243 //long calcCrossCorrMulti(const short *mixingPos, const short *compare) const; 244 #endif 228 245 long calcCrossCorrStereo(const short *mixingPos, const short *compare) const; 229 246 virtual void overlapStereo(short *output, const short *input) const; 230 247 virtual void clearCrossCorrState(); … … 237 254 class TDStretch3DNow : public TDStretch 238 255 { 239 256 protected: 257 #ifdef MULTICHANNEL 258 //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const; 259 #endif 240 260 double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; 241 261 }; 242 262 #endif /// ALLOW_3DNOW … … 247 267 class TDStretchSSE : public TDStretch 248 268 { 249 269 protected: 270 #ifdef MULTICHANNEL 271 //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const; 272 #endif 250 273 double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; 251 274 }; 252 275 -
libs/libmythsoundtouch/RateTransposer.cpp
330 330 { 331 331 if (uChannels == numchannels) return; 332 332 333 #ifdef MULTICHANNEL 334 assert(numchannels >= 1 && numchannels <= MULTICHANNEL); 335 #else 333 336 assert(numchannels == 1 || numchannels == 2); 337 #endif 334 338 uChannels = numchannels; 335 339 336 340 storeBuffer.setChannels(uChannels); -
libs/libmythsoundtouch/STTypes.h
61 61 #define INTEGER_SAMPLES //< 16bit integer samples 62 62 //#define FLOAT_SAMPLES //< 32bit float samples 63 63 64 #define MULTICHANNEL 6 64 65 65 66 /// Define this to allow CPU-specific assembler optimizations. Notice that 66 67 /// having this enabled on non-x86 platforms doesn't matter; the compiler can -
libs/libmythsoundtouch/SoundTouch.cpp
140 140 // Sets the number of channels, 1 = mono, 2 = stereo 141 141 void SoundTouch::setChannels(uint numChannels) 142 142 { 143 #ifdef MULTICHANNEL 144 if (numChannels < 1 || numChannels > MULTICHANNEL) 145 #else 143 146 if (numChannels != 1 && numChannels != 2) 147 #endif 144 148 { 145 149 throw std::runtime_error("Illegal number of channels"); 146 150 } -
programs/mythfrontend/globalsettings.cpp
36 36 dev.setNameFilter("adsp*"); 37 37 gc->fillSelectionsFromDir(dev); 38 38 } 39 #ifdef USE_ALSA 40 gc->addSelection("ALSA:default", "ALSA:default"); 41 gc->addSelection("ALSA:analog", "ALSA:analog"); 42 gc->addSelection("ALSA:digital", "ALSA:digital"); 43 gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog"); 44 gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital"); 45 #endif 46 #ifdef USE_ARTS 47 gc->addSelection("ARTS:", "ARTS:"); 48 #endif 49 #ifdef USE_JACK 50 gc->addSelection("JACK:output", "JACK:output"); 51 #endif 52 gc->addSelection("NULL", "NULL"); 39 53 40 54 return gc; 41 55 } 42 56 57 static HostComboBox *MaxAudioChannels() 58 { 59 HostComboBox *gc = new HostComboBox("MaxChannels",false); 60 gc->setLabel(QObject::tr("Max Audio Channels")); 61 gc->addSelection(QObject::tr("Mono"), "1"); 62 gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default 63 gc->addSelection(QObject::tr("3 Channel: L C R"), "3"); 64 gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4"); 65 gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5"); 66 gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6"); 67 gc->setHelpText( 68 QObject::tr("Set the maximum number of audio channels to be decoded. " 69 "This is for multi-channel/surround audio playback.")); 70 return gc; 71 } 72 43 73 static HostCheckBox *MythControlsVolume() 44 74 { 45 75 HostCheckBox *gc = new HostCheckBox("MythControlsVolume"); … … 2092 2122 setUseLabel(false); 2093 2123 2094 2124 addChild(AudioOutputDevice()); 2125 #if 0 2126 ConfigurationGroup *hg = new HorizontalConfigurationGroup(false, false); 2127 ConfigurationGroup* settingsLeft = new VerticalConfigurationGroup(false,false); 2128 settingsLeft->addChild(AC3PassThrough()); 2129 #ifdef CONFIG_DTS 2130 settingsLeft->addChild(DTSPassThrough()); 2131 #endif 2132 settingsLeft->addChild(AggressiveBuffer()); 2133 hg->addChild(settingsLeft); 2134 2135 ConfigurationGroup* settingsRight = new VerticalConfigurationGroup(false,false); 2136 settingsRight->addChild(MaxAudioChannels()); 2137 hg->addChild(settingsRight); 2138 2139 addChild(hg); 2140 #else 2095 2141 addChild(AC3PassThrough()); 2096 2142 #ifdef CONFIG_DTS 2097 2143 addChild(DTSPassThrough()); 2098 2144 #endif 2099 2145 addChild(AggressiveBuffer()); 2146 addChild(MaxAudioChannels()); 2147 #endif 2100 2148 2101 2149 Setting* volumeControl = MythControlsVolume(); 2102 2150 addChild(volumeControl); -
programs/mythtranscode/transcode.cpp
46 46 47 47 // reconfigure sound out for new params 48 48 virtual void Reconfigure(int audio_bits, 49 int audio_channels, int audio_samplerate) 49 int audio_channels, int audio_samplerate, 50 void * = NULL) 50 51 { 52 ClearError(); 51 53 (void)audio_samplerate; 52 54 bits = audio_bits; 53 55 channels = audio_channels; 54 56 bytes_per_sample = bits * channels / 8; 57 if (channels>2) 58 Error("Invalid channel count"); 55 59 } 56 60 57 61 // dsprate is in 100 * samples/second -
libs/libmythtv/avformatdecoder.h
238 238 bool allow_ac3_passthru; 239 239 bool allow_dts_passthru; 240 240 bool disable_passthru; 241 int max_channels; 241 242 242 243 AudioInfo audioIn; 243 244 AudioInfo audioOut; -
libs/libmythtv/avformatdecoder.cpp
38 38 #define MAX_AC3_FRAME_SIZE 6144 39 39 40 40 /** Set to zero to allow any number of AC3 channels. */ 41 #define MAXCHANNELSELECT 1 42 #if MAXCHANNELSELECT 43 #define MAX_OUTPUT_CHANNELS compiler error 44 #else 41 45 #define MAX_OUTPUT_CHANNELS 2 46 #endif 42 47 #define VB_AUDIO VB_IMPORTANT 43 48 static int dts_syncinfo(uint8_t *indata_ptr, int *flags, 44 49 int *sample_rate, int *bit_rate); … … 286 291 #ifdef CONFIG_DTS 287 292 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 288 293 #endif 294 max_channels = gContext->GetNumSetting("MaxChannels", 2); 289 295 290 296 audioIn.sample_size = -32; // force SetupAudioStream to run once 291 297 } … … 406 412 framesPlayed = lastKey; 407 413 framesRead = lastKey; 408 414 415 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") 416 .arg(desiredFrame) 417 .arg(fps) 418 .arg(ts) 419 .arg(discardFrames) 420 .arg(framesPlayed) 421 .arg(st->cur_dts) 422 .arg(adj_cur_dts) 423 .arg(newts) 424 .arg(frameseekadjust) 425 ); 426 409 427 int normalframes = desiredFrame - framesPlayed; 410 428 429 #if 0 430 if (!exactseeks) 431 normalframes = 0; 432 #endif 433 411 434 SeekReset(lastKey, normalframes, discardFrames, discardFrames); 412 435 413 436 if (discardFrames) … … 739 762 740 763 fmt->flags &= ~AVFMT_NOFILE; 741 764 765 #if 1 766 if ((m_playbackinfo) || livetv || watchingrecording) 767 { 768 const char *name = ic->av_class->item_name(ic); 769 VERBOSE(VB_GENERAL, QString("libavformat type %1").arg(name)); 770 } 771 #endif 772 773 //struct timeval one, two, res; 774 //gettimeofday(&one, NULL); 775 742 776 av_estimate_timings(ic); 743 777 av_read_frame_flush(ic); 744 778 … … 769 803 // If we don't have a position map, set up ffmpeg for seeking 770 804 if (!recordingHasPositionMap) 771 805 { 806 const char *name = ic->av_class->item_name(ic); 772 807 VERBOSE(VB_PLAYBACK, LOC + 773 "Recording has no position -- using libavformat seeking.");808 QString("Recording has no position -- using libavformat seeking. %1").arg(name)); 774 809 int64_t dur = ic->duration / (int64_t)AV_TIME_BASE; 775 810 776 811 if (dur > 0) … … 1048 1083 <<") already open, leaving it alone."); 1049 1084 } 1050 1085 assert(enc->codec_id); 1086 VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels)); 1087 #if 0 1088 if (enc->channels > 2) 1089 enc->channels = 2; 1090 #endif 1051 1091 1092 #if 0 1052 1093 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1053 1094 if (enc->codec_id == CODEC_ID_DTS) 1054 1095 { … … 1057 1098 // enc->bit_rate = what??; 1058 1099 } 1059 1100 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1101 #endif 1060 1102 1061 1103 bitrate += enc->bit_rate; 1062 1104 break; … … 1557 1599 { 1558 1600 long long startpos = pkt->pos; 1559 1601 1560 VERBOSE(VB_PLAYBACK , LOC +1602 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + 1561 1603 QString("positionMap[ %1 ] == %2.") 1562 1604 .arg(prevgoppos / keyframedist) 1563 1605 .arg((int)startpos)); … … 2262 2304 2263 2305 AVStream *curstream = ic->streams[pkt->stream_index]; 2264 2306 2307 #if 0 2308 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("timecode pts:%1 dts:%2 codec:%3") 2309 .arg(pkt->pts) 2310 .arg(pkt->dts) 2311 .arg((curstream && curstream->codec)?curstream->codec->codec_type:-1) 2312 ); 2313 #endif 2314 2265 2315 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 2266 2316 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 2267 2317 … … 2375 2425 if (!curstream->codec->channels) 2376 2426 { 2377 2427 QMutexLocker locker(&avcodeclock); 2428 #if MAXCHANNELSELECT 2429 VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels)); 2430 curstream->codec->channels = audioOut.channels; 2431 #else 2378 2432 curstream->codec->channels = MAX_OUTPUT_CHANNELS; 2433 #endif 2379 2434 ret = avcodec_decode_audio( 2380 2435 curstream->codec, audioSamples, 2381 2436 &data_size, ptr, len); … … 2426 2481 { 2427 2482 AVCodecContext *ctx = curstream->codec; 2428 2483 2484 #if MAXCHANNELSELECT 2429 2485 if ((ctx->channels == 0) || 2486 (ctx->channels > audioOut.channels)) 2487 ctx->channels = audioOut.channels; 2488 #else 2489 if ((ctx->channels == 0) || 2430 2490 (ctx->channels > MAX_OUTPUT_CHANNELS)) 2431 2491 ctx->channels = MAX_OUTPUT_CHANNELS; 2492 #endif 2432 2493 2433 2494 ret = avcodec_decode_audio( 2434 2495 ctx, audioSamples, &data_size, ptr, len); … … 2464 2525 (curstream->codec->channels * 2) / 2465 2526 curstream->codec->sample_rate); 2466 2527 2528 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("audio timecode %1 %2 %3 %4") 2529 .arg(pkt->pts) 2530 .arg(pkt->dts) 2531 .arg(temppts).arg(lastapts)); 2467 2532 GetNVP()->AddAudioData((char *)audioSamples, data_size, 2468 2533 temppts); 2469 2534 … … 2555 2620 else 2556 2621 temppts = lastvpts; 2557 2622 2623 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("video timecode %1 %2 %3 %4") 2624 .arg(pkt->pts) 2625 .arg(pkt->dts) 2626 .arg(temppts).arg(lastvpts)); 2558 2627 /* XXX: Broken. 2559 2628 if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 && 2560 2629 context->height == picframe->height) … … 2649 2718 2650 2719 void AvFormatDecoder::SetDisablePassThrough(bool disable) 2651 2720 { 2721 #if MAXCHANNELSELECT 2722 // can only disable never reenable as once tiemstretch is on its on for the session 2723 if (disable_passthru) 2724 return; 2725 #endif 2652 2726 if (selectedAudioStream.av_stream_index < 0) 2653 2727 { 2654 2728 disable_passthru = disable; 2655 2729 return; 2656 2730 } 2657 2731 2658 2732 if (disable != disable_passthru) 2659 2733 { 2660 2734 disable_passthru = disable; … … 2681 2755 AVCodecContext *codec_ctx = NULL; 2682 2756 AudioInfo old_in = audioIn; 2683 2757 AudioInfo old_out = audioOut; 2758 bool using_passthru = false; 2684 2759 2685 2760 if ((currentAudioTrack >= 0) && 2686 2761 (selectedAudioStream.av_stream_index <= ic->nb_streams) && … … 2690 2765 assert(curstream->codec); 2691 2766 codec_ctx = curstream->codec; 2692 2767 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 2693 !disable_passthru &&2694 2768 (codec_ctx->codec_id == CODEC_ID_AC3)); 2695 2769 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 2696 !disable_passthru &&2697 2770 (codec_ctx->codec_id == CODEC_ID_DTS)); 2771 using_passthru = do_ac3_passthru || do_dts_passthru; 2698 2772 info = AudioInfo(codec_ctx->codec_id, 2699 2773 codec_ctx->sample_rate, codec_ctx->channels, 2700 do_ac3_passthru || do_dts_passthru);2774 using_passthru && !disable_passthru); 2701 2775 } 2702 2776 2703 2777 if (info == audioIn) 2704 2778 return false; // no change 2705 2779 2780 QString ptmsg = ""; 2781 if (using_passthru) 2782 { 2783 ptmsg = QString(" using passthru"); 2784 } 2706 2785 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 2707 QString("audio track #%1").arg(currentAudioTrack+1)); 2786 QString("audio track #%1") 2787 .arg(currentAudioTrack+1) 2788 + ptmsg ); 2708 2789 2709 2790 audioOut = audioIn = info; 2791 #if MAXCHANNELSELECT 2792 if (using_passthru) 2793 #else 2710 2794 if (audioIn.do_passthru) 2795 #endif 2711 2796 { 2712 2797 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 2713 audioOut.channels = 2; 2714 audioOut.sample_rate = 48000; 2715 audioOut.sample_size = 4; 2798 AudioInfo digInfo = audioOut; 2799 if (!disable_passthru) 2800 { 2801 digInfo.channels = 2; 2802 digInfo.sample_rate = 48000; 2803 digInfo.sample_size = 4; 2804 } 2805 if (audioOut.channels > max_channels) 2806 { 2807 audioOut.channels = max_channels; 2808 audioOut.sample_size = audioOut.channels * 2; 2809 codec_ctx->channels = audioOut.channels; 2810 } 2811 #if MAXCHANNELSELECT 2812 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 2813 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 2814 .arg(digInfo.toString()) 2815 .arg(old_in.toString()).arg(old_out.toString()) 2816 .arg(audioIn.toString()).arg(audioOut.toString())); 2817 2818 if (digInfo.sample_rate > 0) 2819 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 2820 2821 //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 2822 // audioOut.sample_rate); 2823 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 2824 digInfo.sample_rate); 2825 // allow the audio stuff to reencode 2826 GetNVP()->SetAudioCodec(codec_ctx); 2827 GetNVP()->ReinitAudio(); 2828 return true; 2829 #endif 2716 2830 } 2831 #if MAXCHANNELSELECT 2717 2832 else 2718 2833 { 2834 if (audioOut.channels > max_channels) 2835 { 2836 audioOut.channels = max_channels; 2837 audioOut.sample_size = audioOut.channels * 2; 2838 codec_ctx->channels = audioOut.channels; 2839 } 2840 } 2841 bool audiook; 2842 do 2843 { 2844 #else 2845 else 2846 { 2719 2847 if (audioOut.channels > MAX_OUTPUT_CHANNELS) 2720 2848 { 2721 2849 audioOut.channels = MAX_OUTPUT_CHANNELS; … … 2723 2851 codec_ctx->channels = MAX_OUTPUT_CHANNELS; 2724 2852 } 2725 2853 } 2854 #endif 2726 2855 2727 2856 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 2728 2857 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") … … 2734 2863 2735 2864 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 2736 2865 audioOut.sample_rate); 2737 GetNVP()->ReinitAudio(); 2866 // allow the audio stuff to reencode 2867 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 2868 QString errMsg = GetNVP()->ReinitAudio(); 2869 #if MAXCHANNELSELECT 2870 audiook = errMsg.isEmpty(); 2871 if (!audiook) 2872 { 2873 switch (audioOut.channels) 2874 { 2875 #if 0 2876 case 8: 2877 audioOut.channels = 6; 2878 break; 2879 #endif 2880 case 6: 2881 audioOut.channels = 5; 2882 break; 2883 case 5: 2884 audioOut.channels = 4; 2885 break; 2886 case 4: 2887 audioOut.channels = 3; 2888 break; 2889 case 3: 2890 audioOut.channels = 2; 2891 break; 2892 case 2: 2893 audioOut.channels = 1; 2894 break; 2895 default: 2896 // failed to reconfigure under any circumstances 2897 audiook = true; 2898 audioOut.channels = 0; 2899 break; 2900 } 2901 audioOut.sample_size = audioOut.channels * 2; 2902 codec_ctx->channels = audioOut.channels; 2903 } 2904 } while (!audiook); 2905 #endif 2738 2906 2739 2907 return true; 2740 2908 } -
libs/libmythtv/NuppelVideoPlayer.h
107 107 float a = 1.33333, FrameScanType scan = kScan_Ignore, 108 108 bool reinit = false); 109 109 void SetAudioParams(int bits, int channels, int samplerate); 110 void SetAudioCodec(void *ac); 110 111 void SetEffDsp(int dsprate); 111 112 void SetFileLength(int total, int frames); 112 113 void Zoom(int direction); … … 142 143 bool AtNormalSpeed(void) const { return next_normal_speed; } 143 144 bool IsDecoderThreadAlive(void) const { return decoder_thread_alive; } 144 145 bool IsNearEnd(long long framesRemaining = -1) const; 146 float GetAudioStretchFactor() { return audio_stretchfactor; } 145 147 bool PlayingSlowForPrebuffer(void) const { return m_playing_slower; } 146 148 bool HasAudioIn(void) const { return !no_audio_in; } 147 149 bool HasAudioOut(void) const { return !no_audio_out; } … … 170 172 bool Play(float speed = 1.0, bool normal = true, 171 173 bool unpauseaudio = true); 172 174 bool GetPause(void) const; 175 float GetNextPlaySpeed() { return next_play_speed; } 173 176 174 177 // Seek stuff 175 178 bool FastForward(float seconds); … … 487 490 int audio_bits; 488 491 int audio_samplerate; 489 492 float audio_stretchfactor; 493 void *audio_codec; 490 494 491 495 // Picture-in-Picture 492 496 NuppelVideoPlayer *pipplayer; -
libs/libmythtv/NuppelVideoPlayer.cpp
124 124 audioOutput(NULL), audiodevice("/dev/dsp"), 125 125 audio_channels(2), audio_bits(-1), 126 126 audio_samplerate(44100), audio_stretchfactor(1.0f), 127 audio_codec(NULL), 127 128 // Picture-in-Picture 128 129 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 129 130 // Filters … … 514 515 515 516 if (audioOutput) 516 517 { 517 audioOutput->Reconfigure(audio_bits, audio_channels, audio_samplerate );518 audioOutput->Reconfigure(audio_bits, audio_channels, audio_samplerate, audio_codec); 518 519 errMsg = audioOutput->GetError(); 519 520 if (!errMsg.isEmpty()) 520 521 audioOutput->SetStretchFactor(audio_stretchfactor); … … 647 648 { 648 649 VERBOSE(VB_IMPORTANT, "Video sync method can't support double " 649 650 "framerate (refresh rate too low for bob deint)"); 651 //m_scan = kScan_Ignore; 652 //m_can_double = false; 650 653 FallbackDeint(); 651 654 } 652 655 } … … 1423 1426 warpfactor_avg = (warpfactor + (warpfactor_avg * (WARPAVLEN - 1))) / 1424 1427 WARPAVLEN; 1425 1428 1426 //cerr << "Divergence: " << divergence << " Rate: " << rate 1427 //<< " Warpfactor: " << warpfactor << " warpfactor_avg: " 1428 //<< warpfactor_avg << endl; 1429 #if 1 1430 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V " 1431 "Divergence: %1 " 1432 " Rate: %2" 1433 " Warpfactor: %3" 1434 " warpfactor_avg: %4") 1435 .arg(divergence) 1436 .arg(rate) 1437 .arg(warpfactor) 1438 .arg(warpfactor_avg) 1439 ); 1440 #endif 1429 1441 return divergence; 1430 1442 } 1431 1443 … … 1506 1518 if (diverge < -MAXDIVERGE) 1507 1519 { 1508 1520 // If video is way ahead of audio, adjust for it... 1509 QString dbg = QString(" Video is %1 frames ahead of audio, ")1521 QString dbg = QString("Audio is %1 frames ahead of video, ") 1510 1522 .arg(-diverge); 1511 1523 1512 1524 // Reset A/V Sync … … 1521 1533 // decoding; display the frame, but don't wait for A/V Sync. 1522 1534 videoOutput->PrepareFrame(buffer, ps); 1523 1535 videoOutput->Show(m_scan); 1524 VERBOSE(VB_PLAYBACK , LOC + dbg + "skipping A/V wait.");1536 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "skipping A/V wait."); 1525 1537 } 1526 1538 else 1527 1539 { 1528 1540 // If we are using software decoding, skip this frame altogether. 1529 VERBOSE(VB_PLAYBACK , LOC + dbg + "dropping frame.");1541 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "dropping frame."); 1530 1542 } 1531 1543 } 1532 1544 else if (!using_null_videoout) … … 1535 1547 if (buffer) 1536 1548 videoOutput->PrepareFrame(buffer, ps); 1537 1549 1550 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2").arg(avsync_adjustment).arg(m_double_framerate)); 1538 1551 videosync->WaitForFrame(avsync_adjustment); 1552 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show"); 1539 1553 if (!resetvideo) 1540 1554 videoOutput->Show(m_scan); 1541 1555 … … 1555 1569 1556 1570 // Display the second field 1557 1571 videosync->AdvanceTrigger(); 1558 videosync->WaitForFrame( 0);1572 videosync->WaitForFrame(avsync_adjustment); 1559 1573 if (!resetvideo) 1560 1574 videoOutput->Show(kScan_Intr2ndField); 1561 1575 } … … 1567 1581 1568 1582 if (output_jmeter && output_jmeter->RecordCycleTime()) 1569 1583 { 1570 //cerr << "avsync_delay: " << avsync_delay / 1000 1571 // << ", avsync_avg: " << avsync_avg / 1000 1572 // << ", warpfactor: " << warpfactor 1573 // << ", warpfactor_avg: " << warpfactor_avg << endl; 1584 #if 1 1585 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V " 1586 "avsync_delay: %1" 1587 ", avsync_avg: %2" 1588 ", warpfactor: %3" 1589 ", warpfactor_avg: %4") 1590 .arg(avsync_delay / 1000) 1591 .arg(avsync_avg / 1000) 1592 .arg(warpfactor) 1593 .arg(warpfactor_avg)); 1594 #endif 1574 1595 } 1575 1596 1576 1597 videosync->AdvanceTrigger(); … … 1581 1602 // If audio is way ahead of video, adjust for it... 1582 1603 // by cutting the frame rate in half for the length of this frame 1583 1604 1584 avsync_adjustment = frame_interval; 1605 //avsync_adjustment = frame_interval; 1606 avsync_adjustment = refreshrate; 1585 1607 lastsync = true; 1586 VERBOSE(VB_PLAYBACK , LOC +1587 QString(" Audio is %1 frames ahead of video,\n"1608 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + 1609 QString("Video is %1 frames ahead of audio,\n" 1588 1610 "\t\t\tdoubling video frame interval.").arg(diverge)); 1589 1611 } 1590 1612 1591 1613 if (audioOutput && normal_speed) 1592 1614 { 1593 1615 long long currentaudiotime = audioOutput->GetAudiotime(); 1594 #if 01595 VERBOSE(VB_PLAYBACK , QString(1616 #if 1 1617 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString( 1596 1618 "A/V timecodes audio %1 video %2 frameinterval %3 " 1597 1619 "avdel %4 avg %5 tcoffset %6") 1598 1620 .arg(currentaudiotime) … … 1844 1866 { 1845 1867 VERBOSE(VB_IMPORTANT, "Video sync method can't support double " 1846 1868 "framerate (refresh rate too low for bob deint)"); 1869 //m_scan = kScan_Ignore; 1870 //m_can_double = false; 1847 1871 FallbackDeint(); 1848 1872 } 1849 1873 } … … 2534 2558 audio_samplerate = samplerate; 2535 2559 } 2536 2560 2561 void NuppelVideoPlayer::SetAudioCodec(void* ac) 2562 { 2563 audio_codec = ac; 2564 } 2565 2537 2566 void NuppelVideoPlayer::SetEffDsp(int dsprate) 2538 2567 { 2539 2568 if (audioOutput) … … 2578 2607 tc_avcheck_framecounter++; 2579 2608 if (tc_avcheck_framecounter == 30) 2580 2609 { 2581 #define AUTO_RESYNC 12610 #define AUTO_RESYNC 0 2582 2611 #if AUTO_RESYNC 2583 2612 // something's terribly, terribly wrong. 2584 2613 if (tc_lastval[TC_AUDIO] < tc_lastval[TC_VIDEO] - 10000000 || -
libs/libavcodec/a52dec.c
149 149 } 150 150 } 151 151 152 static inline int16_t convert (int32_t i) 153 { 154 if (i > 0x43c07fff) 155 return 32767; 156 else if (i < 0x43bf8000) 157 return -32768; 158 else 159 return i - 0x43c00000; 160 } 161 162 void float2s16_2 (float * _f, int16_t * s16) 163 { 164 int i; 165 int32_t * f = (int32_t *) _f; 166 167 for (i = 0; i < 256; i++) { 168 s16[2*i] = convert (f[i]); 169 s16[2*i+1] = convert (f[i+256]); 170 } 171 } 172 173 void float2s16_4 (float * _f, int16_t * s16) 174 { 175 int i; 176 int32_t * f = (int32_t *) _f; 177 178 for (i = 0; i < 256; i++) { 179 s16[4*i] = convert (f[i]); 180 s16[4*i+1] = convert (f[i+256]); 181 s16[4*i+2] = convert (f[i+512]); 182 s16[4*i+3] = convert (f[i+768]); 183 } 184 } 185 186 void float2s16_5 (float * _f, int16_t * s16) 187 { 188 int i; 189 int32_t * f = (int32_t *) _f; 190 191 for (i = 0; i < 256; i++) { 192 s16[5*i] = convert (f[i]); 193 s16[5*i+1] = convert (f[i+256]); 194 s16[5*i+2] = convert (f[i+512]); 195 s16[5*i+3] = convert (f[i+768]); 196 s16[5*i+4] = convert (f[i+1024]); 197 } 198 } 199 200 int channels_multi (int flags) 201 { 202 if (flags & A52_LFE) 203 return 6; 204 else if (flags & 1) /* center channel */ 205 return 5; 206 else if ((flags & A52_CHANNEL_MASK) == A52_2F2R) 207 return 4; 208 else 209 return 2; 210 } 211 212 void float2s16_multi (float * _f, int16_t * s16, int flags) 213 { 214 int i; 215 int32_t * f = (int32_t *) _f; 216 217 switch (flags) { 218 case A52_MONO: 219 for (i = 0; i < 256; i++) { 220 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; 221 s16[5*i+4] = convert (f[i]); 222 } 223 break; 224 case A52_CHANNEL: 225 case A52_STEREO: 226 case A52_DOLBY: 227 float2s16_2 (_f, s16); 228 break; 229 case A52_3F: 230 for (i = 0; i < 256; i++) { 231 s16[5*i] = convert (f[i]); 232 s16[5*i+1] = convert (f[i+512]); 233 s16[5*i+2] = s16[5*i+3] = 0; 234 s16[5*i+4] = convert (f[i+256]); 235 } 236 break; 237 case A52_2F2R: 238 float2s16_4 (_f, s16); 239 break; 240 case A52_3F2R: 241 float2s16_5 (_f, s16); 242 break; 243 case A52_MONO | A52_LFE: 244 for (i = 0; i < 256; i++) { 245 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; 246 s16[6*i+4] = convert (f[i+256]); 247 s16[6*i+5] = convert (f[i]); 248 } 249 break; 250 case A52_CHANNEL | A52_LFE: 251 case A52_STEREO | A52_LFE: 252 case A52_DOLBY | A52_LFE: 253 for (i = 0; i < 256; i++) { 254 s16[6*i] = convert (f[i+256]); 255 s16[6*i+1] = convert (f[i+512]); 256 s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 257 s16[6*i+5] = convert (f[i]); 258 } 259 break; 260 case A52_3F | A52_LFE: 261 for (i = 0; i < 256; i++) { 262 s16[6*i] = convert (f[i+256]); 263 s16[6*i+1] = convert (f[i+768]); 264 s16[6*i+2] = s16[6*i+3] = 0; 265 s16[6*i+4] = convert (f[i+512]); 266 s16[6*i+5] = convert (f[i]); 267 } 268 break; 269 case A52_2F2R | A52_LFE: 270 for (i = 0; i < 256; i++) { 271 s16[6*i] = convert (f[i+256]); 272 s16[6*i+1] = convert (f[i+512]); 273 s16[6*i+2] = convert (f[i+768]); 274 s16[6*i+3] = convert (f[i+1024]); 275 s16[6*i+4] = 0; 276 s16[6*i+5] = convert (f[i]); 277 } 278 break; 279 case A52_3F2R | A52_LFE: 280 for (i = 0; i < 256; i++) { 281 s16[6*i] = convert (f[i+256]); 282 s16[6*i+1] = convert (f[i+768]); 283 s16[6*i+2] = convert (f[i+1024]); 284 s16[6*i+3] = convert (f[i+1280]); 285 s16[6*i+4] = convert (f[i+512]); 286 s16[6*i+5] = convert (f[i]); 287 } 288 break; 289 } 290 } 291 292 152 293 /**** end */ 153 294 154 295 #define HEADER_SIZE 7 … … 212 353 s->inbuf_ptr += len; 213 354 buf_size -= len; 214 355 } else { 356 int chans; 215 357 flags = s->flags; 216 358 if (avctx->channels == 1) 217 359 flags = A52_MONO; 218 else if (avctx->channels == 2) 219 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 } 220 366 else 221 367 flags |= A52_ADJUST_LEVEL; 222 368 level = 1; 369 chans = channels_multi(flags); 223 370 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 224 371 fail: 225 372 s->inbuf_ptr = s->inbuf; … … 229 376 for (i = 0; i < 6; i++) { 230 377 if (s->a52_block(s->state)) 231 378 goto fail; 232 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); 379 //float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); 380 float2s16_multi(s->samples, out_samples + i * 256 * chans, flags); 233 381 } 234 382 s->inbuf_ptr = s->inbuf; 235 383 s->frame_size = 0; 236 *data_size = 6 * avctx->channels * 256 * sizeof(int16_t); 384 //*data_size = 6 * avctx->channels * 256 * sizeof(int16_t); 385 *data_size = 6 * channels_multi(flags) * 256 * sizeof(int16_t); 237 386 break; 238 387 } 239 388 }