Ticket #1104: mythtv_ac3.32.patch
File mythtv_ac3.32.patch, 57.8 KB (added by , 16 years ago) |
---|
-
(a) dummyemptyfile vs. (b) libs/libmyth/audiooutputdigitalencoder.cpp
a b 1 // Std C headers 2 #include <cstdio> 3 4 // libav headers 5 extern "C" { 6 #include "libavcodec/avcodec.h" 7 #ifdef ENABLE_AC3_DECODER 8 #include "libavcodec/parser.h" 9 #else 10 #include <a52dec/a52.h> 11 #endif 12 } 13 14 // MythTV headers 15 #include "config.h" 16 #include "mythcontext.h" 17 #include "audiooutputdigitalencoder.h" 18 #include "compat.h" 19 20 #define LOC QString("DEnc: "); 21 22 #define MAX_AC3_FRAME_SIZE 6144 23 24 AudioOutputDigitalEncoder::AudioOutputDigitalEncoder() 25 { 26 av_context = NULL; 27 outbuf = NULL; 28 outbuf_size = 0; 29 one_frame_bytes = 0; 30 frame_buffer = NULL; 31 } 32 33 AudioOutputDigitalEncoder::~AudioOutputDigitalEncoder() 34 { 35 Dispose(); 36 } 37 38 void AudioOutputDigitalEncoder::Dispose() 39 { 40 if (av_context) 41 { 42 avcodec_close(av_context); 43 av_free(av_context); 44 av_context = NULL; 45 } 46 if (outbuf) 47 { 48 delete [] outbuf; 49 outbuf = NULL; 50 outbuf_size = 0; 51 } 52 if (frame_buffer) 53 { 54 delete [] frame_buffer; 55 frame_buffer = NULL; 56 one_frame_bytes = 0; 57 } 58 } 59 60 //CODEC_ID_AC3 61 bool AudioOutputDigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels) 62 { 63 AVCodec * codec; 64 int ret; 65 66 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4") 67 .arg(codec_id_string(codec_id)) 68 .arg(bitrate) 69 .arg(samplerate) 70 .arg(channels)); 71 //codec = avcodec_find_encoder(codec_id); 72 // always AC3 as there is no DTS encoder at the moment 2005/1/9 73 codec = avcodec_find_encoder(CODEC_ID_AC3); 74 if (!codec) 75 { 76 VERBOSE(VB_IMPORTANT,"Error: could not find codec"); 77 return false; 78 } 79 av_context = avcodec_alloc_context(); 80 av_context->bit_rate = bitrate; 81 av_context->sample_rate = samplerate; 82 av_context->channels = channels; 83 // open it */ 84 if ((ret = avcodec_open(av_context, codec)) < 0) 85 { 86 VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate"); 87 Dispose(); 88 return false; 89 } 90 91 size_t bytes_per_frame = av_context->channels * sizeof(short); 92 audio_bytes_per_sample = bytes_per_frame; 93 one_frame_bytes = bytes_per_frame * av_context->frame_size; 94 95 outbuf_size = 16384; // ok for AC3 but DTS? 96 outbuf = new char [outbuf_size]; 97 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 98 .arg(av_context->frame_size) 99 .arg(bytes_per_frame) 100 .arg(one_frame_bytes) 101 ); 102 103 return true; 104 } 105 106 static int DTS_SAMPLEFREQS[16] = 107 { 108 0, 8000, 16000, 32000, 64000, 128000, 11025, 22050, 109 44100, 88200, 176400, 12000, 24000, 48000, 96000, 192000 110 }; 111 112 static int DTS_BITRATES[30] = 113 { 114 32000, 56000, 64000, 96000, 112000, 128000, 115 192000, 224000, 256000, 320000, 384000, 448000, 116 512000, 576000, 640000, 768000, 896000, 1024000, 117 1152000, 1280000, 1344000, 1408000, 1411200, 1472000, 118 1536000, 1920000, 2048000, 3072000, 3840000, 4096000 119 }; 120 121 static int dts_decode_header(uint8_t *indata_ptr, int *rate, 122 int *nblks, int *sfreq) 123 { 124 uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) | 125 (indata_ptr[2] << 8) | (indata_ptr[3])); 126 127 if (id != 0x7ffe8001) 128 return -1; 129 130 int ftype = indata_ptr[4] >> 7; 131 132 int surp = (indata_ptr[4] >> 2) & 0x1f; 133 surp = (surp + 1) % 32; 134 135 *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2); 136 ++*nblks; 137 138 int fsize = (indata_ptr[5] & 0x03) << 12 | 139 (indata_ptr[6] << 4) | (indata_ptr[7] >> 4); 140 ++fsize; 141 142 *sfreq = (indata_ptr[8] >> 2) & 0x0f; 143 *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07); 144 145 if (ftype != 1) 146 { 147 VERBOSE(VB_IMPORTANT, LOC + 148 QString("DTS: Termination frames not handled (ftype %1)") 149 .arg(ftype)); 150 return -1; 151 } 152 153 if (*sfreq != 13) 154 { 155 VERBOSE(VB_IMPORTANT, LOC + 156 QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq)); 157 return -1; 158 } 159 160 if ((fsize > 8192) || (fsize < 96)) 161 { 162 VERBOSE(VB_IMPORTANT, LOC + 163 QString("DTS: fsize: %1 invalid").arg(fsize)); 164 return -1; 165 } 166 167 if (*nblks != 8 && *nblks != 16 && *nblks != 32 && 168 *nblks != 64 && *nblks != 128 && ftype == 1) 169 { 170 VERBOSE(VB_IMPORTANT, LOC + 171 QString("DTS: nblks %1 not valid for normal frame") 172 .arg(*nblks)); 173 return -1; 174 } 175 176 return fsize; 177 } 178 179 static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/, 180 int *sample_rate, int *bit_rate) 181 { 182 int nblks; 183 int rate; 184 int sfreq; 185 186 int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq); 187 if (fsize >= 0) 188 { 189 if (rate >= 0 && rate <= 29) 190 *bit_rate = DTS_BITRATES[rate]; 191 else 192 *bit_rate = 0; 193 if (sfreq >= 1 && sfreq <= 15) 194 *sample_rate = DTS_SAMPLEFREQS[sfreq]; 195 else 196 *sample_rate = 0; 197 } 198 return fsize; 199 } 200 201 // until there is an easy way to do this with ffmpeg 202 // get the code from libavcodec/parser.c made non static 203 extern "C" int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, 204 int *bit_rate, int *samples); 205 206 static int encode_frame( 207 bool dts, 208 unsigned char *data, 209 size_t &len) 210 { 211 size_t enc_len; 212 int flags, sample_rate, bit_rate; 213 214 // we don't do any length/crc validation of the AC3 frame here; presumably 215 // the receiver will have enough sense to do that. if someone has a 216 // receiver that doesn't, here would be a good place to put in a call 217 // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the 218 // packet is bad? we'd need to send something that the receiver would 219 // ignore, and if so, may as well just assume that it will ignore 220 // anything with a bad CRC... 221 222 uint nr_samples = 0, block_len; 223 if (dts) 224 { 225 enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate); 226 int rate, sfreq, nblks; 227 dts_decode_header(data+8, &rate, &nblks, &sfreq); 228 nr_samples = nblks * 32; 229 block_len = nr_samples * 2 * 2; 230 } 231 else 232 { 233 #ifdef ENABLE_AC3_DECODER 234 enc_len = ac3_sync(data+8, &flags, &sample_rate, &bit_rate, (int*)&block_len); 235 #else 236 enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate); 237 block_len = MAX_AC3_FRAME_SIZE; 238 #endif 239 } 240 241 if (enc_len == 0 || enc_len > len) 242 { 243 int l = len; 244 len = 0; 245 return l; 246 } 247 248 enc_len = min((uint)enc_len, block_len - 8); 249 250 //uint32_t x = *(uint32_t*)(data+8); 251 // in place swab 252 swab(data+8, data+8, enc_len); 253 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, 254 // QString("DigitalEncoder::Encode swab test %1 %2") 255 // .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16)); 256 257 // the following values come from libmpcodecs/ad_hwac3.c in mplayer. 258 // they form a valid IEC958 AC3 header. 259 data[0] = 0x72; 260 data[1] = 0xF8; 261 data[2] = 0x1F; 262 data[3] = 0x4E; 263 data[4] = 0x01; 264 if (dts) 265 { 266 switch(nr_samples) 267 { 268 case 512: 269 data[4] = 0x0B; /* DTS-1 (512-sample bursts) */ 270 break; 271 272 case 1024: 273 data[4] = 0x0C; /* DTS-2 (1024-sample bursts) */ 274 break; 275 276 case 2048: 277 data[4] = 0x0D; /* DTS-3 (2048-sample bursts) */ 278 break; 279 280 default: 281 VERBOSE(VB_IMPORTANT, LOC + 282 QString("DTS: %1-sample bursts not supported") 283 .arg(nr_samples)); 284 data[4] = 0x00; 285 break; 286 } 287 } 288 data[5] = 0x00; 289 data[6] = (enc_len << 3) & 0xFF; 290 data[7] = (enc_len >> 5) & 0xFF; 291 memset(data + 8 + enc_len, 0, block_len - 8 - enc_len); 292 len = block_len; 293 294 return enc_len; 295 } 296 297 // must have exactly 1 frames worth of data 298 size_t AudioOutputDigitalEncoder::Encode(short * buff) 299 { 300 int encsize = 0; 301 size_t outsize = 0; 302 303 // put data in the correct spot for encode frame 304 outsize = avcodec_encode_audio( 305 av_context, 306 ((uchar*)outbuf)+8, 307 outbuf_size-8, 308 buff); 309 size_t tmpsize = outsize; 310 311 outsize = MAX_AC3_FRAME_SIZE; 312 encsize = encode_frame( 313 //av_context->codec_id==CODEC_ID_DTS, 314 false, 315 (unsigned char*)outbuf, outsize); 316 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 317 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 318 .arg(tmpsize) 319 .arg(encsize) 320 .arg(outsize) 321 ); 322 323 return outsize; 324 } -
(a) dummyemptyfile vs. (b) libs/libmyth/audiooutputdigitalencoder.h
a b 1 #ifndef AUDIOOUTPUTREENCODER 2 #define AUDIOOUTPUTREENCODER 3 4 extern "C" { 5 #include "libavcodec/avcodec.h" 6 }; 7 8 class AudioOutputDigitalEncoder 9 { 10 public: 11 AudioOutputDigitalEncoder(); 12 ~AudioOutputDigitalEncoder(); 13 void Dispose(); 14 bool Init(CodecID codec_id, int bitrate, int samplerate, int channels); 15 size_t Encode(short * buff); 16 17 // if needed 18 char * GetFrameBuffer() 19 { 20 if (!frame_buffer && av_context) 21 { 22 frame_buffer = new char [one_frame_bytes]; 23 } 24 return frame_buffer; 25 } 26 size_t FrameSize() const { return one_frame_bytes; } 27 char * GetOutBuff() const { return outbuf; } 28 29 size_t audio_bytes_per_sample; 30 private: 31 AVCodecContext *av_context; 32 char * outbuf; 33 char * frame_buffer; 34 int outbuf_size; 35 size_t one_frame_bytes; 36 }; 37 38 39 #endif -
libs/libmyth/libmyth.pro
25 25 HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h 26 26 HEADERS += mythhdd.h mythcdrom.h 27 27 HEADERS += compat.h 28 HEADERS += audiooutputdigitalencoder.h 28 29 29 30 SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp 30 31 SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp … … 40 41 SOURCES += uilistbtntype.cpp uitypes.cpp util.cpp util-x11.cpp 41 42 SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp 42 43 SOURCES += mythhdd.cpp mythcdrom.cpp 44 SOURCES += audiooutputdigitalencoder.cpp 43 45 44 46 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./ 47 INCLUDEPATH += ../libavutil 45 48 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui 46 49 DEPENDPATH += ../libmythupnp 50 DEPENDPATH += ../libavutil ../libavcodec 47 51 48 52 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION} 49 53 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION} 54 LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION} 50 55 51 56 TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT} 52 57 TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT} … … 208 213 use_hidesyms { 209 214 QMAKE_CXXFLAGS += -fvisibility=hidden 210 215 } 216 217 contains( CONFIG_LIBA52, yes ) { 218 LIBS += -la52 219 } -
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 class AudioOutputDigitalEncoder; 22 struct AVCodecContext; 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 AudioOutputDigitalEncoder * encoder; 147 160 148 161 bool blocking; // do AddSamples calls block? 149 162 … … 162 175 163 176 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 164 177 'audiotime' and 'audiotime_updated' */ 165 intaudiotime; // timecode of audio leaving the soundcard (same units as178 long long audiotime; // timecode of audio leaving the soundcard (same units as 166 179 // timecodes) ... 167 180 struct timeval audiotime_updated; // ... which was last updated at this time 168 181 169 182 /* Audio circular buffer */ 170 183 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 171 184 int raud, waud; /* read and write positions */ 172 intaudbuf_timecode; /* timecode of audio most recently placed into185 long long audbuf_timecode; /* timecode of audio most recently placed into 173 186 buffer */ 174 187 175 188 int numlowbuffer; -
libs/libmyth/audiooutputbase.cpp
15 15 16 16 // MythTV headers 17 17 #include "audiooutputbase.h" 18 #include "audiooutputdigitalencoder.h" 18 19 #include "compat.h" 19 20 20 21 #define LOC QString("AO: ") … … 25 26 int /*laudio_bits*/, int /*laudio_channels*/, 26 27 int /*laudio_samplerate*/, AudioOutputSource lsource, 27 28 bool lset_initial_vol, bool /*laudio_passthru*/) : 28 29 29 effdsp(0), effdspstretched(0), 30 30 audio_channels(-1), audio_bytes_per_sample(0), 31 31 audio_bits(-1), audio_samplerate(-1), … … 36 36 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 37 37 audio_passthru(false), audio_stretchfactor(1.0f), 38 38 39 audio_codec(NULL), 39 40 source(lsource), killaudio(false), 40 41 41 42 pauseaudio(false), audio_actually_paused(false), … … 47 48 48 49 src_ctx(NULL), 49 50 50 pSoundStretch(NULL), blocking(false), 51 pSoundStretch(NULL), 52 encoder(NULL), 53 blocking(false), 51 54 52 55 lastaudiolen(0), samples_buffered(0), 53 56 … … 71 74 memset(tmp_buff, 0, sizeof(short) * AUDIO_TMP_BUF_SIZE); 72 75 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 73 76 memset(audiobuffer, 0, sizeof(char) * AUDBUFSIZE); 77 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 74 78 75 79 // You need to call Reconfigure from your concrete class. 76 80 // Reconfigure(laudio_bits, laudio_channels, … … 111 115 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 112 116 .arg(audio_stretchfactor)); 113 117 pSoundStretch = new soundtouch::SoundTouch(); 114 pSoundStretch->setSampleRate(audio_samplerate); 115 pSoundStretch->setChannels(audio_channels); 118 if (audio_codec) 119 { 120 if (!encoder) 121 { 122 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 123 encoder = new AudioOutputDigitalEncoder(); 124 if (!encoder->Init(audio_codec->codec_id, 125 audio_codec->bit_rate, 126 audio_codec->sample_rate, 127 audio_codec->channels 128 )) 129 { 130 // eeks 131 delete encoder; 132 encoder = NULL; 133 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 134 } 135 } 136 } 137 if (encoder) 138 { 139 pSoundStretch->setSampleRate(audio_codec->sample_rate); 140 pSoundStretch->setChannels(audio_codec->channels); 141 } 142 else 143 { 144 pSoundStretch->setSampleRate(audio_samplerate); 145 pSoundStretch->setChannels(audio_channels); 146 } 116 147 117 148 pSoundStretch->setTempo(audio_stretchfactor); 118 149 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 135 166 } 136 167 137 168 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 138 int laudio_samplerate, bool laudio_passthru) 169 int laudio_samplerate, bool laudio_passthru, 170 void* laudio_codec) 139 171 { 172 int codec_id = CODEC_ID_NONE; 173 int lcodec_id = CODEC_ID_NONE; 174 int lcchannels = 0; 175 int cchannels = 0; 176 if (laudio_codec) 177 { 178 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 179 laudio_bits = 16; 180 laudio_channels = 2; 181 laudio_samplerate = 48000; 182 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 183 } 184 if (audio_codec) 185 { 186 codec_id = audio_codec->codec_id; 187 cchannels = ((AVCodecContext*)audio_codec)->channels; 188 } 189 ClearError(); 140 190 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 141 laudio_samplerate == audio_samplerate && 142 laudio_passthru == audio_passthru && !need_resampler) 191 laudio_samplerate == audio_samplerate && !need_resampler && 192 laudio_passthru == audio_passthru && 193 lcodec_id == codec_id && lcchannels == cchannels) 143 194 return; 144 195 145 196 KillAudio(); … … 151 202 waud = raud = 0; 152 203 audio_actually_paused = false; 153 204 205 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 154 206 audio_channels = laudio_channels; 155 207 audio_bits = laudio_bits; 156 208 audio_samplerate = laudio_samplerate; 209 audio_codec = (AVCodecContext*)laudio_codec; 157 210 audio_passthru = laudio_passthru; 158 211 if (audio_bits != 8 && audio_bits != 16) 159 212 { … … 172 225 173 226 numlowbuffer = 0; 174 227 228 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3") 229 .arg(audio_main_device).arg(audio_channels).arg(audio_samplerate)); 230 175 231 // Actually do the device specific open call 176 232 if (!OpenDevice()) 177 233 { 178 234 VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure"); 179 235 pthread_mutex_unlock(&avsync_lock); 180 236 pthread_mutex_unlock(&audio_buflock); 237 if (GetError().isEmpty()) 238 Error("Aborting reconfigure"); 239 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 181 240 return; 182 241 } 183 242 … … 200 259 current_seconds = -1; 201 260 source_bitrate = -1; 202 261 262 // NOTE: this wont do anything as above samplerate vars are set equal 203 263 // Check if we need the resampler 204 264 if (audio_samplerate != laudio_samplerate) 205 265 { … … 224 284 225 285 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 226 286 .arg(audio_stretchfactor)); 287 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 288 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 227 289 228 SetStretchFactorLocked(audio_stretchfactor); 229 if (pSoundStretch) 290 if (redo_stretch) 230 291 { 231 pSoundStretch->setSampleRate(audio_samplerate); 232 pSoundStretch->setChannels(audio_channels); 292 float laudio_stretchfactor = audio_stretchfactor; 293 delete pSoundStretch; 294 pSoundStretch = NULL; 295 audio_stretchfactor = 0.0; 296 SetStretchFactorLocked(laudio_stretchfactor); 233 297 } 298 else 299 { 300 SetStretchFactorLocked(audio_stretchfactor); 301 if (pSoundStretch) 302 { 303 // if its passthru then we need to reencode 304 if (audio_codec) 305 { 306 if (!encoder) 307 { 308 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 309 encoder = new AudioOutputDigitalEncoder(); 310 if (!encoder->Init(audio_codec->codec_id, 311 audio_codec->bit_rate, 312 audio_codec->sample_rate, 313 audio_codec->channels 314 )) 315 { 316 // eeks 317 delete encoder; 318 encoder = NULL; 319 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 320 } 321 } 322 } 323 if (encoder) 324 { 325 pSoundStretch->setSampleRate(audio_codec->sample_rate); 326 pSoundStretch->setChannels(audio_codec->channels); 327 } 328 else 329 { 330 pSoundStretch->setSampleRate(audio_samplerate); 331 pSoundStretch->setChannels(audio_channels); 332 } 333 } 334 } 234 335 235 336 // Setup visualisations, zero the visualisations buffers 236 337 prepareVisuals(); … … 290 391 pSoundStretch = NULL; 291 392 } 292 393 394 if (encoder) 395 { 396 delete encoder; 397 encoder = NULL; 398 } 399 293 400 CloseDevice(); 294 401 295 402 killAudioLock.unlock(); … … 303 410 304 411 void AudioOutputBase::Pause(bool paused) 305 412 { 413 VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused)); 306 414 pauseaudio = paused; 307 415 audio_actually_paused = false; 308 416 } … … 385 493 The reason is that computing 'audiotime' requires acquiring the audio 386 494 lock, which the video thread should not do. So, we call 'SetAudioTime()' 387 495 from the audio thread, and then call this from the video thread. */ 388 intret;496 long long ret; 389 497 struct timeval now; 390 498 391 499 if (audiotime == 0) … … 397 505 398 506 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 399 507 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 400 ret = ( int)(ret * audio_stretchfactor);508 ret = (long long)(ret * audio_stretchfactor); 401 509 510 #if 1 511 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 512 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 513 .arg(now.tv_sec).arg(now.tv_usec) 514 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 515 .arg(ret) 516 .arg(audiotime) 517 .arg(audio_stretchfactor) 518 ); 519 #endif 520 402 521 ret += audiotime; 403 522 404 523 pthread_mutex_unlock(&avsync_lock); 405 return ret;524 return (int)ret; 406 525 } 407 526 408 527 void AudioOutputBase::SetAudiotime(void) … … 439 558 // include algorithmic latencies 440 559 if (pSoundStretch) 441 560 { 561 // add the effect of any unused but processed samples, AC3 reencode does this 562 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 442 563 // add the effect of unprocessed samples in time stretch algo 443 564 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 444 565 audio_bytes_per_sample) / audio_stretchfactor); 445 566 } 446 567 447 568 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 448 569 (audio_bytes_per_sample * effdspstretched)); 449 570 450 571 gettimeofday(&audiotime_updated, NULL); 572 #if 1 573 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 574 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 575 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 576 .arg(audiotime) 577 .arg(audbuf_timecode) 578 .arg(totalbuffer) 579 .arg(soundcard_buffer) 580 .arg(effdspstretched) 581 .arg(audio_bytes_per_sample) 582 .arg(audio_stretchfactor) 583 ); 584 #endif 451 585 452 586 pthread_mutex_unlock(&avsync_lock); 453 587 pthread_mutex_unlock(&audio_buflock); … … 515 649 // NOTE: This function is not threadsafe 516 650 517 651 int afree = audiofree(true); 518 int len = samples * audio_bytes_per_sample;652 int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 519 653 520 654 // Check we have enough space to write the data 521 655 if (need_resampler && src_ctx) … … 527 661 "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4") 528 662 .arg(len).arg(AUDBUFSIZE-afree).arg(afree) 529 663 .arg(timecode)); 530 531 664 return false; // would overflow 532 665 } 533 666 … … 564 697 565 698 int AudioOutputBase::WaitForFreeSpace(int samples) 566 699 { 567 int len = samples * audio_bytes_per_sample; 700 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 701 int len = samples * abps; 568 702 int afree = audiofree(false); 569 703 570 704 while (len > afree) 571 705 { 572 706 if (blocking) 573 707 { 574 VERBOSE(VB_AUDIO , LOC + "Waiting for free space " +708 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " + 575 709 QString("(need %1, available %2)").arg(len).arg(afree)); 576 710 577 711 // wait for more space … … 580 714 } 581 715 else 582 716 { 583 VERBOSE(VB_IMPORTANT, LOC_ERR + 584 "Audio buffer overflow, audio data lost!"); 585 samples = afree / audio_bytes_per_sample; 586 len = samples * audio_bytes_per_sample; 717 VERBOSE(VB_IMPORTANT, LOC_ERR + 718 QString("Audio buffer overflow, %1 audio samples lost!") 719 .arg(samples-afree / abps)); 720 samples = afree / abps; 721 len = samples * abps; 587 722 if (src_ctx) 588 723 { 589 724 int error = src_reset(src_ctx); … … 608 743 609 744 int afree = audiofree(false); 610 745 611 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 612 LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 613 .arg(samples * audio_bytes_per_sample) 614 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 746 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 747 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 748 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5") 749 .arg(samples) 750 .arg(samples * abps) 751 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)); 615 752 616 753 len = WaitForFreeSpace(samples); 617 754 … … 648 785 649 786 if (pSoundStretch) 650 787 { 788 651 789 // does not change the timecode, only the number of samples 652 790 // back to orig pos 653 791 org_waud = waud; 654 792 int bdiff = AUDBUFSIZE - org_waud; 655 int nSamplesToEnd = bdiff/a udio_bytes_per_sample;793 int nSamplesToEnd = bdiff/abps; 656 794 if (bdiff < len) 657 795 { 658 796 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 659 797 org_waud), nSamplesToEnd); 660 798 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 661 (len - bdiff) / a udio_bytes_per_sample);799 (len - bdiff) / abps); 662 800 } 663 801 else 664 802 { 665 803 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 666 org_waud), len / a udio_bytes_per_sample);804 org_waud), len / abps); 667 805 } 668 806 669 int newLen = 0; 670 int nSamples; 671 len = WaitForFreeSpace(pSoundStretch->numSamples() * 672 audio_bytes_per_sample); 673 do 807 if (encoder) 674 808 { 675 int samplesToGet = len/audio_bytes_per_sample; 676 if (samplesToGet > nSamplesToEnd) 809 // pull out a packet's worth and reencode it until we dont have enough 810 // for any more packets 811 soundtouch::SAMPLETYPE* temp_buff = 812 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 813 size_t frameSize = encoder->FrameSize()/abps; 814 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 815 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 816 .arg(frameSize) 817 .arg(encoder->FrameSize()) 818 .arg(pSoundStretch->numSamples()) 819 ); 820 // process the same number of samples as it creates a full encoded buffer 821 // just like before 822 while (pSoundStretch->numSamples() >= frameSize) 677 823 { 678 samplesToGet = nSamplesToEnd; 824 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 825 int amount = encoder->Encode(temp_buff); 826 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 827 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 828 .arg(amount) 829 .arg(got) 830 .arg(pSoundStretch->numSamples()) 831 ); 832 if (amount == 0) 833 continue; 834 //len = WaitForFreeSpace(amount); 835 char * ob = encoder->GetOutBuff(); 836 if (amount >= bdiff) 837 { 838 memcpy(audiobuffer + org_waud, ob, bdiff); 839 ob += bdiff; 840 amount -= bdiff; 841 org_waud = 0; 842 } 843 if (amount > 0) 844 memcpy(audiobuffer + org_waud, ob, amount); 845 bdiff = AUDBUFSIZE - amount; 846 org_waud += amount; 679 847 } 680 681 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 682 (audiobuffer + org_waud), samplesToGet); 683 if (nSamples == nSamplesToEnd) 848 } 849 else 850 { 851 int newLen = 0; 852 int nSamples; 853 len = WaitForFreeSpace(pSoundStretch->numSamples() * 854 audio_bytes_per_sample); 855 do 684 856 { 685 org_waud = 0; 686 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 687 } 688 else 689 { 690 org_waud += nSamples * audio_bytes_per_sample; 691 nSamplesToEnd -= nSamples; 692 } 857 int samplesToGet = len/audio_bytes_per_sample; 858 if (samplesToGet > nSamplesToEnd) 859 { 860 samplesToGet = nSamplesToEnd; 861 } 693 862 694 newLen += nSamples * audio_bytes_per_sample; 695 len -= nSamples * audio_bytes_per_sample; 696 } while (nSamples > 0); 863 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 864 (audiobuffer + org_waud), samplesToGet); 865 if (nSamples == nSamplesToEnd) 866 { 867 org_waud = 0; 868 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 869 } 870 else 871 { 872 org_waud += nSamples * audio_bytes_per_sample; 873 nSamplesToEnd -= nSamples; 874 } 875 876 newLen += nSamples * audio_bytes_per_sample; 877 len -= nSamples * audio_bytes_per_sample; 878 } while (nSamples > 0); 879 } 697 880 } 698 881 699 882 waud = org_waud; … … 769 952 space_on_soundcard = getSpaceOnSoundcard(); 770 953 771 954 if (space_on_soundcard != last_space_on_soundcard) { 772 VERBOSE(VB_AUDIO , LOC + QString("%1 bytes free on soundcard")955 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard") 773 956 .arg(space_on_soundcard)); 774 957 last_space_on_soundcard = space_on_soundcard; 775 958 } … … 782 965 WriteAudio(zeros, fragment_size); 783 966 } else { 784 967 // this should never happen now -dag 785 VERBOSE(VB_AUDIO , LOC +968 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 786 969 QString("waiting for space on soundcard " 787 970 "to write zeros: have %1 need %2") 788 971 .arg(space_on_soundcard).arg(fragment_size)); … … 818 1001 if (fragment_size > audiolen(true)) 819 1002 { 820 1003 if (audiolen(true) > 0) // only log if we're sending some audio 821 VERBOSE(VB_AUDIO , LOC +1004 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 822 1005 QString("audio waiting for buffer to fill: " 823 1006 "have %1 want %2") 824 1007 .arg(audiolen(true)).arg(fragment_size)); 825 1008 826 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1009 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 827 1010 pthread_mutex_lock(&audio_buflock); 828 1011 pthread_cond_broadcast(&audio_bufsig); 829 1012 pthread_mutex_unlock(&audio_buflock); … … 837 1020 if (fragment_size > space_on_soundcard) 838 1021 { 839 1022 if (space_on_soundcard != last_space_on_soundcard) { 840 VERBOSE(VB_AUDIO , LOC +1023 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 841 1024 QString("audio waiting for space on soundcard: " 842 1025 "have %1 need %2") 843 1026 .arg(space_on_soundcard).arg(fragment_size)); … … 899 1082 900 1083 /* update raud */ 901 1084 raud = (raud + fragment_size) % AUDBUFSIZE; 902 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1085 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 903 1086 pthread_cond_broadcast(&audio_bufsig); 904 1087 905 1088 written_size = fragment_size; -
libs/libmyth/audiooutputalsa.cpp
52 52 QString real_device = (audio_passthru) ? 53 53 audio_passthru_device : audio_main_device; 54 54 55 int index; 56 if ((index=real_device.find('|'))>=0) 57 { 58 if (audio_channels != 2) 59 real_device = real_device.mid(index+1); 60 else 61 real_device = real_device.left(index); 62 } 63 55 64 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 56 65 .arg(real_device)); 57 66 … … 89 98 } 90 99 else 91 100 { 92 fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 93 buffer_time = 500000; // .5 seconds 101 //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 102 //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits 103 fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30); 104 buffer_time = 100000; // .5 seconds 94 105 period_time = buffer_time / 4; // 4 interrupts per buffer 95 106 } 96 107 … … 162 173 163 174 tmpbuf = aubuf; 164 175 165 VERBOSE(VB_AUDIO , QString("WriteAudio: Preparing %1 bytes (%2 frames)")176 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 166 177 .arg(size).arg(frames)); 167 178 168 179 while (frames > 0) -
programs/mythfrontend/globalsettings.cpp
58 58 #endif 59 59 #ifdef USING_ALSA 60 60 gc->addSelection("ALSA:default", "ALSA:default"); 61 gc->addSelection("ALSA:analog", "ALSA:analog"); 62 gc->addSelection("ALSA:digital", "ALSA:digital"); 63 gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog"); 64 gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital"); 61 65 #endif 62 66 #ifdef USING_ARTS 63 67 gc->addSelection("ARTS:", "ARTS:"); … … 73 77 return gc; 74 78 } 75 79 80 static HostComboBox *MaxAudioChannels() 81 { 82 HostComboBox *gc = new HostComboBox("MaxChannels",false); 83 gc->setLabel(QObject::tr("Max Audio Channels")); 84 //gc->addSelection(QObject::tr("Mono"), "1"); 85 //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default 86 //gc->addSelection(QObject::tr("3 Channel: L C R"), "3"); 87 //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4"); 88 //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5"); 89 //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6"); 90 gc->addSelection(QObject::tr("Stereo"), "2", true); // default 91 gc->addSelection(QObject::tr("6 Channel"), "6"); 92 gc->setHelpText( 93 QObject::tr("Set the maximum number of audio channels to be decoded. " 94 "This is for multi-channel/surround audio playback.")); 95 return gc; 96 } 97 76 98 static HostComboBox *PassThroughOutputDevice() 77 99 { 78 100 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3130 3152 new VerticalConfigurationGroup(false, false, true, true); 3131 3153 vgrp0->addChild(AC3PassThrough()); 3132 3154 vgrp0->addChild(DTSPassThrough()); 3155 addChild(MaxAudioChannels()); 3133 3156 3134 3157 VerticalConfigurationGroup *vgrp1 = 3135 3158 new VerticalConfigurationGroup(false, false, true, true); -
programs/mythtranscode/transcode.cpp
55 55 56 56 // reconfigure sound out for new params 57 57 virtual void Reconfigure(int audio_bits, int audio_channels, 58 int audio_samplerate, bool audio_passthru) 58 int audio_samplerate, bool audio_passthru, 59 void * = NULL) 59 60 { 61 ClearError(); 60 62 (void)audio_samplerate; 61 63 (void)audio_passthru; 62 64 bits = audio_bits; 63 65 channels = audio_channels; 64 66 bytes_per_sample = bits * channels / 8; 67 if (channels>2) 68 Error("Invalid channel count"); 65 69 } 66 70 67 71 // dsprate is in 100 * samples/second -
programs/mythuitest/mythuitest.pro
6 6 TARGET = mythuitest 7 7 CONFIG += thread opengl 8 8 9 LIBS += -L../../libs/libavcodec -L../../libs/libavutil 10 LIBS += -lmythavcodec-$$LIBVERSION -lmythavutil-$$LIBVERSION 9 11 LIBS += $$EXTRA_LIBS 10 12 13 TARGETDEPS += ../../libs/libavcodec/libmythavcodec-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB} 14 TARGETDEPS += ../../libs/libavutil/libmythavutil-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB} 15 11 16 macx { 12 17 # Duplication of source with libmyth (e.g. oldsettings.cpp) 13 18 # means that the linker complains, so we have to ignore duplicates -
libs/libmythtv/avformatdecoder.h
259 259 bool allow_ac3_passthru; 260 260 bool allow_dts_passthru; 261 261 bool disable_passthru; 262 int max_channels; 262 263 263 264 AudioInfo audioIn; 264 265 AudioInfo audioOut; -
libs/libmythtv/avformatdecoder.cpp
51 51 52 52 #define MAX_AC3_FRAME_SIZE 6144 53 53 54 /** Set to zero to allow any number of AC3 channels. */55 #define MAX_OUTPUT_CHANNELS 256 57 54 static int cc608_parity(uint8_t byte); 58 55 static int cc608_good_parity(const int *parity_table, uint16_t data); 59 56 static void cc608_build_parity_table(int *parity_table); … … 417 414 418 415 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 419 416 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 417 max_channels = gContext->GetNumSetting("MaxChannels", 2); 420 418 421 419 audioIn.sample_size = -32; // force SetupAudioStream to run once 422 420 itv = GetNVP()->GetInteractiveTV(); … … 1580 1578 <<") already open, leaving it alone."); 1581 1579 } 1582 1580 //assert(enc->codec_id); 1581 VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels)); 1583 1582 1583 #if 0 1584 // HACK MULTICHANNEL DTS passthru disabled for multichannel, dont know how to handle this 1584 1585 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1585 1586 if (enc->codec_id == CODEC_ID_DTS) 1586 1587 { … … 1589 1590 // enc->bit_rate = what??; 1590 1591 } 1591 1592 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1593 #endif 1592 1594 1593 1595 bitrate += enc->bit_rate; 1594 1596 break; … … 3260 3262 if (!curstream->codec->channels) 3261 3263 { 3262 3264 QMutexLocker locker(&avcodeclock); 3263 curstream->codec->channels = MAX_OUTPUT_CHANNELS; 3265 VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels)); 3266 curstream->codec->channels = audioOut.channels; 3264 3267 ret = avcodec_decode_audio( 3265 3268 curstream->codec, audioSamples, 3266 3269 &data_size, ptr, len); … … 3321 3324 AVCodecContext *ctx = curstream->codec; 3322 3325 3323 3326 if ((ctx->channels == 0) || 3324 (ctx->channels > MAX_OUTPUT_CHANNELS))3325 ctx->channels = MAX_OUTPUT_CHANNELS;3327 (ctx->channels > audioOut.channels)) 3328 ctx->channels = audioOut.channels; 3326 3329 3327 3330 ret = avcodec_decode_audio( 3328 3331 ctx, audioSamples, &data_size, ptr, len); … … 3675 3678 3676 3679 void AvFormatDecoder::SetDisablePassThrough(bool disable) 3677 3680 { 3681 // can only disable never reenable as once tiemstretch is on its on for the session 3682 if (disable_passthru) 3683 return; 3678 3684 if (selectedTrack[kTrackTypeAudio].av_stream_index < 0) 3679 3685 { 3680 3686 disable_passthru = disable; … … 3707 3713 AVCodecContext *codec_ctx = NULL; 3708 3714 AudioInfo old_in = audioIn; 3709 3715 AudioInfo old_out = audioOut; 3716 bool using_passthru = false; 3710 3717 3711 3718 if ((currentTrack[kTrackTypeAudio] >= 0) && 3712 3719 (selectedTrack[kTrackTypeAudio].av_stream_index <= … … 3718 3725 assert(curstream->codec); 3719 3726 codec_ctx = curstream->codec; 3720 3727 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3721 !disable_passthru &&3722 3728 (codec_ctx->codec_id == CODEC_ID_AC3)); 3723 3729 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3724 !disable_passthru &&3725 3730 (codec_ctx->codec_id == CODEC_ID_DTS)); 3731 using_passthru = do_ac3_passthru || do_dts_passthru; 3726 3732 info = AudioInfo(codec_ctx->codec_id, 3727 3733 codec_ctx->sample_rate, codec_ctx->channels, 3728 do_ac3_passthru || do_dts_passthru);3734 using_passthru && !disable_passthru); 3729 3735 } 3730 3736 3731 3737 if (info == audioIn) 3732 3738 return false; // no change 3733 3739 3740 QString ptmsg = ""; 3741 if (using_passthru) 3742 { 3743 ptmsg = QString(" using passthru"); 3744 } 3734 3745 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 3735 3746 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 3736 3747 3737 3748 audioOut = audioIn = info; 3738 if ( audioIn.do_passthru)3749 if (using_passthru) 3739 3750 { 3740 3751 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 3741 audioOut.channels = 2; 3742 audioOut.sample_rate = 48000; 3743 audioOut.sample_size = 4; 3752 AudioInfo digInfo = audioOut; 3753 if (!disable_passthru) 3754 { 3755 digInfo.channels = 2; 3756 digInfo.sample_rate = 48000; 3757 digInfo.sample_size = 4; 3758 } 3759 if (audioOut.channels > max_channels) 3760 { 3761 audioOut.channels = max_channels; 3762 audioOut.sample_size = audioOut.channels * 2; 3763 codec_ctx->channels = audioOut.channels; 3764 } 3765 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 3766 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 3767 .arg(digInfo.toString()) 3768 .arg(old_in.toString()).arg(old_out.toString()) 3769 .arg(audioIn.toString()).arg(audioOut.toString())); 3770 3771 if (digInfo.sample_rate > 0) 3772 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 3773 3774 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 3775 digInfo.sample_rate, audioIn.do_passthru); 3776 // allow the audio stuff to reencode 3777 GetNVP()->SetAudioCodec(codec_ctx); 3778 GetNVP()->ReinitAudio(); 3779 return true; 3744 3780 } 3745 3781 else 3746 3782 { 3747 if (audioOut.channels > MAX_OUTPUT_CHANNELS)3783 if (audioOut.channels > max_channels) 3748 3784 { 3749 audioOut.channels = MAX_OUTPUT_CHANNELS;3785 audioOut.channels = max_channels; 3750 3786 audioOut.sample_size = audioOut.channels * 2; 3751 codec_ctx->channels = MAX_OUTPUT_CHANNELS;3787 codec_ctx->channels = audioOut.channels; 3752 3788 } 3753 3789 } 3790 bool audiook; 3754 3791 3755 3792 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 3756 3793 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") … … 3763 3800 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 3764 3801 audioOut.sample_rate, 3765 3802 audioIn.do_passthru); 3766 GetNVP()->ReinitAudio(); 3803 // allow the audio stuff to reencode 3804 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 3805 QString errMsg = GetNVP()->ReinitAudio(); 3806 audiook = errMsg.isEmpty(); 3767 3807 3768 3808 return true; 3769 3809 } -
libs/libmythtv/NuppelVideoPlayer.h
127 127 void SetAudioInfo(const QString &main, const QString &passthru, uint rate); 128 128 void SetAudioParams(int bits, int channels, int samplerate, bool passthru); 129 129 void SetEffDsp(int dsprate); 130 void SetAudioCodec(void *ac); 130 131 131 132 // Sets 132 133 void SetParentWidget(QWidget *widget) { parentWidget = widget; } … … 682 683 int audio_bits; 683 684 int audio_samplerate; 684 685 float audio_stretchfactor; 686 void *audio_codec; 685 687 bool audio_passthru; 686 688 687 689 // Picture-in-Picture -
libs/libmythtv/NuppelVideoPlayer.cpp
207 207 audio_passthru_device(QString::null), 208 208 audio_channels(2), audio_bits(-1), 209 209 audio_samplerate(44100), audio_stretchfactor(1.0f), 210 audio_codec(NULL), 210 211 // Picture-in-Picture 211 212 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 212 213 // Preview window support … … 768 769 if (audioOutput) 769 770 { 770 771 audioOutput->Reconfigure(audio_bits, audio_channels, 771 audio_samplerate, audio_passthru); 772 audio_samplerate, audio_passthru, 773 audio_codec); 772 774 errMsg = audioOutput->GetError(); 773 775 if (!errMsg.isEmpty()) 774 776 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3651 3658 audio_passthru = passthru; 3652 3659 } 3653 3660 3661 void NuppelVideoPlayer::SetAudioCodec(void* ac) 3662 { 3663 audio_codec = ac; 3664 } 3665 3654 3666 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3655 3667 { 3656 3668 if (audioOutput) -
libs/libavcodec/liba52.c
134 134 } 135 135 } 136 136 137 static inline int16_t convert(int32_t i) 138 { 139 return av_clip_int16(i - 0x43c00000); 140 } 141 142 void float2s16_2 (float * _f, int16_t * s16) 143 { 144 int i; 145 int32_t * f = (int32_t *) _f; 146 147 for (i = 0; i < 256; i++) { 148 s16[2*i] = convert (f[i]); 149 s16[2*i+1] = convert (f[i+256]); 150 } 151 } 152 153 void float2s16_4 (float * _f, int16_t * s16) 154 { 155 int i; 156 int32_t * f = (int32_t *) _f; 157 158 for (i = 0; i < 256; i++) { 159 s16[4*i] = convert (f[i]); 160 s16[4*i+1] = convert (f[i+256]); 161 s16[4*i+2] = convert (f[i+512]); 162 s16[4*i+3] = convert (f[i+768]); 163 } 164 } 165 166 void float2s16_5 (float * _f, int16_t * s16) 167 { 168 int i; 169 int32_t * f = (int32_t *) _f; 170 171 for (i = 0; i < 256; i++) { 172 s16[5*i] = convert (f[i]); 173 s16[5*i+1] = convert (f[i+256]); 174 s16[5*i+2] = convert (f[i+512]); 175 s16[5*i+3] = convert (f[i+768]); 176 s16[5*i+4] = convert (f[i+1024]); 177 } 178 } 179 180 #define LIKEAC3DEC 1 181 int channels_multi (int flags) 182 { 183 if (flags & A52_LFE) 184 return 6; 185 else if (flags & 1) /* center channel */ 186 return 5; 187 else if ((flags & A52_CHANNEL_MASK) == A52_2F2R) 188 return 4; 189 else 190 return 2; 191 } 192 193 void float2s16_multi (float * _f, int16_t * s16, int flags) 194 { 195 int i; 196 int32_t * f = (int32_t *) _f; 197 198 switch (flags) { 199 case A52_MONO: 200 for (i = 0; i < 256; i++) { 201 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; 202 s16[5*i+4] = convert (f[i]); 203 } 204 break; 205 case A52_CHANNEL: 206 case A52_STEREO: 207 case A52_DOLBY: 208 float2s16_2 (_f, s16); 209 break; 210 case A52_3F: 211 for (i = 0; i < 256; i++) { 212 s16[5*i] = convert (f[i]); 213 s16[5*i+1] = convert (f[i+512]); 214 s16[5*i+2] = s16[5*i+3] = 0; 215 s16[5*i+4] = convert (f[i+256]); 216 } 217 break; 218 case A52_2F2R: 219 float2s16_4 (_f, s16); 220 break; 221 case A52_3F2R: 222 float2s16_5 (_f, s16); 223 break; 224 case A52_MONO | A52_LFE: 225 for (i = 0; i < 256; i++) { 226 #if LIKEAC3DEC 227 s16[6*i] = s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 228 s16[6*i+1] = convert (f[i+256]); 229 s16[6*i+5] = convert (f[i]); 230 #else 231 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; 232 s16[6*i+4] = convert (f[i+256]); 233 s16[6*i+5] = convert (f[i]); 234 #endif 235 } 236 break; 237 case A52_CHANNEL | A52_LFE: 238 case A52_STEREO | A52_LFE: 239 case A52_DOLBY | A52_LFE: 240 for (i = 0; i < 256; i++) { 241 #if LIKEAC3DEC 242 s16[6*i] = convert (f[i+256]); 243 s16[6*i+2] = convert (f[i+512]); 244 s16[6*i+1] = s16[6*i+3] = s16[6*i+4] = 0; 245 s16[6*i+5] = convert (f[i]); 246 #else 247 s16[6*i] = convert (f[i+256]); 248 s16[6*i+1] = convert (f[i+512]); 249 s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 250 s16[6*i+5] = convert (f[i]); 251 #endif 252 } 253 break; 254 case A52_3F | A52_LFE: 255 for (i = 0; i < 256; i++) { 256 #if LIKEAC3DEC 257 s16[6*i] = convert (f[i+256]); 258 s16[6*i+2] = convert (f[i+768]); 259 s16[6*i+3] = s16[6*i+4] = 0; 260 s16[6*i+1] = convert (f[i+512]); 261 s16[6*i+5] = convert (f[i]); 262 #else 263 s16[6*i] = convert (f[i+256]); 264 s16[6*i+1] = convert (f[i+768]); 265 s16[6*i+2] = s16[6*i+3] = 0; 266 s16[6*i+4] = convert (f[i+512]); 267 s16[6*i+5] = convert (f[i]); 268 #endif 269 } 270 break; 271 case A52_2F2R | A52_LFE: 272 for (i = 0; i < 256; i++) { 273 #if LIKEAC3DEC 274 s16[6*i] = convert (f[i+256]); 275 s16[6*i+1] = 0; 276 s16[6*i+2] = convert (f[i+512]); 277 s16[6*i+3] = convert (f[i+768]); 278 s16[6*i+4] = convert (f[i+1024]); 279 s16[6*i+5] = convert (f[i]); 280 #else 281 s16[6*i] = convert (f[i+256]); 282 s16[6*i+1] = convert (f[i+512]); 283 s16[6*i+2] = convert (f[i+768]); 284 s16[6*i+3] = convert (f[i+1024]); 285 s16[6*i+4] = 0; 286 s16[6*i+5] = convert (f[i]); 287 #endif 288 } 289 break; 290 case A52_3F2R | A52_LFE: 291 for (i = 0; i < 256; i++) { 292 #if LIKEAC3DEC 293 s16[6*i] = convert (f[i+256]); 294 s16[6*i+1] = convert (f[i+512]); 295 s16[6*i+2] = convert (f[i+768]); 296 s16[6*i+3] = convert (f[i+1024]); 297 s16[6*i+4] = convert (f[i+1280]); 298 s16[6*i+5] = convert (f[i]); 299 #else 300 s16[6*i] = convert (f[i+256]); 301 s16[6*i+1] = convert (f[i+768]); 302 s16[6*i+2] = convert (f[i+1024]); 303 s16[6*i+3] = convert (f[i+1280]); 304 s16[6*i+4] = convert (f[i+512]); 305 s16[6*i+5] = convert (f[i]); 306 #endif 307 } 308 break; 309 } 310 } 311 137 312 /**** end */ 138 313 139 314 #define HEADER_SIZE 7 … … 177 352 /* update codec info */ 178 353 avctx->sample_rate = sample_rate; 179 354 s->channels = ac3_channels[s->flags & 7]; 355 if (avctx->cqp >= 0) 356 avctx->channels = avctx->cqp; 180 357 if (s->flags & A52_LFE) 181 358 s->channels++; 182 359 if (avctx->channels == 0) … … 199 376 s->inbuf_ptr += len; 200 377 buf_size -= len; 201 378 } else { 379 int chans; 202 380 flags = s->flags; 203 381 if (avctx->channels == 1) 204 382 flags = A52_MONO; 205 else if (avctx->channels == 2) 206 flags = A52_STEREO; 383 else if (avctx->channels == 2) { 384 if (s->channels>2) 385 flags = A52_DOLBY; 386 else 387 flags = A52_STEREO; 388 } 207 389 else 208 390 flags |= A52_ADJUST_LEVEL; 209 391 level = 1; 392 chans = channels_multi(flags); 210 393 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 211 394 fail: 212 395 av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); … … 217 400 for (i = 0; i < 6; i++) { 218 401 if (s->a52_block(s->state)) 219 402 goto fail; 220 float _to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);403 float2s16_multi(s->samples, out_samples + i * 256 * chans, flags); 221 404 } 222 405 s->inbuf_ptr = s->inbuf; 223 406 s->frame_size = 0; -
libs/libavcodec/ac3_parser.c
84 84 return 0; 85 85 } 86 86 87 staticint ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,87 /*static*/ int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, 88 88 int *bit_rate, int *samples) 89 89 { 90 90 int err;