Ticket #1104: mythtv_ac3.release-19-fixes.patch

File mythtv_ac3.release-19-fixes.patch, 110.6 KB (added by oa@…, 14 years ago)

includes merge of 8941 (trunk) in order to apply to release-19-fixes

  • libs/libmythtv/NuppelVideoPlayer.h

     
    106106    void SetKeyframeDistance(int keyframedistance);
    107107    void SetVideoParams(int w, int h, double fps, int keydist,
    108108                        float a = 1.33333, FrameScanType scan = kScan_Ignore);
    109     void SetAudioParams(int bits, int channels, int samplerate);
     109    void SetAudioParams(int bits, int channels, int samplerate, bool passthru);
     110    void SetAudioCodec(void *ac);
    110111    void SetEffDsp(int dsprate);
    111112    void SetFileLength(int total, int frames);
    112113    void Zoom(int direction);
     
    143144    bool    IsDecoderThreadAlive(void) const  { return decoder_thread_alive; }
    144145    bool    IsReallyNearEnd(void) const;
    145146    bool    IsNearEnd(long long framesRemaining = -1) const;
     147    float   GetAudioStretchFactor() { return audio_stretchfactor; }
    146148    bool    PlayingSlowForPrebuffer(void) const { return m_playing_slower; }
    147149    bool    HasAudioIn(void) const            { return !no_audio_in; }
    148150    bool    HasAudioOut(void) const           { return !no_audio_out; }
     
    171173    bool Play(float speed = 1.0, bool normal = true,
    172174              bool unpauseaudio = true);
    173175    bool GetPause(void) const;
     176    float GetNextPlaySpeed() { return next_play_speed; }
    174177
    175178    // Seek stuff
    176179    bool FastForward(float seconds);
     
    493496    int      audio_bits;
    494497    int      audio_samplerate;
    495498    float    audio_stretchfactor;
     499    void     *audio_codec;
     500    bool     audio_passthru;
    496501
    497502    // Picture-in-Picture
    498503    NuppelVideoPlayer *pipplayer;
  • libs/libmythtv/nuppeldecoder.cpp

     
    474474#endif
    475475        GetNVP()->SetAudioParams(extradata.audio_bits_per_sample,
    476476                                 extradata.audio_channels,
    477                                  extradata.audio_sample_rate);
     477                                 extradata.audio_sample_rate,
     478                                 false /* AC3/DTS pass through */);
    478479        GetNVP()->ReinitAudio();
    479480        foundit = 1;
    480481    }
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    124124      audioOutput(NULL),            audiodevice("/dev/dsp"),
    125125      audio_channels(2),            audio_bits(-1),
    126126      audio_samplerate(44100),      audio_stretchfactor(1.0f),
     127      audio_codec(NULL),
    127128      // Picture-in-Picture
    128129      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
    129130      // Preview window support
     
    510511        audioOutput = AudioOutput::OpenAudio(audiodevice, audio_bits,
    511512                                             audio_channels, audio_samplerate,
    512513                                             AUDIOOUTPUT_VIDEO,
    513                                              setVolume);
     514                                             setVolume, audio_passthru);
    514515        if (!audioOutput)
    515516            errMsg = QObject::tr("Unable to create AudioOutput.");
    516517        else
     
    536537
    537538    if (audioOutput)
    538539    {
    539         audioOutput->Reconfigure(audio_bits, audio_channels, audio_samplerate);
     540        audioOutput->Reconfigure(audio_bits, audio_channels,
     541                                 audio_samplerate, audio_passthru,
     542                                 audio_codec);
    540543        errMsg = audioOutput->GetError();
    541544        if (!errMsg.isEmpty())
    542545            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    669672        {
    670673            VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
    671674                    "framerate (refresh rate too low for bob deint)");
     675            //m_scan = kScan_Ignore;
     676            //m_can_double = false;
    672677            FallbackDeint();
    673678        }
    674679    }
     
    15321537    warpfactor_avg = (warpfactor + (warpfactor_avg * (WARPAVLEN - 1))) /
    15331538                      WARPAVLEN;
    15341539
    1535     //cerr << "Divergence: " << divergence << "  Rate: " << rate
    1536     //<< "  Warpfactor: " << warpfactor << "  warpfactor_avg: "
    1537     //<< warpfactor_avg << endl;
     1540#if 1
     1541    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V "
     1542        "Divergence: %1 "
     1543        "  Rate: %2"
     1544        "  Warpfactor: %3"
     1545        "  warpfactor_avg: %4")
     1546        .arg(divergence)
     1547        .arg(rate)
     1548        .arg(warpfactor)
     1549        .arg(warpfactor_avg)
     1550        );
     1551#endif
    15381552    return divergence;
    15391553}
    15401554
     
    16151629    if (diverge < -MAXDIVERGE)
    16161630    {
    16171631        // If video is way ahead of audio, adjust for it...
    1618         QString dbg = QString("Video is %1 frames ahead of audio, ")
     1632        QString dbg = QString("Audio is %1 frames ahead of video, ")
    16191633            .arg(-diverge);
    16201634
    16211635        // Reset A/V Sync
     
    16301644            // decoding; display the frame, but don't wait for A/V Sync.
    16311645            videoOutput->PrepareFrame(buffer, ps);
    16321646            videoOutput->Show(m_scan);
    1633             VERBOSE(VB_PLAYBACK, LOC + dbg + "skipping A/V wait.");
     1647            VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "skipping A/V wait.");
    16341648        }
    16351649        else
    16361650        {
    16371651            // If we are using software decoding, skip this frame altogether.
    1638             VERBOSE(VB_PLAYBACK, LOC + dbg + "dropping frame.");
     1652            VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "dropping frame.");
    16391653        }
    16401654    }
    16411655    else if (!using_null_videoout)
     
    16441658        if (buffer)
    16451659            videoOutput->PrepareFrame(buffer, ps);
    16461660
     1661        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2").arg(avsync_adjustment).arg(m_double_framerate));
    16471662        videosync->WaitForFrame(avsync_adjustment);
     1663        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show");
    16481664        if (!resetvideo)
    16491665            videoOutput->Show(m_scan);
    16501666
     
    16641680
    16651681            // Display the second field
    16661682            videosync->AdvanceTrigger();
    1667             videosync->WaitForFrame(0);
     1683            videosync->WaitForFrame(avsync_adjustment);
    16681684            if (!resetvideo)
    16691685                videoOutput->Show(kScan_Intr2ndField);
    16701686        }
     
    16761692
    16771693    if (output_jmeter && output_jmeter->RecordCycleTime())
    16781694    {
    1679         //cerr << "avsync_delay: " << avsync_delay / 1000
    1680         //     << ", avsync_avg: " << avsync_avg / 1000
    1681         //     << ", warpfactor: " << warpfactor
    1682         //     << ", warpfactor_avg: " << warpfactor_avg << endl;
     1695#if 1
     1696        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V "
     1697            "avsync_delay: %1"
     1698            ", avsync_avg: %2"
     1699            ", warpfactor: %3"
     1700            ", warpfactor_avg: %4")
     1701                .arg(avsync_delay / 1000)
     1702                .arg(avsync_avg / 1000)
     1703                .arg(warpfactor)
     1704                .arg(warpfactor_avg));
     1705#endif
    16831706    }
    16841707
    16851708    videosync->AdvanceTrigger();
     
    16901713        // If audio is way ahead of video, adjust for it...
    16911714        // by cutting the frame rate in half for the length of this frame
    16921715
    1693         avsync_adjustment = frame_interval;
     1716        //avsync_adjustment = frame_interval;
     1717        avsync_adjustment = refreshrate;
    16941718        lastsync = true;
    1695         VERBOSE(VB_PLAYBACK, LOC +
    1696                 QString("Audio is %1 frames ahead of video,\n"
     1719        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC +
     1720                QString("Video is %1 frames ahead of audio,\n"
    16971721                        "\t\t\tdoubling video frame interval.").arg(diverge));
    16981722    }
    16991723
    17001724    if (audioOutput && normal_speed)
    17011725    {
    17021726        long long currentaudiotime = audioOutput->GetAudiotime();
    1703 #if 0
    1704         VERBOSE(VB_PLAYBACK, QString(
     1727#if 1
     1728        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString(
    17051729                    "A/V timecodes audio %1 video %2 frameinterval %3 "
    17061730                    "avdel %4 avg %5 tcoffset %6")
    17071731                .arg(currentaudiotime)
     
    19471971
    19481972    usevideotimebase = gContext->GetNumSetting("UseVideoTimebase", 0);
    19491973
    1950     if ((print_verbose_messages & VB_PLAYBACK) != 0)
     1974    if ((print_verbose_messages & VB_PLAYBACK|VB_TIMESTAMP) == (VB_PLAYBACK|VB_TIMESTAMP))
    19511975        output_jmeter = new Jitterometer("video_output", 100);
    19521976    else
    19531977        output_jmeter = NULL;
     
    19872011            {
    19882012                VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
    19892013                        "framerate (refresh rate too low for bob deint)");
     2014                //m_scan = kScan_Ignore;
     2015                //m_can_double = false;
    19902016                FallbackDeint();
    19912017            }
    19922018        }
     
    26962722    }
    26972723}
    26982724
    2699 void NuppelVideoPlayer::SetAudioParams(int bps, int channels, int samplerate)
     2725void NuppelVideoPlayer::SetAudioParams(int bps, int channels,
     2726                                       int samplerate, bool passthru)
    27002727{
    27012728    audio_bits = bps;
    27022729    audio_channels = channels;
    27032730    audio_samplerate = samplerate;
     2731    audio_passthru = passthru;
    27042732}
    27052733
     2734void NuppelVideoPlayer::SetAudioCodec(void* ac)
     2735{
     2736    audio_codec = ac;
     2737}
     2738
    27062739void NuppelVideoPlayer::SetEffDsp(int dsprate)
    27072740{
    27082741    if (audioOutput)
     
    27472780        tc_avcheck_framecounter++;
    27482781        if (tc_avcheck_framecounter == 30)
    27492782        {
    2750 #define AUTO_RESYNC 1
     2783#define AUTO_RESYNC 0
    27512784#if AUTO_RESYNC
    27522785            // something's terribly, terribly wrong.
    27532786            if (tc_lastval[TC_AUDIO] < tc_lastval[TC_VIDEO] - 10000000 ||
  • libs/libmythtv/avformatdecoder.cpp

     
    3838#define MAX_AC3_FRAME_SIZE 6144
    3939
    4040/** Set to zero to allow any number of AC3 channels. */
     41#define MAXCHANNELSELECT 1
     42#if MAXCHANNELSELECT
     43#define MAX_OUTPUT_CHANNELS compiler error
     44#else
    4145#define MAX_OUTPUT_CHANNELS 2
     46#endif
    4247
    4348static int dts_syncinfo(uint8_t *indata_ptr, int *flags,
    4449                        int *sample_rate, int *bit_rate);
     
    286291#ifdef CONFIG_DTS
    287292    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
    288293#endif
     294    max_channels = gContext->GetNumSetting("MaxChannels", 2);
    289295
    290296    audioIn.sample_size = -32; // force SetupAudioStream to run once
    291297}
     
    406412    framesPlayed = lastKey;
    407413    framesRead = lastKey;
    408414
     415    VERBOSE(VB_PLAYBACK, QString("AvFormatDecoder::DoFastForward newframe %5 frame %1 fps %2 ts %3 disc %4 cur_dts %6 adj %7 newts %8 fsa %9")
     416        .arg(desiredFrame)
     417        .arg(fps)
     418        .arg(ts)
     419        .arg(discardFrames)
     420        .arg(framesPlayed)
     421        .arg(st->cur_dts)
     422        .arg(adj_cur_dts)
     423        .arg(newts)
     424        .arg(frameseekadjust)
     425        );
     426
    409427    int normalframes = desiredFrame - framesPlayed;
    410428
     429#if 0
     430    if (!exactseeks)
     431        normalframes = 0;
     432#endif
     433
    411434    SeekReset(lastKey, normalframes, discardFrames, discardFrames);
    412435
    413436    if (discardFrames)
     
    739762
    740763    fmt->flags &= ~AVFMT_NOFILE;
    741764
     765#if 1
     766    if ((m_playbackinfo) || livetv || watchingrecording)
     767    {
     768        const char *name = ic->av_class->item_name(ic);
     769        VERBOSE(VB_GENERAL, QString("libavformat type %1").arg(name));
     770    }
     771#endif
     772
    742773    av_estimate_timings(ic);
    743774    av_read_frame_flush(ic);
    744775
     
    747778    if (-1 == ret)
    748779        return ret;
    749780
     781    // make sure its at the real start due to av_find_stream_info reading
     782    ret = av_seek_frame(ic, -1, 0, AVSEEK_FLAG_BACKWARD);
     783    if (ret < 0)
     784        av_seek_frame(ic, -1, 0, AVSEEK_FLAG_BYTE);     // reposition to start of stream
     785
    750786    // Select some starting audio and subtitle tracks.
    751787    // TODO do we need this? They will be called by GetFrame() anyway...
    752788    autoSelectAudioTrack();
     
    769805    // If we don't have a position map, set up ffmpeg for seeking
    770806    if (!recordingHasPositionMap)
    771807    {
     808        const char *name = ic->av_class->item_name(ic);
    772809        VERBOSE(VB_PLAYBACK, LOC +
    773                 "Recording has no position -- using libavformat seeking.");
     810                QString("Recording has no position -- using libavformat seeking. %1").arg(name));
    774811        int64_t dur = ic->duration / (int64_t)AV_TIME_BASE;
    775812
    776813        if (dur > 0)
     
    815852            QString("Successfully opened decoder for file: "
    816853                    "\"%1\". novideo(%2)").arg(filename).arg(novideo));
    817854
     855    // set initial position correctly
     856    //DoFastForward(0, true);
     857
    818858    // Return true if recording has position map
    819859    return recordingHasPositionMap;
    820860}
     
    10531093                }
    10541094                assert(enc->codec_id);
    10551095
     1096                VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels));
     1097#if 0
     1098                if (enc->channels > 2)
     1099                    enc->channels = 2;
     1100#endif
     1101 
     1102#if 0
    10561103                // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU
    10571104                if (enc->codec_id == CODEC_ID_DTS)
    10581105                {
     
    10611108                    // enc->bit_rate = what??;
    10621109                }
    10631110                // HACK END REALLY UGLY HACK FOR DTS PASSTHRU
     1111#endif
    10641112
    10651113                bitrate += enc->bit_rate;
    10661114                break;
     
    11851233    // waiting on audio.
    11861234    if (GetNVP()->HasAudioIn() && audioStreams.empty())
    11871235    {
    1188         GetNVP()->SetAudioParams(-1, -1, -1);
     1236        GetNVP()->SetAudioParams(-1, -1, -1, false /* AC3/DTS pass-through */);
    11891237        GetNVP()->ReinitAudio();
    11901238    }
    11911239
     
    15611609        {
    15621610            long long startpos = pkt->pos;
    15631611
    1564             VERBOSE(VB_PLAYBACK, LOC +
     1612            VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC +
    15651613                    QString("positionMap[ %1 ] == %2.")
    15661614                    .arg(prevgoppos / keyframedist)
    15671615                    .arg((int)startpos));
     
    22762324
    22772325        AVStream *curstream = ic->streams[pkt->stream_index];
    22782326
     2327#if 0
     2328        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("timecode pts:%1 dts:%2 codec:%3")
     2329                .arg(pkt->pts)
     2330                .arg(pkt->dts)
     2331                .arg((curstream && curstream->codec)?curstream->codec->codec_type:-1)
     2332               );
     2333#endif
     2334
    22792335        if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
    22802336            pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000);
    22812337
     
    23892445                    if (!curstream->codec->channels)
    23902446                    {
    23912447                        QMutexLocker locker(&avcodeclock);
     2448#if MAXCHANNELSELECT
     2449                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels));
     2450                        curstream->codec->cqp = max_channels;
     2451                        curstream->codec->channels = audioOut.channels;
     2452#else
    23922453                        curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     2454#endif
    23932455                        ret = avcodec_decode_audio(
    23942456                            curstream->codec, audioSamples,
    23952457                            &data_size, ptr, len);
     
    24402502                    {
    24412503                        AVCodecContext *ctx = curstream->codec;
    24422504
     2505#if MAXCHANNELSELECT
    24432506                        if ((ctx->channels == 0) ||
     2507                            (ctx->channels > audioOut.channels))
     2508                            ctx->channels = audioOut.channels;
     2509#else
     2510                        if ((ctx->channels == 0) ||
    24442511                            (ctx->channels > MAX_OUTPUT_CHANNELS))
    24452512                            ctx->channels = MAX_OUTPUT_CHANNELS;
     2513#endif
    24462514
    24472515                        ret = avcodec_decode_audio(
    24482516                            ctx, audioSamples, &data_size, ptr, len);
     
    24782546                                (curstream->codec->channels * 2) /
    24792547                                curstream->codec->sample_rate);
    24802548
     2549                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("audio timecode %1 %2 %3 %4")
     2550                            .arg(pkt->pts)
     2551                            .arg(pkt->dts)
     2552                            .arg(temppts).arg(lastapts));
    24812553                    GetNVP()->AddAudioData((char *)audioSamples, data_size,
    24822554                                           temppts);
    24832555
     
    25692641                    else
    25702642                        temppts = lastvpts;
    25712643
     2644                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("video timecode %1 %2 %3 %4")
     2645                            .arg(pkt->pts)
     2646                            .arg(pkt->dts)
     2647                            .arg(temppts).arg(lastvpts));
    25722648/* XXX: Broken.
    25732649                    if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 &&
    25742650                        context->height == picframe->height)
     
    26632739
    26642740void AvFormatDecoder::SetDisablePassThrough(bool disable)
    26652741{
     2742#if MAXCHANNELSELECT
     2743    // can only disable never reenable as once tiemstretch is on its on for the session
     2744    if (disable_passthru)
     2745        return;
     2746#endif
    26662747    if (selectedAudioStream.av_stream_index < 0)
    26672748    {
    26682749        disable_passthru = disable;
    26692750        return;
    26702751    }
    2671 
     2752 
    26722753    if (disable != disable_passthru)
    26732754    {
    26742755        disable_passthru = disable;
     
    26952776    AVCodecContext *codec_ctx = NULL;
    26962777    AudioInfo old_in  = audioIn;
    26972778    AudioInfo old_out = audioOut;
     2779    bool using_passthru = false;
    26982780
    26992781    if ((currentAudioTrack >= 0) &&
    27002782        (selectedAudioStream.av_stream_index <= ic->nb_streams) &&
     
    27022784    {
    27032785        assert(curstream);
    27042786        assert(curstream->codec);
    2705         codec_ctx = curstream->codec;       
     2787        codec_ctx = curstream->codec;
    27062788        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    2707                                 !disable_passthru &&
    27082789                                (codec_ctx->codec_id == CODEC_ID_AC3));
    27092790        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    2710                                 !disable_passthru &&
    27112791                                (codec_ctx->codec_id == CODEC_ID_DTS));
     2792        using_passthru = do_ac3_passthru || do_dts_passthru;
    27122793        info = AudioInfo(codec_ctx->codec_id,
    27132794                         codec_ctx->sample_rate, codec_ctx->channels,
    2714                          do_ac3_passthru || do_dts_passthru);
     2795                         using_passthru && !disable_passthru);
    27152796    }
    27162797
    27172798    if (info == audioIn)
    27182799        return false; // no change
    27192800
     2801    QString ptmsg = "";
     2802    if (using_passthru)
     2803    {
     2804        ptmsg = QString(" using passthru");
     2805    }
    27202806    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    2721             QString("audio track #%1").arg(currentAudioTrack+1));
     2807            QString("audio track #%1")
     2808                .arg(currentAudioTrack+1)
     2809            + ptmsg );
    27222810
    27232811    audioOut = audioIn = info;
     2812#if MAXCHANNELSELECT
     2813    if (using_passthru)
     2814#else
    27242815    if (audioIn.do_passthru)
     2816#endif
    27252817    {
    27262818        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    2727         audioOut.channels    = 2;
    2728         audioOut.sample_rate = 48000;
    2729         audioOut.sample_size = 4;
     2819        AudioInfo digInfo = audioOut;
     2820        if (!disable_passthru)
     2821        {
     2822            digInfo.channels    = 2;
     2823            digInfo.sample_rate = 48000;
     2824            digInfo.sample_size = 4;
     2825        }
     2826        if (audioOut.channels > max_channels)
     2827        {
     2828            audioOut.channels = max_channels;
     2829            audioOut.sample_size = audioOut.channels * 2;
     2830            codec_ctx->channels = audioOut.channels;
     2831        }
     2832#if MAXCHANNELSELECT
     2833        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     2834                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     2835                .arg(digInfo.toString())
     2836                .arg(old_in.toString()).arg(old_out.toString())
     2837                .arg(audioIn.toString()).arg(audioOut.toString()));
     2838
     2839        if (digInfo.sample_rate > 0)
     2840            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     2841
     2842        //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
     2843        //                         audioOut.sample_rate);
     2844        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     2845                                 digInfo.sample_rate, audioIn.do_passthru);
     2846        // allow the audio stuff to reencode
     2847        GetNVP()->SetAudioCodec(codec_ctx);
     2848        GetNVP()->ReinitAudio();
     2849        return true;
     2850#endif
    27302851    }
     2852#if MAXCHANNELSELECT
    27312853    else
    27322854    {
     2855        if (audioOut.channels > max_channels)
     2856        {
     2857            audioOut.channels = max_channels;
     2858            audioOut.sample_size = audioOut.channels * 2;
     2859            codec_ctx->channels = audioOut.channels;
     2860        }
     2861    }
     2862    bool audiook;
     2863#if 0
     2864    do
     2865    {
     2866#endif
     2867#else
     2868    else
     2869    {
    27332870        if (audioOut.channels > MAX_OUTPUT_CHANNELS)
    27342871        {
    27352872            audioOut.channels = MAX_OUTPUT_CHANNELS;
     
    27372874            codec_ctx->channels = MAX_OUTPUT_CHANNELS;
    27382875        }
    27392876    }
     2877#endif
    27402878
    27412879    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
    27422880            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
     
    27472885        GetNVP()->SetEffDsp(audioOut.sample_rate * 100);
    27482886
    27492887    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    2750                              audioOut.sample_rate);
    2751     GetNVP()->ReinitAudio();
     2888                             audioOut.sample_rate,
     2889                             audioIn.do_passthru);
     2890    // allow the audio stuff to reencode
     2891    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     2892    QString errMsg = GetNVP()->ReinitAudio();
     2893#if MAXCHANNELSELECT
     2894        audiook = errMsg.isEmpty();
     2895#if 0
     2896        if (!audiook)
     2897        {
     2898            switch (audioOut.channels)
     2899            {
     2900#if 0
     2901                case 8:
     2902                    audioOut.channels = 6;
     2903                    break;
     2904#endif
     2905                case 6:
     2906#if 0
     2907                    audioOut.channels = 5;
     2908                    break;
     2909                case 5:
     2910                    audioOut.channels = 4;
     2911                    break;
     2912                case 4:
     2913                    audioOut.channels = 3;
     2914                    break;
     2915                case 3:
     2916#endif
     2917                    audioOut.channels = 2;
     2918                    break;
     2919#if 0
     2920                case 2:
     2921                    audioOut.channels = 1;
     2922                    break;
     2923#endif
     2924                default:
     2925                    // failed to reconfigure under any circumstances
     2926                    audiook = true;
     2927                    audioOut.channels = 0;
     2928                    break;
     2929            }
     2930            audioOut.sample_size = audioOut.channels * 2;
     2931            codec_ctx->channels = audioOut.channels;
     2932        }
     2933    } while (!audiook);
     2934#endif
     2935#endif
    27522936
    27532937    return true;
    27542938}
  • libs/libmythtv/avformatdecoder.h

     
    238238    bool              allow_ac3_passthru;
    239239    bool              allow_dts_passthru;
    240240    bool              disable_passthru;
     241    int               max_channels;
    241242
    242243    AudioInfo         audioIn;
    243244    AudioInfo         audioOut;
  • libs/libmythsoundtouch/TDStretch.cpp

     
    9696
    9797    pMidBuffer = NULL;
    9898    pRefMidBufferUnaligned = NULL;
     99    midBufferLength = 0;
    99100    overlapLength = 0;
    100101
    101102    setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
     
    108109
    109110TDStretch::~TDStretch()
    110111{
    111     delete[] pMidBuffer;
    112     delete[] pRefMidBufferUnaligned;
     112    if (midBufferLength)
     113    {
     114        delete[] pMidBuffer;
     115        delete[] pRefMidBufferUnaligned;
     116        midBufferLength = 0;
     117    }
    113118}
    114119
    115120
     
    196201
    197202void TDStretch::clearMidBuffer()
    198203{
    199     if (bMidBufferDirty)
     204    if (bMidBufferDirty && midBufferLength)
    200205    {
    201         memset(pMidBuffer, 0, 2 * sizeof(SAMPLETYPE) * overlapLength);
     206        memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength);
    202207        bMidBufferDirty = FALSE;
    203208    }
    204209}
     
    239244// Seeks for the optimal overlap-mixing position.
    240245uint TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
    241246{
     247#ifdef MULTICHANNEL
     248    if (channels > 2)
     249    {
     250        // stereo sound
     251        if (bQuickseek)
     252        {
     253            return seekBestOverlapPositionMultiQuick(refPos);
     254        }
     255        else
     256        {
     257            return seekBestOverlapPositionMulti(refPos);
     258        }
     259    }
     260    else
     261#endif
    242262    if (channels == 2)
    243263    {
    244264        // stereo sound
     
    272292// of 'ovlPos'.
    273293inline void TDStretch::overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const
    274294{
     295#ifdef MULTICHANNEL
     296    if (channels > 2)
     297    {
     298        overlapMulti(output, input + channels * ovlPos);
     299    }
     300    else
     301#endif
    275302    if (channels == 2)
    276303    {
    277304        // stereo sound
     
    285312
    286313
    287314
     315#ifdef MULTICHANNEL
    288316// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
    289317// routine
    290318//
    291319// The best position is determined as the position where the two overlapped
    292320// sample sequences are 'most alike', in terms of the highest cross-correlation
    293321// value over the overlapping period
     322uint TDStretch::seekBestOverlapPositionMulti(const SAMPLETYPE *refPos)
     323{
     324    uint bestOffs;
     325    LONG_SAMPLETYPE bestCorr, corr;
     326    uint i;
     327
     328    // Slopes the amplitudes of the 'midBuffer' samples
     329    precalcCorrReference();
     330
     331    bestCorr = INT_MIN;
     332    bestOffs = 0;
     333
     334    // Scans for the best correlation value by testing each possible position
     335    // over the permitted range.
     336    for (i = 0; i < seekLength; i ++)
     337    {
     338        // Calculates correlation value for the mixing position corresponding
     339        // to 'i'
     340        corr = calcCrossCorrMulti(refPos + channels * i, pRefMidBuffer);
     341
     342        // Checks for the highest correlation value
     343        if (corr > bestCorr)
     344        {
     345            bestCorr = corr;
     346            bestOffs = i;
     347        }
     348    }
     349    // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
     350    clearCrossCorrState();
     351
     352    return bestOffs;
     353}
     354
     355
     356// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
     357// routine
     358//
     359// The best position is determined as the position where the two overlapped
     360// sample sequences are 'most alike', in terms of the highest cross-correlation
     361// value over the overlapping period
     362uint TDStretch::seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos)
     363{
     364    uint j;
     365    uint bestOffs;
     366    LONG_SAMPLETYPE bestCorr, corr;
     367    uint scanCount, corrOffset, tempOffset;
     368
     369    // Slopes the amplitude of the 'midBuffer' samples
     370    precalcCorrReference();
     371
     372    bestCorr = INT_MIN;
     373    bestOffs = 0;
     374    corrOffset = 0;
     375    tempOffset = 0;
     376
     377    // Scans for the best correlation value using four-pass hierarchical search.
     378    //
     379    // The look-up table 'scans' has hierarchical position adjusting steps.
     380    // In first pass the routine searhes for the highest correlation with
     381    // relatively coarse steps, then rescans the neighbourhood of the highest
     382    // correlation with better resolution and so on.
     383    for (scanCount = 0;scanCount < 4; scanCount ++)
     384    {
     385        j = 0;
     386        while (scanOffsets[scanCount][j])
     387        {
     388            tempOffset = corrOffset + scanOffsets[scanCount][j];
     389            if (tempOffset >= seekLength) break;
     390
     391            // Calculates correlation value for the mixing position corresponding
     392            // to 'tempOffset'
     393            corr = calcCrossCorrMulti(refPos + channels * tempOffset, pRefMidBuffer);
     394
     395            // Checks for the highest correlation value
     396            if (corr > bestCorr)
     397            {
     398                bestCorr = corr;
     399                bestOffs = tempOffset;
     400            }
     401            j ++;
     402        }
     403        corrOffset = bestOffs;
     404    }
     405    // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
     406    clearCrossCorrState();
     407
     408    return bestOffs;
     409}
     410#endif
     411
     412// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
     413// routine
     414//
     415// The best position is determined as the position where the two overlapped
     416// sample sequences are 'most alike', in terms of the highest cross-correlation
     417// value over the overlapping period
    294418uint TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos)
    295419{
    296420    uint bestOffs;
     
    512636void TDStretch::setChannels(uint numChannels)
    513637{
    514638    if (channels == numChannels) return;
     639#ifdef MULTICHANNEL
     640    assert(numChannels >= 1 && numChannels <= MULTICHANNEL);
     641#else
    515642    assert(numChannels == 1 || numChannels == 2);
     643#endif
    516644
    517645    channels = numChannels;
    518646    inputBuffer.setChannels(channels);
     
    635763/// Set new overlap length parameter & reallocate RefMidBuffer if necessary.
    636764void TDStretch::acceptNewOverlapLength(uint newOverlapLength)
    637765{
    638     uint prevOvl;
    639 
    640     prevOvl = overlapLength;
    641766    overlapLength = newOverlapLength;
    642767
    643     if (overlapLength > prevOvl)
     768    if (overlapLength*channels > midBufferLength)
    644769    {
    645         delete[] pMidBuffer;
    646         delete[] pRefMidBufferUnaligned;
     770        if (midBufferLength)
     771        {
     772            delete[] pMidBuffer;
     773            delete[] pRefMidBufferUnaligned;
     774            midBufferLength = 0;
     775        }
    647776
    648         pMidBuffer = new SAMPLETYPE[overlapLength * 2];
     777        midBufferLength = overlapLength * channels;
     778        pMidBuffer = new SAMPLETYPE[midBufferLength];
    649779        bMidBufferDirty = TRUE;
    650780        clearMidBuffer();
    651781
    652         pRefMidBufferUnaligned = new SAMPLETYPE[2 * overlapLength + 16 / sizeof(SAMPLETYPE)];
     782        pRefMidBufferUnaligned = new SAMPLETYPE[midBufferLength + 16 / sizeof(SAMPLETYPE)];
    653783        // ensure that 'pRefMidBuffer' is aligned to 16 byte boundary for efficiency
    654784        pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & -16);
    655785    }
     
    718848
    719849#ifdef INTEGER_SAMPLES
    720850
     851#ifdef MULTICHANNEL
    721852// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
    722853// is faster to calculate
     854void TDStretch::precalcCorrReference()
     855{
     856    int i,j;
     857    int temp, temp2;
     858    short *src = pMidBuffer;
     859    short *dest = pRefMidBuffer;
     860
     861    for (i=0 ; i < (int)overlapLength ;i ++)
     862    {
     863        temp = i * (overlapLength - i);
     864
     865        for(j=0;j<channels;j++)
     866        {
     867            temp2 = (*src++ * temp) / slopingDivider;
     868            *dest++ = (short)(temp2);
     869        }
     870    }
     871}
     872#endif
     873
     874// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
     875// is faster to calculate
    723876void TDStretch::precalcCorrReferenceStereo()
    724877{
    725878    int i, cnt2;
     
    772925    }
    773926}
    774927
     928#ifdef MULTICHANNEL
     929// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo'
     930// version of the routine.
     931void TDStretch::overlapMulti(short *output, const short *input) const
     932{
     933    int i,j;
     934    short temp;
     935    //uint cnt2;
     936    const short *ip = input;
     937    short *op = output;
     938    const short *md = pMidBuffer;
    775939
     940    for (i = 0; i < (int)overlapLength ; i ++)
     941    {
     942        temp = (short)(overlapLength - i);
     943        for(j=0;j<channels;j++)
     944            *op++ = (*ip++ * i + *md++ * temp )  / overlapLength;
     945    }
     946}
     947#endif
     948
     949
    776950/// Calculates overlap period length in samples.
    777951/// Integer version rounds overlap length to closest power of 2
    778952/// for a divide scaling operation.
     
    824998    return corr;
    825999}
    8261000
     1001#ifdef MULTICHANNEL
     1002long TDStretch::calcCrossCorrMulti(const short *mixingPos, const short *compare) const
     1003{
     1004    long corr;
     1005    uint i;
     1006
     1007    corr = 0;
     1008    for (i = channels; i < channels * overlapLength; i++)
     1009    {
     1010        corr += (mixingPos[i] * compare[i]) >> overlapDividerBits;
     1011    }
     1012
     1013    return corr;
     1014}
     1015#endif
     1016
    8271017#endif // INTEGER_SAMPLES
    8281018
    8291019//////////////////////////////////////////////////////////////////////////////
     
    9311121    return corr;
    9321122}
    9331123
    934 #endif // FLOAT_SAMPLES
    935  No newline at end of file
     1124#endif // FLOAT_SAMPLES
  • libs/libmythsoundtouch/TDStretch.h

     
    4848#include "RateTransposer.h"
    4949#include "FIFOSamplePipe.h"
    5050
     51#ifdef MULTICHANNEL
     52#define USE_MULTI_MMX
     53#endif
     54
    5155namespace soundtouch
    5256{
    5357
     
    100104    SAMPLETYPE *pMidBuffer;
    101105    SAMPLETYPE *pRefMidBuffer;
    102106    SAMPLETYPE *pRefMidBufferUnaligned;
     107    uint midBufferLength;
    103108    uint overlapLength;
    104109    uint overlapDividerBits;
    105110    uint slopingDivider;
     
    123128    virtual void clearCrossCorrState();
    124129    void calculateOverlapLength(uint overlapMs);
    125130
     131#ifdef MULTICHANNEL
     132    virtual LONG_SAMPLETYPE calcCrossCorrMulti(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
     133#endif
    126134    virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
    127135    virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
    128136
     137#ifdef MULTICHANNEL
     138    virtual uint seekBestOverlapPositionMulti(const SAMPLETYPE *refPos);
     139    virtual uint seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos);
     140#endif
    129141    virtual uint seekBestOverlapPositionStereo(const SAMPLETYPE *refPos);
    130142    virtual uint seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos);
    131143    virtual uint seekBestOverlapPositionMono(const SAMPLETYPE *refPos);
    132144    virtual uint seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos);
    133145    uint seekBestOverlapPosition(const SAMPLETYPE *refPos);
    134146
     147#ifdef MULTICHANNEL
     148    virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const;
     149#endif
    135150    virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
    136151    virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const;
    137152
    138153    void clearMidBuffer();
    139154    void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
    140155
     156#ifdef MULTICHANNEL
     157    void precalcCorrReference();
     158#endif
    141159    void precalcCorrReferenceMono();
    142160    void precalcCorrReferenceStereo();
    143161
     
    225243    class TDStretchMMX : public TDStretch
    226244    {
    227245    protected:
     246#ifdef USE_MULTI_MMX
     247#ifdef MULTICHANNEL
     248        long calcCrossCorrMulti(const short *mixingPos, const short *compare) const;
     249#endif
     250#endif
    228251        long calcCrossCorrStereo(const short *mixingPos, const short *compare) const;
    229252        virtual void overlapStereo(short *output, const short *input) const;
    230253        virtual void clearCrossCorrState();
     
    237260    class TDStretch3DNow : public TDStretch
    238261    {
    239262    protected:
     263#ifdef MULTICHANNEL
     264        //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const;
     265#endif
    240266        double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
    241267    };
    242268#endif /// ALLOW_3DNOW
     
    247273    class TDStretchSSE : public TDStretch
    248274    {
    249275    protected:
     276#ifdef MULTICHANNEL
     277        //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const;
     278#endif
    250279        double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
    251280    };
    252281
  • libs/libmythsoundtouch/RateTransposer.cpp

     
    330330{
    331331    if (uChannels == numchannels) return;
    332332
     333#ifdef MULTICHANNEL
     334    assert(numchannels >= 1 && numchannels <= MULTICHANNEL);
     335#else
    333336    assert(numchannels == 1 || numchannels == 2);
     337#endif
    334338    uChannels = numchannels;
    335339
    336340    storeBuffer.setChannels(uChannels);
  • libs/libmythsoundtouch/mmx_gcc.cpp

     
    141141    return tmp;
    142142}
    143143
     144#ifdef USE_MULTI_MMX
     145// Calculates cross correlation of two buffers
     146long TDStretchMMX::calcCrossCorrMulti(const short *pV1, const short *pV2) const
     147{
     148    //static const unsigned long long int mm_half __attribute__ ((aligned(8))) = 0xffffffffULL;
     149    static const __m64 mm_mask[4][8] __attribute__ ((aligned(8))) = {
     150        {
     151            // even bit
     152            0xffffffffffffffffULL,
     153            0xffffffffffffffffULL,
     154            0xffffffffffffffffULL,
     155            0xffffffffffffffffULL,
     156            0,
     157            0,
     158            0,
     159            0
     160        },
     161        {
     162            0xffffffffffffffffULL,
     163            0xffffffffffffffffULL,
     164            0xffffffffffffffffULL,
     165            0x0000ffffffffffffULL,
     166            0,
     167            0,
     168            0,
     169            0
     170        },
     171        {
     172            0xffffffffffffffffULL,
     173            0xffffffffffffffffULL,
     174            0xffffffffffffffffULL,
     175            0x00000000ffffffffULL,
     176            0,
     177            0,
     178            0,
     179            0
     180        },
     181        {
     182            0xffffffffffffffffULL,
     183            0xffffffffffffffffULL,
     184            0xffffffffffffffffULL,
     185            0x000000000000ffffULL,
     186            0,
     187            0,
     188            0,
     189            0
     190        }
     191    };
     192    uint tmp;
     193    uint adjustedOverlapLength = overlapLength*channels;
     194    uint counter = ((adjustedOverlapLength+15)>>4)-1;    // load counter to counter = overlapLength / 8 - 1
     195    uint remainder = (16-adjustedOverlapLength)&0xf;     // since there are 1/3 sample per 1/2 quadword
     196
     197    __m64 *ph = (__m64*)&mm_mask[remainder&3][remainder>>2];
     198    __m64 *pv1=(__m64*)pV1, *pv2=(__m64*)pV2;
     199    GI(__m64 m0, m1, m2, m3, m4, m5, m6); // temporaries
     200    uint shift = overlapDividerBits;
     201
     202    // prepare to the first round by loading
     203    SI(m1 = pv1[0],             movq_a2r(0, pv1, mm1)); // load m1 = pv1[0]
     204    SI(m2 = pv1[1],             movq_a2r(8, pv1, mm2)); // load m2 = pv1[1]
     205    SI(m0 = _mm_setzero_si64(), pxor_r2r(mm0, mm0));    // clear m0
     206    SI(m5 = _mm_cvtsi32_si64(shift),movd_v2r(shift, mm5));   // shift in 64bit reg
     207
     208    do {
     209        // Calculate cross-correlation between the tempOffset and tmpbid_buffer.
     210        // Process 4 parallel batches of 2 * stereo samples each during one
     211        // round to improve CPU-level parallellization.
     212        SI(m1 = _mm_madd_pi16(m1, pv2[0]),pmaddwd_a2r(0, pv2, mm1)); // multiply-add m1 = m1 * pv2[0]
     213        SI(m3 = pv1[2],                   movq_a2r(16, pv1, mm3));   // load mm3 = pv1[2]
     214        SI(m2 = _mm_madd_pi16(m2, pv2[1]),pmaddwd_a2r(8, pv2, mm2)); // multiply-add m2 = m2 * pv2[1]
     215        SI(m4 = pv1[3],                   movq_a2r(24, pv1, mm4));   // load mm4 = pv1[3]
     216        SI(m3 = _mm_madd_pi16(m3, pv2[2]),pmaddwd_a2r(16, pv2, mm3));// multiply-add m3 = m3 * pv2[2]
     217        SI(m2 = _mm_add_pi32(m2, m1),     paddd_r2r(mm1, mm2));      // add m2 += m1
     218        SI(m4 = _mm_madd_pi16(m4, pv2[3]),pmaddwd_a2r(24, pv2, mm4));// multiply-add m4 = m4 * pv2[3]
     219        SI(m1 = pv1[4],                   movq_a2r(32, pv1, mm1));   // mm1 = pv1[0] for next round
     220        SI(m2 = _mm_srai_pi32(m2, m5),    psrad_r2r(mm5, mm2));      // m2 >>= shift (mm5)
     221        pv1 += 4;                                                    // increment first pointer
     222        SI(m3 = _mm_add_pi32(m3, m4),     paddd_r2r(mm4, mm3));      // m3 += m4
     223        SI(m0 = _mm_add_pi32(m0, m2),     paddd_r2r(mm2, mm0));      // m0 += m2
     224        SI(m2 = pv1[1],                   movq_a2r(8, pv1, mm2));    // mm2 = pv1[1] for next round
     225        SI(m3 = _mm_srai_pi32(m3, m5),    psrad_r2r(mm5, mm3));    // m3 >>= shift (mm5)
     226        pv2 += 4;                                                    // increment second pointer
     227        SI(m0 = _mm_add_pi32(m0, m3),     paddd_r2r(mm3, mm0));      // add m0 += m3
     228    } while ((--counter)!=0);
     229
     230    SI(m6 = ph[0], movq_a2r(0, ph, mm6));
     231    // Finalize the last partial loop:
     232    SI(m1 = _mm_madd_pi16(m1, pv2[0]), pmaddwd_a2r(0, pv2, mm1));
     233    SI(m1 = _mm_and_si64(m1, m6),      pand_r2r(mm6, mm1));
     234    SI(m3 = pv1[2],                    movq_a2r(16, pv1, mm3));
     235    SI(m6 = ph[1], movq_a2r(8, ph, mm6));
     236    SI(m2 = _mm_madd_pi16(m2, pv2[1]), pmaddwd_a2r(8, pv2, mm2));
     237    SI(m2 = _mm_and_si64(m2, m6),      pand_r2r(mm6, mm2));
     238    SI(m4 = pv1[3],                    movq_a2r(24, pv1, mm4));
     239    SI(m6 = ph[2], movq_a2r(16, ph, mm6));
     240    SI(m3 = _mm_madd_pi16(m3, pv2[2]), pmaddwd_a2r(16, pv2, mm3));
     241    SI(m3 = _mm_and_si64(m3, m6),      pand_r2r(mm6, mm3));
     242    SI(m2 = _mm_add_pi32(m2, m1),      paddd_r2r(mm1, mm2));
     243    SI(m6 = ph[3], movq_a2r(24, ph, mm6));
     244    SI(m4 = _mm_madd_pi16(m4, pv2[3]), pmaddwd_a2r(24, pv2, mm4));
     245    SI(m4 = _mm_and_si64(m4, m6),      pand_r2r(mm6, mm4));
     246    SI(m2 = _mm_srai_pi32(m2, m5),     psrad_r2r(mm5, mm2));
     247    SI(m3 = _mm_add_pi32(m3, m4),      paddd_r2r(mm4, mm3));
     248    SI(m0 = _mm_add_pi32(m0, m2),      paddd_r2r(mm2, mm0));
     249    SI(m3 = _mm_srai_pi32(m3, m5),     psrad_r2r(mm5, mm3));
     250    SI(m0 = _mm_add_pi32(m0, m3),      paddd_r2r(mm3, mm0));
     251
     252    // copy hi-dword of mm0 to lo-dword of mm1, then sum mm0+mm1
     253    // and finally return the result
     254    SI(m1 = m0,                        movq_r2r(mm0, mm1));
     255    SI(m1 = _mm_srli_si64(m1, 32),     psrld_i2r(32, mm1));
     256    SI(m0 = _mm_add_pi32(m0, m1),      paddd_r2r(mm1, mm0));
     257    SI(tmp = _mm_cvtsi64_si32(m0),     movd_r2m(mm0, tmp));
     258    return tmp;
     259}
     260#endif
     261
    144262void TDStretchMMX::clearCrossCorrState()
    145263{
    146264    _mm_empty();
     
    224342    _mm_empty();
    225343}
    226344
     345#if 0
     346// MMX-optimized version of the function overlapMulti
     347void TDStretchMMX::overlapMulti(short *output, const short *input) const
     348{
     349    _mm_empty();
     350    uint shift = overlapDividerBits;
     351    uint counter = overlapLength>>2;                 // counter = overlapLength / 4
     352    __m64 *inPtr = (__m64*) input;                   // load address of inputBuffer
     353    __m64 *midPtr = (__m64*) pMidBuffer;             // load address of midBuffer
     354    __m64 *outPtr = ((__m64*) output)-2;             // load address of outputBuffer
     355    GI(__m64 m0, m1, m2, m3, m4, m5, m6, m7);        // temporaries
     356
     357    // load mixing value adder to mm5
     358    uint tmp0 = 0x0002fffe;                                      // tmp0 = 0x0002 fffe
     359    SI(m5 = _mm_cvtsi32_si64(tmp0),    movd_v2r(tmp0, mm5));     // mm5 = 0x0000 0000 0002 fffe
     360    SI(m5 = _mm_unpacklo_pi32(m5,m5),  punpckldq_r2r(mm5, mm5)); // mm5 = 0x0002 fffe 0002 fffe
     361    // load sliding mixing value counter to mm6
     362    SI(m6 = _mm_cvtsi32_si64(overlapLength), movd_v2r(overlapLength, mm6));
     363    SI(m6 = _mm_unpacklo_pi32(m6, m6), punpckldq_r2r(mm6, mm6)); // mm6 = 0x0000 OVL_ 0000 OVL_
     364    // load sliding mixing value counter to mm7
     365    uint tmp1 = (overlapLength-1)|0x00010000;                    // tmp1 = 0x0001 overlapLength-1
     366    SI(m7 = _mm_cvtsi32_si64(tmp1),    movd_v2r(tmp1, mm7));     // mm7 = 0x0000 0000 0001 01ff
     367    SI(m7 = _mm_unpacklo_pi32(m7, m7), punpckldq_r2r(mm7, mm7)); // mm7 = 0x0001 01ff 0001 01ff
     368
     369    do {
     370        // Process two parallel batches of 2+2 stereo samples during each round
     371        // to improve CPU-level parallellization.
     372        //
     373        // Load [midPtr] into m0 and m1
     374        // Load [inPtr] into m3
     375        // unpack words of m0, m1 and m3 into m0 and m1
     376        // multiply-add m0*m6 and m1*m7, store results into m0 and m1
     377        // divide m0 and m1 by 512 (=right-shift by overlapDividerBits)
     378        // pack the result into m0 and store into [edx]
     379        //
     380        // Load [midPtr+8] into m2 and m3
     381        // Load [inPtr+8] into m4
     382        // unpack words of m2, m3 and m4 into m2 and m3
     383        // multiply-add m2*m6 and m3*m7, store results into m2 and m3
     384        // divide m2 and m3 by 512 (=right-shift by overlapDividerBits)
     385        // pack the result into m2 and store into [edx+8]
     386        SI(m0 = midPtr[0],                movq_a2r(0, midPtr, mm0));// mm0 = m1l m1r m0l m0r
     387        outPtr += 2;
     388        SI(m3 = inPtr[0],                 movq_a2r(0, inPtr, mm3)); // mm3 = i1l i1r i0l i0r
     389        SI(m1 = m0,                       movq_r2r(mm0, mm1));      // mm1 = m1l m1r m0l m0r
     390        SI(m2 = midPtr[1],                movq_a2r(8, midPtr, mm2));// mm2 = m3l m3r m2l m2r
     391        SI(m0 = _mm_unpacklo_pi16(m0, m3),punpcklwd_r2r(mm3, mm0)); // mm0 = i0l m0l i0r m0r
     392        midPtr += 2;
     393        SI(m4 = inPtr[1],                 movq_a2r(8, inPtr, mm4)); // mm4 = i3l i3r i2l i2r
     394        SI(m1 = _mm_unpackhi_pi16(m1, m3),punpckhwd_r2r(mm3, mm1)); // mm1 = i1l m1l i1r m1r
     395        inPtr+=2;
     396        SI(m3 = m2,                       movq_r2r(mm2, mm3));      // mm3 = m3l m3r m2l m2r
     397        SI(m2 = _mm_unpacklo_pi16(m2, m4),punpcklwd_r2r(mm4, mm2)); // mm2 = i2l m2l i2r m2r
     398        // mm0 = i0l*m63+m0l*m62 i0r*m61+m0r*m60
     399        SI(m0 = _mm_madd_pi16(m0, m6),    pmaddwd_r2r(mm6, mm0));
     400        SI(m3 = _mm_unpackhi_pi16(m3, m4),punpckhwd_r2r(mm4, mm3)); // mm3 = i3l m3l i3r m3r
     401        SI(m4 = _mm_cvtsi32_si64(shift),  movd_v2r(shift, mm4));    // mm4 = shift
     402        // mm1 = i1l*m73+m1l*m72 i1r*m71+m1r*m70
     403        SI(m1 = _mm_madd_pi16(m1, m7),    pmaddwd_r2r(mm7, mm1));
     404        SI(m6 = _mm_add_pi16(m6, m5),     paddw_r2r(mm5, mm6));
     405        SI(m7 = _mm_add_pi16(m7, m5),     paddw_r2r(mm5, mm7));
     406        SI(m0 = _mm_srai_pi32(m0, m4),    psrad_r2r(mm4, mm0));    // mm0 >>= shift
     407        // mm2 = i2l*m63+m2l*m62 i2r*m61+m2r*m60
     408        SI(m2 = _mm_madd_pi16(m2, m6),    pmaddwd_r2r(mm6, mm2));
     409        SI(m1 = _mm_srai_pi32(m1, m4),    psrad_r2r(mm4, mm1));    // mm1 >>= shift
     410        // mm3 = i3l*m73+m3l*m72 i3r*m71+m3r*m70
     411        SI(m3 = _mm_madd_pi16(m3, m7),    pmaddwd_r2r(mm7, mm3));
     412        SI(m2 = _mm_srai_pi32(m2, m4),    psrad_r2r(mm4, mm2));    // mm2 >>= shift
     413        SI(m0 = _mm_packs_pi32(m0, m1),   packssdw_r2r(mm1, mm0)); // mm0 = mm1h mm1l mm0h mm0l
     414        SI(m3 = _mm_srai_pi32(m3, m4),    psrad_r2r(mm4, mm3));    // mm3 >>= shift
     415        SI(m6 = _mm_add_pi16(m6, m5),     paddw_r2r(mm5, mm6));
     416        SI(m2 = _mm_packs_pi32(m2, m3),   packssdw_r2r(mm3, mm2)); // mm2 = mm2h mm2l mm3h mm3l
     417        SI(m7 = _mm_add_pi16(m7, m5),     paddw_r2r(mm5, mm7));
     418        SI(outPtr[0] = m0,                movq_r2a(mm0, 0, outPtr));
     419        SI(outPtr[1] = m2,                movq_r2a(mm2, 8, outPtr));
     420    } while ((--counter)!=0);
     421    _mm_empty();
     422}
     423#endif
     424
    227425//////////////////////////////////////////////////////////////////////////////
    228426//
    229427// implementation of MMX optimized functions of class 'FIRFilter'
  • libs/libmythsoundtouch/STTypes.h

     
    6161    #define INTEGER_SAMPLES       //< 16bit integer samples
    6262    //#define FLOAT_SAMPLES       //< 32bit float samples
    6363
     64    #define MULTICHANNEL 6
    6465
    6566    /// Define this to allow CPU-specific assembler optimizations. Notice that
    6667    /// having this enabled on non-x86 platforms doesn't matter; the compiler can
  • libs/libmythsoundtouch/SoundTouch.cpp

     
    140140// Sets the number of channels, 1 = mono, 2 = stereo
    141141void SoundTouch::setChannels(uint numChannels)
    142142{
     143#ifdef MULTICHANNEL
     144    if (numChannels < 1 || numChannels > MULTICHANNEL)
     145#else
    143146    if (numChannels != 1 && numChannels != 2)
     147#endif
    144148    {
    145149        throw std::runtime_error("Illegal number of channels");
    146150    }
  • libs/libmyth/audiooutputjack.h

     
    1414  public:
    1515    AudioOutputJACK(QString audiodevice, int laudio_bits,
    1616                    int laudio_channels, int laudio_samplerate,
    17                     AudioOutputSource source, bool set_initial_vol);
     17                    AudioOutputSource source,
     18                    bool set_initial_vol, bool laudio_passthru);
    1819    virtual ~AudioOutputJACK();
    1920   
    2021    // Volume control
  • libs/libmyth/audiooutputbase.h

     
    1212#include "samplerate.h"
    1313#include "SoundTouch.h"
    1414
    15 #define AUDBUFSIZE 768000
     15struct AVCodecContext;
     16class DigitalEncoder;
    1617
     18//#define AUDBUFSIZE 768000
     19//divisible by 12,10,8,6,4,2 and around 1024000
     20//#define AUDBUFSIZE 1024080
     21#define AUDBUFSIZE 1536000
     22
    1723class AudioOutputBase : public AudioOutput
    1824{
    1925 public:
    2026    AudioOutputBase(QString audiodevice, int laudio_bits,
    2127                    int laudio_channels, int laudio_samplerate,
    22                     AudioOutputSource source, bool set_initial_vol);
     28                    AudioOutputSource source,
     29                    bool set_initial_vol, bool laudio_passthru);
    2330    virtual ~AudioOutputBase();
    2431
    2532    // reconfigure sound out for new params
    2633    virtual void Reconfigure(int audio_bits,
    27                              int audio_channels, int audio_samplerate);
     34                             int audio_channels,
     35                             int audio_samplerate,
     36                             bool audio_passthru,
     37                             void* audio_codec = NULL);
    2838   
    2939    // do AddSamples calls block?
    3040    virtual void SetBlocking(bool blocking);
     
    106116    long soundcard_buffer_size;
    107117    QString audiodevice;
    108118
     119    bool audio_passthru;
     120
    109121    float audio_stretchfactor;
    110122    AudioOutputSource source;
     123    AVCodecContext *audio_codec;
    111124
    112125    bool killaudio;
    113126
     
    115128    bool set_initial_vol;
    116129    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    117130   
     131    int configured_audio_channels;
     132
    118133 private:
    119134    QString lastError;
    120135
     
    127142
    128143    // timestretch
    129144    soundtouch::SoundTouch * pSoundStretch;
     145    DigitalEncoder * encoder;
    130146
    131147    bool blocking; // do AddSamples calls block?
    132148
     
    142158
    143159    pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
    144160                                    'audiotime' and 'audiotime_updated' */
    145     int audiotime; // timecode of audio leaving the soundcard (same units as
     161    long long audiotime; // timecode of audio leaving the soundcard (same units as
    146162                   //                                          timecodes) ...
    147163    struct timeval audiotime_updated; // ... which was last updated at this time
    148164
    149165    /* Audio circular buffer */
    150166    unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
    151167    int raud, waud;     /* read and write positions */
    152     int audbuf_timecode;    /* timecode of audio most recently placed into
     168    long long audbuf_timecode;    /* timecode of audio most recently placed into
    153169                   buffer */
    154170
    155171    int numlowbuffer;
  • libs/libmyth/audiooutputalsa.cpp

     
    1212
    1313AudioOutputALSA::AudioOutputALSA(QString audiodevice, int laudio_bits,
    1414                                 int laudio_channels, int laudio_samplerate,
    15                                  AudioOutputSource source, bool set_initial_vol)
    16               : AudioOutputBase(audiodevice, laudio_bits,
    17                               laudio_channels, laudio_samplerate, source, set_initial_vol)
     15                                 AudioOutputSource source,
     16                                 bool set_initial_vol, bool laudio_passthru)
     17    : AudioOutputBase(audiodevice, laudio_bits,
     18                      laudio_channels, laudio_samplerate, source,
     19                      set_initial_vol, laudio_passthru)
    1820{
    1921    // our initalisation
    2022    pcm_handle = NULL;
     
    2224    mixer_handle = NULL;
    2325
    2426    // Set everything up
    25     Reconfigure(laudio_bits, laudio_channels, laudio_samplerate);
     27    Reconfigure(laudio_bits, laudio_channels,
     28                laudio_samplerate, laudio_passthru);
    2629}
    2730
    2831AudioOutputALSA::~AudioOutputALSA()
     
    4144
    4245    pcm_handle = NULL;
    4346    numbadioctls = 0;
     47
     48    QString real_device = audiodevice;
     49    if (audio_passthru)
     50        real_device.append(":{ AES0 0x02 }");
    4451   
    45     err = snd_pcm_open(&pcm_handle, audiodevice,
     52    err = snd_pcm_open(&pcm_handle, real_device,
    4653          SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
    4754
    4855    if (err < 0)
     
    7582    }
    7683    else
    7784    {
    78         fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits
    79         buffer_time = 500000;  // .5 seconds
     85        //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits
     86        //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits
     87        fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30);
     88        buffer_time = 100000;  // .5 seconds
    8089        period_time = buffer_time / 4;  // 4 interrupts per buffer
    8190    }
    8291
     
    148157   
    149158    tmpbuf = aubuf;
    150159
    151     VERBOSE(VB_AUDIO, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
     160    VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
    152161            .arg(size).arg(frames));
    153162   
    154163    while (frames > 0)
  • libs/libmyth/audiooutputca.cpp

     
    3838
    3939AudioOutputCA::AudioOutputCA(QString audiodevice, int laudio_bits,
    4040                             int laudio_channels, int laudio_samplerate,
    41                              AudioOutputSource source, bool set_initial_vol)
    42              : AudioOutputBase(audiodevice, laudio_bits,
    43                                laudio_channels, laudio_samplerate,
    44                                source, set_initial_vol)
     41                             AudioOutputSource source,
     42                             bool set_initial_vol, bool laudio_passthru)
     43    : AudioOutputBase(audiodevice, laudio_bits,
     44                      laudio_channels, laudio_samplerate, source,
     45                      set_initial_vol, laudio_passthru)
    4546{
    4647    // Create private data
    4748    coreaudio_data = new CoreAudioData();
    4849    coreaudio_data->output_unit = NULL;
    4950   
    50     Reconfigure(laudio_bits, laudio_channels, laudio_samplerate);
     51    Reconfigure(laudio_bits, laudio_channels,
     52                laudio_samplerate, laudio_passthru);
    5153}
    5254
    5355AudioOutputCA::~AudioOutputCA()
  • libs/libmyth/audiooutputjack.cpp

     
    2323
    2424AudioOutputJACK::AudioOutputJACK(QString audiodevice, int laudio_bits,
    2525                                 int laudio_channels, int laudio_samplerate,
    26                                  AudioOutputSource source, bool set_initial_vol)
    27                : AudioOutputBase(audiodevice, laudio_bits, laudio_channels,
    28                                  laudio_samplerate, source, set_initial_vol)
     26                                 AudioOutputSource source,
     27                                 bool set_initial_vol, bool laudio_passthru)
     28    : AudioOutputBase(audiodevice, laudio_bits,
     29                      laudio_channels, laudio_samplerate, source,
     30                      set_initial_vol, laudio_passthru)
    2931{
    3032    // Initialise the Jack output layer
    3133    JACK_Init();
     
    3436    audioid = -1;
    3537
    3638    // Set everything up
    37     Reconfigure(laudio_bits, laudio_channels, laudio_samplerate);
     39    Reconfigure(laudio_bits, laudio_channels,
     40                laudio_samplerate, laudio_passthru);
    3841}
    3942
    4043AudioOutputJACK::~AudioOutputJACK()
  • libs/libmyth/audiooutputoss.h

     
    1515public:
    1616    AudioOutputOSS(QString audiodevice, int laudio_bits,
    1717                   int laudio_channels, int laudio_samplerate,
    18                    AudioOutputSource source, bool set_initial_vol);
     18                   AudioOutputSource source, bool set_initial_vol,
     19                   bool laudio_passthru);
    1920    virtual ~AudioOutputOSS();
    2021
    2122    // Volume control
  • libs/libmyth/audiooutputbase.cpp

     
    1212#include <sys/time.h>
    1313#include <unistd.h>
    1414
     15extern "C" {
     16#include "libavcodec/avcodec.h"
     17#include "libavcodec/liba52/a52.h"
     18}
    1519
     20#if QT_VERSION < 0x030200
     21#define LONGLONGCONVERT (long)
     22#else
     23#define LONGLONGCONVERT
     24#endif
     25
     26#define LOC QString("DEnc: ");
     27#define MAX_AC3_FRAME_SIZE 6144
     28class DigitalEncoder
     29{
     30public:
     31    DigitalEncoder();
     32    ~DigitalEncoder();
     33    void Dispose();
     34    bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels);
     35    size_t Encode(short * buff);
     36
     37    // if needed
     38    char * GetFrameBuffer()
     39    {
     40        if (!frame_buffer && av_context)
     41        {
     42            frame_buffer = new char [one_frame_bytes];
     43        }
     44        return frame_buffer;
     45    }   
     46    size_t FrameSize() const { return one_frame_bytes; }
     47    char * GetOutBuff() const { return outbuf; }
     48
     49    size_t audio_bytes_per_sample;
     50private:
     51    AVCodecContext *av_context;
     52    char * outbuf;
     53    char * frame_buffer;
     54    int outbuf_size;
     55    size_t one_frame_bytes;
     56};
     57
     58DigitalEncoder::DigitalEncoder()
     59{
     60    av_context = NULL;
     61    outbuf = NULL;
     62    outbuf_size = 0;
     63    one_frame_bytes = 0;
     64    frame_buffer = NULL;
     65}
     66
     67DigitalEncoder::~DigitalEncoder()
     68{
     69    Dispose();
     70}
     71
     72void DigitalEncoder::Dispose()
     73{
     74    if (av_context)
     75    {
     76        avcodec_close(av_context);
     77        av_free(av_context);
     78        av_context = NULL;
     79    }
     80    if (outbuf)
     81    {
     82        delete [] outbuf;
     83        outbuf = NULL;
     84        outbuf_size = 0;
     85    }
     86    if (frame_buffer)
     87    {
     88        delete [] frame_buffer;
     89        frame_buffer = NULL;
     90        one_frame_bytes = 0;
     91    }
     92}
     93
     94//CODEC_ID_AC3
     95bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels)
     96{
     97    AVCodec * codec;
     98    int ret;
     99
     100    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4")
     101            .arg(codec_id_string(codec_id))
     102            .arg(bitrate)
     103            .arg(samplerate)
     104            .arg(channels));
     105    //codec = avcodec_find_encoder(codec_id);
     106    // always AC3 as there is no DTS encoder at the moment 2005/1/9
     107    codec = avcodec_find_encoder(CODEC_ID_AC3);
     108    if (!codec)
     109    {
     110        VERBOSE(VB_IMPORTANT,"Error: could not find codec");
     111        return false;
     112    }
     113    av_context = avcodec_alloc_context();
     114    av_context->bit_rate = bitrate;
     115    av_context->sample_rate = samplerate;
     116    av_context->channels = channels;
     117    // open it */
     118    if ((ret = avcodec_open(av_context, codec)) < 0)
     119    {
     120        VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate");
     121        Dispose();
     122        return false;
     123    }
     124
     125    size_t bytes_per_frame = av_context->channels * sizeof(short);
     126    audio_bytes_per_sample = bytes_per_frame;
     127    one_frame_bytes = bytes_per_frame * av_context->frame_size;
     128
     129    outbuf_size = 16384;    // ok for AC3 but DTS?
     130    outbuf = new char [outbuf_size];
     131    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3")
     132            .arg(av_context->frame_size)
     133            .arg(bytes_per_frame)
     134            .arg(one_frame_bytes)
     135           );
     136
     137    return true;
     138}
     139
     140static int DTS_SAMPLEFREQS[16] =
     141{
     142    0,      8000,   16000,  32000,  64000,  128000, 11025,  22050,
     143    44100,  88200,  176400, 12000,  24000,  48000,  96000,  192000
     144};
     145
     146static int DTS_BITRATES[30] =
     147{
     148    32000,    56000,    64000,    96000,    112000,   128000,
     149    192000,   224000,   256000,   320000,   384000,   448000,
     150    512000,   576000,   640000,   768000,   896000,   1024000,
     151    1152000,  1280000,  1344000,  1408000,  1411200,  1472000,
     152    1536000,  1920000,  2048000,  3072000,  3840000,  4096000
     153};
     154
     155static int dts_decode_header(uint8_t *indata_ptr, int *rate,
     156                             int *nblks, int *sfreq)
     157{
     158    uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) |
     159               (indata_ptr[2] << 8)  | (indata_ptr[3]));
     160
     161    if (id != 0x7ffe8001)
     162        return -1;
     163
     164    int ftype = indata_ptr[4] >> 7;
     165
     166    int surp = (indata_ptr[4] >> 2) & 0x1f;
     167    surp = (surp + 1) % 32;
     168
     169    *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
     170    ++*nblks;
     171
     172    int fsize = (indata_ptr[5] & 0x03) << 12 |
     173                (indata_ptr[6]         << 4) | (indata_ptr[7] >> 4);
     174    ++fsize;
     175
     176    *sfreq = (indata_ptr[8] >> 2) & 0x0f;
     177    *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
     178
     179    if (ftype != 1)
     180    {
     181        VERBOSE(VB_IMPORTANT, LOC +
     182                QString("DTS: Termination frames not handled (ftype %1)")
     183                .arg(ftype));
     184        return -1;
     185    }
     186
     187    if (*sfreq != 13)
     188    {
     189        VERBOSE(VB_IMPORTANT, LOC +
     190                QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
     191        return -1;
     192    }
     193
     194    if ((fsize > 8192) || (fsize < 96))
     195    {
     196        VERBOSE(VB_IMPORTANT, LOC +
     197                QString("DTS: fsize: %1 invalid").arg(fsize));
     198        return -1;
     199    }
     200
     201    if (*nblks != 8 && *nblks != 16 && *nblks != 32 &&
     202        *nblks != 64 && *nblks != 128 && ftype == 1)
     203    {
     204        VERBOSE(VB_IMPORTANT, LOC +
     205                QString("DTS: nblks %1 not valid for normal frame")
     206                .arg(*nblks));
     207        return -1;
     208    }
     209
     210    return fsize;
     211}
     212
     213static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/,
     214                        int *sample_rate, int *bit_rate)
     215{
     216    int nblks;
     217    int rate;
     218    int sfreq;
     219
     220    int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
     221    if (fsize >= 0)
     222    {
     223        if (rate >= 0 && rate <= 29)
     224            *bit_rate = DTS_BITRATES[rate];
     225        else
     226            *bit_rate = 0;
     227        if (sfreq >= 1 && sfreq <= 15)
     228            *sample_rate = DTS_SAMPLEFREQS[sfreq];
     229        else
     230            *sample_rate = 0;
     231    }
     232    return fsize;
     233}
     234
     235static int encode_frame(
     236        bool dts,
     237        unsigned char *data,
     238        size_t &len)
     239{
     240    size_t enc_len;
     241    int flags, sample_rate, bit_rate;
     242
     243    // we don't do any length/crc validation of the AC3 frame here; presumably
     244    // the receiver will have enough sense to do that.  if someone has a
     245    // receiver that doesn't, here would be a good place to put in a call
     246    // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the
     247    // packet is bad?  we'd need to send something that the receiver would
     248    // ignore, and if so, may as well just assume that it will ignore
     249    // anything with a bad CRC...
     250
     251    uint nr_samples = 0, block_len;
     252    if (dts)
     253    {
     254        enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     255        int rate, sfreq, nblks;
     256        dts_decode_header(data+8, &rate, &nblks, &sfreq);
     257        nr_samples = nblks * 32;
     258        block_len = nr_samples * 2 * 2;
     259    }
     260    else
     261    {
     262        enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     263        block_len = MAX_AC3_FRAME_SIZE;
     264    }
     265
     266    if (enc_len == 0 || enc_len > len)
     267    {
     268        int l = len;
     269        len = 0;
     270        return l;
     271    }
     272
     273    enc_len = min((uint)enc_len, block_len - 8);
     274
     275    //uint32_t x = *(uint32_t*)(data+8);
     276    // in place swab
     277    swab(data+8, data+8, enc_len);
     278    //VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     279    //        QString("DigitalEncoder::Encode swab test %1 %2")
     280    //        .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16));
     281
     282    // the following values come from libmpcodecs/ad_hwac3.c in mplayer.
     283    // they form a valid IEC958 AC3 header.
     284    data[0] = 0x72;
     285    data[1] = 0xF8;
     286    data[2] = 0x1F;
     287    data[3] = 0x4E;
     288    data[4] = 0x01;
     289    if (dts)
     290    {
     291        switch(nr_samples)
     292        {
     293            case 512:
     294                data[4] = 0x0B;      /* DTS-1 (512-sample bursts) */
     295                break;
     296
     297            case 1024:
     298                data[4] = 0x0C;      /* DTS-2 (1024-sample bursts) */
     299                break;
     300
     301            case 2048:
     302                data[4] = 0x0D;      /* DTS-3 (2048-sample bursts) */
     303                break;
     304
     305            default:
     306                VERBOSE(VB_IMPORTANT, LOC +
     307                        QString("DTS: %1-sample bursts not supported")
     308                        .arg(nr_samples));
     309                data[4] = 0x00;
     310                break;
     311        }
     312    }
     313    data[5] = 0x00;
     314    data[6] = (enc_len << 3) & 0xFF;
     315    data[7] = (enc_len >> 5) & 0xFF;
     316    memset(data + 8 + enc_len, 0, block_len - 8 - enc_len);
     317    len = block_len;
     318
     319    return enc_len;
     320}
     321
     322// must have exactly 1 frames worth of data
     323size_t DigitalEncoder::Encode(short * buff)
     324{
     325    int encsize = 0;
     326    size_t outsize = 0;
     327 
     328    // put data in the correct spot for encode frame
     329    outsize = avcodec_encode_audio(
     330                av_context,
     331                ((uchar*)outbuf)+8,
     332                outbuf_size-8,
     333                buff);
     334    size_t tmpsize = outsize;
     335
     336    outsize = MAX_AC3_FRAME_SIZE;
     337    encsize = encode_frame(
     338            //av_context->codec_id==CODEC_ID_DTS,
     339            false,
     340            (unsigned char*)outbuf, outsize);
     341    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     342            QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3")
     343                .arg(tmpsize)
     344                .arg(encsize)
     345                .arg(outsize)
     346           );
     347
     348    return outsize;
     349}
     350#undef LOC
     351#define LOC QString("AO: ")
     352
    16353AudioOutputBase::AudioOutputBase(QString audiodevice, int,
    17354                                 int, int,
    18                                  AudioOutputSource source, bool set_initial_vol)
     355                                 AudioOutputSource source,
     356                                 bool set_initial_vol,
     357                                 bool /*laudio_passthru*/)
    19358{
    20359    pthread_mutex_init(&audio_buflock, NULL);
    21360    pthread_mutex_init(&avsync_lock, NULL);
     
    29368    current_seconds = -1;
    30369    source_bitrate = -1;
    31370    audio_stretchfactor = 1.0;
     371    audio_codec = NULL;
    32372    pSoundStretch = NULL;
     373    encoder = NULL;
    33374    blocking = false;
    34375    this->source = source;
    35376    this->set_initial_vol = set_initial_vol;
    36377    soundcard_buffer_size = 0;
    37378    buffer_output_data_for_use = false; // used by AudioOutputNULL
     379    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
    38380
    39 
    40381    src_ctx = NULL;
    41382
    42383    // You need to call the next line from your concrete class.
    43384    // Virtuals cause problems in the base class constructors
    44     // Reconfigure(laudio_bits, laudio_channels, laudio_samplerate);
     385    // Reconfigure(laudio_bits, laudio_channels, laudio_samplerate, laudio_passthru);
    45386}
    46387
    47388AudioOutputBase::~AudioOutputBase()
     
    78419            VERBOSE(VB_GENERAL, QString("Using time stretch %1")
    79420                                        .arg(audio_stretchfactor));
    80421            pSoundStretch = new soundtouch::SoundTouch();
    81             pSoundStretch->setSampleRate(audio_samplerate);
    82             pSoundStretch->setChannels(audio_channels);
     422            if (audio_codec)
     423            {
     424                if (!encoder)
     425                {
     426                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size));
     427                    encoder = new DigitalEncoder();
     428                    if (!encoder->Init(audio_codec->codec_id,
     429                                audio_codec->bit_rate,
     430                                audio_codec->sample_rate,
     431                                audio_codec->channels
     432                                ))
     433                    {
     434                        // eeks
     435                        delete encoder;
     436                        encoder = NULL;
     437                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     438                    }
     439                }
     440            }
     441            if (encoder)
     442            {
     443                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     444                pSoundStretch->setChannels(audio_codec->channels);
     445            }
     446            else
     447            {
     448                pSoundStretch->setSampleRate(audio_samplerate);
     449                pSoundStretch->setChannels(audio_channels);
     450            }
    83451
    84452            pSoundStretch->setTempo(audio_stretchfactor);
    85453            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
     
    102470}
    103471
    104472void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    105                                  int laudio_samplerate)
     473                                 int laudio_samplerate, bool laudio_passthru,
     474                                 void* laudio_codec)
    106475{
     476    int codec_id = CODEC_ID_NONE;
     477    int lcodec_id = CODEC_ID_NONE;
     478    int lcchannels = 0;
     479    int cchannels = 0;
     480    if (laudio_codec)
     481    {
     482        lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
     483        laudio_bits = 16;
     484        laudio_channels = 2;
     485        laudio_samplerate = 48000;
     486        lcchannels = ((AVCodecContext*)laudio_codec)->channels;
     487    }
     488    if (audio_codec)
     489    {
     490        codec_id = audio_codec->codec_id;
     491        cchannels = ((AVCodecContext*)audio_codec)->channels;
     492    }
     493    ClearError();
    107494    if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    108         laudio_samplerate == audio_samplerate && !need_resampler)
     495        laudio_samplerate == audio_samplerate && !need_resampler &&
     496        laudio_passthru == audio_passthru &&
     497        lcodec_id == codec_id && lcchannels == cchannels)
    109498        return;
    110499
    111500    KillAudio();
     
    117506    waud = raud = 0;
    118507    audio_actually_paused = false;
    119508   
     509    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    120510    audio_channels = laudio_channels;
    121511    audio_bits = laudio_bits;
    122512    audio_samplerate = laudio_samplerate;
     513    audio_codec = (AVCodecContext*)laudio_codec;
     514    audio_passthru = laudio_passthru;
    123515    if (audio_bits != 8 && audio_bits != 16)
    124516    {
    125517        pthread_mutex_unlock(&avsync_lock);
     
    137529   
    138530    numlowbuffer = 0;
    139531
    140     VERBOSE(VB_GENERAL, QString("Opening audio device '%1'.")
    141             .arg(audiodevice));
     532    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3")
     533            .arg(audiodevice).arg(audio_channels).arg(audio_samplerate));
    142534   
    143535    // Actually do the device specific open call
    144536    if (!OpenDevice())
    145537    {
    146         VERBOSE(VB_AUDIO, "Aborting reconfigure");
    147538        pthread_mutex_unlock(&avsync_lock);
    148539        pthread_mutex_unlock(&audio_buflock);
     540        if (GetError().isEmpty())
     541            Error("Aborting reconfigure");
     542        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    149543        return;
    150544    }
    151545
     
    167561    current_seconds = -1;
    168562    source_bitrate = -1;
    169563
     564    // NOTE: this wont do anything as above samplerate vars are set equal
    170565    // Check if we need the resampler
    171566    if (audio_samplerate != laudio_samplerate)
    172567    {
     
    190585    }
    191586
    192587    VERBOSE(VB_AUDIO, QString("Audio Stretch Factor: %1").arg(audio_stretchfactor));
     588    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     589            .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set"));
    193590
    194     SetStretchFactorLocked(audio_stretchfactor);
    195     if (pSoundStretch)
     591    if (redo_stretch)
    196592    {
    197         pSoundStretch->setSampleRate(audio_samplerate);
    198         pSoundStretch->setChannels(audio_channels);
     593        float laudio_stretchfactor = audio_stretchfactor;
     594        delete pSoundStretch;
     595        pSoundStretch = NULL;
     596        audio_stretchfactor = 0.0;
     597        SetStretchFactorLocked(laudio_stretchfactor);
    199598    }
     599    else
     600    {
     601        SetStretchFactorLocked(audio_stretchfactor);
     602        if (pSoundStretch)
     603        {
     604            // if its passthru then we need to reencode
     605            if (audio_codec)
     606            {
     607                if (!encoder)
     608                {
     609                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id));
     610                    encoder = new DigitalEncoder();
     611                    if (!encoder->Init(audio_codec->codec_id,
     612                                audio_codec->bit_rate,
     613                                audio_codec->sample_rate,
     614                                audio_codec->channels
     615                                ))
     616                    {
     617                        // eeks
     618                        delete encoder;
     619                        encoder = NULL;
     620                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     621                    }
     622                }
     623            }
     624            if (encoder)
     625            {
     626                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     627                pSoundStretch->setChannels(audio_codec->channels);
     628            }
     629            else
     630            {
     631                pSoundStretch->setSampleRate(audio_samplerate);
     632                pSoundStretch->setChannels(audio_channels);
     633            }
     634        }
     635    }
    200636
    201637    // Setup visualisations, zero the visualisations buffers
    202638    prepareVisuals();
     
    242678        pSoundStretch = NULL;
    243679    }
    244680
     681    if (encoder)
     682    {
     683        delete encoder;
     684        encoder = NULL;
     685    }
     686
    245687    CloseDevice();
    246688
    247689    killAudioLock.unlock();
     
    255697
    256698void AudioOutputBase::Pause(bool paused)
    257699{
     700    VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused));
    258701    pauseaudio = paused;
    259702    audio_actually_paused = false;
    260703}
     
    335778       The reason is that computing 'audiotime' requires acquiring the audio
    336779       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    337780       from the audio thread, and then call this from the video thread. */
    338     int ret;
     781    long long ret;
    339782    struct timeval now;
    340783
    341784    if (audiotime == 0)
     
    347790
    348791    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    349792    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    350     ret = (int)(ret * audio_stretchfactor);
     793    ret = (long long)(ret * audio_stretchfactor);
    351794
     795#if 1
     796    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     797            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     798            .arg(now.tv_sec).arg(now.tv_usec)
     799            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     800            .arg(ret)
     801            .arg(audiotime)
     802            .arg(audio_stretchfactor)
     803           );
     804#endif
     805
    352806    ret += audiotime;
    353807
    354808    pthread_mutex_unlock(&avsync_lock);
    355     return ret;
     809    return (int)ret;
    356810}
    357811
    358812void AudioOutputBase::SetAudiotime(void)
     
    389843    // include algorithmic latencies
    390844    if (pSoundStretch)
    391845    {
     846        // if encoder is active, then use its idea of audiobytes
     847        //size_t abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     848
     849        // add the effect of any unused but processed samples, AC3 reencode does this
     850        totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample);
    392851        // add the effect of unprocessed samples in time stretch algo
    393852        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    394853                              audio_bytes_per_sample) / audio_stretchfactor);
    395854    }
    396                
     855
    397856    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    398857                                   (audio_bytes_per_sample * effdspstretched));
    399858 
    400859    gettimeofday(&audiotime_updated, NULL);
     860#if 1
     861    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     862            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     863            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     864            .arg(audiotime)
     865            .arg(audbuf_timecode)
     866            .arg(totalbuffer)
     867            .arg(soundcard_buffer)
     868            .arg(effdspstretched)
     869            .arg(audio_bytes_per_sample)
     870            .arg(audio_stretchfactor)
     871           );
     872#endif
    401873
    402874    pthread_mutex_unlock(&avsync_lock);
    403875    pthread_mutex_unlock(&audio_buflock);
     
    457929    // NOTE: This function is not threadsafe
    458930
    459931    int afree = audiofree(true);
    460     int len = samples * audio_bytes_per_sample;
     932    int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    461933
    462934    // Check we have enough space to write the data
    463935    if (need_resampler && src_ctx)
    464936        len = (int)ceilf(float(len) * src_data.src_ratio);
    465937    if ((len > afree) && !blocking)
     938    {
     939        VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4")
     940            .arg(len)
     941            .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode));
    466942        return false; // would overflow
     943    }
    467944
    468945    // resample input if necessary
    469946    if (need_resampler && src_ctx)
     
    497974
    498975int AudioOutputBase::WaitForFreeSpace(int samples)
    499976{
    500     int len = samples * audio_bytes_per_sample;
     977    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     978    int len = samples * abps;
    501979    int afree = audiofree(false);
    502980
    503981    while (len > afree)
    504982    {
    505983        if (blocking)
    506984        {
    507             VERBOSE(VB_AUDIO, "Waiting for free space");
     985            VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Waiting for free space");
    508986            // wait for more space
    509987            pthread_cond_wait(&audio_bufsig, &audio_buflock);
    510988            afree = audiofree(false);
    511989        }
    512990        else
    513991        {
    514             VERBOSE(VB_IMPORTANT, "Audio buffer overflow, audio data lost!");
    515             samples = afree / audio_bytes_per_sample;
    516             len = samples * audio_bytes_per_sample;
     992            VERBOSE(VB_IMPORTANT,
     993                    QString("Audio buffer overflow, %1 audio samples lost!")
     994                        .arg(samples-afree / abps));
     995            samples = afree / abps;
     996            len = samples * abps;
    517997            if (src_ctx)
    518998            {
    519999                int error = src_reset(src_ctx);
     
    5381018   
    5391019    int afree = audiofree(false);
    5401020
    541     VERBOSE(VB_AUDIO, QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4")
    542             .arg(samples * audio_bytes_per_sample)
    543             .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode));
     1021    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     1022    VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5")
     1023            .arg(samples)
     1024            .arg(samples * abps)
     1025            .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode));
    5441026   
    5451027    len = WaitForFreeSpace(samples);
    5461028
     
    5771059
    5781060    if (pSoundStretch)
    5791061    {
     1062
    5801063        // does not change the timecode, only the number of samples
    5811064        // back to orig pos
    5821065        org_waud = waud;
    5831066        int bdiff = AUDBUFSIZE - org_waud;
    584         int nSamplesToEnd = bdiff/audio_bytes_per_sample;
     1067        int nSamplesToEnd = bdiff/abps;
    5851068        if (bdiff < len)
    5861069        {
    5871070            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    5881071                                      org_waud), nSamplesToEnd);
    5891072            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
    590                                       (len - bdiff) / audio_bytes_per_sample);
     1073                                      (len - bdiff) / abps);
    5911074        }
    5921075        else
    5931076        {
    5941077            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    595                                       org_waud), len / audio_bytes_per_sample);
     1078                                      org_waud), len / abps);
    5961079        }
    5971080
    598         int newLen = 0;
    599         int nSamples;
    600         len = WaitForFreeSpace(pSoundStretch->numSamples() *
    601                                audio_bytes_per_sample);
    602         do
     1081        if (encoder)
    6031082        {
    604             int samplesToGet = len/audio_bytes_per_sample;
    605             if (samplesToGet > nSamplesToEnd)
     1083            // pull out a packet's worth and reencode it until we dont have enough
     1084            // for any more packets
     1085            soundtouch::SAMPLETYPE* temp_buff =
     1086                (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     1087            size_t frameSize = encoder->FrameSize()/abps;
     1088            VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1089                    QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     1090                    .arg(frameSize)
     1091                    .arg(encoder->FrameSize())
     1092                    .arg(pSoundStretch->numSamples())
     1093                   );
     1094            // process the same number of samples as it creates a full encoded buffer
     1095            // just like before
     1096            while (pSoundStretch->numSamples() >= frameSize)
    6061097            {
    607                 samplesToGet = nSamplesToEnd;   
     1098                int got = pSoundStretch->receiveSamples(temp_buff, frameSize);
     1099                int amount = encoder->Encode(temp_buff);
     1100                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1101                        QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     1102                        .arg(amount)
     1103                        .arg(got)
     1104                        .arg(pSoundStretch->numSamples())
     1105                       );
     1106                if (amount == 0)
     1107                    continue;
     1108                //len = WaitForFreeSpace(amount);
     1109                char * ob = encoder->GetOutBuff();
     1110                if (amount >= bdiff)
     1111                {
     1112                    memcpy(audiobuffer + org_waud, ob, bdiff);
     1113                    ob += bdiff;
     1114                    amount -= bdiff;
     1115                    org_waud = 0;
     1116                }
     1117                if (amount > 0)
     1118                    memcpy(audiobuffer + org_waud, ob, amount);
     1119                bdiff = AUDBUFSIZE - amount;
     1120                org_waud += amount;
    6081121            }
    609 
    610             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    611                                       (audiobuffer + org_waud), samplesToGet);
    612             if (nSamples == nSamplesToEnd)
     1122        }
     1123        else
     1124        {
     1125            int newLen = 0;
     1126            int nSamples;
     1127            len = WaitForFreeSpace(pSoundStretch->numSamples() *
     1128                                   audio_bytes_per_sample);
     1129            do
    6131130            {
    614                 org_waud = 0;
    615                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
    616             }
    617             else
    618             {
    619                 org_waud += nSamples * audio_bytes_per_sample;
    620                 nSamplesToEnd -= nSamples;
    621             }
     1131                int samplesToGet = len/audio_bytes_per_sample;
     1132                if (samplesToGet > nSamplesToEnd)
     1133                {
     1134                    samplesToGet = nSamplesToEnd;   
     1135                }
    6221136
    623             newLen += nSamples * audio_bytes_per_sample;
    624             len -= nSamples * audio_bytes_per_sample;
    625         } while (nSamples > 0);
     1137                nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
     1138                                          (audiobuffer + org_waud), samplesToGet);
     1139                if (nSamples == nSamplesToEnd)
     1140                {
     1141                    org_waud = 0;
     1142                    nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     1143                }
     1144                else
     1145                {
     1146                    org_waud += nSamples * audio_bytes_per_sample;
     1147                    nSamplesToEnd -= nSamples;
     1148                }
     1149
     1150                newLen += nSamples * audio_bytes_per_sample;
     1151                len -= nSamples * audio_bytes_per_sample;
     1152            } while (nSamples > 0);
     1153        }
    6261154    }
    6271155
    6281156    waud = org_waud;
     
    6921220            space_on_soundcard = getSpaceOnSoundcard();
    6931221
    6941222            if (space_on_soundcard != last_space_on_soundcard) {
    695                 VERBOSE(VB_AUDIO, QString("%1 bytes free on soundcard")
     1223                VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("%1 bytes free on soundcard")
    6961224                        .arg(space_on_soundcard));
    6971225                last_space_on_soundcard = space_on_soundcard;
    6981226            }
     
    7051233                    WriteAudio(zeros, fragment_size);
    7061234                } else {
    7071235                    // this should never happen now -dag
    708                     VERBOSE(VB_AUDIO,
     1236                    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    7091237                            QString("waiting for space on soundcard "
    7101238                                    "to write zeros: have %1 need %2")
    7111239                            .arg(space_on_soundcard).arg(fragment_size));
     
    7411269        if (fragment_size > audiolen(true))
    7421270        {
    7431271            if (audiolen(true) > 0)  // only log if we're sending some audio
    744                 VERBOSE(VB_AUDIO,
     1272                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    7451273                        QString("audio waiting for buffer to fill: "
    7461274                                "have %1 want %2")
    7471275                        .arg(audiolen(true)).arg(fragment_size));
    7481276
    749             VERBOSE(VB_AUDIO, "Broadcasting free space avail");
     1277            //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail");
    7501278            pthread_mutex_lock(&audio_buflock);
    7511279            pthread_cond_broadcast(&audio_bufsig);
    7521280            pthread_mutex_unlock(&audio_buflock);
     
    7601288        if (fragment_size > space_on_soundcard)
    7611289        {
    7621290            if (space_on_soundcard != last_space_on_soundcard) {
    763                 VERBOSE(VB_AUDIO,
     1291                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    7641292                        QString("audio waiting for space on soundcard: "
    7651293                                "have %1 need %2")
    7661294                        .arg(space_on_soundcard).arg(fragment_size));
     
    8221350
    8231351        /* update raud */
    8241352        raud = (raud + fragment_size) % AUDBUFSIZE;
    825         VERBOSE(VB_AUDIO, "Broadcasting free space avail");
     1353        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail");
    8261354        pthread_cond_broadcast(&audio_bufsig);
    8271355
    8281356        written_size = fragment_size;
  • libs/libmyth/audiooutput.cpp

     
    2828
    2929AudioOutput *AudioOutput::OpenAudio(QString audiodevice, int audio_bits,
    3030                                    int audio_channels, int audio_samplerate,
    31                                     AudioOutputSource source, bool set_initial_vol)
     31                                    AudioOutputSource source,
     32                                    bool set_initial_vol, bool audio_passthru)
    3233{
    3334    if (audiodevice.startsWith("ALSA:"))
    3435    {
    3536#ifdef USE_ALSA
    3637        return new AudioOutputALSA(audiodevice.remove(0, 5), audio_bits,
    37                                    audio_channels, audio_samplerate, source, set_initial_vol);
     38                                   audio_channels, audio_samplerate, source,
     39                                   set_initial_vol, audio_passthru);
    3840#else
    3941        VERBOSE(VB_IMPORTANT, "Audio output device is set to an ALSA device "
    4042                              "but ALSA support is not compiled in!");
     
    4446    else if (audiodevice.startsWith("NULL"))
    4547    {
    4648        return new AudioOutputNULL(audiodevice, audio_bits,
    47                                    audio_channels, audio_samplerate, source, set_initial_vol);
     49                                   audio_channels, audio_samplerate, source,
     50                                   set_initial_vol, audio_passthru);
    4851    }
    4952    else if (audiodevice.startsWith("ARTS:"))
    5053    {
    5154#ifdef USE_ARTS
    5255        return new AudioOutputARTS(audiodevice.remove(0, 5), audio_bits,
    53                                    audio_channels, audio_samplerate, source, set_initial_vol);
     56                                   audio_channels, audio_samplerate, source,
     57                                   set_initial_vol, audio_passthru);
    5458#else
    5559        VERBOSE(VB_IMPORTANT, "Audio output device is set to an ARTS device "
    5660                              "but ARTS support is not compiled in!");
     
    6165    {
    6266#ifdef USE_JACK
    6367        return new AudioOutputJACK(audiodevice.remove(0, 5), audio_bits,
    64                                    audio_channels, audio_samplerate, source, set_initial_vol);
     68                                   audio_channels, audio_samplerate, source,
     69                                   set_initial_vol, audio_passthru);
    6570#else
    6671        VERBOSE(VB_IMPORTANT, "Audio output device is set to a JACK device "
    6772                              "but JACK support is not compiled in!");
     
    7176#if defined(USING_DIRECTX)
    7277    else
    7378        return new AudioOutputDX(audiodevice, audio_bits,
    74                                   audio_channels, audio_samplerate, source, set_initial_vol);
     79                                 audio_channels, audio_samplerate, source,
     80                                 set_initial_vol, audio_passthru);
    7581#elif defined(USING_OSS)
    7682    else
    7783        return new AudioOutputOSS(audiodevice, audio_bits,
    78                                   audio_channels, audio_samplerate, source, set_initial_vol);
     84                                  audio_channels, audio_samplerate, source,
     85                                  set_initial_vol, audio_passthru);
    7986#elif defined(CONFIG_DARWIN)
    8087    else
    8188        return new AudioOutputCA(audiodevice, audio_bits,
    82                                  audio_channels, audio_samplerate, source, set_initial_vol);
     89                                 audio_channels, audio_samplerate, source,
     90                                 set_initial_vol, audio_passthru);
    8391#endif
    8492
    8593    VERBOSE(VB_IMPORTANT, "No useable audio output driver found.");
  • libs/libmyth/libmyth.pro

     
    3434SOURCES += virtualkeyboard.cpp mythobservable.cpp
    3535
    3636INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../..
     37INCLUDEPATH += ../libavutil ..
    3738DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch
     39DEPENDPATH += ../libavutil ../libavcodec
    3840
    3941
    4042LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}
    4143LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}
     44LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION}
    4245
    4346isEmpty(QMAKE_EXTENSION_SHLIB) {
    4447  QMAKE_EXTENSION_SHLIB=so
  • libs/libmyth/audiooutputca.h

     
    1919public:
    2020    AudioOutputCA(QString audiodevice, int laudio_bits,
    2121                  int laudio_channels, int laudio_samplerate,
    22                   AudioOutputSource source, bool set_initial_vol);
     22                  AudioOutputSource source,
     23                  bool set_initial_vol, bool laudio_passthru);
    2324    virtual ~AudioOutputCA();
    2425   
    2526    // callback for delivering audio to output device
  • libs/libmyth/audiooutputoss.cpp

     
    2727
    2828AudioOutputOSS::AudioOutputOSS(QString audiodevice, int laudio_bits,
    2929                               int laudio_channels, int laudio_samplerate,
    30                                AudioOutputSource source, bool set_initial_vol)
    31               : AudioOutputBase(audiodevice, laudio_bits,
    32                               laudio_channels, laudio_samplerate, source, set_initial_vol)
     30                               AudioOutputSource source, bool set_initial_vol,
     31                               bool laudio_passthru)
     32    : AudioOutputBase(audiodevice, laudio_bits,
     33                      laudio_channels, laudio_samplerate, source,
     34                      set_initial_vol, laudio_passthru)
    3335{
    3436    // our initalisation
    3537    audiofd = -1;
     
    3739    numbadioctls = 0;
    3840
    3941    // Set everything up
    40     Reconfigure(laudio_bits, laudio_channels, laudio_samplerate);
     42    Reconfigure(laudio_bits, laudio_channels,
     43                laudio_samplerate, laudio_passthru);
    4144}
    4245
    4346AudioOutputOSS::~AudioOutputOSS()
  • libs/libmyth/audiooutputarts.cpp

     
    99
    1010AudioOutputARTS::AudioOutputARTS(QString audiodevice, int audio_bits,
    1111                                 int audio_channels, int audio_samplerate,
    12                                  AudioOutputSource source, bool set_initial_vol)
    13               : AudioOutputBase(audiodevice, audio_bits, audio_channels,
    14                                 audio_samplerate, source, set_initial_vol)
     12                                 AudioOutputSource source,
     13                                 bool set_initial_vol, bool audio_passthru)
     14    : AudioOutputBase(audiodevice, audio_bits, audio_channels,
     15                      audio_samplerate, source, set_initial_vol,
     16                      audio_passthru)
    1517{
    1618    // our initalisation
    1719    pcm_handle = NULL;
    1820
    1921    // Set everything up
    20     Reconfigure(audio_bits, audio_channels, audio_samplerate);
     22    Reconfigure(audio_bits, audio_channels, audio_samplerate, audio_passthru);
    2123}
    2224
    2325AudioOutputARTS::~AudioOutputARTS()
  • libs/libmyth/audiooutputdx.cpp

     
    9797
    9898AudioOutputDX::AudioOutputDX(QString audiodevice, int audio_bits,
    9999                             int audio_channels, int audio_samplerate,
    100                              AudioOutputSource source, bool set_initial_vol)
     100                             AudioOutputSource source,
     101                             bool set_initial_vol, bool audio_passthru)
    101102{
    102103    this->audiodevice = audiodevice;
    103104   
     
    110111   
    111112    InitDirectSound();
    112113   
    113     Reconfigure(audio_bits, audio_channels, audio_samplerate);
     114    Reconfigure(audio_bits, audio_channels, audio_samplerate, audio_passthru);
    114115}
    115116
    116117void AudioOutputDX::SetBlocking(bool blocking)
     
    119120}
    120121
    121122void AudioOutputDX::Reconfigure(int audio_bits,
    122                                   int audio_channels, int audio_samplerate)
     123                                int audio_channels,
     124                                int audio_samplerate,
     125                                int audio_passthru,
     126                                AudioCodecMode laom
     127                                )
    123128{
    124129    if (dsbuffer)
    125130        DestroyDSBuffer();
     
    132137    effdsp = audio_samplerate;
    133138    this->audio_bits = audio_bits;
    134139    this->audio_channels = audio_channels;
     140    this->audio_passthru = audio_passthru;
    135141}
    136142
    137143AudioOutputDX::~AudioOutputDX()
  • libs/libmyth/audiooutputnull.h

     
    2626public:
    2727    AudioOutputNULL(QString audiodevice, int laudio_bits,
    2828                   int laudio_channels, int laudio_samplerate,
    29                    AudioOutputSource source, bool set_initial_vol);
     29                   AudioOutputSource source,
     30                    bool set_initial_vol, bool laudio_passthru);
    3031    virtual ~AudioOutputNULL();
    3132
    3233    virtual void Reset(void);
  • libs/libmyth/audiooutput.h

     
    1919 public:
    2020    // opens one of the concrete subclasses
    2121    static AudioOutput *OpenAudio(QString audiodevice, int audio_bits,
    22                                  int audio_channels, int audio_samplerate,
    23                                  AudioOutputSource source, bool set_initial_vol);
     22                                  int audio_channels, int audio_samplerate,
     23                                  AudioOutputSource source,
     24                                  bool set_initial_vol, bool audio_passthru);
    2425
    2526    AudioOutput() : VolumeBase(), OutputListeners() { lastError = QString::null; };
    2627    virtual ~AudioOutput() { };
    2728
    2829    // reconfigure sound out for new params
    2930    virtual void Reconfigure(int audio_bits,
    30                              int audio_channels, int audio_samplerate) = 0;
     31                             int audio_channels,
     32                             int audio_samplerate,
     33                             bool audio_passthru,
     34                             void* audio_codec = NULL
     35                             ) = 0;
    3136   
    3237    virtual void SetStretchFactor(float factor);
    3338
     
    6570 protected:
    6671    void Error(QString msg)
    6772     { lastError = msg; VERBOSE(VB_IMPORTANT, lastError); };
     73    void ClearError()
     74     { lastError = QString::null; };
    6875
    6976 private:
    7077    QString lastError;
  • libs/libmyth/audiooutputnull.cpp

     
    1818
    1919AudioOutputNULL::AudioOutputNULL(QString audiodevice, int laudio_bits,
    2020                                 int laudio_channels, int laudio_samplerate,
    21                                  AudioOutputSource source, bool set_initial_vol)
     21                                 AudioOutputSource source, bool set_initial_vol,
     22                                 bool laudio_passthru)
    2223               : AudioOutputBase(audiodevice, laudio_bits, laudio_channels,
    23                                  laudio_samplerate, source, set_initial_vol)
     24                                 laudio_samplerate, source, set_initial_vol,
     25                                 laudio_passthru)
    2426{
    2527    locked_audio_channels = laudio_channels;
    2628    locked_audio_bits = laudio_bits;
    2729    locked_audio_samplerate = laudio_samplerate;
    28     Reconfigure(laudio_bits, laudio_channels, laudio_samplerate);
     30    Reconfigure(laudio_bits, laudio_channels, laudio_samplerate, laudio_passthru);
    2931    current_buffer_size = 0;
    3032}
    3133
  • libs/libmyth/audiooutputarts.h

     
    1616  public:
    1717     AudioOutputARTS(QString audiodevice, int audio_bits,
    1818                     int audio_channels, int audio_samplerate,
    19                      AudioOutputSource source, bool set_initial_vol);
     19                     AudioOutputSource source,
     20                     bool set_initial_vol, bool laudio_passthru);
    2021     virtual ~AudioOutputARTS();
    2122
    2223    // Volume control
  • libs/libmyth/audiooutputdx.h

     
    1616public:
    1717    AudioOutputDX(QString audiodevice, int audio_bits,
    1818                  int audio_channels, int audio_samplerate,
    19                   AudioOutputSource source, bool set_initial_vol);
     19                  AudioOutputSource source,
     20                  bool set_initial_vol, bool laudio_passthru);
    2021    virtual ~AudioOutputDX();
    2122
    2223    virtual void Reset(void);
    2324    virtual void Reconfigure(int audio_bits,
    24                          int audio_channels, int audio_samplerate);
     25                         int audio_channels,
     26                         int audio_samplerate,
     27                         bool audio_passthru,
     28                         AudioCodecMode aom = AUDIOCODECMODE_NORMAL);
    2529    virtual void SetBlocking(bool blocking);
    2630
    2731    virtual bool AddSamples(char *buffer, int samples, long long timecode);
  • libs/libmyth/audiooutputalsa.h

     
    1717{
    1818  public:
    1919    AudioOutputALSA(QString audiodevice, int laudio_bits,
    20                    int laudio_channels, int laudio_samplerate,
    21                    AudioOutputSource source, bool set_initial_vol);
     20                    int laudio_channels, int laudio_samplerate,
     21                    AudioOutputSource source,
     22                    bool set_initial_vol, bool laudio_passthru);
    2223    virtual ~AudioOutputALSA();
    2324
    2425    // Volume control
  • libs/libavcodec/a52dec.c

     
    149149    }
    150150}
    151151
     152static inline int16_t convert (int32_t i)
     153{
     154    if (i > 0x43c07fff)
     155        return 32767;
     156    else if (i < 0x43bf8000)
     157        return -32768;
     158    else
     159        return i - 0x43c00000;
     160}
     161
     162void float2s16_2 (float * _f, int16_t * s16)
     163{
     164    int i;
     165    int32_t * f = (int32_t *) _f;
     166
     167    for (i = 0; i < 256; i++) {
     168        s16[2*i] = convert (f[i]);
     169        s16[2*i+1] = convert (f[i+256]);
     170    }
     171}
     172
     173void float2s16_4 (float * _f, int16_t * s16)
     174{
     175    int i;
     176    int32_t * f = (int32_t *) _f;
     177
     178    for (i = 0; i < 256; i++) {
     179        s16[4*i] = convert (f[i]);
     180        s16[4*i+1] = convert (f[i+256]);
     181        s16[4*i+2] = convert (f[i+512]);
     182        s16[4*i+3] = convert (f[i+768]);
     183    }
     184}
     185
     186void float2s16_5 (float * _f, int16_t * s16)
     187{
     188    int i;
     189    int32_t * f = (int32_t *) _f;
     190
     191    for (i = 0; i < 256; i++) {
     192        s16[5*i] = convert (f[i]);
     193        s16[5*i+1] = convert (f[i+256]);
     194        s16[5*i+2] = convert (f[i+512]);
     195        s16[5*i+3] = convert (f[i+768]);
     196        s16[5*i+4] = convert (f[i+1024]);
     197    }
     198}
     199
     200int channels_multi (int flags)
     201{
     202    if (flags & A52_LFE)
     203        return 6;
     204    else if (flags & 1) /* center channel */
     205        return 5;
     206    else if ((flags & A52_CHANNEL_MASK) == A52_2F2R)
     207        return 4;
     208    else
     209        return 2;
     210}
     211
     212void float2s16_multi (float * _f, int16_t * s16, int flags)
     213{
     214    int i;
     215    int32_t * f = (int32_t *) _f;
     216
     217    switch (flags) {
     218    case A52_MONO:
     219        for (i = 0; i < 256; i++) {
     220            s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0;
     221            s16[5*i+4] = convert (f[i]);
     222        }
     223        break;
     224    case A52_CHANNEL:
     225    case A52_STEREO:
     226    case A52_DOLBY:
     227        float2s16_2 (_f, s16);
     228        break;
     229    case A52_3F:
     230        for (i = 0; i < 256; i++) {
     231            s16[5*i] = convert (f[i]);
     232            s16[5*i+1] = convert (f[i+512]);
     233            s16[5*i+2] = s16[5*i+3] = 0;
     234            s16[5*i+4] = convert (f[i+256]);
     235        }
     236        break;
     237    case A52_2F2R:
     238        float2s16_4 (_f, s16);
     239        break;
     240    case A52_3F2R:
     241        float2s16_5 (_f, s16);
     242        break;
     243    case A52_MONO | A52_LFE:
     244        for (i = 0; i < 256; i++) {
     245            s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0;
     246            s16[6*i+4] = convert (f[i+256]);
     247            s16[6*i+5] = convert (f[i]);
     248        }
     249        break;
     250    case A52_CHANNEL | A52_LFE:
     251    case A52_STEREO | A52_LFE:
     252    case A52_DOLBY | A52_LFE:
     253        for (i = 0; i < 256; i++) {
     254            s16[6*i] = convert (f[i+256]);
     255            s16[6*i+1] = convert (f[i+512]);
     256            s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
     257            s16[6*i+5] = convert (f[i]);
     258        }
     259        break;
     260    case A52_3F | A52_LFE:
     261        for (i = 0; i < 256; i++) {
     262            s16[6*i] = convert (f[i+256]);
     263            s16[6*i+1] = convert (f[i+768]);
     264            s16[6*i+2] = s16[6*i+3] = 0;
     265            s16[6*i+4] = convert (f[i+512]);
     266            s16[6*i+5] = convert (f[i]);
     267        }
     268        break;
     269    case A52_2F2R | A52_LFE:
     270        for (i = 0; i < 256; i++) {
     271            s16[6*i] = convert (f[i+256]);
     272            s16[6*i+1] = convert (f[i+512]);
     273            s16[6*i+2] = convert (f[i+768]);
     274            s16[6*i+3] = convert (f[i+1024]);
     275            s16[6*i+4] = 0;
     276            s16[6*i+5] = convert (f[i]);
     277        }
     278        break;
     279    case A52_3F2R | A52_LFE:
     280        for (i = 0; i < 256; i++) {
     281            s16[6*i] = convert (f[i+256]);
     282            s16[6*i+1] = convert (f[i+768]);
     283            s16[6*i+2] = convert (f[i+1024]);
     284            s16[6*i+3] = convert (f[i+1280]);
     285            s16[6*i+4] = convert (f[i+512]);
     286            s16[6*i+5] = convert (f[i]);
     287        }
     288        break;
     289    }
     290}
     291
     292
    152293/**** end */
    153294
    154295#define HEADER_SIZE 7
     
    190331                    /* update codec info */
    191332                    avctx->sample_rate = sample_rate;
    192333                    s->channels = ac3_channels[s->flags & 7];
     334                    if (avctx->cqp >= 0)
     335                        avctx->channels = avctx->cqp;
    193336                    if (s->flags & A52_LFE)
    194337                        s->channels++;
    195338                    if (avctx->channels == 0)
     
    212355            s->inbuf_ptr += len;
    213356            buf_size -= len;
    214357        } else {
     358            int chans;
    215359            flags = s->flags;
    216360            if (avctx->channels == 1)
    217361                flags = A52_MONO;
    218             else if (avctx->channels == 2)
    219                 flags = A52_STEREO;
     362            else if (avctx->channels == 2) {
     363                if (s->channels>2)
     364                    flags = A52_DOLBY;
     365                else
     366                    flags = A52_STEREO;
     367            }
    220368            else
    221369                flags |= A52_ADJUST_LEVEL;
    222370            level = 1;
     371            chans = channels_multi(flags);
    223372            if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) {
    224373            fail:
    225374                s->inbuf_ptr = s->inbuf;
     
    229378            for (i = 0; i < 6; i++) {
    230379                if (s->a52_block(s->state))
    231380                    goto fail;
    232                 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);
     381                //float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);
     382                float2s16_multi(s->samples, out_samples + i * 256 * chans, flags);
    233383            }
    234384            s->inbuf_ptr = s->inbuf;
    235385            s->frame_size = 0;
    236             *data_size = 6 * avctx->channels * 256 * sizeof(int16_t);
     386            //*data_size = 6 * avctx->channels * 256 * sizeof(int16_t);
     387            *data_size = 6 * chans * 256 * sizeof(int16_t);
    237388            break;
    238389        }
    239390    }
  • libs/libavcodec/ac3enc.c

     
    13621362{
    13631363    AC3EncodeContext *s = avctx->priv_data;
    13641364    int16_t *samples = data;
     1365    // expects L C R LS RS LFE
     1366    // audio format is L R LS RS C LFE
     1367    static int channel_index[6] = { 0, 4, 1, 2, 3, 5 };
     1368    /*
     1369     * A52->Analog->AC3Enc
     1370     * 1->0->0
     1371     * 3->1->2
     1372     * 4->2->3
     1373     * 5->3->4
     1374     * 2->4->1
     1375     * 0->5->5
     1376     */
    13651377    int i, j, k, v, ch;
    13661378    int16_t input_samples[N];
    13671379    int32_t mdct_coef[NB_BLOCKS][AC3_MAX_CHANNELS][N/2];
     
    13821394            /* compute input samples */
    13831395            memcpy(input_samples, s->last_samples[ch], N/2 * sizeof(int16_t));
    13841396            sinc = s->nb_all_channels;
    1385             sptr = samples + (sinc * (N/2) * i) + ch;
     1397            sptr = samples + (sinc * (N/2) * i) + channel_index[ch];
    13861398            for(j=0;j<N/2;j++) {
    13871399                v = *sptr;
    13881400                input_samples[j + N/2] = v;
     
    14031415            v = 14 - log2_tab(input_samples, N);
    14041416            if (v < 0)
    14051417                v = 0;
    1406             exp_samples[i][ch] = v - 8;
     1418            exp_samples[i][ch] = v - 9;
    14071419            lshift_tab(input_samples, N, v);
    14081420
    14091421            /* do the MDCT */
  • programs/mythfrontend/globalsettings.cpp

     
    3636        dev.setNameFilter("adsp*");
    3737        gc->fillSelectionsFromDir(dev);
    3838    }
     39#ifdef USE_ALSA
     40    gc->addSelection("ALSA:default", "ALSA:default");
     41    gc->addSelection("ALSA:analog", "ALSA:analog");
     42    gc->addSelection("ALSA:digital", "ALSA:digital");
     43    gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog");
     44    gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital");
     45#endif
     46#ifdef USE_ARTS
     47    gc->addSelection("ARTS:", "ARTS:");
     48#endif
     49#ifdef USE_JACK
     50    gc->addSelection("JACK:output", "JACK:output");
     51#endif
     52    gc->addSelection("NULL", "NULL");
    3953
    4054    return gc;
    4155}
    4256
     57static HostComboBox *MaxAudioChannels()
     58{
     59    HostComboBox *gc = new HostComboBox("MaxChannels",false);
     60    gc->setLabel(QObject::tr("Max Audio Channels"));
     61    //gc->addSelection(QObject::tr("Mono"), "1");
     62    //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default
     63    //gc->addSelection(QObject::tr("3 Channel: L C R"), "3");
     64    //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4");
     65    //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5");
     66    //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6");
     67    gc->addSelection(QObject::tr("Stereo"), "2", true); // default
     68    gc->addSelection(QObject::tr("6 Channel"), "6");
     69    gc->setHelpText(
     70            QObject::tr("Set the maximum number of audio channels to be decoded. "
     71                "This is for multi-channel/surround audio playback."));
     72    return gc;
     73}
     74
    4375static HostCheckBox *MythControlsVolume()
    4476{
    4577    HostCheckBox *gc = new HostCheckBox("MythControlsVolume");
     
    20922124         setUseLabel(false);
    20932125
    20942126         addChild(AudioOutputDevice());
     2127#if 0
     2128         ConfigurationGroup *hg = new HorizontalConfigurationGroup(false, false);
     2129         ConfigurationGroup* settingsLeft = new VerticalConfigurationGroup(false,false);
     2130         settingsLeft->addChild(AC3PassThrough());
     2131#ifdef CONFIG_DTS
     2132         settingsLeft->addChild(DTSPassThrough());
     2133#endif
     2134         settingsLeft->addChild(AggressiveBuffer());
     2135         hg->addChild(settingsLeft);
     2136
     2137         ConfigurationGroup* settingsRight = new VerticalConfigurationGroup(false,false);
     2138         settingsRight->addChild(MaxAudioChannels());
     2139         hg->addChild(settingsRight);
     2140
     2141         addChild(hg);
     2142#else
    20952143         addChild(AC3PassThrough());
    20962144#ifdef CONFIG_DTS
    20972145         addChild(DTSPassThrough());
    20982146#endif
    20992147         addChild(AggressiveBuffer());
     2148         addChild(MaxAudioChannels());
     2149#endif
    21002150
    21012151         Setting* volumeControl = MythControlsVolume();
    21022152         addChild(volumeControl);
  • programs/mythtranscode/transcode.cpp

     
    3434    AudioReencodeBuffer(int audio_bits, int audio_channels)
    3535    {
    3636        Reset();
    37         Reconfigure(audio_bits, audio_channels, 0);
     37        Reconfigure(audio_bits, audio_channels, 0, 0);
    3838        bufsize = 512000;
    3939        audiobuffer = new unsigned char[bufsize];
    4040    }
     
    4545    }
    4646
    4747    // reconfigure sound out for new params
    48     virtual void Reconfigure(int audio_bits,
    49                         int audio_channels, int audio_samplerate)
     48    virtual void Reconfigure(int audio_bits, int audio_channels,
     49                             int audio_samplerate, bool audio_passthru,
     50                             void * = NULL)
    5051    {
     52        ClearError();
    5153        (void)audio_samplerate;
    5254        bits = audio_bits;
    5355        channels = audio_channels;
    5456        bytes_per_sample = bits * channels / 8;
     57        if (channels>2)
     58            Error("Invalid channel count");
    5559    }
    5660
    5761    // dsprate is in 100 * samples/second