Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 259009 | Differences between
and this patch

Collapse All | Expand All

(-)a/libs/libmyth/audiooutput.h (-2 / +2 lines)
Lines 34-44 Link Here
34
    virtual void Reconfigure(int audio_bits, 
34
    virtual void Reconfigure(int audio_bits, 
35
                             int audio_channels, 
35
                             int audio_channels, 
36
                             int audio_samplerate,
36
                             int audio_samplerate,
37
                             bool audio_passthru,
37
                             bool audio_passthru) = 0;
38
                             void* audio_codec = NULL) = 0;
39
    
38
    
40
    virtual void SetStretchFactor(float factor);
39
    virtual void SetStretchFactor(float factor);
41
    virtual float GetStretchFactor(void) { return 1.0f; }
40
    virtual float GetStretchFactor(void) { return 1.0f; }
41
    virtual bool ToggleUpmix(void) = 0;
42
42
43
    // do AddSamples calls block?
43
    // do AddSamples calls block?
44
    virtual void SetBlocking(bool blocking) = 0;
44
    virtual void SetBlocking(bool blocking) = 0;
(-)a/libs/libmyth/audiooutputalsa.cpp (-3 / +61 lines)
Lines 35-40 Link Here
35
AudioOutputALSA::~AudioOutputALSA()
35
AudioOutputALSA::~AudioOutputALSA()
36
{
36
{
37
    KillAudio();
37
    KillAudio();
38
    SetIECStatus(true);
39
}
40
41
void AudioOutputALSA::SetIECStatus(bool audio) {
42
    
43
    snd_ctl_t *ctl;
44
    const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT);
45
    int spdif_index = -1;
46
    snd_ctl_elem_list_t *clist;
47
    snd_ctl_elem_id_t *cid;
48
    snd_ctl_elem_value_t *cval;
49
    snd_aes_iec958_t iec958;
50
    int cidx, controls;
51
52
    VERBOSE(VB_AUDIO, QString("Setting IEC958 status: %1")
53
                      .arg(audio ? "audio" : "non-audio"));
54
    
55
    snd_ctl_open(&ctl, "default", 0);
56
    snd_ctl_elem_list_alloca(&clist);
57
    snd_ctl_elem_list(ctl, clist);
58
    snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist));
59
    snd_ctl_elem_list(ctl, clist);
60
    controls = snd_ctl_elem_list_get_used(clist);
61
    for (cidx = 0; cidx < controls; cidx++) 
62
    {
63
        if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str))
64
            if (spdif_index < 0 ||
65
                snd_ctl_elem_list_get_index(clist, cidx) == (uint)spdif_index)
66
                    break;
67
    }
68
69
    if (cidx >= controls)
70
        return;
71
72
    snd_ctl_elem_id_alloca(&cid);
73
    snd_ctl_elem_list_get_id(clist, cidx, cid);
74
    snd_ctl_elem_value_alloca(&cval);
75
    snd_ctl_elem_value_set_id(cval, cid);
76
    snd_ctl_elem_read(ctl,cval);
77
    snd_ctl_elem_value_get_iec958(cval, &iec958);
78
    
79
    if (!audio) 
80
        iec958.status[0] |= IEC958_AES0_NONAUDIO;
81
    else
82
        iec958.status[0] &= ~IEC958_AES0_NONAUDIO;
83
84
    snd_ctl_elem_value_set_iec958(cval, &iec958);
85
    snd_ctl_elem_write(ctl, cval);
86
38
}
87
}
39
88
40
bool AudioOutputALSA::OpenDevice()
89
bool AudioOutputALSA::OpenDevice()
Lines 42-56 Link Here
42
    snd_pcm_format_t format;
91
    snd_pcm_format_t format;
43
    unsigned int buffer_time, period_time;
92
    unsigned int buffer_time, period_time;
44
    int err;
93
    int err;
94
    QString real_device;
45
95
46
    if (pcm_handle != NULL)
96
    if (pcm_handle != NULL)
47
        CloseDevice();
97
        CloseDevice();
48
98
49
    pcm_handle = NULL;
99
    pcm_handle = NULL;
50
    numbadioctls = 0;
100
    numbadioctls = 0;
51
101
    
52
    QString real_device = (audio_passthru) ?
102
    if (audio_passthru || audio_enc)
53
        audio_passthru_device : audio_main_device;
103
    {
104
        real_device = audio_passthru_device;
105
        SetIECStatus(false);
106
    }
107
    else 
108
    {
109
        real_device = audio_main_device;
110
        SetIECStatus(true);
111
    }
54
112
55
    VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.")
113
    VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.")
56
            .arg(real_device));
114
            .arg(real_device));
(-)a/libs/libmyth/audiooutputalsa.h (+1 lines)
Lines 37-42 Link Here
37
    virtual inline int getBufferedOnSoundcard(void);
37
    virtual inline int getBufferedOnSoundcard(void);
38
38
39
  private:
39
  private:
40
    void SetIECStatus(bool audio);
40
    inline int SetParameters(snd_pcm_t *handle,
41
    inline int SetParameters(snd_pcm_t *handle,
41
                             snd_pcm_format_t format, unsigned int channels,
42
                             snd_pcm_format_t format, unsigned int channels,
42
                             unsigned int rate, unsigned int buffer_time,
43
                             unsigned int rate, unsigned int buffer_time,
(-)a/libs/libmyth/audiooutputbase.cpp (-290 / +213 lines)
Lines 37-45 Link Here
37
37
38
    audio_main_device(QDeepCopy<QString>(laudio_main_device)),
38
    audio_main_device(QDeepCopy<QString>(laudio_main_device)),
39
    audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)),
39
    audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)),
40
    audio_passthru(false),      audio_stretchfactor(1.0f),
40
    audio_passthru(false),      audio_enc(false),
41
    audio_reenc(false),         audio_stretchfactor(1.0f),
41
42
42
    audio_codec(NULL),
43
    source(lsource),            killaudio(false),
43
    source(lsource),            killaudio(false),
44
44
45
    pauseaudio(false),          audio_actually_paused(false),
45
    pauseaudio(false),          audio_actually_paused(false),
Lines 54-63 Link Here
54
    pSoundStretch(NULL),        
54
    pSoundStretch(NULL),        
55
    encoder(NULL),
55
    encoder(NULL),
56
    upmixer(NULL),
56
    upmixer(NULL),
57
57
    source_audio_channels(-1),
58
    source_audio_channels(-1),
59
    source_audio_samplerate(0),
58
    source_audio_bytes_per_sample(0),
60
    source_audio_bytes_per_sample(0),
59
    needs_upmix(false),
61
    needs_upmix(false),
60
    surround_mode(FreeSurround::SurroundModePassive),
62
    surround_mode(FreeSurround::SurroundModePassive),
63
    old_audio_stretchfactor(1.0),
61
64
62
    blocking(false),
65
    blocking(false),
63
66
Lines 84-89 Link Here
84
    memset(&audiotime_updated, 0, sizeof(audiotime_updated));
87
    memset(&audiotime_updated, 0, sizeof(audiotime_updated));
85
    memset(audiobuffer,        0, sizeof(char)  * AUDBUFSIZE);
88
    memset(audiobuffer,        0, sizeof(char)  * AUDBUFSIZE);
86
    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
89
    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
90
    orig_config_channels = configured_audio_channels;
91
    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
92
    src_quality = gContext->GetNumSetting("SRCQuality", 2);
87
93
88
    // You need to call Reconfigure from your concrete class.
94
    // You need to call Reconfigure from your concrete class.
89
    // Reconfigure(laudio_bits,       laudio_channels,
95
    // Reconfigure(laudio_bits,       laudio_channels,
Lines 124-163 Link Here
124
            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
130
            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
125
                                        .arg(audio_stretchfactor));
131
                                        .arg(audio_stretchfactor));
126
            pSoundStretch = new soundtouch::SoundTouch();
132
            pSoundStretch = new soundtouch::SoundTouch();
127
            if (audio_codec)
133
            pSoundStretch->setSampleRate(audio_samplerate);
128
            {
134
            pSoundStretch->setChannels(upmixer ? 
129
                if (!encoder)
135
                configured_audio_channels : source_audio_channels);
130
                {
131
                    VERBOSE(VB_AUDIO, LOC +
132
                            QString("Creating Encoder for codec %1 origfs %2")
133
                            .arg(audio_codec->codec_id)
134
                            .arg(audio_codec->frame_size));
135
136
                    encoder = new AudioOutputDigitalEncoder();
137
                    if (!encoder->Init(audio_codec->codec_id,
138
                                audio_codec->bit_rate,
139
                                audio_codec->sample_rate,
140
                                audio_codec->channels
141
                                ))
142
                    {
143
                        // eeks
144
                        delete encoder;
145
                        encoder = NULL;
146
                        VERBOSE(VB_AUDIO, LOC +
147
                                QString("Failed to Create Encoder"));
148
                    }
149
                }
150
            }
151
            if (audio_codec && encoder)
152
            {
153
                pSoundStretch->setSampleRate(audio_codec->sample_rate);
154
                pSoundStretch->setChannels(audio_codec->channels);
155
            }
156
            else
157
            {
158
                pSoundStretch->setSampleRate(audio_samplerate);
159
                pSoundStretch->setChannels(audio_channels);
160
            }
161
136
162
            pSoundStretch->setTempo(audio_stretchfactor);
137
            pSoundStretch->setTempo(audio_stretchfactor);
163
            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
138
            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
Lines 165-171 Link Here
165
            // dont need these with only tempo change
140
            // dont need these with only tempo change
166
            //pSoundStretch->setPitch(1.0);
141
            //pSoundStretch->setPitch(1.0);
167
            //pSoundStretch->setRate(1.0);
142
            //pSoundStretch->setRate(1.0);
168
169
            //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true);
143
            //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true);
170
            //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false);
144
            //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false);
171
        }
145
        }
Lines 184-218 Link Here
184
    return audio_stretchfactor;
158
    return audio_stretchfactor;
185
}
159
}
186
160
161
bool AudioOutputBase::ToggleUpmix(void)
162
{
163
    if (orig_config_channels == 2 || audio_passthru)
164
        return false;
165
    if (configured_audio_channels == 6)
166
        configured_audio_channels = 2;
167
    else
168
        configured_audio_channels = 6;
169
    
170
    Reconfigure(audio_bits, source_audio_channels, 
171
        source_audio_samplerate, audio_passthru);
172
    return (configured_audio_channels == 6);
173
}
174
187
void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 
175
void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 
188
                                  int laudio_samplerate, bool laudio_passthru,
176
                                  int laudio_samplerate, bool laudio_passthru)
189
                                  void *laudio_codec)
190
{
177
{
191
    int codec_id = CODEC_ID_NONE;
192
    int lcodec_id = CODEC_ID_NONE;
193
    int lcchannels = 0;
194
    int cchannels = 0;
195
    int lsource_audio_channels = laudio_channels;
178
    int lsource_audio_channels = laudio_channels;
196
    bool lneeds_upmix = false;
179
    bool lneeds_upmix = false;
197
180
    bool laudio_reenc = false;
198
    if (laudio_codec)
181
   
199
    {
182
    // Are we perhaps reencoding a (previously) timestretched bitstream?
200
        lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
183
    if (laudio_channels > 2 && !laudio_passthru)
201
        laudio_bits = 16;
184
        laudio_reenc = true;
202
        laudio_channels = 2;
185
  
203
        lsource_audio_channels = laudio_channels;
186
    // Enough channels? Upmix if not
204
        laudio_samplerate = 48000;
187
    if (laudio_channels < configured_audio_channels && !laudio_passthru)
205
        lcchannels = ((AVCodecContext*)laudio_codec)->channels;
206
    }
207
208
    if (audio_codec)
209
    {
210
        codec_id = audio_codec->codec_id;
211
        cchannels = ((AVCodecContext*)audio_codec)->channels;
212
    }
213
214
    if ((configured_audio_channels == 6) && 
215
        !(laudio_codec || audio_codec))
216
    {
188
    {
217
        laudio_channels = configured_audio_channels;
189
        laudio_channels = configured_audio_channels;
218
        lneeds_upmix = true;
190
        lneeds_upmix = true;
Lines 225-231 Link Here
225
        laudio_samplerate == audio_samplerate && !need_resampler &&
197
        laudio_samplerate == audio_samplerate && !need_resampler &&
226
        laudio_passthru == audio_passthru &&
198
        laudio_passthru == audio_passthru &&
227
        lneeds_upmix == needs_upmix &&
199
        lneeds_upmix == needs_upmix &&
228
        lcodec_id == codec_id && lcchannels == cchannels);
200
        laudio_reenc == audio_reenc);
229
    bool upmix_deps =
201
    bool upmix_deps =
230
        (lsource_audio_channels == source_audio_channels);
202
        (lsource_audio_channels == source_audio_channels);
231
    if (general_deps && upmix_deps)
203
    if (general_deps && upmix_deps)
Lines 252-263 Link Here
252
    waud = raud = 0;
224
    waud = raud = 0;
253
    audio_actually_paused = false;
225
    audio_actually_paused = false;
254
    
226
    
255
    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
256
    audio_channels = laudio_channels;
227
    audio_channels = laudio_channels;
257
    source_audio_channels = lsource_audio_channels;
228
    source_audio_channels = lsource_audio_channels;
258
    audio_bits = laudio_bits;
229
    audio_bits = laudio_bits;
259
    audio_samplerate = laudio_samplerate;
230
    source_audio_samplerate = audio_samplerate = laudio_samplerate;
260
    audio_codec = (AVCodecContext*)laudio_codec;
231
    audio_reenc = laudio_reenc;
261
    audio_passthru = laudio_passthru;
232
    audio_passthru = laudio_passthru;
262
    needs_upmix = lneeds_upmix;
233
    needs_upmix = lneeds_upmix;
263
234
Lines 268-275 Link Here
268
        Error("AudioOutput only supports 8 or 16bit audio.");
239
        Error("AudioOutput only supports 8 or 16bit audio.");
269
        return;
240
        return;
270
    }
241
    }
271
    audio_bytes_per_sample = audio_channels * audio_bits / 8;
272
    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
273
    
242
    
274
    need_resampler = false;
243
    need_resampler = false;
275
    killaudio = false;
244
    killaudio = false;
Lines 278-284 Link Here
278
    internal_vol = gContext->GetNumSetting("MythControlsVolume", 0);
247
    internal_vol = gContext->GetNumSetting("MythControlsVolume", 0);
279
    
248
    
280
    numlowbuffer = 0;
249
    numlowbuffer = 0;
250
    
251
    // Encode to AC-3 if not passing thru, there's more than 2 channels
252
    // and we're allowed to passthru AC-3
253
    // This won't reencode timestretched 2ch AC-3 but there's no point doing so
254
    if (!audio_passthru && audio_channels > 2 && allow_ac3_passthru) 
255
    {
256
        VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder");
257
        int srate = src_quality == 0 ? audio_samplerate : 48000;
258
        encoder = new AudioOutputDigitalEncoder();
259
        if (!encoder->Init(CODEC_ID_AC3, 448000, srate, 
260
                           audio_channels, audio_reenc)) 
261
        {
262
            VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder");
263
            delete encoder;
264
            encoder = NULL;
265
        }
266
        
267
        audio_enc = true;
268
    }        
269
    
270
    if(audio_passthru || audio_enc)
271
        // AC-3 output - soundcard expects a 2ch 48k stream
272
	audio_channels = 2;
273
    
274
    audio_bytes_per_sample = audio_channels * audio_bits / 8;
275
    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
281
276
277
    // Always resample to 48k - many cards can't do anything else
278
    // and ALSA will do it with linear interpolation (yuk) if we don't anyway
279
    if (src_quality != 0 && audio_samplerate != 48000)
280
    {
281
        int error;
282
        audio_samplerate = 48000;
283
        VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")
284
            .arg(laudio_samplerate).arg(audio_samplerate));
285
        src_ctx = src_new(3-src_quality, audio_channels, &error);
286
        if (error)
287
        {
288
            Error(QString("Error creating resampler, the error was: %1")
289
                  .arg(src_strerror(error)) );
290
            pthread_mutex_unlock(&avsync_lock);
291
            pthread_mutex_unlock(&audio_buflock);
292
	    src_ctx = NULL;
293
            return;
294
        }
295
        src_data.src_ratio = (double) audio_samplerate / laudio_samplerate;
296
        src_data.data_in = src_in;
297
        src_data.data_out = src_out;
298
        src_data.output_frames = 16384*6;
299
        need_resampler = true;
300
    }
301
    
282
    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
302
    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
283
            .arg(audio_main_device).arg(audio_channels)
303
            .arg(audio_main_device).arg(audio_channels)
284
            .arg(source_audio_channels).arg(audio_samplerate));
304
            .arg(source_audio_channels).arg(audio_samplerate));
Lines 314-345 Link Here
314
    current_seconds = -1;
334
    current_seconds = -1;
315
    source_bitrate = -1;
335
    source_bitrate = -1;
316
336
317
    // NOTE: this won't do anything as above samplerate vars are set equal
318
    // Check if we need the resampler
319
    if (audio_samplerate != laudio_samplerate)
320
    {
321
        int error;
322
        VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")
323
                               .arg(laudio_samplerate).arg(audio_samplerate));
324
        src_ctx = src_new (SRC_SINC_BEST_QUALITY, audio_channels, &error);
325
        if (error)
326
        {
327
            Error(QString("Error creating resampler, the error was: %1")
328
                  .arg(src_strerror(error)) );
329
            pthread_mutex_unlock(&avsync_lock);
330
            pthread_mutex_unlock(&audio_buflock);
331
            return;
332
        }
333
        src_data.src_ratio = (double) audio_samplerate / laudio_samplerate;
334
        src_data.data_in = src_in;
335
        src_data.data_out = src_out;
336
        src_data.output_frames = 16384*6;
337
        need_resampler = true;
338
    }
339
340
    if (needs_upmix)
337
    if (needs_upmix)
341
    {
338
    {
342
        VERBOSE(VB_AUDIO, LOC + QString("create upmixer"));
343
        if (configured_audio_channels == 6)
339
        if (configured_audio_channels == 6)
344
        {
340
        {
345
            surround_mode = gContext->GetNumSetting("AudioUpmixType", 2);
341
            surround_mode = gContext->GetNumSetting("AudioUpmixType", 2);
Lines 351-414 Link Here
351
            (FreeSurround::SurroundMode)surround_mode);
347
            (FreeSurround::SurroundMode)surround_mode);
352
348
353
        VERBOSE(VB_AUDIO, LOC +
349
        VERBOSE(VB_AUDIO, LOC +
354
                QString("create upmixer done with surround mode %1")
350
                QString("Create upmixer done with surround mode %1")
355
                .arg(surround_mode));
351
                .arg(surround_mode));
356
    }
352
    }
357
353
358
    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
354
    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
359
            .arg(audio_stretchfactor));
355
            .arg(audio_stretchfactor));
360
    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
361
            .arg((audio_codec) ?
362
                 codec_id_string(audio_codec->codec_id) : "not set"));
363
356
364
    if (redo_stretch)
357
    SetStretchFactorLocked(old_audio_stretchfactor);
365
    {
366
        float laudio_stretchfactor = audio_stretchfactor;
367
        delete pSoundStretch;
368
        pSoundStretch = NULL;
369
        audio_stretchfactor = 0.0f;
370
        SetStretchFactorLocked(laudio_stretchfactor);
371
    }
372
    else
373
    {
374
        SetStretchFactorLocked(audio_stretchfactor);
375
        if (pSoundStretch)
376
        {
377
            // if its passthru then we need to reencode
378
            if (audio_codec)
379
            {
380
                if (!encoder)
381
                {
382
                    VERBOSE(VB_AUDIO, LOC +
383
                            QString("Creating Encoder for codec %1")
384
                            .arg(audio_codec->codec_id));
385
386
                    encoder = new AudioOutputDigitalEncoder();
387
                    if (!encoder->Init(audio_codec->codec_id,
388
                                audio_codec->bit_rate,
389
                                audio_codec->sample_rate,
390
                                audio_codec->channels
391
                                ))
392
                    {
393
                        // eeks
394
                        delete encoder;
395
                        encoder = NULL;
396
                        VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");
397
                    }
398
                }
399
            }
400
            if (audio_codec && encoder)
401
            {
402
                pSoundStretch->setSampleRate(audio_codec->sample_rate);
403
                pSoundStretch->setChannels(audio_codec->channels);
404
            }
405
            else
406
            {
407
                pSoundStretch->setSampleRate(audio_samplerate);
408
                pSoundStretch->setChannels(audio_channels);
409
            }
410
        }
411
    }
412
358
413
    // Setup visualisations, zero the visualisations buffers
359
    // Setup visualisations, zero the visualisations buffers
414
    prepareVisuals();
360
    prepareVisuals();
Lines 455-464 Link Here
455
    VERBOSE(VB_AUDIO, LOC + "Killing AudioOutputDSP");
401
    VERBOSE(VB_AUDIO, LOC + "Killing AudioOutputDSP");
456
    killaudio = true;
402
    killaudio = true;
457
    StopOutputThread();
403
    StopOutputThread();
404
    
405
    pthread_mutex_lock(&audio_buflock);
458
406
459
    // Close resampler?
407
    // Close resampler?
460
    if (src_ctx)
408
    if (src_ctx)
409
    {
461
        src_delete(src_ctx);
410
        src_delete(src_ctx);
411
        src_ctx = NULL;
412
    }
413
		
462
    need_resampler = false;
414
    need_resampler = false;
463
415
464
    // close sound stretcher
416
    // close sound stretcher
Lines 466-471 Link Here
466
    {
418
    {
467
        delete pSoundStretch;
419
        delete pSoundStretch;
468
        pSoundStretch = NULL;
420
        pSoundStretch = NULL;
421
        old_audio_stretchfactor = audio_stretchfactor;
422
        audio_stretchfactor = 1.0;
469
    }
423
    }
470
424
471
    if (encoder)
425
    if (encoder)
Lines 480-488 Link Here
480
        upmixer = NULL;
434
        upmixer = NULL;
481
    }
435
    }
482
    needs_upmix = false;
436
    needs_upmix = false;
437
    audio_enc = false;
483
438
484
    CloseDevice();
439
    CloseDevice();
485
440
441
    pthread_mutex_unlock(&audio_buflock);
486
    killAudioLock.unlock();
442
    killAudioLock.unlock();
487
}
443
}
488
444
Lines 591-597 Link Here
591
    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
547
    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
592
    ret = (long long)(ret * audio_stretchfactor);
548
    ret = (long long)(ret * audio_stretchfactor);
593
549
594
#if 1
595
    VERBOSE(VB_AUDIO|VB_TIMESTAMP, 
550
    VERBOSE(VB_AUDIO|VB_TIMESTAMP, 
596
            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
551
            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
597
            .arg(now.tv_sec).arg(now.tv_usec)
552
            .arg(now.tv_sec).arg(now.tv_usec)
Lines 600-606 Link Here
600
            .arg(audiotime)
555
            .arg(audiotime)
601
            .arg(audio_stretchfactor)
556
            .arg(audio_stretchfactor)
602
           );
557
           );
603
#endif
604
558
605
    ret += audiotime;
559
    ret += audiotime;
606
560
Lines 638-666 Link Here
638
 
592
 
639
    soundcard_buffer = getBufferedOnSoundcard(); // bytes
593
    soundcard_buffer = getBufferedOnSoundcard(); // bytes
640
    totalbuffer = audiolen(false) + soundcard_buffer;
594
    totalbuffer = audiolen(false) + soundcard_buffer;
641
 
595
642
    // include algorithmic latencies
596
    // include algorithmic latencies
643
    if (pSoundStretch)
597
    if (pSoundStretch)
644
    {
645
        // add the effect of any unused but processed samples,
646
        // AC3 reencode does this
647
        totalbuffer += (int)(pSoundStretch->numSamples() *
648
                             audio_bytes_per_sample);
649
        // add the effect of unprocessed samples in time stretch algo
650
        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
598
        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
651
                              audio_bytes_per_sample) / audio_stretchfactor);
599
                              audio_bytes_per_sample) / audio_stretchfactor);
652
    }
653
600
654
    if (upmixer && needs_upmix)
601
    if (upmixer && needs_upmix)
655
    {
656
        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
602
        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
657
    }
603
604
    if (encoder) 
605
        totalbuffer += encoder->Buffered();
658
606
659
    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
607
    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
660
                                   (audio_bytes_per_sample * effdspstretched));
608
                                   (audio_bytes_per_sample * effdspstretched));
661
 
609
 
662
    gettimeofday(&audiotime_updated, NULL);
610
    gettimeofday(&audiotime_updated, NULL);
663
#if 1
611
    
664
    VERBOSE(VB_AUDIO|VB_TIMESTAMP, 
612
    VERBOSE(VB_AUDIO|VB_TIMESTAMP, 
665
            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 "
613
            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 "
666
                    "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
614
                    "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
Lines 672-678 Link Here
672
            .arg(effdspstretched)
620
            .arg(effdspstretched)
673
            .arg(audio_bytes_per_sample)
621
            .arg(audio_bytes_per_sample)
674
            .arg(audio_stretchfactor));
622
            .arg(audio_stretchfactor));
675
#endif
676
623
677
    pthread_mutex_unlock(&avsync_lock);
624
    pthread_mutex_unlock(&avsync_lock);
678
    pthread_mutex_unlock(&audio_buflock);
625
    pthread_mutex_unlock(&audio_buflock);
Lines 686-692 Link Here
686
    int abps = (encoder) ?
633
    int abps = (encoder) ?
687
        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
634
        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
688
    int len = samples * abps;
635
    int len = samples * abps;
689
636
 
690
    // Check we have enough space to write the data
637
    // Check we have enough space to write the data
691
    if (need_resampler && src_ctx)
638
    if (need_resampler && src_ctx)
692
        len = (int)ceilf(float(len) * src_data.src_ratio);
639
        len = (int)ceilf(float(len) * src_data.src_ratio);
Lines 708-713 Link Here
708
655
709
        return false; // would overflow
656
        return false; // would overflow
710
    }
657
    }
658
    
659
    pthread_mutex_lock(&audio_buflock);
711
660
712
    // resample input if necessary
661
    // resample input if necessary
713
    if (need_resampler && src_ctx) 
662
    if (need_resampler && src_ctx) 
Lines 741-746 Link Here
741
        // Call our function to do the work
690
        // Call our function to do the work
742
        _AddSamples(buffers, false, samples, timecode);
691
        _AddSamples(buffers, false, samples, timecode);
743
    }
692
    }
693
    
694
    pthread_mutex_unlock(&audio_buflock);
744
695
745
    return true;
696
    return true;
746
}
697
}
Lines 753-758 Link Here
753
    int abps = (encoder) ?
704
    int abps = (encoder) ?
754
        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
705
        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
755
    int len = samples * abps;
706
    int len = samples * abps;
707
 
708
    // Give original samples to mythmusic visualisation
709
    dispatchVisual((unsigned char *)buffer, len, timecode,
710
                   source_audio_channels, audio_bits);
756
711
757
    // Check we have enough space to write the data
712
    // Check we have enough space to write the data
758
    if (need_resampler && src_ctx)
713
    if (need_resampler && src_ctx)
Lines 776-781 Link Here
776
                .arg(timecode)); 
731
                .arg(timecode)); 
777
        return false; // would overflow
732
        return false; // would overflow
778
    }
733
    }
734
    
735
    pthread_mutex_lock(&audio_buflock);
779
736
780
    // resample input if necessary
737
    // resample input if necessary
781
    if (need_resampler && src_ctx) 
738
    if (need_resampler && src_ctx) 
Lines 804-809 Link Here
804
        // Call our function to do the work
761
        // Call our function to do the work
805
        _AddSamples(buffer, true, samples, timecode);
762
        _AddSamples(buffer, true, samples, timecode);
806
    }
763
    }
764
    
765
    pthread_mutex_unlock(&audio_buflock);
807
766
808
    return true;
767
    return true;
809
}
768
}
Lines 836-845 Link Here
836
            if (src_ctx) 
795
            if (src_ctx) 
837
            {
796
            {
838
                int error = src_reset(src_ctx);
797
                int error = src_reset(src_ctx);
839
                if (error)
798
                if (error) 
799
                {
840
                    VERBOSE(VB_IMPORTANT, LOC_ERR + QString(
800
                    VERBOSE(VB_IMPORTANT, LOC_ERR + QString(
841
                            "Error occured while resetting resampler: %1")
801
                            "Error occured while resetting resampler: %1")
842
                            .arg(src_strerror(error)));
802
                            .arg(src_strerror(error)));
803
                    src_ctx = NULL;
804
                }
843
            }
805
            }
844
        }
806
        }
845
    }
807
    }
Lines 849-856 Link Here
849
void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 
811
void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 
850
                                  long long timecode)
812
                                  long long timecode)
851
{
813
{
852
    pthread_mutex_lock(&audio_buflock);
853
854
    int len; // = samples * audio_bytes_per_sample;
814
    int len; // = samples * audio_bytes_per_sample;
855
    int audio_bytes = audio_bits / 8;
815
    int audio_bytes = audio_bits / 8;
856
    int org_waud = waud;
816
    int org_waud = waud;
Lines 867-883 Link Here
867
            .arg(samples * abps)
827
            .arg(samples * abps)
868
            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
828
            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
869
            .arg(needs_upmix));
829
            .arg(needs_upmix));
830
831
    len = WaitForFreeSpace(samples);
870
    
832
    
871
    if (upmixer && needs_upmix)
833
    if (upmixer && needs_upmix)
872
    {
834
    {
873
        int out_samples = 0;
835
        int out_samples = 0;
836
        org_waud = waud;
874
        int step = (interleaved)?source_audio_channels:1;
837
        int step = (interleaved)?source_audio_channels:1;
875
        len = WaitForFreeSpace(samples);    // test
838
	
876
        for (int itemp = 0; itemp < samples; )
839
        for (int itemp = 0; itemp < samples; )
877
        {
840
        {
878
            // just in case it does a processing cycle, release the lock
879
            // to allow the output loop to do output
880
            pthread_mutex_unlock(&audio_buflock);
881
            if (audio_bytes == 2)
841
            if (audio_bytes == 2)
882
            {
842
            {
883
                itemp += upmixer->putSamples(
843
                itemp += upmixer->putSamples(
Lines 894-900 Link Here
894
                    source_audio_channels,
854
                    source_audio_channels,
895
                    (interleaved) ? 0 : samples);
855
                    (interleaved) ? 0 : samples);
896
            }
856
            }
897
            pthread_mutex_lock(&audio_buflock);
898
857
899
            int copy_samples = upmixer->numSamples();
858
            int copy_samples = upmixer->numSamples();
900
            if (copy_samples)
859
            if (copy_samples)
Lines 913-922 Link Here
913
                        (short*)(audiobuffer), (copy_samples - bdiff_samples));
872
                        (short*)(audiobuffer), (copy_samples - bdiff_samples));
914
                }
873
                }
915
                else
874
                else
916
                {
917
                    upmixer->receiveSamples(
875
                    upmixer->receiveSamples(
918
                        (short*)(audiobuffer + org_waud), copy_samples);
876
                        (short*)(audiobuffer + org_waud), copy_samples);
919
                }
877
                
920
                org_waud = (org_waud + copy_len) % AUDBUFSIZE;
878
                org_waud = (org_waud + copy_len) % AUDBUFSIZE;
921
            }
879
            }
922
        }
880
        }
Lines 928-935 Link Here
928
    }
886
    }
929
    else
887
    else
930
    {
888
    {
931
        len = WaitForFreeSpace(samples);
932
933
        if (interleaved) 
889
        if (interleaved) 
934
        {
890
        {
935
            char *mybuf = (char*)buffer;
891
            char *mybuf = (char*)buffer;
Lines 964-1101 Link Here
964
            }
920
            }
965
        }
921
        }
966
    }
922
    }
967
923
    
968
    if (samples > 0)
924
    if (samples <= 0)
925
        return;
926
    
927
    if (pSoundStretch)
969
    {
928
    {
970
        if (pSoundStretch)
929
        // does not change the timecode, only the number of samples
971
        {
930
        // back to orig pos
972
931
        org_waud = waud;
973
            // does not change the timecode, only the number of samples
932
        int bdiff = AUDBUFSIZE - org_waud;
974
            // back to orig pos
933
        int nSamplesToEnd = bdiff/abps;
975
            org_waud = waud;
934
        if (bdiff < len)
976
            int bdiff = AUDBUFSIZE - org_waud;
935
        {
977
            int nSamplesToEnd = bdiff/abps;
936
            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
978
            if (bdiff < len)
937
                                      (audiobuffer + 
979
            {
938
                                       org_waud), nSamplesToEnd);
980
                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
939
            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
981
                                          (audiobuffer + 
940
                                      (len - bdiff) / abps);
982
                                           org_waud), nSamplesToEnd);
941
        }
983
                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
942
        else
984
                                          (len - bdiff) / abps);
943
            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
985
            }
944
                                      (audiobuffer + org_waud),
986
            else
945
                                      len / abps);
987
            {
988
                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
989
                                          (audiobuffer + org_waud),
990
                                          len / abps);
991
            }
992
993
            if (encoder)
994
            {
995
                // pull out a packet's worth and reencode it until we
996
                // don't have enough for any more packets
997
                soundtouch::SAMPLETYPE *temp_buff = 
998
                    (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
999
                size_t frameSize = encoder->FrameSize()/abps;
1000
1001
                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
1002
                        QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
1003
                        .arg(frameSize)
1004
                        .arg(encoder->FrameSize())
1005
                        .arg(pSoundStretch->numSamples()));
1006
1007
                // process the same number of samples as it creates
1008
                // a full encoded buffer just like before
1009
                while (pSoundStretch->numSamples() >= frameSize)
1010
                {
1011
                    int got = pSoundStretch->receiveSamples(
1012
                        temp_buff, frameSize);
1013
                    int amount = encoder->Encode(temp_buff);
1014
1015
                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, 
1016
                            QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
1017
                            .arg(amount)
1018
                            .arg(got)
1019
                            .arg(pSoundStretch->numSamples()));
1020
1021
                    if (!amount)
1022
                        continue;
1023
1024
                    //len = WaitForFreeSpace(amount);
1025
                    char *ob = encoder->GetOutBuff();
1026
                    if (amount >= bdiff)
1027
                    {
1028
                        memcpy(audiobuffer + org_waud, ob, bdiff);
1029
                        ob += bdiff;
1030
                        amount -= bdiff;
1031
                        org_waud = 0;
1032
                    }
1033
                    if (amount > 0)
1034
                        memcpy(audiobuffer + org_waud, ob, amount);
1035
946
1036
                    bdiff = AUDBUFSIZE - amount;
947
        int nSamples = pSoundStretch->numSamples();
1037
                    org_waud += amount;
948
        len = WaitForFreeSpace(nSamples); 
1038
                }
949
        
1039
            }
950
        while ((nSamples = pSoundStretch->numSamples())) 
1040
            else
951
        {
1041
            {
952
            if (nSamples > nSamplesToEnd) 
1042
                int newLen = 0;
953
                nSamples = nSamplesToEnd;
1043
                int nSamples;
954
            
1044
                len = WaitForFreeSpace(pSoundStretch->numSamples() * 
955
            nSamples = pSoundStretch->receiveSamples(
1045
                                       audio_bytes_per_sample);
956
                (soundtouch::SAMPLETYPE*)
1046
                do 
957
                (audiobuffer + org_waud), nSamples
1047
                {
958
            );
1048
                    int samplesToGet = len/audio_bytes_per_sample;
959
            
1049
                    if (samplesToGet > nSamplesToEnd)
960
            if (nSamples == nSamplesToEnd) {
1050
                    {
961
                org_waud = 0;
1051
                        samplesToGet = nSamplesToEnd;    
962
                nSamplesToEnd = AUDBUFSIZE/abps;
1052
                    }
963
            }
1053
964
            else {
1054
                    nSamples = pSoundStretch->receiveSamples(
965
                org_waud += nSamples * abps;
1055
                        (soundtouch::SAMPLETYPE*)
966
                nSamplesToEnd -= nSamples;
1056
                        (audiobuffer + org_waud), samplesToGet);
1057
                    if (nSamples == nSamplesToEnd)
1058
                    {
1059
                        org_waud = 0;
1060
                        nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
1061
                    }
1062
                    else
1063
                    {
1064
                        org_waud += nSamples * audio_bytes_per_sample;
1065
                        nSamplesToEnd -= nSamples;
1066
                    }
1067
1068
                    newLen += nSamples * audio_bytes_per_sample;
1069
                    len -= nSamples * audio_bytes_per_sample;
1070
                } while (nSamples > 0);
1071
            }
967
            }
968
            
1072
        }
969
        }
970
        
971
    }
1073
972
1074
        waud = org_waud;
973
    // Encode to AC-3? 
1075
        lastaudiolen = audiolen(false);
974
    if (encoder) 
975
    {
976
        
977
        org_waud = waud;
978
        int bdiff = AUDBUFSIZE - org_waud;
979
        int to_get = 0;
1076
980
1077
        if (timecode < 0)
981
        if (bdiff < len) 
1078
        {
982
        {
1079
            // mythmusic doesn't give timestamps..
983
            encoder->Encode(audiobuffer + org_waud, bdiff);
1080
            timecode = (int)((samples_buffered * 100000.0) / effdsp);
984
            to_get = encoder->Encode(audiobuffer, len - bdiff);
1081
        }
985
        }
986
        else 
987
            to_get = encoder->Encode(audiobuffer + org_waud, len);
1082
        
988
        
1083
        samples_buffered += samples;
989
        if (to_get > 0) 
1084
        
1085
        /* we want the time at the end -- but the file format stores
1086
           time at the start of the chunk. */
1087
        // even with timestretch, timecode is still calculated from original
1088
        // sample count
1089
        audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
1090
1091
        if (interleaved)
1092
        {
990
        {
1093
            dispatchVisual((unsigned char *)buffer, len, timecode,
991
            
1094
                           source_audio_channels, audio_bits);
992
            if (to_get >= bdiff)
993
            {
994
                encoder->GetFrames(audiobuffer + org_waud, bdiff);
995
                to_get -= bdiff;
996
                org_waud = 0;
997
            }
998
            if (to_get > 0)
999
                encoder->GetFrames(audiobuffer + org_waud, to_get);
1000
1001
            org_waud += to_get;
1002
1095
        }
1003
        }
1004
1096
    }
1005
    }
1097
1006
1098
    pthread_mutex_unlock(&audio_buflock);
1007
    waud = org_waud;
1008
    lastaudiolen = audiolen(false);
1009
1010
    if (timecode < 0)
1011
        // mythmusic doesn't give timestamps..
1012
        timecode = (int)((samples_buffered * 100000.0) / effdsp);
1013
    
1014
    samples_buffered += samples;
1015
    
1016
    /* we want the time at the end -- but the file format stores
1017
       time at the start of the chunk. */
1018
    // even with timestretch, timecode is still calculated from original
1019
    // sample count
1020
    audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
1021
1099
}
1022
}
1100
1023
1101
void AudioOutputBase::Status()
1024
void AudioOutputBase::Status()
(-)a/libs/libmyth/audiooutputbase.h (-3 / +9 lines)
Lines 48-55 Link Here
48
    virtual void Reconfigure(int   audio_bits, 
48
    virtual void Reconfigure(int   audio_bits, 
49
                             int   audio_channels, 
49
                             int   audio_channels, 
50
                             int   audio_samplerate,
50
                             int   audio_samplerate,
51
                             bool  audio_passthru,
51
                             bool  audio_passthru);
52
                             void *audio_codec = NULL);
53
    
52
    
54
    // do AddSamples calls block?
53
    // do AddSamples calls block?
55
    virtual void SetBlocking(bool blocking);
54
    virtual void SetBlocking(bool blocking);
Lines 59-64 Link Here
59
58
60
    virtual void SetStretchFactor(float factor);
59
    virtual void SetStretchFactor(float factor);
61
    virtual float GetStretchFactor(void);
60
    virtual float GetStretchFactor(void);
61
    virtual bool ToggleUpmix(void);
62
62
63
    virtual void Reset(void);
63
    virtual void Reset(void);
64
64
Lines 139-147 Link Here
139
    QString audio_passthru_device;
139
    QString audio_passthru_device;
140
140
141
    bool audio_passthru;
141
    bool audio_passthru;
142
    bool audio_enc;
143
    bool audio_reenc;
142
144
143
    float audio_stretchfactor;
145
    float audio_stretchfactor;
144
    AVCodecContext *audio_codec;
145
    AudioOutputSource source;
146
    AudioOutputSource source;
146
147
147
    bool killaudio;
148
    bool killaudio;
Lines 151-156 Link Here
151
    bool buffer_output_data_for_use; //  used by AudioOutputNULL
152
    bool buffer_output_data_for_use; //  used by AudioOutputNULL
152
    
153
    
153
    int configured_audio_channels;
154
    int configured_audio_channels;
155
    int orig_config_channels;
156
    int src_quality;
154
157
155
 private:
158
 private:
156
    // resampler
159
    // resampler
Lines 167-175 Link Here
167
    FreeSurround              *upmixer;
170
    FreeSurround              *upmixer;
168
171
169
    int source_audio_channels;
172
    int source_audio_channels;
173
    int source_audio_samplerate;
170
    int source_audio_bytes_per_sample;
174
    int source_audio_bytes_per_sample;
171
    bool needs_upmix;
175
    bool needs_upmix;
172
    int surround_mode;
176
    int surround_mode;
177
    bool allow_ac3_passthru;
178
    float old_audio_stretchfactor;
173
179
174
    bool blocking; // do AddSamples calls block?
180
    bool blocking; // do AddSamples calls block?
175
181
(-)a/libs/libmyth/audiooutputdigitalencoder.cpp (-55 / +66 lines)
Lines 27-36 Link Here
27
27
28
AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) :
28
AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) :
29
    av_context(NULL),
29
    av_context(NULL),
30
    outbuf(NULL),
30
    outbuflen(0),
31
    outbuf_size(0),
31
    inbuflen(0),
32
    frame_buffer(NULL),
32
    one_frame_bytes(0),
33
    one_frame_bytes(0)
33
    reorder(true)
34
{
34
{
35
}
35
}
36
36
Lines 47-82 Link Here
47
        av_free(av_context);
47
        av_free(av_context);
48
        av_context = NULL;
48
        av_context = NULL;
49
    }
49
    }
50
51
    if (outbuf)
52
    {
53
        delete [] outbuf;
54
        outbuf = NULL;
55
        outbuf_size = 0;
56
    }
57
58
    if (frame_buffer)
59
    {
60
        delete [] frame_buffer;
61
        frame_buffer = NULL;
62
        one_frame_bytes = 0;
63
    }
64
}
50
}
65
51
66
//CODEC_ID_AC3
52
//CODEC_ID_AC3
67
bool AudioOutputDigitalEncoder::Init(
53
bool AudioOutputDigitalEncoder::Init(
68
    CodecID codec_id, int bitrate, int samplerate, int channels)
54
    CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding)
69
{
55
{
70
    AVCodec *codec;
56
    AVCodec *codec;
71
    int ret;
57
    int ret;
72
58
73
    VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4")
59
    VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 re=%5")
74
            .arg(codec_id_string(codec_id))
60
            .arg(codec_id_string(codec_id))
75
            .arg(bitrate)
61
            .arg(bitrate)
76
            .arg(samplerate)
62
            .arg(samplerate)
77
            .arg(channels));
63
            .arg(channels)
78
64
            .arg(reencoding));
79
    //codec = avcodec_find_encoder(codec_id);
65
    
66
    reorder = !reencoding;
67
68
    // We need to do this when called from mythmusic
69
    avcodec_init();
70
    avcodec_register_all();
80
    // always AC3 as there is no DTS encoder at the moment 2005/1/9
71
    // always AC3 as there is no DTS encoder at the moment 2005/1/9
81
    codec = avcodec_find_encoder(CODEC_ID_AC3);
72
    codec = avcodec_find_encoder(CODEC_ID_AC3);
82
    if (!codec)
73
    if (!codec)
Lines 105-112 Link Here
105
    audio_bytes_per_sample = bytes_per_frame;
96
    audio_bytes_per_sample = bytes_per_frame;
106
    one_frame_bytes = bytes_per_frame * av_context->frame_size;
97
    one_frame_bytes = bytes_per_frame * av_context->frame_size;
107
98
108
    outbuf_size = 16384;    // ok for AC3 but DTS?
109
    outbuf = new char [outbuf_size];
110
    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3")
99
    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3")
111
            .arg(av_context->frame_size)
100
            .arg(av_context->frame_size)
112
            .arg(bytes_per_frame)
101
            .arg(bytes_per_frame)
Lines 256-267 Link Here
256
245
257
} AESHeader;
246
} AESHeader;
258
247
248
249
void reorder_6ch_ac3(void *buf, unsigned int len) {
250
    unsigned short *src = (unsigned short *)buf;
251
    unsigned short tmp;
252
    unsigned int samples = len >> 1;
253
254
    for (uint i = 0; i < samples; i += 6) {
255
        tmp = src[i+4];
256
        src[i+4] = src[i+3];
257
        src[i+3] = src[i+2];
258
        src[i+2] = src[i+1];
259
        src[i+1] = tmp;
260
    }
261
}
262
259
static int encode_frame(
263
static int encode_frame(
260
        bool dts, 
264
        bool dts, 
261
        unsigned char *data,
265
        unsigned char *data,
262
        size_t &len)
266
        size_t enc_len)
263
{
267
{
264
    size_t enc_len;
265
    int flags, sample_rate, bit_rate;
268
    int flags, sample_rate, bit_rate;
266
269
267
    // we don't do any length/crc validation of the AC3 frame here; presumably
270
    // we don't do any length/crc validation of the AC3 frame here; presumably
Lines 273-278 Link Here
273
    // anything with a bad CRC...
276
    // anything with a bad CRC...
274
277
275
    uint nr_samples = 0, block_len;
278
    uint nr_samples = 0, block_len;
279
    
276
    if (dts)
280
    if (dts)
277
    {
281
    {
278
        enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
282
        enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
Lines 293-307 Link Here
293
#endif
297
#endif
294
    }
298
    }
295
299
296
    if (enc_len == 0 || enc_len > len)
297
    {
298
        int l = len;
299
        len = 0;
300
        return l;
301
    }
302
303
    enc_len = min((uint)enc_len, block_len - 8);
300
    enc_len = min((uint)enc_len, block_len - 8);
304
301
    
305
    //uint32_t x = *(uint32_t*)(data+8);
302
    //uint32_t x = *(uint32_t*)(data+8);
306
    // in place swab
303
    // in place swab
307
    swab((const char *)data + 8, (char *)data + 8, enc_len);
304
    swab((const char *)data + 8, (char *)data + 8, enc_len);
Lines 348-382 Link Here
348
                break;
345
                break;
349
        }
346
        }
350
    }
347
    }
351
    data[5] = 0x00;
348
    data[5] = 0;
352
    data[6] = (enc_len << 3) & 0xFF;
349
    data[6] = (enc_len << 3) & 0xFF;
353
    data[7] = (enc_len >> 5) & 0xFF;
350
    data[7] = (enc_len >> 5) & 0xFF;
354
    memset(data + 8 + enc_len, 0, block_len - 8 - enc_len);
351
    memset(data + 8 + enc_len, 0, block_len - 8 - enc_len);
355
    len = block_len;
356
352
357
    return enc_len;
353
    return enc_len;
358
}
354
}
359
355
360
// must have exactly 1 frames worth of data
356
size_t AudioOutputDigitalEncoder::Encode(void *buf, int len)
361
size_t AudioOutputDigitalEncoder::Encode(short *buff)
362
{
357
{
363
    int encsize = 0;
364
    size_t outsize = 0;
358
    size_t outsize = 0;
365
 
359
 
366
    // put data in the correct spot for encode frame
360
    int fs = FrameSize();
367
    outsize = avcodec_encode_audio(
361
    memcpy(inbuf+inbuflen, buf, len);
368
        av_context, ((uchar*)outbuf) + 8, outbuf_size - 8, buff);
362
    inbuflen += len;
369
363
    int frames = inbuflen / fs;
370
    size_t tmpsize = outsize;
364
371
365
    while (frames--) 
372
    outsize = MAX_AC3_FRAME_SIZE;
366
    {
373
    encsize = encode_frame(
367
        if (reorder)
374
        /*av_context->codec_id==CODEC_ID_DTS*/ false,
368
            reorder_6ch_ac3(inbuf, fs);
375
        (unsigned char*)outbuf, outsize);
369
        
376
370
	// put data in the correct spot for encode frame
377
    VERBOSE(VB_AUDIO|VB_TIMESTAMP, 
371
        outsize = avcodec_encode_audio(
378
            QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3")
372
            av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf);
379
                .arg(tmpsize).arg(encsize).arg(outsize));
373
374
        encode_frame(
375
            /*av_context->codec_id==CODEC_ID_DTS*/ false,
376
            (unsigned char*)outbuf + outbuflen, outsize
377
        );
378
379
        outbuflen += MAX_AC3_FRAME_SIZE;
380
        inbuflen -= fs;
381
        memmove(inbuf, inbuf+fs, inbuflen);
382
    }
383
384
    return outbuflen;
385
}
380
386
381
    return outsize;
387
void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen)
388
{
389
    int len = (maxlen < outbuflen ? maxlen : outbuflen);
390
    memcpy(ptr, outbuf, len);
391
    outbuflen -= len;
392
    memmove(outbuf, outbuf+len, outbuflen);
382
}
393
}
(-)a/libs/libmyth/audiooutputdigitalencoder.h (-16 / +13 lines)
Lines 5-41 Link Here
5
#include "libavcodec/avcodec.h"
5
#include "libavcodec/avcodec.h"
6
};
6
};
7
7
8
#define INBUFSIZE 131072
9
#define OUTBUFSIZE 98304
10
8
class AudioOutputDigitalEncoder
11
class AudioOutputDigitalEncoder
9
{
12
{
10
  public:
13
  public:
11
    AudioOutputDigitalEncoder(void);
14
    AudioOutputDigitalEncoder(void);
12
    ~AudioOutputDigitalEncoder();
15
    ~AudioOutputDigitalEncoder();
13
16
14
    bool   Init(CodecID codec_id, int bitrate, int samplerate, int channels);
17
    bool   Init(CodecID codec_id, int bitrate, int samplerate, 
18
                int channels, bool reencoding);
15
    void   Dispose(void);
19
    void   Dispose(void);
16
    size_t Encode(short * buff);
20
    size_t Encode(void *buf, int len);
17
21
    void   GetFrames(void *ptr, int maxlen);
18
    inline char *GetFrameBuffer(void);
19
    size_t FrameSize(void)  const { return one_frame_bytes; }
22
    size_t FrameSize(void)  const { return one_frame_bytes; }
20
    char  *GetOutBuff(void) const { return outbuf;          }
23
    int    Buffered(void) const { return inbuflen; }
21
24
22
  public:
25
  public:
23
    size_t audio_bytes_per_sample;
26
    size_t audio_bytes_per_sample;
24
27
25
  private:
28
  private:
26
    AVCodecContext *av_context;
29
    AVCodecContext *av_context;
27
    char           *outbuf;
30
    char            outbuf[OUTBUFSIZE];
28
    int             outbuf_size;
31
    char            inbuf[INBUFSIZE];
29
    char           *frame_buffer;
32
    int             outbuflen;
33
    int             inbuflen;
30
    size_t          one_frame_bytes;
34
    size_t          one_frame_bytes;
35
    bool            reorder;
31
};
36
};
32
37
33
inline char *AudioOutputDigitalEncoder::GetFrameBuffer(void)
34
{
35
    if (!frame_buffer && av_context)
36
        frame_buffer = new char [one_frame_bytes];
37
38
    return frame_buffer; 
39
}
40
41
#endif
38
#endif
(-)a/libs/libmythfreesurround/el_processor.cpp (-69 / +7 lines)
Lines 40-56 Link Here
40
40
41
const float PI = 3.141592654;
41
const float PI = 3.141592654;
42
const float epsilon = 0.000001;
42
const float epsilon = 0.000001;
43
//const float center_level = 0.5*sqrt(0.5);   // gain of the center channel
43
const float center_level = 0.5*sqrt(0.5);
44
//const float center_level = sqrt(0.5);   // gain of the center channel
45
const float center_level = 1.0;   // gain of the center channel
46
//const float center_level = 0.5;   // gain of the center channel
47
48
// should be .6-.7
49
// but with centerlevel 2x what its supposed to be, we halve 0.68
50
// to keep center from clipping
51
//const float window_gain = 0.34;     
52
//const float window_gain = 0.68;     
53
const float window_gain = 0.95;     // to prive a bit of margin
54
44
55
// private implementation of the surround decoder
45
// private implementation of the surround decoder
56
class decoder_impl {
46
class decoder_impl {
Lines 98-116 Link Here
98
            outbuf[c].resize(N);
88
            outbuf[c].resize(N);
99
            filter[c].resize(N);
89
            filter[c].resize(N);
100
        }
90
        }
101
        // DC component of filters is always 0
102
        for (unsigned c=0;c<5;c++)
103
        {
104
            filter[c][0] = 0.0;
105
            filter[c][1] = 0.0;
106
            filter[c][halfN] = 0.0;
107
        }
108
        sample_rate(48000);
91
        sample_rate(48000);
109
        // generate the window function (square root of hann, b/c it is applied before and after the transform)
92
        // generate the window function (square root of hann, b/c it is applied before and after the transform)
110
        wnd.resize(N);
93
        wnd.resize(N);
111
        // dft normalization included in the window for zero cost scaling
94
        for (unsigned k=0;k<N;k++)
112
        // also add a gain factor of *2 due to processing gain in algo (see center_level)
95
            wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N);
113
        surround_gain(1.0);
114
        current_buf = 0;
96
        current_buf = 0;
115
        // set the default coefficients
97
        // set the default coefficients
116
        surround_coefficients(0.8165,0.5774);
98
        surround_coefficients(0.8165,0.5774);
Lines 192-201 Link Here
192
    // set lfe filter params
174
    // set lfe filter params
193
    void sample_rate(unsigned int srate) {
175
    void sample_rate(unsigned int srate) {
194
        // lfe filter is just straight through band limited
176
        // lfe filter is just straight through band limited
195
        unsigned int cutoff = (250*N)/srate;
177
        unsigned int cutoff = (30*N)/srate;
196
        for (unsigned f=0;f<=halfN;f++) {           
178
        for (unsigned f=0;f<=halfN;f++) {           
197
            if ((f>=2) && (f<cutoff))
179
            if (f<cutoff)
198
                filter[5][f] = 1.0;
180
                filter[5][f] = 0.5*sqrt(0.5);
199
            else
181
            else
200
                filter[5][f] = 0.0;
182
                filter[5][f] = 0.0;
201
        }
183
        }
Lines 214-225 Link Here
214
        E = (o+v)*n; F = (o+u)*n; G = (o-v)*n;  H = (o-u)*n;
196
        E = (o+v)*n; F = (o+u)*n; G = (o-v)*n;  H = (o-u)*n;
215
    }
197
    }
216
198
217
    void surround_gain(float gain) {
218
        master_gain = gain * window_gain * 0.5 * 0.25;
219
        for (unsigned k=0;k<N;k++)
220
            wnd[k] = sqrt(master_gain*(1-cos(2*PI*k/N))/N);
221
    }
222
223
    // set the phase shifting mode
199
    // set the phase shifting mode
224
    void phase_mode(unsigned mode) {
200
    void phase_mode(unsigned mode) {
225
        const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}};
201
        const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}};
Lines 290-296 Link Here
290
266
291
        // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field
267
        // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field
292
        //    but dont do DC or N/2 component
268
        //    but dont do DC or N/2 component
293
        for (unsigned f=2;f<halfN;f++) {           
269
        for (unsigned f=0;f<halfN;f++) {           
294
            // get left/right amplitudes/phases
270
            // get left/right amplitudes/phases
295
            float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]);
271
            float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]);
296
            float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]);
272
            float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]);
Lines 305-345 Link Here
305
            phaseDiff = abs(phaseDiff);
281
            phaseDiff = abs(phaseDiff);
306
282
307
            if (linear_steering) {
283
            if (linear_steering) {
308
/*              cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2);
309
                cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w;              */
310
//              xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real();
311
//              yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G);
312
313
                /*
314
                Problem: 
315
                This assumes that the values are interpolated linearly between the cardinal points.
316
                But this way we have no chance of knowing the average volume...
317
                - Can we solve that computing everything under the assumption of normalized volume?
318
                  No. Seemingly not.
319
                - Maybe we should add w explitcitly into the equation and see if we can solve it...
320
                */
321
322
323
                //cfloat lt(0.5,0),rt(0.5,0);
324
                //cfloat x(0,0), y(1,0);
325
                /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E);
326
                cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E);
327
                cfloat s = sqrt(p*p/4.0f - q);
328
                cfloat x = -p;
329
                cfloat x1 = -p/2.0f + s;
330
                cfloat x2 = -p/2.0f - s;
331
                float x = 0;
332
                if (x1.real() >= -1 && x1.real() <= 1)
333
                    x = x1.real();
334
                else if (x2.real() >= -1 && x2.real() <= 1)
335
                    x = x2.real();*/
336
337
                //cfloat yp = (rt - (x*E+H))/(F+x*G);
338
                //cfloat xp = (lt - (y*B+D))/(A+y*C);
339
340
                /*xfs[f] = x;
341
                yfs[f] = y.real();*/
342
343
                // --- this is the fancy new linear mode ---
284
                // --- this is the fancy new linear mode ---
344
285
345
                // get sound field x/y position
286
                // get sound field x/y position
Lines 597-603 Link Here
597
    float surround_high,surround_low;  // high and low surround mixing coefficient (e.g. 0.8165/0.5774)
538
    float surround_high,surround_low;  // high and low surround mixing coefficient (e.g. 0.8165/0.5774)
598
    float surround_balance;            // the xfs balance that follows from the coeffs
539
    float surround_balance;            // the xfs balance that follows from the coeffs
599
    float surround_level;              // gain for the surround channels (follows from the coeffs
540
    float surround_level;              // gain for the surround channels (follows from the coeffs
600
    float master_gain;                 // gain for all channels
601
    float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels
541
    float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels
602
    float front_separation;            // front stereo separation
542
    float front_separation;            // front stereo separation
603
    float rear_separation;             // rear stereo separation
543
    float rear_separation;             // rear stereo separation
Lines 625-632 Link Here
625
565
626
void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); }
566
void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); }
627
567
628
void fsurround_decoder::gain(float gain) { impl->surround_gain(gain); }
629
630
void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); }
568
void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); }
631
569
632
void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); }
570
void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); }
(-)a/libs/libmythfreesurround/el_processor.h (-3 lines)
Lines 47-55 Link Here
47
	//  a is the coefficient of left rear in left total, b is the coefficient of left rear in right total; the same is true for right.
47
	//  a is the coefficient of left rear in left total, b is the coefficient of left rear in right total; the same is true for right.
48
	void surround_coefficients(float a, float b);
48
	void surround_coefficients(float a, float b);
49
49
50
	// override for master surround gain
51
	void gain(float gain);
52
53
	// set the phase shifting mode for decoding
50
	// set the phase shifting mode for decoding
54
	// 0 = (+0°,+0°)   - music mode
51
	// 0 = (+0°,+0°)   - music mode
55
	// 1 = (+0°,+180°) - PowerDVD compatibility
52
	// 1 = (+0°,+180°) - PowerDVD compatibility
(-)a/libs/libmythfreesurround/freesurround.cpp (-22 / +7 lines)
Lines 63-72 Link Here
63
const unsigned default_block_size = 8192;
63
const unsigned default_block_size = 8192;
64
// there will be a slider for this in the future
64
// there will be a slider for this in the future
65
//const float master_gain = 1.0;
65
//const float master_gain = 1.0;
66
//#define MASTER_GAIN * master_gain
66
//#define MASTER_GAIN * master_gain 
67
#define MASTER_GAIN
67
#define MASTER_GAIN
68
//const float master_gain = 1.0/(1<<15);
68
//const float inv_master_gain = 1.0;
69
//const float inv_master_gain = (1<<15);
70
//#define INV_MASTER_GAIN * inv_master_gain
69
//#define INV_MASTER_GAIN * inv_master_gain
71
#define INV_MASTER_GAIN
70
#define INV_MASTER_GAIN
72
71
Lines 191-205 Link Here
191
    if (moviemode)
190
    if (moviemode)
192
    {
191
    {
193
        params.phasemode = 1;
192
        params.phasemode = 1;
194
        params.center_width = 0;
193
        params.center_width = 25;
195
        params.gain = 1.0;
194
        params.dimension = 0.5;
196
    }
195
    }
197
    else
196
    else
198
    {
197
    {
199
        params.center_width = 70;
198
        params.center_width = 65;
200
        // for 50, gain should be about 1.9, c/lr about 2.7
199
        params.dimension = 0.3;
201
        // for 70, gain should be about 3.1, c/lr about 1.5
202
        params.gain = 3.1;
203
    }
200
    }
204
    switch (surround_mode)
201
    switch (surround_mode)
205
    {
202
    {
Lines 235-241 Link Here
235
        decoder->phase_mode(params.phasemode);
232
        decoder->phase_mode(params.phasemode);
236
        decoder->surround_coefficients(params.coeff_a, params.coeff_b);				
233
        decoder->surround_coefficients(params.coeff_a, params.coeff_b);				
237
        decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
234
        decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
238
        decoder->gain(params.gain);
239
    }
235
    }
240
}
236
}
241
237
Lines 249-256 Link Here
249
    phasemode(0),
245
    phasemode(0),
250
    steering(1),
246
    steering(1),
251
    front_sep(100),
247
    front_sep(100),
252
    rear_sep(100), 
248
    rear_sep(100) 
253
    gain(1.0)
254
{
249
{
255
}
250
}
256
251
Lines 654-669 Link Here
654
    {
649
    {
655
        if (decoder) 
650
        if (decoder) 
656
        {
651
        {
657
            // actually these params need only be set when they change... but it doesn't hurt
658
#if 0
659
            decoder->steering_mode(params.steering);
660
            decoder->phase_mode(params.phasemode);
661
            decoder->surround_coefficients(params.coeff_a, params.coeff_b);				
662
            decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
663
#endif
664
            // decode the bufs->block
665
            //decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0);
666
            //decoder->decode(output,params.center_width/100.0,params.dimension/100.0);
667
            decoder->decode(params.center_width/100.0,params.dimension/100.0);
652
            decoder->decode(params.center_width/100.0,params.dimension/100.0);
668
        }
653
        }
669
    }
654
    }
(-)a/libs/libmythsamplerate/samplerate.c (-2 / +2 lines)
Lines 452-462 Link Here
452
	{	len -- ;
452
	{	len -- ;
453
453
454
		scaled_value = in [len] * (8.0 * 0x10000000) ;
454
		scaled_value = in [len] * (8.0 * 0x10000000) ;
455
		if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
455
		if (scaled_value >= (1.0 * 0x7FFFFFFF))
456
		{	out [len] = 32767 ;
456
		{	out [len] = 32767 ;
457
			continue ;
457
			continue ;
458
			} ;
458
			} ;
459
		if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
459
		if (scaled_value <= (-8.0 * 0x10000000))
460
		{	out [len] = -32768 ;
460
		{	out [len] = -32768 ;
461
			continue ;
461
			continue ;
462
			} ;
462
			} ;
(-)a/libs/libmythtv/NuppelVideoPlayer.cpp (-8 / +3 lines)
Lines 209-215 Link Here
209
      audio_passthru_device(QString::null),
209
      audio_passthru_device(QString::null),
210
      audio_channels(2),            audio_bits(-1),
210
      audio_channels(2),            audio_bits(-1),
211
      audio_samplerate(44100),      audio_stretchfactor(1.0f),
211
      audio_samplerate(44100),      audio_stretchfactor(1.0f),
212
      audio_codec(NULL),
213
      // Picture-in-Picture
212
      // Picture-in-Picture
214
      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
213
      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
215
      // Preview window support
214
      // Preview window support
Lines 804-811 Link Here
804
    if (audioOutput)
803
    if (audioOutput)
805
    {
804
    {
806
        audioOutput->Reconfigure(audio_bits, audio_channels,
805
        audioOutput->Reconfigure(audio_bits, audio_channels,
807
                                 audio_samplerate, audio_passthru,
806
                                 audio_samplerate, audio_passthru);
808
                                 audio_codec);
807
	if (audio_passthru)
808
	    audio_channels = 2;
809
        errMsg = audioOutput->GetError();
809
        errMsg = audioOutput->GetError();
810
        if (!errMsg.isEmpty())
810
        if (!errMsg.isEmpty())
811
            audioOutput->SetStretchFactor(audio_stretchfactor);
811
            audioOutput->SetStretchFactor(audio_stretchfactor);
Lines 3718-3728 Link Here
3718
    audio_passthru = passthru;
3718
    audio_passthru = passthru;
3719
}
3719
}
3720
3720
3721
void NuppelVideoPlayer::SetAudioCodec(void *ac)
3722
{
3723
    audio_codec = ac;
3724
}
3725
3726
void NuppelVideoPlayer::SetEffDsp(int dsprate)
3721
void NuppelVideoPlayer::SetEffDsp(int dsprate)
3727
{
3722
{
3728
    if (audioOutput)
3723
    if (audioOutput)
(-)a/libs/libmythtv/NuppelVideoPlayer.h (-1 lines)
Lines 685-691 Link Here
685
    int      audio_bits;
685
    int      audio_bits;
686
    int      audio_samplerate;
686
    int      audio_samplerate;
687
    float    audio_stretchfactor;
687
    float    audio_stretchfactor;
688
    void    *audio_codec;
689
    bool     audio_passthru;
688
    bool     audio_passthru;
690
689
691
    // Picture-in-Picture
690
    // Picture-in-Picture
(-)a/libs/libmythtv/avformatdecoder.cpp (-126 / +94 lines)
Lines 425-431 Link Here
425
      audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
425
      audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
426
      allow_ac3_passthru(false),    allow_dts_passthru(false),
426
      allow_ac3_passthru(false),    allow_dts_passthru(false),
427
      disable_passthru(false),      max_channels(2),
427
      disable_passthru(false),      max_channels(2),
428
      dummy_frame(NULL),
428
      last_ac3_channels(0),	    dummy_frame(NULL),
429
      // DVD
429
      // DVD
430
      lastdvdtitle(-1),
430
      lastdvdtitle(-1),
431
      decodeStillFrame(false),
431
      decodeStillFrame(false),
Lines 2944-2958 Link Here
2944
    {
2944
    {
2945
        int idx = atracks[i].av_stream_index;
2945
        int idx = atracks[i].av_stream_index;
2946
        AVCodecContext *codec_ctx = ic->streams[idx]->codec;
2946
        AVCodecContext *codec_ctx = ic->streams[idx]->codec;
2947
        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
2948
                                !disable_passthru &&
2949
                                (codec_ctx->codec_id == CODEC_ID_AC3));
2950
        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
2951
                                !disable_passthru &&
2952
                                (codec_ctx->codec_id == CODEC_ID_DTS));
2953
        AudioInfo item(codec_ctx->codec_id,
2947
        AudioInfo item(codec_ctx->codec_id,
2954
                       codec_ctx->sample_rate, codec_ctx->channels,
2948
                       codec_ctx->sample_rate, codec_ctx->channels,
2955
                       do_ac3_passthru || do_dts_passthru);
2949
                       DoPassThrough(codec_ctx));
2956
        VERBOSE(VB_AUDIO, LOC + " * " + item.toString());
2950
        VERBOSE(VB_AUDIO, LOC + " * " + item.toString());
2957
    }
2951
    }
2958
#endif
2952
#endif
Lines 3086-3091 Link Here
3086
bool AvFormatDecoder::GetFrame(int onlyvideo)
3080
bool AvFormatDecoder::GetFrame(int onlyvideo)
3087
{
3081
{
3088
    AVPacket *pkt = NULL;
3082
    AVPacket *pkt = NULL;
3083
    AC3HeaderInfo hdr;
3089
    int len;
3084
    int len;
3090
    unsigned char *ptr;
3085
    unsigned char *ptr;
3091
    int data_size = 0;
3086
    int data_size = 0;
Lines 3272-3283 Link Here
3272
        pts = 0;
3267
        pts = 0;
3273
3268
3274
        AVStream *curstream = ic->streams[pkt->stream_index];
3269
        AVStream *curstream = ic->streams[pkt->stream_index];
3270
        AVCodecContext *ctx = curstream->codec;
3275
3271
3276
        if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
3272
        if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
3277
            pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000);
3273
            pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000);
3278
3274
3279
        if (ringBuffer->isDVD() && 
3275
        if (ringBuffer->isDVD() && 
3280
            curstream->codec->codec_type == CODEC_TYPE_VIDEO)
3276
            ctx->codec_type == CODEC_TYPE_VIDEO)
3281
        {
3277
        {
3282
            MpegPreProcessPkt(curstream, pkt);
3278
            MpegPreProcessPkt(curstream, pkt);
3283
3279
Lines 3305-3311 Link Here
3305
3301
3306
            if (!d->HasMPEG2Dec())
3302
            if (!d->HasMPEG2Dec())
3307
            {
3303
            {
3308
                int current_width = curstream->codec->width;
3304
                int current_width = ctx->width;
3309
                int video_width = GetNVP()->GetVideoSize().width();
3305
                int video_width = GetNVP()->GetVideoSize().width();
3310
                if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput())
3306
                if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput())
3311
                {
3307
                {
Lines 3346-3352 Link Here
3346
        }
3342
        }
3347
3343
3348
        if (storevideoframes &&
3344
        if (storevideoframes &&
3349
            curstream->codec->codec_type == CODEC_TYPE_VIDEO)
3345
            ctx->codec_type == CODEC_TYPE_VIDEO)
3350
        {
3346
        {
3351
            av_dup_packet(pkt);
3347
            av_dup_packet(pkt);
3352
            storedPackets.append(pkt);
3348
            storedPackets.append(pkt);
Lines 3354-3375 Link Here
3354
            continue;
3350
            continue;
3355
        }
3351
        }
3356
3352
3357
        if (len > 0 && curstream->codec->codec_type == CODEC_TYPE_VIDEO &&
3353
        if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO &&
3358
            pkt->stream_index == selectedVideoIndex)
3354
            pkt->stream_index == selectedVideoIndex)
3359
        {
3355
        {
3360
            AVCodecContext *context = curstream->codec;
3361
3356
3362
            if (context->codec_id == CODEC_ID_MPEG1VIDEO ||
3357
            if (ctx->codec_id == CODEC_ID_MPEG1VIDEO ||
3363
                context->codec_id == CODEC_ID_MPEG2VIDEO ||
3358
                ctx->codec_id == CODEC_ID_MPEG2VIDEO ||
3364
                context->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||
3359
                ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||
3365
                context->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||
3360
                ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||
3366
                context->codec_id == CODEC_ID_MPEGVIDEO_VDPAU)
3361
                ctx->codec_id == CODEC_ID_MPEGVIDEO_VDPAU)
3367
            {
3362
            {
3368
                if (!ringBuffer->isDVD())
3363
                if (!ringBuffer->isDVD())
3369
                    MpegPreProcessPkt(curstream, pkt);
3364
                    MpegPreProcessPkt(curstream, pkt);
3370
            }
3365
            }
3371
            else if (context->codec_id == CODEC_ID_H264 ||
3366
            else if (ctx->codec_id == CODEC_ID_H264 ||
3372
                     context->codec_id == CODEC_ID_H264_VDPAU)
3367
                     ctx->codec_id == CODEC_ID_H264_VDPAU)
3373
            {
3368
            {
3374
                H264PreProcessPkt(curstream, pkt);
3369
                H264PreProcessPkt(curstream, pkt);
3375
            }
3370
            }
Lines 3415-3422 Link Here
3415
        }
3410
        }
3416
3411
3417
        if (len > 0 &&
3412
        if (len > 0 &&
3418
            curstream->codec->codec_type == CODEC_TYPE_DATA &&
3413
            ctx->codec_type == CODEC_TYPE_DATA &&
3419
            curstream->codec->codec_id   == CODEC_ID_MPEG2VBI)
3414
            ctx->codec_id   == CODEC_ID_MPEG2VBI)
3420
        {
3415
        {
3421
            ProcessVBIDataPacket(curstream, pkt);
3416
            ProcessVBIDataPacket(curstream, pkt);
3422
3417
Lines 3425-3432 Link Here
3425
        }
3420
        }
3426
3421
3427
        if (len > 0 &&
3422
        if (len > 0 &&
3428
            curstream->codec->codec_type == CODEC_TYPE_DATA &&
3423
            ctx->codec_type == CODEC_TYPE_DATA &&
3429
            curstream->codec->codec_id   == CODEC_ID_DVB_VBI)
3424
            ctx->codec_id   == CODEC_ID_DVB_VBI)
3430
        {
3425
        {
3431
            ProcessDVBDataPacket(curstream, pkt);
3426
            ProcessDVBDataPacket(curstream, pkt);
3432
3427
Lines 3435-3442 Link Here
3435
        }
3430
        }
3436
3431
3437
        if (len > 0 &&
3432
        if (len > 0 &&
3438
            curstream->codec->codec_type == CODEC_TYPE_DATA &&
3433
            ctx->codec_type == CODEC_TYPE_DATA &&
3439
            curstream->codec->codec_id   == CODEC_ID_DSMCC_B)
3434
            ctx->codec_id   == CODEC_ID_DSMCC_B)
3440
        {
3435
        {
3441
            ProcessDSMCCPacket(curstream, pkt);
3436
            ProcessDSMCCPacket(curstream, pkt);
3442
3437
Lines 3456-3475 Link Here
3456
        }
3451
        }
3457
3452
3458
        // we don't care about other data streams
3453
        // we don't care about other data streams
3459
        if (curstream->codec->codec_type == CODEC_TYPE_DATA)
3454
        if (ctx->codec_type == CODEC_TYPE_DATA)
3460
        {
3455
        {
3461
            av_free_packet(pkt);
3456
            av_free_packet(pkt);
3462
            continue;
3457
            continue;
3463
        }
3458
        }
3464
3459
3465
        if (!curstream->codec->codec)
3460
        if (!ctx->codec)
3466
        {
3461
        {
3467
            VERBOSE(VB_PLAYBACK, LOC +
3462
            VERBOSE(VB_PLAYBACK, LOC +
3468
                    QString("No codec for stream index %1, type(%2) id(%3:%4)")
3463
                    QString("No codec for stream index %1, type(%2) id(%3:%4)")
3469
                    .arg(pkt->stream_index)
3464
                    .arg(pkt->stream_index)
3470
                    .arg(codec_type_string(curstream->codec->codec_type))
3465
                    .arg(codec_type_string(ctx->codec_type))
3471
                    .arg(codec_id_string(curstream->codec->codec_id))
3466
                    .arg(codec_id_string(ctx->codec_id))
3472
                    .arg(curstream->codec->codec_id));
3467
                    .arg(ctx->codec_id));
3473
            av_free_packet(pkt);
3468
            av_free_packet(pkt);
3474
            continue;
3469
            continue;
3475
        }
3470
        }
Lines 3478-3484 Link Here
3478
        have_err = false;
3473
        have_err = false;
3479
3474
3480
        avcodeclock.lock();
3475
        avcodeclock.lock();
3481
        int ctype  = curstream->codec->codec_type;
3476
        int ctype  = ctx->codec_type;
3482
        int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index;
3477
        int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index;
3483
        int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index;
3478
        int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index;
3484
        int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index;
3479
        int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index;
Lines 3503-3552 Link Here
3503
3498
3504
                    // detect switches between stereo and dual languages
3499
                    // detect switches between stereo and dual languages
3505
                    bool wasDual = audSubIdx != -1;
3500
                    bool wasDual = audSubIdx != -1;
3506
                    bool isDual = curstream->codec->avcodec_dual_language;
3501
                    bool isDual = ctx->avcodec_dual_language;
3507
                    if ((wasDual && !isDual) || (!wasDual &&  isDual))
3502
                    if ((wasDual && !isDual) || (!wasDual &&  isDual))
3508
                    {
3503
                    {
3509
                        SetupAudioStreamSubIndexes(audIdx);
3504
                        SetupAudioStreamSubIndexes(audIdx);
3510
                        reselectAudioTrack = true;
3505
                        reselectAudioTrack = true;
3511
                    }                            
3506
                    }                            
3512
3507
3513
                    bool do_ac3_passthru =
3514
                        (allow_ac3_passthru && !transcoding &&
3515
                         (curstream->codec->codec_id == CODEC_ID_AC3));
3516
                    bool do_dts_passthru =
3517
                        (allow_dts_passthru && !transcoding &&
3518
                         (curstream->codec->codec_id == CODEC_ID_DTS));
3519
                    bool using_passthru = do_ac3_passthru || do_dts_passthru;
3520
3521
                    // detect channels on streams that need
3508
                    // detect channels on streams that need
3522
                    // to be decoded before we can know this
3509
                    // to be decoded before we can know this
3523
                    bool already_decoded = false;
3510
                    bool already_decoded = false;
3524
                    if (!curstream->codec->channels)
3511
                    if (!ctx->channels)
3525
                    {
3512
                    {
3526
                        QMutexLocker locker(&avcodeclock);
3513
                        QMutexLocker locker(&avcodeclock);
3527
                        VERBOSE(VB_IMPORTANT, LOC +
3514
                        VERBOSE(VB_IMPORTANT, LOC +
3528
                                QString("Setting channels to %1")
3515
                                QString("Setting channels to %1")
3529
                                .arg(audioOut.channels));
3516
                                .arg(audioOut.channels));
3530
3517
3531
                        if (using_passthru)
3518
                        if (DoPassThrough(ctx))
3532
                        {
3519
                        {
3533
                            // for passthru let it select the max number
3520
                            // for passthru let it select the max number
3534
                            // of channels
3521
                            // of channels
3535
                            curstream->codec->channels = 0;
3522
                            ctx->channels = 0;
3536
                            curstream->codec->request_channels = 0;
3523
                            ctx->request_channels = 0;
3537
                        }
3524
                        }
3538
                        else
3525
                        else
3539
                        {
3526
                        {
3540
                            curstream->codec->channels = audioOut.channels;
3527
                            ctx->channels = audioOut.channels;
3541
                            curstream->codec->request_channels =
3528
                            ctx->request_channels =
3542
                                audioOut.channels;
3529
                                audioOut.channels;
3543
                        }
3530
                        }
3544
                        ret = avcodec_decode_audio(
3531
                        ret = avcodec_decode_audio(
3545
                            curstream->codec, audioSamples,
3532
                            ctx, audioSamples,
3546
                            &data_size, ptr, len);
3533
                            &data_size, ptr, len);
3547
                        already_decoded = true;
3534
                        already_decoded = true;
3548
3535
3549
                        reselectAudioTrack |= curstream->codec->channels;
3536
                        reselectAudioTrack |= ctx->channels;
3537
                    }
3538
3539
                    if (ctx->codec_id == CODEC_ID_AC3 && 
3540
                        !ff_ac3_parse_header(ptr, &hdr)) 
3541
                    {
3542
                        if (hdr.channels != last_ac3_channels) 
3543
                        {
3544
                            last_ac3_channels = ctx->channels = hdr.channels;
3545
                            SetupAudioStream();
3546
                        }
3550
                    }
3547
                    }
3551
3548
3552
                    if (reselectAudioTrack)
3549
                    if (reselectAudioTrack)
Lines 3562-3567 Link Here
3562
                            .av_stream_index;
3559
                            .av_stream_index;
3563
                        audSubIdx = selectedTrack[kTrackTypeAudio]
3560
                        audSubIdx = selectedTrack[kTrackTypeAudio]
3564
                            .av_substream_index;
3561
                            .av_substream_index;
3562
                        ctx = curstream->codec;
3565
                    }
3563
                    }
3566
3564
3567
                    if ((onlyvideo > 0) || (pkt->stream_index != audIdx))
3565
                    if ((onlyvideo > 0) || (pkt->stream_index != audIdx))
Lines 3593-3606 Link Here
3593
                    if (audioOut.do_passthru)
3591
                    if (audioOut.do_passthru)
3594
                    {
3592
                    {
3595
                        data_size = pkt->size;
3593
                        data_size = pkt->size;
3596
                        bool dts = CODEC_ID_DTS == curstream->codec->codec_id;
3594
                        bool dts = CODEC_ID_DTS == ctx->codec_id;
3597
                        ret = encode_frame(dts, ptr, len,
3595
                        ret = encode_frame(dts, ptr, len,
3598
                                           audioSamples, data_size);
3596
                                           audioSamples, data_size);
3599
                    }
3597
                    }
3600
                    else
3598
                    else
3601
                    {
3599
                    {
3602
                        AVCodecContext *ctx = curstream->codec;
3603
3604
                        if ((ctx->channels == 0) ||
3600
                        if ((ctx->channels == 0) ||
3605
                            (ctx->channels > audioOut.channels))
3601
                            (ctx->channels > audioOut.channels))
3606
                        {
3602
                        {
Lines 3609-3616 Link Here
3609
3605
3610
                        if (!already_decoded)
3606
                        if (!already_decoded)
3611
                        {
3607
                        {
3612
                            curstream->codec->request_channels =
3608
                            ctx->request_channels = audioOut.channels;
3613
                                audioOut.channels;
3614
                            ret = avcodec_decode_audio(
3609
                            ret = avcodec_decode_audio(
3615
                                ctx, audioSamples, &data_size, ptr, len);
3610
                                ctx, audioSamples, &data_size, ptr, len);
3616
                        }
3611
                        }
Lines 3627-3632 Link Here
3627
                            audIdx = -1;
3622
                            audIdx = -1;
3628
                            AutoSelectAudioTrack();
3623
                            AutoSelectAudioTrack();
3629
                            data_size = 0;
3624
                            data_size = 0;
3625
                            ctx = curstream->codec;
3630
                        }
3626
                        }
3631
                    }
3627
                    }
3632
                    avcodeclock.unlock();
3628
                    avcodeclock.unlock();
Lines 3644-3651 Link Here
3644
3640
3645
                    // calc for next frame
3641
                    // calc for next frame
3646
                    lastapts += (long long)((double)(data_size * 1000) /
3642
                    lastapts += (long long)((double)(data_size * 1000) /
3647
                                (curstream->codec->channels * 2) / 
3643
                                (ctx->channels * 2) / ctx->sample_rate);
3648
                                curstream->codec->sample_rate);
3649
3644
3650
                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP,
3645
                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP,
3651
                            LOC + QString("audio timecode %1 %2 %3 %4") 
3646
                            LOC + QString("audio timecode %1 %2 %3 %4") 
Lines 3705-3711 Link Here
3705
                        continue;
3700
                        continue;
3706
                    }
3701
                    }
3707
3702
3708
                    AVCodecContext *context = curstream->codec;
3709
                    AVFrame mpa_pic;
3703
                    AVFrame mpa_pic;
3710
                    bzero(&mpa_pic, sizeof(AVFrame));
3704
                    bzero(&mpa_pic, sizeof(AVFrame));
3711
3705
Lines 3720-3743 Link Here
3720
                            // HACK
3714
                            // HACK
3721
                            while (!gotpicture && count < 5)
3715
                            while (!gotpicture && count < 5)
3722
                            {
3716
                            {
3723
                                ret = d->DecodeMPEG2Video(context, &mpa_pic,
3717
                                ret = d->DecodeMPEG2Video(ctx, &mpa_pic,
3724
                                                  &gotpicture, ptr, len);
3718
                                                  &gotpicture, ptr, len);
3725
                                count++;
3719
                                count++;
3726
                            }
3720
                            }
3727
                        }
3721
                        }
3728
                        else
3722
                        else
3729
                        {
3723
                        {
3730
                            ret = d->DecodeMPEG2Video(context, &mpa_pic,
3724
                            ret = d->DecodeMPEG2Video(ctx, &mpa_pic,
3731
                                                &gotpicture, ptr, len);
3725
                                                &gotpicture, ptr, len);
3732
                        }
3726
                        }
3733
                    }
3727
                    }
3734
                    else
3728
                    else
3735
                    {
3729
                    {
3736
                        ret = avcodec_decode_video(context, &mpa_pic,
3730
                        ret = avcodec_decode_video(ctx, &mpa_pic,
3737
                                                   &gotpicture, ptr, len);
3731
                                                   &gotpicture, ptr, len);
3738
                        // Reparse it to not drop the DVD still frame
3732
                        // Reparse it to not drop the DVD still frame
3739
                        if (decodeStillFrame)
3733
                        if (decodeStillFrame)
3740
                            ret = avcodec_decode_video(context, &mpa_pic,
3734
                            ret = avcodec_decode_video(ctx, &mpa_pic,
3741
                                                        &gotpicture, ptr, len);
3735
                                                        &gotpicture, ptr, len);
3742
                    }
3736
                    }
3743
                    avcodeclock.unlock();
3737
                    avcodeclock.unlock();
Lines 3804-3812 Link Here
3804
3798
3805
                        img_convert(&tmppicture, PIX_FMT_YUV420P, 
3799
                        img_convert(&tmppicture, PIX_FMT_YUV420P, 
3806
                                    (AVPicture *)&mpa_pic,
3800
                                    (AVPicture *)&mpa_pic,
3807
                                    context->pix_fmt,
3801
                                    ctx->pix_fmt,
3808
                                    context->width,
3802
                                    ctx->width,
3809
                                    context->height);
3803
                                    ctx->height);
3810
3804
3811
                        if (xf)
3805
                        if (xf)
3812
                        {
3806
                        {
Lines 3829-3838 Link Here
3829
                        (temppts + 10000 > lastvpts || temppts < 0))
3823
                        (temppts + 10000 > lastvpts || temppts < 0))
3830
                    {
3824
                    {
3831
                        temppts = lastvpts;
3825
                        temppts = lastvpts;
3832
                        temppts += (long long)(1000 * av_q2d(context->time_base));
3826
                        temppts += (long long)(1000 * av_q2d(ctx->time_base));
3833
                        // MPEG2 frames can be repeated, update pts accordingly
3827
                        // MPEG2 frames can be repeated, update pts accordingly
3834
                        temppts += (long long)(mpa_pic.repeat_pict * 500
3828
                        temppts += (long long)(mpa_pic.repeat_pict * 500
3835
                                      * av_q2d(curstream->codec->time_base));
3829
                                      * av_q2d(ctx->time_base));
3836
                    }
3830
                    }
3837
3831
3838
                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC +
3832
                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC +
Lines 3868-3874 Link Here
3868
                    picframe->frameNumber = framesPlayed;
3862
                    picframe->frameNumber = framesPlayed;
3869
                    GetNVP()->ReleaseNextVideoFrame(picframe, temppts);
3863
                    GetNVP()->ReleaseNextVideoFrame(picframe, temppts);
3870
                    if (d->HasMPEG2Dec() && mpa_pic.data[3])
3864
                    if (d->HasMPEG2Dec() && mpa_pic.data[3])
3871
                        context->release_buffer(context, &mpa_pic);
3865
                        ctx->release_buffer(ctx, &mpa_pic);
3872
3866
3873
                    decoded_video_frame = picframe;
3867
                    decoded_video_frame = picframe;
3874
                    gotvideo = 1;
3868
                    gotvideo = 1;
Lines 3927-3937 Link Here
3927
                }
3921
                }
3928
                default:
3922
                default:
3929
                {
3923
                {
3930
                    AVCodecContext *enc = curstream->codec;
3931
                    VERBOSE(VB_IMPORTANT, LOC_ERR +
3924
                    VERBOSE(VB_IMPORTANT, LOC_ERR +
3932
                            QString("Decoding - id(%1) type(%2)")
3925
                            QString("Decoding - id(%1) type(%2)")
3933
                            .arg(codec_id_string(enc->codec_id))
3926
                            .arg(codec_id_string(ctx->codec_id))
3934
                            .arg(codec_type_string(enc->codec_type)));
3927
                            .arg(codec_type_string(ctx->codec_type)));
3935
                    have_err = true;
3928
                    have_err = true;
3936
                    break;
3929
                    break;
3937
                }
3930
                }
Lines 4080-4085 Link Here
4080
    }
4073
    }
4081
}
4074
}
4082
4075
4076
bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx)
4077
{
4078
    bool passthru = false; 
4079
4080
    if (ctx->codec_id == CODEC_ID_AC3)
4081
        passthru = allow_ac3_passthru && 
4082
                   ctx->channels >= (int)max_channels;
4083
    else if (ctx->codec_id == CODEC_ID_DTS)
4084
        passthru = allow_dts_passthru;
4085
    
4086
    passthru &= !transcoding && !disable_passthru;
4087
    // Don't know any cards that support spdif clocked at < 44100
4088
    // Some US cable transmissions have 2ch 32k AC-3 streams
4089
    passthru &= ctx->sample_rate >= 44100;
4090
4091
    return passthru;
4092
}
4093
4094
4083
/** \fn AvFormatDecoder::SetupAudioStream(void)
4095
/** \fn AvFormatDecoder::SetupAudioStream(void)
4084
 *  \brief Reinitializes audio if it needs to be reinitialized.
4096
 *  \brief Reinitializes audio if it needs to be reinitialized.
4085
 *
4097
 *
Lines 4093-4099 Link Here
4093
    AVStream *curstream = NULL;
4105
    AVStream *curstream = NULL;
4094
    AVCodecContext *codec_ctx = NULL;
4106
    AVCodecContext *codec_ctx = NULL;
4095
    AudioInfo old_in  = audioIn;
4107
    AudioInfo old_in  = audioIn;
4096
    AudioInfo old_out = audioOut;
4097
    bool using_passthru = false;
4108
    bool using_passthru = false;
4098
4109
4099
    if ((currentTrack[kTrackTypeAudio] >= 0) &&
4110
    if ((currentTrack[kTrackTypeAudio] >= 0) &&
Lines 4105-4118 Link Here
4105
        assert(curstream);
4116
        assert(curstream);
4106
        assert(curstream->codec);
4117
        assert(curstream->codec);
4107
        codec_ctx = curstream->codec;        
4118
        codec_ctx = curstream->codec;        
4108
        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
4119
        using_passthru = DoPassThrough(codec_ctx);
4109
                                (codec_ctx->codec_id == CODEC_ID_AC3));
4120
        info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, 
4110
        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
4121
                         codec_ctx->channels, using_passthru);
4111
                                (codec_ctx->codec_id == CODEC_ID_DTS));
4112
        using_passthru = do_ac3_passthru || do_dts_passthru;
4113
        info = AudioInfo(codec_ctx->codec_id,
4114
                         codec_ctx->sample_rate, codec_ctx->channels,
4115
                         using_passthru && !disable_passthru);
4116
    }
4122
    }
4117
4123
4118
    if (info == audioIn)
4124
    if (info == audioIn)
Lines 4123-4186 Link Here
4123
            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
4129
            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
4124
4130
4125
    audioOut = audioIn = info;
4131
    audioOut = audioIn = info;
4126
    if (using_passthru)
4132
4127
    {
4133
    if (!using_passthru && audioOut.channels > (int)max_channels)
4128
        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
4129
        AudioInfo digInfo = audioOut;
4130
        if (!disable_passthru)
4131
        {
4132
            digInfo.channels    = 2;
4133
            digInfo.sample_rate = 48000;
4134
            digInfo.sample_size = 4;
4135
        }
4136
        if (audioOut.channels > (int) max_channels)
4137
        {
4138
            audioOut.channels = (int) max_channels;
4139
            audioOut.sample_size = audioOut.channels * 2;
4140
            codec_ctx->channels = audioOut.channels;
4141
        }
4142
        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
4143
                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
4144
                .arg(digInfo.toString())
4145
                .arg(old_in.toString()).arg(old_out.toString())
4146
                .arg(audioIn.toString()).arg(audioOut.toString()));
4147
4148
        if (digInfo.sample_rate > 0)
4149
            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
4150
4151
        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
4152
                                 digInfo.sample_rate, audioIn.do_passthru);
4153
        // allow the audio stuff to reencode
4154
        GetNVP()->SetAudioCodec(codec_ctx);
4155
        GetNVP()->ReinitAudio();
4156
        return true;
4157
    }
4158
    else
4159
    {
4134
    {
4160
        if (audioOut.channels > (int) max_channels)
4135
        audioOut.channels = (int)max_channels;
4161
        {
4136
        audioOut.sample_size = audioOut.channels * 2;
4162
            audioOut.channels = (int) max_channels;
4137
        codec_ctx->channels = audioOut.channels;
4163
            audioOut.sample_size = audioOut.channels * 2;
4164
            codec_ctx->channels = audioOut.channels;
4165
        }
4166
    }
4138
    }
4167
4139
    
4168
    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
4140
    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
4169
            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
4141
            QString("\n\t\t\tfrom %1 to %2")
4170
            .arg(old_in.toString()).arg(old_out.toString())
4142
            .arg(old_in.toString()).arg(audioOut.toString()));
4171
            .arg(audioIn.toString()).arg(audioOut.toString()));
4172
4143
4173
    if (audioOut.sample_rate > 0)
4144
    if (audioOut.sample_rate > 0)
4174
        GetNVP()->SetEffDsp(audioOut.sample_rate * 100);
4145
        GetNVP()->SetEffDsp(audioOut.sample_rate * 100);
4175
4146
4176
    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
4147
    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
4177
                             audioOut.sample_rate,
4148
                             audioOut.sample_rate,
4178
                             audioIn.do_passthru);
4149
                             audioOut.do_passthru);
4179
4150
4180
    // allow the audio stuff to reencode
4181
    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
4182
    QString errMsg = GetNVP()->ReinitAudio();
4151
    QString errMsg = GetNVP()->ReinitAudio();
4183
    bool audiook = errMsg.isEmpty();
4184
4152
4185
    return true;
4153
    return true;
4186
}
4154
}
(-)a/libs/libmythtv/avformatdecoder.h (+2 lines)
Lines 198-203 Link Here
198
198
199
    void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames);
199
    void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames);
200
200
201
    bool DoPassThrough(const AVCodecContext *ctx);
201
    bool SetupAudioStream(void);
202
    bool SetupAudioStream(void);
202
    void SetupAudioStreamSubIndexes(int streamIndex);
203
    void SetupAudioStreamSubIndexes(int streamIndex);
203
    void RemoveAudioStreams();
204
    void RemoveAudioStreams();
Lines 266-271 Link Here
266
    bool              allow_dts_passthru;
267
    bool              allow_dts_passthru;
267
    bool              disable_passthru;
268
    bool              disable_passthru;
268
    uint              max_channels;
269
    uint              max_channels;
270
    uint              last_ac3_channels;
269
271
270
    VideoFrame       *dummy_frame;
272
    VideoFrame       *dummy_frame;
271
273
(-)a/libs/libmythtv/tv_play.cpp (-7 / +30 lines)
Lines 348-353 Link Here
348
    REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down");
348
    REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down");
349
    REG_KEY("TV Playback", "VOLUMEUP",   "Volume up",   "],},F11,Volume Up");
349
    REG_KEY("TV Playback", "VOLUMEUP",   "Volume up",   "],},F11,Volume Up");
350
    REG_KEY("TV Playback", "MUTE",       "Mute",        "|,\\,F9,Volume Mute");
350
    REG_KEY("TV Playback", "MUTE",       "Mute",        "|,\\,F9,Volume Mute");
351
    REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U");
351
    REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture mode",
352
    REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture mode",
352
            "V");
353
            "V");
353
    REG_KEY("TV Playback", "TOGGLEPIPWINDOW", "Toggle active PiP window", "B");
354
    REG_KEY("TV Playback", "TOGGLEPIPWINDOW", "Toggle active PiP window", "B");
Lines 480-486 Link Here
480
  Teletext     F2,F3,F4,F5,F6,F7,F8
481
  Teletext     F2,F3,F4,F5,F6,F7,F8
481
  ITV          F2,F3,F4,F5,F6,F7,F12
482
  ITV          F2,F3,F4,F5,F6,F7,F12
482
483
483
  Playback: Ctrl-B,Ctrl-G,Ctrl-Y
484
  Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U
484
*/
485
*/
485
}
486
}
486
487
Lines 2710-2716 Link Here
2710
            else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" ||
2711
            else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" ||
2711
                     action == "STRETCHINC" || action == "STRETCHDEC" ||
2712
                     action == "STRETCHINC" || action == "STRETCHDEC" ||
2712
                     action == "MUTE"       || action == "TOGGLEASPECT" ||
2713
                     action == "MUTE"       || action == "TOGGLEASPECT" ||
2713
                     action == "TOGGLEFILL" )
2714
                     action == "TOGGLEFILL" || action == "TOGGLEUPMIX")
2714
            {
2715
            {
2715
                passThru = 1;
2716
                passThru = 1;
2716
                handled = false;
2717
                handled = false;
Lines 2725-2735 Link Here
2725
            else
2726
            else
2726
                handled = false;
2727
                handled = false;
2727
        }
2728
        }
2728
2729
        
2729
        if (!passThru)
2730
        if (!passThru)
2730
            return;
2731
            return;
2731
    }
2732
    }
2732
2733
 
2733
    if (zoomMode)
2734
    if (zoomMode)
2734
    {
2735
    {
2735
        int passThru = 0;
2736
        int passThru = 0;
Lines 2765-2771 Link Here
2765
            else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" ||
2766
            else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" ||
2766
                     action == "STRETCHINC" || action == "STRETCHDEC" ||
2767
                     action == "STRETCHINC" || action == "STRETCHDEC" ||
2767
                     action == "MUTE" || action == "PAUSE" ||
2768
                     action == "MUTE" || action == "PAUSE" ||
2768
                     action == "CLEAROSD")
2769
                     action == "CLEAROSD" || action == "TOGGLEUPMIX")
2769
            {
2770
            {
2770
                passThru = 1;
2771
                passThru = 1;
2771
                handled = false;
2772
                handled = false;
Lines 2777-2783 Link Here
2777
        if (!passThru)
2778
        if (!passThru)
2778
            return;
2779
            return;
2779
    }
2780
    }
2780
2781
    
2781
    if (dialogname != "" && GetOSD() && GetOSD()->DialogShowing(dialogname))
2782
    if (dialogname != "" && GetOSD() && GetOSD()->DialogShowing(dialogname))
2782
    {
2783
    {
2783
        for (unsigned int i = 0; i < actions.size() && !handled; i++)
2784
        for (unsigned int i = 0; i < actions.size() && !handled; i++)
Lines 3036-3042 Link Here
3036
                return;
3037
                return;
3037
       }
3038
       }
3038
    }
3039
    }
3039
             
3040
    
3040
    for (unsigned int i = 0; i < actions.size() && !handled; i++)
3041
    for (unsigned int i = 0; i < actions.size() && !handled; i++)
3041
    {
3042
    {
3042
        QString action = actions[i];
3043
        QString action = actions[i];
Lines 3070-3075 Link Here
3070
            ChangeTimeStretch(0);   // just display
3071
            ChangeTimeStretch(0);   // just display
3071
        else if (action == "TOGGLESTRETCH")
3072
        else if (action == "TOGGLESTRETCH")
3072
            ToggleTimeStretch();
3073
            ToggleTimeStretch();
3074
        else if (action == "TOGGLEUPMIX")
3075
            ToggleUpmix();
3073
        else if (action == "CYCLECOMMSKIPMODE") {
3076
        else if (action == "CYCLECOMMSKIPMODE") {
3074
            SetAutoCommercialSkip((enum commSkipMode)
3077
            SetAutoCommercialSkip((enum commSkipMode)
3075
                                  ((autoCommercialSkip + 1) % CommSkipModes));
3078
                                  ((autoCommercialSkip + 1) % CommSkipModes));
Lines 6054-6059 Link Here
6054
    }
6057
    }
6055
}
6058
}
6056
6059
6060
void TV::ToggleUpmix()
6061
{
6062
    AudioOutput *aud = nvp->getAudioOutput();
6063
    if (!aud)
6064
        return;
6065
    QString text;
6066
    if (aud->ToggleUpmix())
6067
        text = tr("Upmixer On");
6068
    else
6069
        text = tr("Upmixer Off");
6070
    
6071
    if (GetOSD() && !browsemode)
6072
        GetOSD()->SetSettingsText(text, 5);
6073
}
6074
    
6075
6057
// dir in 10ms jumps
6076
// dir in 10ms jumps
6058
void TV::ChangeAudioSync(int dir, bool allowEdit)
6077
void TV::ChangeAudioSync(int dir, bool allowEdit)
6059
{
6078
{
Lines 7300-7305 Link Here
7300
7319
7301
        ChangeTimeStretch(0, !floatRead);   // just display
7320
        ChangeTimeStretch(0, !floatRead);   // just display
7302
    }
7321
    }
7322
    else if (action == "TOGGLEUPMIX")
7323
        ToggleUpmix();
7303
    else if (action.left(11) == "SELECTSCAN_")
7324
    else if (action.left(11) == "SELECTSCAN_")
7304
        activenvp->SetScanType((FrameScanType) action.right(1).toInt());
7325
        activenvp->SetScanType((FrameScanType) action.right(1).toInt());
7305
    else if (action.left(15) == "TOGGLEAUDIOSYNC")
7326
    else if (action.left(15) == "TOGGLEAUDIOSYNC")
Lines 7547-7552 Link Here
7547
    subitem = new OSDGenericTree(item, tr("1.5X"), "ADJUSTSTRETCH1.5",
7568
    subitem = new OSDGenericTree(item, tr("1.5X"), "ADJUSTSTRETCH1.5",
7548
                                 (speedX100 == 150) ? 1 : 0, NULL,
7569
                                 (speedX100 == 150) ? 1 : 0, NULL,
7549
                                 "STRETCHGROUP");
7570
                                 "STRETCHGROUP");
7571
    
7572
    item = new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX");
7550
7573
7551
    // add scan mode override settings to menu
7574
    // add scan mode override settings to menu
7552
    FrameScanType scan_type = kScan_Ignore;
7575
    FrameScanType scan_type = kScan_Ignore;
(-)a/libs/libmythtv/tv_play.h (+1 lines)
Lines 314-319 Link Here
314
    void ChangeSpeed(int direction);
314
    void ChangeSpeed(int direction);
315
    void ToggleTimeStretch(void);
315
    void ToggleTimeStretch(void);
316
    void ChangeTimeStretch(int dir, bool allowEdit = true);
316
    void ChangeTimeStretch(int dir, bool allowEdit = true);
317
    void ToggleUpmix(void);
317
    void ChangeAudioSync(int dir, bool allowEdit = true);
318
    void ChangeAudioSync(int dir, bool allowEdit = true);
318
    float StopFFRew(void);
319
    float StopFFRew(void);
319
    void ChangeFFRew(int direction);
320
    void ChangeFFRew(int direction);
(-)a/programs/mythfrontend/globalsettings.cpp (+25 lines)
Lines 116-121 Link Here
116
    return gc;
116
    return gc;
117
}
117
}
118
118
119
static HostComboBox *SRCQuality()
120
{
121
    HostComboBox *gc = new HostComboBox("SRCQuality", false);
122
    gc->setLabel(QObject::tr("Sample Rate Conversion"));
123
    gc->addSelection(QObject::tr("Best"), "3", true); // default
124
    gc->addSelection(QObject::tr("Medium"), "2");
125
    gc->addSelection(QObject::tr("Fastest"), "1");
126
    gc->addSelection(QObject::tr("Disabled"), "0");
127
    gc->setHelpText(
128
            QObject::tr(
129
                "Set the quality of audio sample rate conversion. "
130
                "This only affects non 48000Hz PCM audio. "
131
                "All three options offer a worst-case SNR of 97dB. "
132
                "'Best' at a bandwidth of 97%. "
133
                "'Medium' at a bandwidth of 90%. "
134
                "'Fastest' at a bandwidth of 80%. "
135
                "Set 'Disabled' only if you know what you are doing . "));
136
    return gc;
137
}
138
119
static HostComboBox *PassThroughOutputDevice()
139
static HostComboBox *PassThroughOutputDevice()
120
{
140
{
121
    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
141
    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
Lines 3307-3312 Link Here
3307
         agrp->addChild(MaxAudioChannels());
3327
         agrp->addChild(MaxAudioChannels());
3308
         agrp->addChild(AudioUpmixType());
3328
         agrp->addChild(AudioUpmixType());
3309
         addChild(agrp);
3329
         addChild(agrp);
3330
         
3331
         HorizontalConfigurationGroup *agrp1 =
3332
             new HorizontalConfigurationGroup(false, false, true, true);
3333
         agrp1->addChild(SRCQuality());
3334
         addChild(agrp1);
3310
3335
3311
         VerticalConfigurationGroup *vgrp1 =
3336
         VerticalConfigurationGroup *vgrp1 =
3312
             new VerticalConfigurationGroup(false, false, true, true);
3337
             new VerticalConfigurationGroup(false, false, true, true);
(-)a/programs/mythtranscode/transcode.cpp (-3 / +6 lines)
Lines 55-66 Link Here
55
55
56
    // reconfigure sound out for new params
56
    // reconfigure sound out for new params
57
    virtual void Reconfigure(int audio_bits, int audio_channels,
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 *audio_codec = NULL)
60
    {
59
    {
61
        (void)audio_samplerate;
60
        (void)audio_samplerate;
62
        (void)audio_passthru;
61
        (void)audio_passthru;
63
        (void)audio_codec;
64
62
65
        ClearError();
63
        ClearError();
66
        bits = audio_bits;
64
        bits = audio_bits;
Lines 218-223 Link Here
218
        // Do nothing
216
        // Do nothing
219
        return MUTE_OFF;
217
        return MUTE_OFF;
220
    }
218
    }
219
    virtual bool ToggleUpmix(void) 
220
    {
221
        // Do nothing
222
        return false;
223
    }
221
224
222
    //  These are pure virtual in AudioOutput, but we don't need them here
225
    //  These are pure virtual in AudioOutput, but we don't need them here
223
    virtual void bufferOutputData(bool){ return; }
226
    virtual void bufferOutputData(bool){ return; }

Return to bug 259009