Ticket #5900: audioencoding-trunk-jya7.patch

File audioencoding-trunk-jya7.patch, 88.0 KB (added by jyavenard@…, 15 years ago)

AC3 upmixer for trunk (tested on 20533)

  • trunk/mythplugins/mythmusic/mythmusic/playbackbox.cpp

     
    367367            changeSpeed(true);
    368368        else if (action == "MUTE")
    369369            toggleMute();
     370        else if (action == "TOGGLEUPMIX")
     371            toggleUpmix();
    370372        else if (action == "MENU" && visualizer_status != 2)
    371373        {
    372374            menufilters = false;
     
    12021204    }
    12031205}
    12041206
     1207void PlaybackBoxMusic::toggleUpmix()
     1208{
     1209    if (gPlayer->getOutput())
     1210        gPlayer->getOutput()->ToggleUpmix();
     1211}
     1212   
     1213
    12051214void PlaybackBoxMusic::showProgressBar()
    12061215{
    12071216    if (progress_bar && visualizer_status != 2)
  • trunk/mythplugins/mythmusic/mythmusic/main.cpp

     
    365365    REG_KEY("Music", "VOLUMEDOWN", "Volume down",       "[,{,F10,Volume Down");
    366366    REG_KEY("Music", "VOLUMEUP",   "Volume up",         "],},F11,Volume Up");
    367367    REG_KEY("Music", "MUTE",       "Mute",              "|,\\,F9,Volume Mute");
     368    REG_KEY("Music", "TOGGLEUPMIX","Toggle upmixer",             "Ctrl+U");
    368369    REG_KEY("Music", "CYCLEVIS",   "Cycle visualizer mode",      "6");
    369370    REG_KEY("Music", "BLANKSCR",   "Blank screen",               "5");
    370371    REG_KEY("Music", "THMBUP",     "Increase rating",            "9");
  • trunk/mythplugins/mythmusic/mythmusic/musicplayer.cpp

     
    348348
    349349void MusicPlayer::openOutputDevice(void)
    350350{
    351     QString adevice;
     351    QString adevice, pdevice;
    352352
    353353    if (gContext->GetSetting("MusicAudioDevice") == "default")
    354354        adevice = gContext->GetSetting("AudioOutputDevice");
    355355    else
    356356        adevice = gContext->GetSetting("MusicAudioDevice");
    357357
     358    pdevice = gContext->GetSetting("PassThruOutputDevice");
     359
    358360    // TODO: Error checking that device is opened correctly!
    359     m_output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100,
     361    m_output = AudioOutput::OpenAudio(adevice, pdevice, 16, 2, 44100,
    360362                                    AUDIOOUTPUT_MUSIC, true, false);
    361363    m_output->setBufferSize(256 * 1024);
    362364    m_output->SetBlocking(false);
  • trunk/mythplugins/mythmusic/mythmusic/playbackbox.h

     
    6969    void changeVolume(bool up_or_down);
    7070    void changeSpeed(bool up_or_down);
    7171    void toggleMute();
     72    void toggleUpmix();
    7273    void resetTimer();
    7374    void hideVolume(){showVolume(false);}
    7475    void showVolume(bool on_or_off);
  • trunk/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp

     
    868868
    869869    no_audio_in = false;
    870870
     871    bool isAC3upmix = gContext->GetNumSetting("MythAC3Upmix",0);
     872    // If previously AC3 upmixer was different than current state, delete AudioOutput
     873    if (audioOutput && (audioOutput->isAC3upmix != isAC3upmix))
     874    {
     875        delete audioOutput;
     876        audioOutput = NULL;
     877    }
     878
    871879    if (!audioOutput && !using_null_videoout && player_ctx->IsAudioNeeded())
    872880    {
    873881        bool setVolume = gContext->GetNumSetting("MythControlsVolume", 1);
     
    876884                                             audio_bits, audio_channels,
    877885                                             audio_samplerate,
    878886                                             AUDIOOUTPUT_VIDEO,
    879                                              setVolume, audio_passthru);
     887                                             setVolume, audio_passthru, isAC3upmix);
    880888        if (!audioOutput)
    881889            errMsg = QObject::tr("Unable to create AudioOutput.");
    882890        else
     
    906914            audio_bits, audio_channels, audio_samplerate,
    907915            audio_passthru, audio_codec);
    908916        audioOutput->Reconfigure(settings);
     917        if (audioOutput->isAC3upmix && audio_passthru)
     918            audio_channels = 2;
    909919        errMsg = audioOutput->GetError();
    910920        if (!errMsg.isEmpty())
    911921            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    52685278    }
    52695279}
    52705280
     5281bool NuppelVideoPlayer::GetisAC3upmix()
     5282{
     5283    if (audioOutput)
     5284        return audioOutput->isAC3upmix;
     5285    return false;
     5286}
     5287
     5288bool NuppelVideoPlayer::ToggleUpmix()
     5289{
     5290    if (audioOutput)
     5291        return audioOutput->ToggleUpmix();
     5292    return false;
     5293}
     5294
    52715295void NuppelVideoPlayer::Zoom(ZoomDirection direction)
    52725296{
    52735297    if (videoOutput)
  • trunk/mythtv/libs/libmythtv/avformatdecoder.cpp

     
    430430      audioSamples(NULL),
    431431      allow_ac3_passthru(false),    allow_dts_passthru(false),
    432432      disable_passthru(false),      max_channels(2),
    433       dummy_frame(NULL),
     433      last_ac3_channels(0),         dummy_frame(NULL),
    434434      // DVD
    435435      lastdvdtitle(-1),
    436436      decodeStillFrame(false),
     
    451451    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
    452452    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
    453453    max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2);
     454    isAC3upmix = gContext->GetNumSetting("MythAC3Upmix", 0);
    454455
    455456    audioIn.sample_size = -32; // force SetupAudioStream to run once
    456457    itv = GetNVP()->GetInteractiveTV();
     
    29752976    {
    29762977        int idx = atracks[i].av_stream_index;
    29772978        AVCodecContext *codec_ctx = ic->streams[idx]->codec;
    2978         bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    2979                                 !disable_passthru &&
    2980                                 (codec_ctx->codec_id == CODEC_ID_AC3));
    2981         bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    2982                                 !disable_passthru &&
    2983                                 (codec_ctx->codec_id == CODEC_ID_DTS));
    29842979        AudioInfo item(codec_ctx->codec_id,
    29852980                       codec_ctx->sample_rate, codec_ctx->channels,
    2986                        do_ac3_passthru || do_dts_passthru);
     2981                       DoPassThrough(codec_ctx));
    29872982        VERBOSE(VB_AUDIO, LOC + " * " + item.toString());
    29882983    }
    29892984#endif
     
    31173112bool AvFormatDecoder::GetFrame(int onlyvideo)
    31183113{
    31193114    AVPacket *pkt = NULL;
     3115    AC3HeaderInfo hdr;
    31203116    int len;
    31213117    unsigned char *ptr;
    31223118    int data_size = 0;
     
    33133309        pts = 0;
    33143310
    33153311        AVStream *curstream = ic->streams[pkt->stream_index];
     3312        AVCodecContext *ctx = curstream->codec;
    33163313
    33173314        if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
    33183315            pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000);
    33193316
    3320         if (ringBuffer->isDVD() &&
    3321             curstream->codec->codec_type == CODEC_TYPE_VIDEO)
     3317        if (ringBuffer->isDVD() && 
     3318            ctx->codec_type == CODEC_TYPE_VIDEO)
    33223319        {
    33233320            MpegPreProcessPkt(curstream, pkt);
    33243321
     
    33403337
    33413338            if (!d->HasMPEG2Dec())
    33423339            {
    3343                 int current_width = curstream->codec->width;
     3340                int current_width = ctx->width;
    33443341                int video_width = GetNVP()->GetVideoSize().width();
    33453342                if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput())
    33463343                {
     
    33813378        }
    33823379
    33833380        if (storevideoframes &&
    3384             curstream->codec->codec_type == CODEC_TYPE_VIDEO)
     3381            ctx->codec_type == CODEC_TYPE_VIDEO)
    33853382        {
    33863383            av_dup_packet(pkt);
    33873384            storedPackets.append(pkt);
     
    33893386            continue;
    33903387        }
    33913388
    3392         if (len > 0 && curstream->codec->codec_type == CODEC_TYPE_VIDEO &&
     3389        if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO &&
    33933390            pkt->stream_index == selectedVideoIndex)
    33943391        {
    3395             AVCodecContext *context = curstream->codec;
    33963392
    3397             if (context->codec_id == CODEC_ID_MPEG1VIDEO ||
    3398                 context->codec_id == CODEC_ID_MPEG2VIDEO ||
    3399                 context->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||
    3400                 context->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||
    3401                 context->codec_id == CODEC_ID_MPEGVIDEO_VDPAU)
     3393            if (ctx->codec_id == CODEC_ID_MPEG1VIDEO ||
     3394                ctx->codec_id == CODEC_ID_MPEG2VIDEO ||
     3395                ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||
     3396                ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||
     3397                ctx->codec_id == CODEC_ID_MPEGVIDEO_VDPAU)
    34023398            {
    34033399                if (!ringBuffer->isDVD())
    34043400                    MpegPreProcessPkt(curstream, pkt);
    34053401            }
    3406             else if (context->codec_id == CODEC_ID_H264 ||
    3407                      context->codec_id == CODEC_ID_H264_VDPAU)
     3402            else if (ctx->codec_id == CODEC_ID_H264 ||
     3403                     ctx->codec_id == CODEC_ID_H264_VDPAU)
    34083404            {
    34093405                H264PreProcessPkt(curstream, pkt);
    34103406            }
     
    34493445        }
    34503446
    34513447        if (len > 0 &&
    3452             curstream->codec->codec_type == CODEC_TYPE_DATA &&
    3453             curstream->codec->codec_id   == CODEC_ID_MPEG2VBI)
     3448            ctx->codec_type == CODEC_TYPE_DATA &&
     3449            ctx->codec_id   == CODEC_ID_MPEG2VBI)
    34543450        {
    34553451            ProcessVBIDataPacket(curstream, pkt);
    34563452
     
    34593455        }
    34603456
    34613457        if (len > 0 &&
    3462             curstream->codec->codec_type == CODEC_TYPE_DATA &&
    3463             curstream->codec->codec_id   == CODEC_ID_DVB_VBI)
     3458            ctx->codec_type == CODEC_TYPE_DATA &&
     3459            ctx->codec_id   == CODEC_ID_DVB_VBI)
    34643460        {
    34653461            ProcessDVBDataPacket(curstream, pkt);
    34663462
     
    34703466
    34713467#ifdef USING_MHEG
    34723468        if (len > 0 &&
    3473             curstream->codec->codec_type == CODEC_TYPE_DATA &&
    3474             curstream->codec->codec_id   == CODEC_ID_DSMCC_B)
     3469            ctx->codec_type == CODEC_TYPE_DATA &&
     3470            ctx->codec_id   == CODEC_ID_DSMCC_B)
    34753471        {
    34763472            ProcessDSMCCPacket(curstream, pkt);
    34773473
     
    34923488#endif // USING_MHEG
    34933489
    34943490        // we don't care about other data streams
    3495         if (curstream->codec->codec_type == CODEC_TYPE_DATA)
     3491        if (ctx->codec_type == CODEC_TYPE_DATA)
    34963492        {
    34973493            av_free_packet(pkt);
    34983494            continue;
    34993495        }
    35003496
    3501         if (!curstream->codec->codec)
     3497        if (!ctx->codec)
    35023498        {
    35033499            VERBOSE(VB_PLAYBACK, LOC +
    35043500                    QString("No codec for stream index %1, type(%2) id(%3:%4)")
    35053501                    .arg(pkt->stream_index)
    3506                     .arg(codec_type_string(curstream->codec->codec_type))
    3507                     .arg(codec_id_string(curstream->codec->codec_id))
    3508                     .arg(curstream->codec->codec_id));
     3502                    .arg(codec_type_string(ctx->codec_type))
     3503                    .arg(codec_id_string(ctx->codec_id))
     3504                    .arg(ctx->codec_id));
    35093505            av_free_packet(pkt);
    35103506            continue;
    35113507        }
     
    35143510        have_err = false;
    35153511
    35163512        avcodeclock.lock();
    3517         int ctype  = curstream->codec->codec_type;
     3513        int ctype  = ctx->codec_type;
    35183514        int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index;
    35193515        int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index;
    35203516        int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index;
     
    35393535
    35403536                    // detect switches between stereo and dual languages
    35413537                    bool wasDual = audSubIdx != -1;
    3542                     bool isDual = curstream->codec->avcodec_dual_language;
     3538                    bool isDual = ctx->avcodec_dual_language;
    35433539                    if ((wasDual && !isDual) || (!wasDual &&  isDual))
    35443540                    {
    35453541                        SetupAudioStreamSubIndexes(audIdx);
    35463542                        reselectAudioTrack = true;
    35473543                    }
    35483544
    3549                     bool do_ac3_passthru =
    3550                         (allow_ac3_passthru && !transcoding &&
    3551                          (curstream->codec->codec_id == CODEC_ID_AC3));
    3552                     bool do_dts_passthru =
    3553                         (allow_dts_passthru && !transcoding &&
    3554                          (curstream->codec->codec_id == CODEC_ID_DTS));
    3555                     bool using_passthru = do_ac3_passthru || do_dts_passthru;
    3556 
    35573545                    // detect channels on streams that need
    35583546                    // to be decoded before we can know this
    35593547                    bool already_decoded = false;
    3560                     if (!curstream->codec->channels)
     3548                    if (!ctx->channels)
    35613549                    {
    35623550                        QMutexLocker locker(&avcodeclock);
    35633551                        VERBOSE(VB_IMPORTANT, LOC +
    35643552                                QString("Setting channels to %1")
    35653553                                .arg(audioOut.channels));
    35663554
    3567                         if (using_passthru)
     3555                        if (DoPassThrough(ctx))
    35683556                        {
    35693557                            // for passthru let it select the max number
    35703558                            // of channels
    3571                             curstream->codec->channels = 0;
    3572                             curstream->codec->request_channels = 0;
     3559                            ctx->channels = 0;
     3560                            ctx->request_channels = 0;
    35733561                        }
    35743562                        else
    35753563                        {
    3576                             curstream->codec->channels = audioOut.channels;
    3577                             curstream->codec->request_channels =
     3564                            ctx->channels = audioOut.channels;
     3565                            ctx->request_channels =
    35783566                                audioOut.channels;
    35793567                        }
     3568                       
    35803569                        data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
    3581                         ret = avcodec_decode_audio2(curstream->codec,
    3582                                                     audioSamples, &data_size,
    3583                                                     ptr, len);
     3570                        ret = avcodec_decode_audio2(ctx, audioSamples,
     3571                                                   &data_size, ptr, len);
    35843572                        already_decoded = true;
    35853573
    3586                         reselectAudioTrack |= curstream->codec->channels;
     3574                        reselectAudioTrack |= ctx->channels;
    35873575                    }
    35883576
     3577                    if (isAC3upmix && ctx->codec_id == CODEC_ID_AC3)
     3578                    {
     3579                        GetBitContext gbc;
     3580                        init_get_bits(&gbc, ptr, len * 8);
     3581                        if (!ff_ac3_parse_header(&gbc, &hdr))
     3582                        {
     3583                            if (hdr.channels != last_ac3_channels)
     3584                            {
     3585                                last_ac3_channels = ctx->channels = hdr.channels;
     3586                                SetupAudioStream();
     3587                            }
     3588                        }
     3589                    }
     3590
    35893591                    if (reselectAudioTrack)
    35903592                    {
    35913593                        QMutexLocker locker(&avcodeclock);
     
    35993601                            .av_stream_index;
    36003602                        audSubIdx = selectedTrack[kTrackTypeAudio]
    36013603                            .av_substream_index;
     3604                        ctx = curstream->codec;
    36023605                    }
    36033606
    36043607                    if ((onlyvideo > 0) || (pkt->stream_index != audIdx))
     
    36303633                    if (audioOut.do_passthru)
    36313634                    {
    36323635                        data_size = pkt->size;
    3633                         bool dts = CODEC_ID_DTS == curstream->codec->codec_id;
     3636                        bool dts = CODEC_ID_DTS == ctx->codec_id;
    36343637                        ret = encode_frame(dts, ptr, len,
    36353638                                           audioSamples, data_size);
    36363639                    }
    36373640                    else
    36383641                    {
    3639                         AVCodecContext *ctx = curstream->codec;
    3640 
    36413642                        if ((ctx->channels == 0) ||
    36423643                            (ctx->channels > audioOut.channels))
    36433644                        {
     
    36463647
    36473648                        if (!already_decoded)
    36483649                        {
    3649                             curstream->codec->request_channels =
    3650                                 audioOut.channels;
    36513650                            data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
    3652                             ret = avcodec_decode_audio2(ctx, audioSamples,
     3651                            ctx->request_channels = audioOut.channels;
     3652                            ret = avcodec_decode_audio2(ctx, audioSamples,
    36533653                                                        &data_size, ptr, len);
    36543654                        }
    36553655
     
    36653665                            audIdx = -1;
    36663666                            AutoSelectAudioTrack();
    36673667                            data_size = 0;
     3668                            ctx = curstream->codec;
    36683669                        }
    36693670                    }
    36703671                    avcodeclock.unlock();
     
    36823683
    36833684                    // calc for next frame
    36843685                    lastapts += (long long)((double)(data_size * 1000) /
    3685                                 (curstream->codec->channels * 2) /
    3686                                 curstream->codec->sample_rate);
     3686                                (ctx->channels * 2) / ctx->sample_rate);
    36873687
    36883688                    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP,
    36893689                            LOC + QString("audio timecode %1 %2 %3 %4")
     
    37513751                        continue;
    37523752                    }
    37533753
    3754                     AVCodecContext *context = curstream->codec;
    37553754                    AVFrame mpa_pic;
    37563755                    bzero(&mpa_pic, sizeof(AVFrame));
    37573756
     
    37663765                            // HACK
    37673766                            while (!gotpicture && count < 5)
    37683767                            {
    3769                                 ret = d->DecodeMPEG2Video(context, &mpa_pic,
     3768                                ret = d->DecodeMPEG2Video(ctx, &mpa_pic,
    37703769                                                  &gotpicture, ptr, len);
    37713770                                count++;
    37723771                            }
    37733772                        }
    37743773                        else
    37753774                        {
    3776                             ret = d->DecodeMPEG2Video(context, &mpa_pic,
     3775                            ret = d->DecodeMPEG2Video(ctx, &mpa_pic,
    37773776                                                &gotpicture, ptr, len);
    37783777                        }
    37793778                    }
    37803779                    else
    37813780                    {
    3782                         ret = avcodec_decode_video(context, &mpa_pic,
     3781                        ret = avcodec_decode_video(ctx, &mpa_pic,
    37833782                                                   &gotpicture, ptr, len);
    37843783                        // Reparse it to not drop the DVD still frame
    37853784                        if (decodeStillFrame)
    3786                             ret = avcodec_decode_video(context, &mpa_pic,
     3785                            ret = avcodec_decode_video(ctx, &mpa_pic,
    37873786                                                        &gotpicture, ptr, len);
    37883787                    }
    37893788                    avcodeclock.unlock();
     
    38553854#endif
    38563855                            &tmppicture, PIX_FMT_YUV420P,
    38573856                                    (AVPicture *)&mpa_pic,
    3858                                     context->pix_fmt,
    3859                                     context->width,
    3860                                     context->height);
     3857                                    ctx->pix_fmt,
     3858                                    ctx->width,
     3859                                    ctx->height);
    38613860
    38623861                        if (xf)
    38633862                        {
     
    38803879                        (temppts + 10000 > lastvpts || temppts < 0))
    38813880                    {
    38823881                        temppts = lastvpts;
    3883                         temppts += (long long)(1000 * av_q2d(context->time_base));
     3882                        temppts += (long long)(1000 * av_q2d(ctx->time_base));
    38843883                        // MPEG2 frames can be repeated, update pts accordingly
    38853884                        temppts += (long long)(mpa_pic.repeat_pict * 500
    3886                                       * av_q2d(curstream->codec->time_base));
     3885                                      * av_q2d(ctx->time_base));
    38873886                    }
    38883887
    38893888                    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC +
     
    39193918                    picframe->frameNumber = framesPlayed;
    39203919                    GetNVP()->ReleaseNextVideoFrame(picframe, temppts);
    39213920                    if (d->HasMPEG2Dec() && mpa_pic.data[3])
    3922                         context->release_buffer(context, &mpa_pic);
     3921                        ctx->release_buffer(ctx, &mpa_pic);
    39233922
    39243923                    decoded_video_frame = picframe;
    39253924                    gotvideo = 1;
     
    39753974                }
    39763975                default:
    39773976                {
    3978                     AVCodecContext *enc = curstream->codec;
    39793977                    VERBOSE(VB_IMPORTANT, LOC_ERR +
    39803978                            QString("Decoding - id(%1) type(%2)")
    3981                             .arg(codec_id_string(enc->codec_id))
    3982                             .arg(codec_type_string(enc->codec_type)));
     3979                            .arg(codec_id_string(ctx->codec_id))
     3980                            .arg(codec_type_string(ctx->codec_type)));
    39833981                    have_err = true;
    39843982                    break;
    39853983                }
     
    41284126    }
    41294127}
    41304128
     4129bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx)
     4130{
     4131    bool do_ac3_passthru =
     4132        (allow_ac3_passthru && !transcoding &&
     4133        (ctx->codec_id == CODEC_ID_AC3));
     4134    bool do_dts_passthru =
     4135        (allow_dts_passthru && !transcoding &&
     4136        (ctx->codec_id == CODEC_ID_DTS));
     4137    bool using_passthru = do_ac3_passthru || do_dts_passthru;
     4138
     4139    if (!isAC3upmix)
     4140        return using_passthru;
     4141
     4142    bool passthru = false;
     4143
     4144    if (ctx->codec_id == CODEC_ID_AC3)
     4145        passthru = allow_ac3_passthru &&
     4146                   ctx->channels >= (int)max_channels;
     4147    else if (ctx->codec_id == CODEC_ID_DTS)
     4148        passthru = allow_dts_passthru;
     4149   
     4150    passthru &= !transcoding && !disable_passthru;
     4151    // Don't know any cards that support spdif clocked at < 44100
     4152    // Some US cable transmissions have 2ch 32k AC-3 streams
     4153    passthru &= ctx->sample_rate >= 44100;
     4154
     4155    return passthru;
     4156}
     4157
    41314158/** \fn AvFormatDecoder::SetupAudioStream(void)
    41324159 *  \brief Reinitializes audio if it needs to be reinitialized.
    41334160 *
     
    41554182        codec_ctx = curstream->codec;
    41564183        if (codec_ctx)
    41574184        {
    4158             bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    4159                                     (codec_ctx->codec_id == CODEC_ID_AC3));
    4160             bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    4161                                     (codec_ctx->codec_id == CODEC_ID_DTS));
    4162             using_passthru = do_ac3_passthru || do_dts_passthru;
    4163             info = AudioInfo(codec_ctx->codec_id,
    4164                              codec_ctx->sample_rate, codec_ctx->channels,
    4165                              using_passthru && !disable_passthru);
     4185            using_passthru = DoPassThrough(codec_ctx);
     4186            if (!isAC3upmix)
     4187                info = AudioInfo(codec_ctx->codec_id,
     4188                                 codec_ctx->sample_rate, codec_ctx->channels,
     4189                                 using_passthru && !disable_passthru);
     4190            else
     4191                info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate,
     4192                                codec_ctx->channels, using_passthru);
    41664193        }
    41674194    }
    41684195
     
    41794206            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    41804207
    41814208    audioOut = audioIn = info;
     4209
     4210    if (!isAC3upmix) {
    41824211    AudioInfo tmpAudioOut = audioOut;
    41834212
    41844213    // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
     
    42144243
    42154244    // allow the audio stuff to reencode
    42164245    GetNVP()->SetAudioCodec((using_passthru) ? codec_ctx : NULL);
     4246    } else {
     4247    if (!using_passthru && audioOut.channels > (int)max_channels)
     4248    {
     4249        audioOut.channels = (int)max_channels;
     4250        audioOut.sample_size = audioOut.channels * 2;
     4251        codec_ctx->channels = audioOut.channels;
     4252    }
     4253
     4254    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
     4255            QString("\n\t\t\tfrom %1 to %2")
     4256            .arg(old_in.toString()).arg(audioOut.toString()));
     4257
     4258    if (audioOut.sample_rate > 0)
     4259        GetNVP()->SetEffDsp(audioOut.sample_rate * 100);
     4260
     4261    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
     4262                             audioOut.sample_rate, audioOut.do_passthru);
     4263
     4264    }
    42174265    GetNVP()->ReinitAudio();
    42184266
    42194267    return true;
  • trunk/mythtv/libs/libmythtv/tv_play.h

     
    415415        ARBSEEK_FORWARD,
    416416        ARBSEEK_END
    417417    };
     418   
    418419    void DoArbSeek(PlayerContext*, ArbSeekWhence whence);
    419420    void NormalSpeed(PlayerContext*);
    420421    void ChangeSpeed(PlayerContext*, int direction);
     
    423424    bool TimeStretchHandleAction(PlayerContext*,
    424425                                 const QStringList &actions);
    425426
     427    void ToggleUpmix(PlayerContext*);
    426428    void ChangeAudioSync(PlayerContext*, int dir, bool allowEdit = true);
    427429    bool AudioSyncHandleAction(PlayerContext*, const QStringList &actions);
    428430
  • trunk/mythtv/libs/libmythtv/NuppelVideoPlayer.h

     
    182182    // Toggle Sets
    183183    void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle);
    184184    void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle);
     185    bool GetisAC3upmix(void);
     186    bool ToggleUpmix(void);
    185187
    186188    // Gets
    187189    QSize   GetVideoBufferSize(void) const    { return video_dim; }
  • trunk/mythtv/libs/libmythtv/tv_play.cpp

     
    491491    REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down");
    492492    REG_KEY("TV Playback", "VOLUMEUP",   "Volume up",   "],},F11,Volume Up");
    493493    REG_KEY("TV Playback", "MUTE",       "Mute",        "|,\\,F9,Volume Mute");
     494    REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U");
    494495    REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture view",
    495496            "V");
    496497    REG_KEY("TV Playback", "TOGGLEPBPMODE", "Toggle Picture-by-Picture view",
     
    630631  Teletext     F2,F3,F4,F5,F6,F7,F8
    631632  ITV          F2,F3,F4,F5,F6,F7,F12
    632633
    633   Playback: Ctrl-B,Ctrl-G,Ctrl-Y
     634  Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U
    634635*/
    635636}
    636637
     
    43454346        DoTogglePictureAttribute(ctx, kAdjustingPicture_Playback);
    43464347    else if (has_action("TOGGLESTRETCH", actions))
    43474348        ToggleTimeStretch(ctx);
     4349    else if (has_action("TOGGLEUPMIX", actions))
     4350        ToggleUpmix(ctx);
    43484351    else if (has_action("TOGGLESLEEP", actions))
    43494352        ToggleSleepTimer(ctx);
    43504353    else if (has_action("TOGGLERECORD", actions) && islivetv)
     
    79937996    SetSpeedChangeTimer(0, __LINE__);
    79947997}
    79957998
     7999void TV::ToggleUpmix(PlayerContext *ctx)
     8000{
     8001    if (!ctx->nvp || !ctx->nvp->HasAudioOut())
     8002        return;
     8003    QString text;
     8004    if(!ctx->nvp->GetisAC3upmix()) {
     8005        text = tr("Upmixer disabled !");
     8006    } else {
     8007        if (ctx->nvp->ToggleUpmix())
     8008            text = tr("Upmixer On");
     8009        else
     8010            text = tr("Upmixer Off");
     8011    }
     8012
     8013    if (ctx->nvp->GetOSD() && !browsemode)
     8014        ctx->nvp->GetOSD()->SetSettingsText(text, 5);
     8015}
     8016   
    79968017// dir in 10ms jumps
    79978018void TV::ChangeAudioSync(PlayerContext *ctx, int dir, bool allowEdit)
    79988019{
     
    96069627        SetManualZoom(actx, true, tr("Zoom Mode ON"));
    96079628    else if (action == "TOGGLESTRETCH")
    96089629        ToggleTimeStretch(actx);
     9630    else if (action == "TOGGLEUPMIX")
     9631        ToggleUpmix(actx);
    96099632    else if (action.left(13) == "ADJUSTSTRETCH")
    96109633    {
    96119634        bool floatRead;
     
    99739996
    99749997    if (category == "AUDIOSYNC")
    99759998        new OSDGenericTree(treeMenu, tr("Adjust Audio Sync"), "TOGGLEAUDIOSYNC");
     9999    else if ((category == "TOGGLEUPMIX") && ctx->nvp && ctx->nvp->GetisAC3upmix())
     10000        new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX");
    997610001    else if (category == "TIMESTRETCH")
    997710002        FillMenuTimeStretch(ctx, treeMenu);
    997810003    else if (category == "VIDEOSCAN")
  • trunk/mythtv/libs/libmythtv/tvosdmenuentry.cpp

     
    232232    curMenuEntries.append(
    233233        new TVOSDMenuEntry("AUDIOSYNC",           1, 1, 1, 1 , "Audio Sync"));
    234234    curMenuEntries.append(
     235        new TVOSDMenuEntry("TOGGLEUPMIX",        1, 1, 1, 1, "Toggle Upmixer"));
     236    curMenuEntries.append(
    235237        new TVOSDMenuEntry("TIMESTRETCH",        1, 1, 1, 1, "Time Stretch"));
    236238    curMenuEntries.append(
    237239        new TVOSDMenuEntry("VIDEOSCAN",            1, 1, 1, 1, "Video Scan"));
  • trunk/mythtv/libs/libmythtv/avformatdecoder.h

     
    200200
    201201    void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames);
    202202
     203    bool DoPassThrough(const AVCodecContext *ctx);
    203204    bool SetupAudioStream(void);
    204205    void SetupAudioStreamSubIndexes(int streamIndex);
    205206    void RemoveAudioStreams();
     
    272273    bool              allow_dts_passthru;
    273274    bool              disable_passthru;
    274275    uint              max_channels;
     276    uint              last_ac3_channels;
     277    bool              isAC3upmix;
    275278
    276279    VideoFrame       *dummy_frame;
    277280
  • trunk/mythtv/libs/libmythsamplerate/samplerate.c

     
    452452        {       len -- ;
    453453
    454454                scaled_value = in [len] * (8.0 * 0x10000000) ;
    455                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
     455                if (scaled_value >= (1.0 * 0x7FFFFFFF))
    456456                {       out [len] = 32767 ;
    457457                        continue ;
    458458                        } ;
    459                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
     459                if (scaled_value <= (-8.0 * 0x10000000))
    460460                {       out [len] = -32768 ;
    461461                        continue ;
    462462                        } ;
  • trunk/mythtv/libs/libmyth/audiosettings.cpp

     
    1616    set_initial_vol(false),
    1717    use_passthru(false),
    1818    codec(NULL),
    19     source(AUDIOOUTPUT_UNKNOWN)
     19    source(AUDIOOUTPUT_UNKNOWN),
     20    isAC3upmix(false)
    2021{
    2122}
    2223
     
    2930    set_initial_vol(other.set_initial_vol),
    3031    use_passthru(other.use_passthru),
    3132    codec(other.codec),
    32     source(other.source)
     33    source(other.source),
     34    isAC3upmix(other.isAC3upmix)
    3335{
    3436}
    3537
     
    4244    AudioOutputSource audio_source,
    4345    bool audio_set_initial_vol,
    4446    bool audio_use_passthru,
    45     void *audio_codec) :
     47    void *audio_codec,
     48    bool AC3upmix) :
    4649    main_device(audio_main_device),
    4750    passthru_device(audio_passthru_device),
    4851    bits(audio_bits),
     
    5154    set_initial_vol(audio_set_initial_vol),
    5255    use_passthru(audio_use_passthru),
    5356    codec(audio_codec),
    54     source(audio_source)
     57    source(audio_source),
     58    isAC3upmix(AC3upmix)
    5559{
    5660}
    5761
     
    6064    int   audio_channels,
    6165    int   audio_samplerate,
    6266    bool  audio_use_passthru,
    63     void *audio_codec) :
     67    void *audio_codec,
     68    bool  AC3upmix) :
    6469    main_device(QString::null),
    6570    passthru_device(QString::null),
    6671    bits(audio_bits),
     
    6974    set_initial_vol(false),
    7075    use_passthru(audio_use_passthru),
    7176    codec(audio_codec),
    72     source(AUDIOOUTPUT_UNKNOWN)
     77    source(AUDIOOUTPUT_UNKNOWN),
     78    isAC3upmix(AC3upmix)
    7379{
    7480}
    7581
  • trunk/mythtv/libs/libmyth/audiooutputbase.h

     
    4343
    4444    virtual void SetStretchFactor(float factor);
    4545    virtual float GetStretchFactor(void) const;
     46    virtual bool ToggleUpmix(void);
    4647
    4748    virtual void Reset(void);
    4849
     
    132133    QString audio_passthru_device;
    133134
    134135    bool audio_passthru;
     136    bool audio_enc;
     137    bool audio_reenc;
    135138
    136139    float audio_stretchfactor;
    137140    AVCodecContext *audio_codec;
     
    144147    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    145148
    146149    int configured_audio_channels;
     150    int orig_config_channels;
     151    int src_quality;
    147152
    148153 private:
    149154    // resampler
     
    156161    FreeSurround              *upmixer;
    157162
    158163    int source_audio_channels;
     164    int source_audio_samplerate;
    159165    int source_audio_bytes_per_sample;
    160166    bool needs_upmix;
    161167    int surround_mode;
     168    bool allow_ac3_passthru;
     169    float old_audio_stretchfactor;
    162170
    163171    bool blocking; // do AddSamples calls block?
    164172
  • trunk/mythtv/libs/libmyth/audiooutputalsa.cpp

     
    3232AudioOutputALSA::~AudioOutputALSA()
    3333{
    3434    KillAudio();
     35    if (isAC3upmix)
     36        SetIECStatus(true);
    3537}
    3638
     39void AudioOutputALSA::SetIECStatus(bool audio) {
     40   
     41    snd_ctl_t *ctl;
     42    const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT);
     43    int spdif_index = -1;
     44    snd_ctl_elem_list_t *clist;
     45    snd_ctl_elem_id_t *cid;
     46    snd_ctl_elem_value_t *cval;
     47    snd_aes_iec958_t iec958;
     48    int cidx, controls;
     49
     50    VERBOSE(VB_AUDIO, QString("Setting IEC958 status: %1")
     51                      .arg(audio ? "audio" : "non-audio"));
     52   
     53    snd_ctl_open(&ctl, "default", 0);
     54    snd_ctl_elem_list_alloca(&clist);
     55    snd_ctl_elem_list(ctl, clist);
     56    snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist));
     57    snd_ctl_elem_list(ctl, clist);
     58    controls = snd_ctl_elem_list_get_used(clist);
     59    for (cidx = 0; cidx < controls; cidx++) {
     60        if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str))
     61            if (spdif_index < 0 ||
     62                snd_ctl_elem_list_get_index(clist, cidx) == (uint)spdif_index)
     63                    break;
     64    }
     65
     66    if (cidx >= controls)
     67        return;
     68
     69    snd_ctl_elem_id_alloca(&cid);
     70    snd_ctl_elem_list_get_id(clist, cidx, cid);
     71    snd_ctl_elem_value_alloca(&cval);
     72    snd_ctl_elem_value_set_id(cval, cid);
     73    snd_ctl_elem_read(ctl,cval);
     74    snd_ctl_elem_value_get_iec958(cval, &iec958);
     75   
     76    if (!audio)
     77        iec958.status[0] |= IEC958_AES0_NONAUDIO;
     78    else
     79        iec958.status[0] &= ~IEC958_AES0_NONAUDIO;
     80
     81    snd_ctl_elem_value_set_iec958(cval, &iec958);
     82    snd_ctl_elem_write(ctl, cval);
     83
     84}
     85
    3786bool AudioOutputALSA::OpenDevice()
    3887{
    3988    snd_pcm_format_t format;
    4089    unsigned int buffer_time, period_time;
    4190    int err;
     91    QString real_device;
    4292
    4393    if (pcm_handle != NULL)
    4494        CloseDevice();
    4595
    4696    pcm_handle = NULL;
    4797    numbadioctls = 0;
     98   
     99    if (!isAC3upmix) {
     100        real_device = (audio_passthru) ?
     101            audio_passthru_device : audio_main_device;
     102    }
     103    else
     104        if (audio_passthru || audio_enc)
     105        {
     106            real_device = audio_passthru_device;
     107            SetIECStatus(false);
     108        }
     109        else
     110        {
     111            real_device = audio_main_device;
     112            SetIECStatus(true);
     113        }
    48114
    49     QString real_device = (audio_passthru) ?
    50         audio_passthru_device : audio_main_device;
    51 
    52115    VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.")
    53116            .arg(real_device));
    54117
  • trunk/mythtv/libs/libmyth/audiooutputbase.cpp

     
    2828
    2929    audio_main_device(settings.GetMainDevice()),
    3030    audio_passthru_device(settings.GetPassthruDevice()),
    31     audio_passthru(false),      audio_stretchfactor(1.0f),
     31    audio_passthru(false),      audio_enc(false),
     32    audio_reenc(false),         audio_stretchfactor(1.0f),
    3233
    3334    audio_codec(NULL),
    3435    source(settings.source),    killaudio(false),
     
    4748    pSoundStretch(NULL),
    4849    encoder(NULL),
    4950    upmixer(NULL),
     51
    5052    source_audio_channels(-1),
     53    source_audio_samplerate(0),
    5154    source_audio_bytes_per_sample(0),
    5255    needs_upmix(false),
    5356    surround_mode(FreeSurround::SurroundModePassive),
     57    old_audio_stretchfactor(1.0),
    5458
    5559    blocking(false),
    5660
     
    7983    memset(&audiotime_updated, 0, sizeof(audiotime_updated));
    8084    memset(audiobuffer,        0, sizeof(char)  * kAudioRingBufferSize);
    8185    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
     86    orig_config_channels = configured_audio_channels;
     87    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
     88    src_quality = gContext->GetNumSetting("SRCQuality", 3);
     89    isAC3upmix = settings.isAC3upmix;
    8290
    8391    // You need to call Reconfigure from your concrete class.
    8492    // Reconfigure(laudio_bits,       laudio_channels,
     
    110118void AudioOutputBase::SetStretchFactorLocked(float laudio_stretchfactor)
    111119{
    112120    effdspstretched = (int)((float)effdsp / laudio_stretchfactor);
    113     if ((audio_stretchfactor != laudio_stretchfactor) ||  !pSoundStretch)
     121    if ((audio_stretchfactor != laudio_stretchfactor) || !pSoundStretch)
    114122    {
    115123        audio_stretchfactor = laudio_stretchfactor;
    116124        if (pSoundStretch)
     
    124132            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
    125133                                        .arg(audio_stretchfactor));
    126134            pSoundStretch = new soundtouch::SoundTouch();
    127             if (audio_codec)
    128             {
    129                 if (!encoder)
     135            if (!isAC3upmix) {
     136                if (audio_codec)
    130137                {
    131                     VERBOSE(VB_AUDIO, LOC +
    132                             QString("Creating Encoder for codec %1 origfs %2")
    133                             .arg(audio_codec->codec_id)
    134                             .arg(audio_codec->frame_size));
    135 
    136                     encoder = new AudioOutputDigitalEncoder();
    137                     if (!encoder->Init(audio_codec->codec_id,
    138                                 audio_codec->bit_rate,
    139                                 audio_codec->sample_rate,
    140                                 audio_codec->channels
    141                                 ))
     138                    if (!encoder)
    142139                    {
    143                         // eeks
    144                         delete encoder;
    145                         encoder = NULL;
    146140                        VERBOSE(VB_AUDIO, LOC +
    147                                 QString("Failed to Create Encoder"));
     141                                QString("Creating Encoder for codec %1 origfs %2")
     142                                .arg(audio_codec->codec_id)
     143                                .arg(audio_codec->frame_size));
     144
     145                        encoder = new AudioOutputDigitalEncoder(isAC3upmix);
     146                        if (!encoder->Init(audio_codec->codec_id,
     147                                    audio_codec->bit_rate,
     148                                    audio_codec->sample_rate,
     149                                    audio_codec->channels
     150                                    ))
     151                        {
     152                            // eeks
     153                            delete encoder;
     154                            encoder = NULL;
     155                            VERBOSE(VB_AUDIO, LOC +
     156                                    QString("Failed to Create Encoder"));
     157                        }
    148158                    }
    149159                }
    150             }
    151             if (audio_codec && encoder)
    152             {
    153                 pSoundStretch->setSampleRate(audio_codec->sample_rate);
    154                 pSoundStretch->setChannels(audio_codec->channels);
    155             }
    156             else
    157             {
     160                if (audio_codec && encoder)
     161                {
     162                    pSoundStretch->setSampleRate(audio_codec->sample_rate);
     163                    pSoundStretch->setChannels(audio_codec->channels);
     164                }
     165                else
     166                {
     167                    pSoundStretch->setSampleRate(audio_samplerate);
     168                    pSoundStretch->setChannels(audio_channels);
     169                }
     170            } else {
    158171                pSoundStretch->setSampleRate(audio_samplerate);
    159                 pSoundStretch->setChannels(audio_channels);
     172                pSoundStretch->setChannels(upmixer ?
     173                    configured_audio_channels : source_audio_channels);
    160174            }
    161 
    162175            pSoundStretch->setTempo(audio_stretchfactor);
    163176            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
    164177
    165178            // dont need these with only tempo change
    166179            //pSoundStretch->setPitch(1.0);
    167180            //pSoundStretch->setRate(1.0);
    168 
    169181            //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true);
    170182            //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false);
    171183        }
     
    183195    return audio_stretchfactor;
    184196}
    185197
     198bool AudioOutputBase::ToggleUpmix(void)
     199{
     200    if (orig_config_channels == 2 || audio_passthru)
     201        return false;
     202    if (configured_audio_channels == 6)
     203        configured_audio_channels = 2;
     204    else
     205        configured_audio_channels = 6;
     206
     207    const AudioSettings settings(audio_bits, source_audio_channels,
     208                            source_audio_samplerate, audio_passthru);
     209    Reconfigure(settings);
     210    return (configured_audio_channels == 6);
     211}
     212
     213
    186214void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
    187215{
    188216    AudioSettings settings = orig_settings;
     
    193221    int cchannels = 0;
    194222    int lsource_audio_channels = settings.channels;
    195223    bool lneeds_upmix = false;
     224    bool laudio_reenc = false;
    196225
    197     if (settings.codec)
    198     {
    199         lcodec_id = ((AVCodecContext*)settings.codec)->codec_id;
    200         settings.bits = 16;
    201         settings.channels = 2;
    202         lsource_audio_channels = settings.channels;
    203         settings.samplerate = 48000;
    204         lcchannels = ((AVCodecContext*)settings.codec)->channels;
    205     }
     226    if (!isAC3upmix) {
     227        if (settings.codec)
     228        {
     229            lcodec_id = ((AVCodecContext*)settings.codec)->codec_id;
     230            settings.bits = 16;
     231            settings.channels = 2;
     232            lsource_audio_channels = settings.channels;
     233            settings.samplerate = 48000;
     234            lcchannels = ((AVCodecContext*)settings.codec)->channels;
     235        }
    206236
    207     if (audio_codec)
    208     {
    209         codec_id = audio_codec->codec_id;
    210         cchannels = ((AVCodecContext*)audio_codec)->channels;
    211     }
     237        if (audio_codec)
     238        {
     239            codec_id = audio_codec->codec_id;
     240            cchannels = ((AVCodecContext*)audio_codec)->channels;
     241        }
    212242
    213     if ((configured_audio_channels == 6) &&
    214         !(settings.codec || audio_codec))
    215     {
    216         settings.channels = configured_audio_channels;
    217         lneeds_upmix = true;
    218         VERBOSE(VB_AUDIO,LOC + "Needs upmix");
     243        if ((configured_audio_channels == 6) &&
     244            !(settings.codec || audio_codec))
     245        {
     246            settings.channels = configured_audio_channels;
     247            lneeds_upmix = true;
     248            VERBOSE(VB_AUDIO,LOC + "Needs upmix");
     249        }
     250    } else { //AC3 Upmix
     251        // Are we reencoding a (previously) timestretched bitstream?
     252        if (settings.channels > 2 && !settings.use_passthru)
     253            laudio_reenc = true;
     254
     255        // Enough channels? Upmix if not
     256        if (settings.channels < configured_audio_channels &&
     257            !settings.use_passthru)
     258        {
     259            settings.channels = configured_audio_channels;
     260            lneeds_upmix = true;
     261            VERBOSE(VB_AUDIO,LOC + "Needs upmix");
     262        }
    219263    }
    220264
    221265    ClearError();
     
    224268        settings.samplerate == audio_samplerate && !need_resampler &&
    225269        settings.use_passthru == audio_passthru &&
    226270        lneeds_upmix == needs_upmix &&
    227         lcodec_id == codec_id && lcchannels == cchannels);
     271        (isAC3upmix ? (laudio_reenc == audio_reenc) : (lcodec_id == codec_id && lcchannels == cchannels))
     272        );
    228273    bool upmix_deps =
    229274        (lsource_audio_channels == source_audio_channels);
    230275    if (general_deps && upmix_deps)
     
    255300    audio_channels = settings.channels;
    256301    source_audio_channels = lsource_audio_channels;
    257302    audio_bits = settings.bits;
    258     audio_samplerate = settings.samplerate;
    259     audio_codec = (AVCodecContext*)settings.codec;
     303    if (!isAC3upmix) {
     304        audio_samplerate = settings.samplerate;
     305        audio_codec = (AVCodecContext*)settings.codec;
     306    } else {
     307        source_audio_samplerate = audio_samplerate = settings.samplerate;
     308        audio_reenc = laudio_reenc;
     309    }
    260310    audio_passthru = settings.use_passthru;
    261311    needs_upmix = lneeds_upmix;
    262312
     
    265315        Error("AudioOutput only supports 8 or 16bit audio.");
    266316        return;
    267317    }
    268     audio_bytes_per_sample = audio_channels * audio_bits / 8;
    269     source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    270318
    271319    need_resampler = false;
    272320    killaudio = false;
     
    275323    internal_vol = gContext->GetNumSetting("MythControlsVolume", 0);
    276324
    277325    numlowbuffer = 0;
     326   
     327    if (!isAC3upmix) {
     328    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     329    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
     330    } else {
     331    // Encode to AC-3 if not passing thru, there's more than 2 channels
     332    // and we're allowed to passthru AC-3
     333    if (!audio_passthru && audio_channels > 2 && allow_ac3_passthru)
     334    {
     335        VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder");
     336        int srate = src_quality == 0 ? audio_samplerate : 48000;
     337        encoder = new AudioOutputDigitalEncoder();
     338        if (!encoder->Init(CODEC_ID_AC3, 448000, srate,
     339                           configured_audio_channels, audio_reenc))
     340        {
     341            VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder");
     342            delete encoder;
     343            encoder = NULL;
     344        }
     345       
     346        audio_enc = true;
     347    }       
     348   
     349    if(audio_passthru || audio_enc)
     350        // AC-3 output - soundcard expects a 2ch 48k stream
     351        audio_channels = 2;
     352   
     353    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     354    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    278355
     356    // Always resample to 48k - many cards can't do anything else
     357    // and ALSA will do it with linear interpolation (yuk) if we don't anyway
     358    if (src_quality != 0 && audio_samplerate != 48000)
     359    {
     360        int error;
     361        audio_samplerate = 48000;
     362        VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")
     363            .arg(settings.samplerate).arg(audio_samplerate));
     364        src_ctx = src_new(3-src_quality, audio_channels, &error);
     365        if (error)
     366        {
     367            Error(QString("Error creating resampler, the error was: %1")
     368                  .arg(src_strerror(error)) );
     369            src_ctx = NULL;
     370            return;
     371        }
     372        src_data.src_ratio = (double) audio_samplerate / settings.samplerate;
     373        src_data.data_in = src_in;
     374        src_data.data_out = src_out;
     375        src_data.output_frames = 16384*6;
     376        need_resampler = true;
     377    }
     378    }
    279379    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
    280380            .arg(audio_main_device).arg(audio_channels)
    281381            .arg(source_audio_channels).arg(audio_samplerate));
     
    309409    current_seconds = -1;
    310410    source_bitrate = -1;
    311411
     412    if (!isAC3upmix) {
    312413    // NOTE: this won't do anything as above samplerate vars are set equal
    313414    // Check if we need the resampler
    314415    if (audio_samplerate != settings.samplerate)
     
    329430        src_data.output_frames = 16384*6;
    330431        need_resampler = true;
    331432    }
    332 
     433    }
    333434    if (needs_upmix)
    334435    {
    335436        VERBOSE(VB_AUDIO, LOC + QString("create upmixer"));
     
    341442        upmixer = new FreeSurround(
    342443            audio_samplerate,
    343444            source == AUDIOOUTPUT_VIDEO,
    344             (FreeSurround::SurroundMode)surround_mode);
     445            (FreeSurround::SurroundMode)surround_mode,isAC3upmix);
    345446
    346447        VERBOSE(VB_AUDIO, LOC +
    347448                QString("create upmixer done with surround mode %1")
     
    350451
    351452    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    352453            .arg(audio_stretchfactor));
    353     VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
    354             .arg((audio_codec) ?
     454    if (!isAC3upmix) {
     455        VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     456                .arg((audio_codec) ?
    355457                 codec_id_string(audio_codec->codec_id) : "not set"));
    356458
    357     if (redo_stretch)
    358     {
    359         delete pSoundStretch;
    360         pSoundStretch = NULL;
    361         SetStretchFactorLocked(audio_stretchfactor);
    362     }
    363     else
    364     {
    365         SetStretchFactorLocked(audio_stretchfactor);
    366         if (pSoundStretch)
     459        if (redo_stretch)
    367460        {
    368             // if its passthru then we need to reencode
    369             if (audio_codec)
     461            delete pSoundStretch;
     462            pSoundStretch = NULL;
     463            SetStretchFactorLocked(audio_stretchfactor);
     464        }
     465        else
     466        {
     467            SetStretchFactorLocked(audio_stretchfactor);
     468            if (pSoundStretch)
    370469            {
    371                 if (!encoder)
     470                // if its passthru then we need to reencode
     471                if (audio_codec)
    372472                {
    373                     VERBOSE(VB_AUDIO, LOC +
    374                             QString("Creating Encoder for codec %1")
    375                             .arg(audio_codec->codec_id));
     473                    if (!encoder)
     474                    {
     475                        VERBOSE(VB_AUDIO, LOC +
     476                                QString("Creating Encoder for codec %1")
     477                                .arg(audio_codec->codec_id));
    376478
    377                     encoder = new AudioOutputDigitalEncoder();
    378                     if (!encoder->Init(audio_codec->codec_id,
    379                                 audio_codec->bit_rate,
    380                                 audio_codec->sample_rate,
    381                                 audio_codec->channels
    382                                 ))
    383                     {
    384                         // eeks
    385                         delete encoder;
    386                         encoder = NULL;
    387                         VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");
     479                        encoder = new AudioOutputDigitalEncoder(isAC3upmix);
     480                        if (!encoder->Init(audio_codec->codec_id,
     481                                    audio_codec->bit_rate,
     482                                    audio_codec->sample_rate,
     483                                    audio_codec->channels
     484                                    ))
     485                        {
     486                            // eeks
     487                            delete encoder;
     488                            encoder = NULL;
     489                            VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");
     490                        }
    388491                    }
    389492                }
     493                if (audio_codec && encoder)
     494                {
     495                    pSoundStretch->setSampleRate(audio_codec->sample_rate);
     496                    pSoundStretch->setChannels(audio_codec->channels);
     497                }
     498                else
     499                {
     500                    pSoundStretch->setSampleRate(audio_samplerate);
     501                    pSoundStretch->setChannels(audio_channels);
     502                }
    390503            }
    391             if (audio_codec && encoder)
    392             {
    393                 pSoundStretch->setSampleRate(audio_codec->sample_rate);
    394                 pSoundStretch->setChannels(audio_codec->channels);
    395             }
    396             else
    397             {
    398                 pSoundStretch->setSampleRate(audio_samplerate);
    399                 pSoundStretch->setChannels(audio_channels);
    400             }
    401504        }
     505    } else {
     506        SetStretchFactorLocked(old_audio_stretchfactor);
    402507    }
    403 
    404508    // Setup visualisations, zero the visualisations buffers
    405509    prepareVisuals();
    406510
     
    437541    killaudio = true;
    438542    StopOutputThread();
    439543
     544    if (isAC3upmix)
     545        QMutexLocker lock1(&audio_buflock);
     546
    440547    // Close resampler?
    441     if (src_ctx)
     548    if (src_ctx) {
    442549        src_delete(src_ctx);
     550        if (isAC3upmix)
     551            src_ctx = NULL;
     552    }
    443553    need_resampler = false;
    444554
    445555    // close sound stretcher
     
    447557    {
    448558        delete pSoundStretch;
    449559        pSoundStretch = NULL;
     560        if (isAC3upmix) {
     561            old_audio_stretchfactor = audio_stretchfactor;
     562            audio_stretchfactor = 1.0;
     563        }
    450564    }
    451565
    452566    if (encoder)
     
    461575        upmixer = NULL;
    462576    }
    463577    needs_upmix = false;
     578    if (isAC3upmix)
     579        audio_enc = false;
    464580
    465581    CloseDevice();
    466582
     
    612728    // include algorithmic latencies
    613729    if (pSoundStretch)
    614730    {
    615         // add the effect of any unused but processed samples,
    616         // AC3 reencode does this
    617         totalbuffer += (int)(pSoundStretch->numSamples() *
    618                              audio_bytes_per_sample);
     731        if (!isAC3upmix) {
     732            // add the effect of any unused but processed samples,
     733            // AC3 reencode does this
     734            totalbuffer += (int)(pSoundStretch->numSamples() *
     735                                 audio_bytes_per_sample);
     736        }
    619737        // add the effect of unprocessed samples in time stretch algo
    620738        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    621739                              audio_bytes_per_sample) / audio_stretchfactor);
     
    626744        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
    627745    }
    628746
     747    if (isAC3upmix && encoder)
     748        totalbuffer += encoder->Buffered();
     749
    629750    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    630751                                   (audio_bytes_per_sample * effdspstretched));
    631752
     
    681802        return false; // would overflow
    682803    }
    683804
     805    if (isAC3upmix)
     806        QMutexLocker lock1(&audio_buflock);
     807
    684808    // resample input if necessary
    685809    if (need_resampler && src_ctx)
    686810    {
     
    725849    int abps = (encoder) ?
    726850        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
    727851    int len = samples * abps;
     852   
     853    if (isAC3upmix) {
     854        // Give original samples to mythmusic visualisation
     855        dispatchVisual((unsigned char *)buffer, len, timecode,
     856                       source_audio_channels, audio_bits);
     857    }
    728858
    729859    // Check we have enough space to write the data
    730860    if (need_resampler && src_ctx)
     
    749879        return false; // would overflow
    750880    }
    751881
     882    if (isAC3upmix)
     883        QMutexLocker lock1(&audio_buflock);
     884
    752885    // resample input if necessary
    753886    if (need_resampler && src_ctx)
    754887    {
     
    808941            if (src_ctx)
    809942            {
    810943                int error = src_reset(src_ctx);
    811                 if (error)
     944                if (error)
     945                {
    812946                    VERBOSE(VB_IMPORTANT, LOC_ERR + QString(
    813947                            "Error occured while resetting resampler: %1")
    814948                            .arg(src_strerror(error)));
     949                    if (isAC3upmix)
     950                        src_ctx = NULL;
     951                }
    815952            }
    816953        }
    817954    }
     
    821958void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples,
    822959                                  long long timecode)
    823960{
    824     audio_buflock.lock();
     961    if (!isAC3upmix)
     962        audio_buflock.lock();
    825963
    826964    int len; // = samples * audio_bytes_per_sample;
    827965    int audio_bytes = audio_bits / 8;
     
    839977            .arg(samples * abps)
    840978            .arg(kAudioRingBufferSize-afree).arg(afree).arg(timecode)
    841979            .arg(needs_upmix));
    842 
     980   
     981    if (isAC3upmix)
     982        len = WaitForFreeSpace(samples);
     983       
    843984    if (upmixer && needs_upmix)
    844985    {
    845986        int out_samples = 0;
    846987        int step = (interleaved)?source_audio_channels:1;
    847         len = WaitForFreeSpace(samples);    // test
     988       
     989        if (!isAC3upmix) {
     990            len = WaitForFreeSpace(samples);
     991        }
    848992        for (int itemp = 0; itemp < samples; )
    849993        {
    850994            // just in case it does a processing cycle, release the lock
    851995            // to allow the output loop to do output
    852             audio_buflock.unlock();
     996            if (!isAC3upmix)
     997                audio_buflock.unlock();
    853998            if (audio_bytes == 2)
    854999            {
    8551000                itemp += upmixer->putSamples(
     
    8661011                    source_audio_channels,
    8671012                    (interleaved) ? 0 : samples);
    8681013            }
    869             audio_buflock.lock();
     1014            if (!isAC3upmix)
     1015                audio_buflock.lock();
    8701016
    8711017            int copy_samples = upmixer->numSamples();
    8721018            if (copy_samples)
     
    9001046    }
    9011047    else
    9021048    {
    903         len = WaitForFreeSpace(samples);
    904 
     1049        if (!isAC3upmix)
     1050            len = WaitForFreeSpace(samples);
    9051051        if (interleaved)
    9061052        {
    9071053            char *mybuf = (char*)buffer;
     
    9361082        }
    9371083    }
    9381084
     1085    if (!isAC3upmix) {
    9391086    if (samples > 0)
    9401087    {
    9411088        if (pSoundStretch)
     
    9931140                        continue;
    9941141
    9951142                    //len = WaitForFreeSpace(amount);
    996                     char *ob = encoder->GetOutBuff();
     1143                    const char *ob = encoder->GetOutBuff();
    9971144                    if (amount >= bdiff)
    9981145                    {
    9991146                        memcpy(audiobuffer + org_waud, ob, bdiff);
     
    10681215    }
    10691216
    10701217    audio_buflock.unlock();
     1218    } else {
     1219    if (samples <= 0)
     1220        return;
     1221       
     1222    if (pSoundStretch)
     1223    {
     1224        // does not change the timecode, only the number of samples
     1225        // back to orig pos
     1226        org_waud = waud;
     1227        int bdiff = kAudioRingBufferSize - org_waud;
     1228        int nSamplesToEnd = bdiff/abps;
     1229        if (bdiff < len)
     1230        {
     1231            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     1232                                      (audiobuffer +
     1233                                       org_waud), nSamplesToEnd);
     1234            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
     1235                                      (len - bdiff) / abps);
     1236        }
     1237        else
     1238            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     1239                                      (audiobuffer + org_waud),
     1240                                      len / abps);
     1241
     1242        int nSamples = pSoundStretch->numSamples();
     1243        len = WaitForFreeSpace(nSamples);
     1244       
     1245        while ((nSamples = pSoundStretch->numSamples()))
     1246        {
     1247            if (nSamples > nSamplesToEnd)
     1248                nSamples = nSamplesToEnd;
     1249           
     1250            nSamples = pSoundStretch->receiveSamples(
     1251                (soundtouch::SAMPLETYPE*)
     1252                (audiobuffer + org_waud), nSamples
     1253            );
     1254           
     1255            if (nSamples == nSamplesToEnd) {
     1256                org_waud = 0;
     1257                nSamplesToEnd = kAudioRingBufferSize/abps;
     1258            }
     1259            else {
     1260                org_waud += nSamples * abps;
     1261                nSamplesToEnd -= nSamples;
     1262            }
     1263           
     1264        }
     1265       
     1266    }
     1267
     1268    // Encode to AC-3?
     1269    if (encoder)
     1270    {
     1271       
     1272        org_waud = waud;
     1273        int bdiff = kAudioRingBufferSize - org_waud;
     1274        int to_get = 0;
     1275
     1276        if (bdiff < len)
     1277        {
     1278            encoder->EncodeUpmix(audiobuffer + org_waud, bdiff);
     1279            to_get = encoder->EncodeUpmix(audiobuffer, len - bdiff);
     1280        }
     1281        else
     1282            to_get = encoder->EncodeUpmix(audiobuffer + org_waud, len);
     1283       
     1284        if (to_get > 0)
     1285        {
     1286           
     1287            if (to_get >= bdiff)
     1288            {
     1289                encoder->GetFrames(audiobuffer + org_waud, bdiff);
     1290                to_get -= bdiff;
     1291                org_waud = 0;
     1292            }
     1293            if (to_get > 0)
     1294                encoder->GetFrames(audiobuffer + org_waud, to_get);
     1295
     1296            org_waud += to_get;
     1297
     1298        }
     1299
     1300    }
     1301
     1302    waud = org_waud;
     1303    lastaudiolen = audiolen(false);
     1304
     1305    if (timecode < 0)
     1306        // mythmusic doesn't give timestamps..
     1307        timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1308
     1309    samples_buffered += samples;
     1310
     1311    /* we want the time at the end -- but the file format stores
     1312       time at the start of the chunk. */
     1313    // even with timestretch, timecode is still calculated from original
     1314    // sample count
     1315    audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
     1316    } // End AC3 upmiz
    10711317}
    10721318
    10731319void AudioOutputBase::Status()
  • trunk/mythtv/libs/libmyth/audiooutput.cpp

     
    3535    const QString &passthru_device,
    3636    int audio_bits, int audio_channels, int audio_samplerate,
    3737    AudioOutputSource source,
    38     bool set_initial_vol, bool audio_passthru)
     38    bool set_initial_vol, bool audio_passthru, bool AC3upmix)
    3939{
    4040    AudioSettings settings(
    4141        main_device, passthru_device, audio_bits,
    4242        audio_channels, audio_samplerate, source,
    43         set_initial_vol, audio_passthru);
     43        set_initial_vol, audio_passthru, NULL, AC3upmix);
    4444
    4545    settings.FixPassThrough();
    4646
  • trunk/mythtv/libs/libmyth/audiosettings.h

     
    3333        AudioOutputSource audio_source,
    3434        bool              audio_set_initial_vol,
    3535        bool              audio_use_passthru,
    36         void             *audio_codec = NULL);
     36        void             *audio_codec = NULL,
     37        bool              AC3upmix = false);
    3738
    3839    AudioSettings(int   audio_bits,
    3940                  int   audio_channels,
    4041                  int   audio_samplerate,
    4142                  bool  audio_use_passthru,
    42                   void *audio_codec = NULL);
     43                  void *audio_codec = NULL,
     44                  bool  AC3upmix = false);
    4345
    4446    void FixPassThrough(void);
    4547    void TrimDeviceType(void);
     
    5961    bool    use_passthru;
    6062    void   *codec;
    6163    AudioOutputSource source;
     64    bool    isAC3upmix;
    6265};
    6366
    6467#endif // _AUDIO_SETTINGS_H_
  • trunk/mythtv/libs/libmyth/audiooutputdigitalencoder.cpp

     
    2929AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) :
    3030    audio_bytes_per_sample(0),
    3131    av_context(NULL),
    32     outbuf(NULL),
    33     outbuf_size(0),
    3432    frame_buffer(NULL),
    35     one_frame_bytes(0)
     33    one_frame_bytes(0),
     34    outbuflen(0),
     35    inbuflen(0),
     36    reorder(true),
     37    isAC3upmix(false)
    3638{
    3739}
    3840
     41AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(bool AC3upmix) :
     42    audio_bytes_per_sample(0),
     43    av_context(NULL),
     44    frame_buffer(NULL),
     45    one_frame_bytes(0),
     46    outbuflen(0),
     47    inbuflen(0),
     48    reorder(true),
     49    isAC3upmix(AC3upmix)
     50{
     51}
     52
    3953AudioOutputDigitalEncoder::~AudioOutputDigitalEncoder()
    4054{
    4155    Dispose();
     
    5064        av_context = NULL;
    5165    }
    5266
    53     if (outbuf)
     67    if (!isAC3upmix && frame_buffer)
    5468    {
    55         delete [] outbuf;
    56         outbuf = NULL;
    57         outbuf_size = 0;
    58     }
    59 
    60     if (frame_buffer)
    61     {
    6269        delete [] frame_buffer;
    6370        frame_buffer = NULL;
    6471        one_frame_bytes = 0;
     
    6774
    6875//CODEC_ID_AC3
    6976bool AudioOutputDigitalEncoder::Init(
    70     CodecID codec_id, int bitrate, int samplerate, int channels)
     77    CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding)
    7178{
    7279    AVCodec *codec;
    7380    int ret;
    7481
    75     VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4")
     82    VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 re=%5")
    7683            .arg(codec_id_string(codec_id))
    7784            .arg(bitrate)
    7885            .arg(samplerate)
    79             .arg(channels));
     86            .arg(channels)
     87            .arg(reencoding));
     88   
     89    reorder = !reencoding;
    8090
     91    // We need to do this when called from mythmusic
     92    if (isAC3upmix) {
     93        avcodec_init();
     94        avcodec_register_all();
     95    }
    8196    //codec = avcodec_find_encoder(codec_id);
    8297    // always AC3 as there is no DTS encoder at the moment 2005/1/9
    8398    codec = avcodec_find_encoder(CODEC_ID_AC3);
     
    107122    audio_bytes_per_sample = bytes_per_frame;
    108123    one_frame_bytes = bytes_per_frame * av_context->frame_size;
    109124
    110     outbuf_size = 16384;    // ok for AC3 but DTS?
    111     outbuf = new char [outbuf_size];
    112125    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3")
    113126            .arg(av_context->frame_size)
    114127            .arg(bytes_per_frame)
     
    253266
    254267} AESHeader;
    255268
     269void reorder_6ch_ac3(void *buf, unsigned int len) {
     270    unsigned short *src = (unsigned short *)buf;
     271    unsigned short tmp;
     272    unsigned int samples = len >> 1;
     273
     274    for (uint i = 0; i < samples; i += 6) {
     275        tmp = src[i+4];
     276        src[i+4] = src[i+3];
     277        src[i+3] = src[i+2];
     278        src[i+2] = src[i+1];
     279        src[i+1] = tmp;
     280    }
     281}
     282
    256283static int encode_frame(
    257284        bool dts,
    258285        unsigned char *data,
    259         size_t &len)
     286        size_t &len, bool AC3upmix)
    260287{
    261288    unsigned char *payload = data + 8;  // skip header, currently 52 or 54bits
    262     size_t         enc_len;
     289    size_t enc_len = len;
    263290    int            flags, sample_rate, bit_rate;
    264291
    265292    // we don't do any length/crc validation of the AC3 frame here; presumably
     
    270297    // ignore, and if so, may as well just assume that it will ignore
    271298    // anything with a bad CRC...
    272299
    273     uint nr_samples = 0, block_len;
     300    uint nr_samples = 0, block_len = 0;
     301   
    274302    if (dts)
    275303    {
    276304        enc_len = dts_syncinfo(payload, &flags, &sample_rate, &bit_rate);
     
    305333#endif
    306334    }
    307335
    308     if (enc_len == 0 || enc_len > len)
     336    if (!AC3upmix && (enc_len == 0 || enc_len > len))
    309337    {
    310338        int l = len;
    311339        len = 0;
     
    364392    data[6] = (enc_len << 3) & 0xFF;
    365393    data[7] = (enc_len >> 5) & 0xFF;
    366394    memset(payload + enc_len, 0, block_len - 8 - enc_len);
    367     len = block_len;
     395    if (!AC3upmix)
     396        len = block_len;
    368397
    369398    return enc_len;
    370399}
     
    377406 
    378407    // put data in the correct spot for encode frame
    379408    outsize = avcodec_encode_audio(
    380         av_context, ((uchar*)outbuf) + 8, outbuf_size - 8, buff);
     409        av_context, ((uchar*)outbuf) + 8, OUTBUFSIZE - 8, buff);
    381410
    382411    size_t tmpsize = outsize;
    383412
    384413    outsize = MAX_AC3_FRAME_SIZE;
    385414    encsize = encode_frame(
    386415        /*av_context->codec_id==CODEC_ID_DTS*/ false,
    387         (unsigned char*)outbuf, outsize);
     416        (unsigned char*)outbuf, outsize, false);
    388417
    389418    VERBOSE(VB_AUDIO+VB_TIMESTAMP,
    390419            QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3")
     
    392421
    393422    return outsize;
    394423}
     424
     425size_t AudioOutputDigitalEncoder::EncodeUpmix(void *buf, int len)
     426{
     427    size_t outsize = 0;
     428 
     429    int fs = FrameSize();
     430    memcpy(inbuf+inbuflen, buf, len);
     431    inbuflen += len;
     432    int frames = inbuflen / fs;
     433
     434    while (frames--)
     435    {
     436        if (reorder)
     437            reorder_6ch_ac3(inbuf, fs);
     438       
     439        // put data in the correct spot for encode frame
     440        outsize = avcodec_encode_audio(
     441            av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf);
     442       
     443        encode_frame(
     444            /*av_context->codec_id==CODEC_ID_DTS*/ false,
     445            (unsigned char*)outbuf + outbuflen, outsize, true
     446        );
     447
     448        outbuflen += MAX_AC3_FRAME_SIZE;
     449        inbuflen -= fs;
     450        memmove(inbuf, inbuf+fs, inbuflen);
     451    }
     452 
     453    return outbuflen;
     454}
     455
     456void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen)
     457{
     458    int len = (maxlen < outbuflen ? maxlen : outbuflen);
     459    memcpy(ptr, outbuf, len);
     460    outbuflen -= len;
     461    memmove(outbuf, outbuf+len, outbuflen);
     462}
  • trunk/mythtv/libs/libmyth/audiooutput.h

     
    1717        const QString &passthrudevice,
    1818        int audio_bits, int audio_channels, int audio_samplerate,
    1919        AudioOutputSource source,
    20         bool set_initial_vol, bool audio_passthru);
     20        bool set_initial_vol, bool audio_passthru, bool AC3upmix=false);
    2121
    2222    AudioOutput() :
    2323        VolumeBase(),             OutputListeners(),
     24        isAC3upmix(false),
    2425        lastError(QString::null), lastWarn(QString::null) {}
    2526
    2627    virtual ~AudioOutput() { };
     
    6970    virtual void bufferOutputData(bool y) = 0;
    7071    virtual int readOutputData(unsigned char *read_buffer, int max_length) = 0;
    7172
     73    // Audio AC3 Upmixer
     74    virtual bool ToggleUpmix(void) = 0;
     75    bool isAC3upmix;
     76
    7277  protected:
    7378    void Error(const QString &msg);
    7479    void Warn(const QString &msg);
  • trunk/mythtv/libs/libmyth/audiooutputdigitalencoder.h

     
    55#include "libavcodec/avcodec.h"
    66};
    77
     8#define INBUFSIZE 131072
     9#define OUTBUFSIZE 98304
     10
    811class AudioOutputDigitalEncoder
    912{
    1013  public:
    1114    AudioOutputDigitalEncoder(void);
     15    AudioOutputDigitalEncoder(bool AC3upmix);
    1216    ~AudioOutputDigitalEncoder();
    1317
    14     bool   Init(CodecID codec_id, int bitrate, int samplerate, int channels);
     18    bool   Init(CodecID codec_id, int bitrate, int samplerate,
     19                int channels, bool reencoding = false);
    1520    void   Dispose(void);
    1621    size_t Encode(short * buff);
    1722
    1823    inline char *GetFrameBuffer(void);
    1924    size_t FrameSize(void)  const { return one_frame_bytes; }
    20     char  *GetOutBuff(void) const { return outbuf;          }
     25    const char  *GetOutBuff(void) const { return outbuf; }
     26    //AC3 upmix
     27    size_t EncodeUpmix(void *buf, int len);
     28    void   GetFrames(void *ptr, int maxlen);
     29    int    Buffered(void) const { return inbuflen; }
    2130
    2231  public:
    2332    size_t audio_bytes_per_sample;
    2433
    2534  private:
    2635    AVCodecContext *av_context;
    27     char           *outbuf;
    28     int             outbuf_size;
     36    char            outbuf[OUTBUFSIZE];
    2937    char           *frame_buffer;
    3038    size_t          one_frame_bytes;
     39    // AC3 upmix
     40    char            inbuf[INBUFSIZE];
     41    int             outbuflen;
     42    int             inbuflen;
     43    bool            reorder;
     44    bool            isAC3upmix;
    3145};
    3246
    3347inline char *AudioOutputDigitalEncoder::GetFrameBuffer(void)
  • trunk/mythtv/libs/libmyth/audiooutputalsa.h

     
    6767    virtual int  GetBufferedOnSoundcard(void) const;
    6868
    6969  private:
     70    void SetIECStatus(bool audio);
    7071    inline int SetParameters(snd_pcm_t *handle,
    7172                             snd_pcm_format_t format, unsigned int channels,
    7273                             unsigned int rate, unsigned int buffer_time,
  • trunk/mythtv/libs/libmythfreesurround/el_processor.cpp

     
    4040
    4141const float PI = 3.141592654;
    4242const float epsilon = 0.000001;
     43const float center_level_upmix = 0.5*sqrt(0.5);
    4344//const float center_level = 0.5*sqrt(0.5);   // gain of the center channel
    4445//const float center_level = sqrt(0.5);   // gain of the center channel
    4546const float center_level = 1.0;   // gain of the center channel
     
    5758public:
    5859    // create an instance of the decoder
    5960    //  blocksize is fixed over the lifetime of this object for performance reasons
    60     decoder_impl(unsigned blocksize=8192): N(blocksize), halfN(blocksize/2) {
     61  decoder_impl(unsigned blocksize=8192, bool AC3upmix=false): N(blocksize), halfN(blocksize/2), isAC3upmix(AC3upmix) {
    6162#ifdef USE_FFTW3
    6263        // create FFTW buffers
    6364        lt = (float*)fftwf_malloc(sizeof(float)*N);
     
    99100            filter[c].resize(N);
    100101        }
    101102        // DC component of filters is always 0
    102         for (unsigned c=0;c<5;c++)
    103         {
    104             filter[c][0] = 0.0;
    105             filter[c][1] = 0.0;
    106             filter[c][halfN] = 0.0;
     103        if (!isAC3upmix) {
     104            for (unsigned c=0;c<5;c++)
     105            {
     106                filter[c][0] = 0.0;
     107                filter[c][1] = 0.0;
     108                filter[c][halfN] = 0.0;
     109            }
     110            sample_rate(48000);
     111            // generate the window function (square root of hann, b/c it is applied before and after the transform)
     112            wnd.resize(N);
     113            // dft normalization included in the window for zero cost scaling
     114            // also add a gain factor of *2 due to processing gain in algo (see center_level)
     115            surround_gain(1.0);
     116        } else {
     117            sample_rate(48000);
     118            // generate the window function (square root of hann, b/c it is applied before and after the transform)
     119            wnd.resize(N);
     120            for (unsigned k=0;k<N;k++)
     121                wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N);
    107122        }
    108         sample_rate(48000);
    109         // generate the window function (square root of hann, b/c it is applied before and after the transform)
    110         wnd.resize(N);
    111         // dft normalization included in the window for zero cost scaling
    112         // also add a gain factor of *2 due to processing gain in algo (see center_level)
    113         surround_gain(1.0);
    114123        current_buf = 0;
    115124        // set the default coefficients
    116125        surround_coefficients(0.8165,0.5774);
     
    192201    // set lfe filter params
    193202    void sample_rate(unsigned int srate) {
    194203        // lfe filter is just straight through band limited
    195         unsigned int cutoff = (250*N)/srate;
    196         for (unsigned f=0;f<=halfN;f++) {           
    197             if ((f>=2) && (f<cutoff))
    198                 filter[5][f] = 1.0;
    199             else
    200                 filter[5][f] = 0.0;
     204        unsigned int cutoff;
     205        if (!isAC3upmix) {
     206             cutoff = (250*N)/srate;
     207            for (unsigned f=0;f<=halfN;f++) {           
     208                if ((f>=2) && (f<cutoff))
     209                    filter[5][f] = 1.0;
     210                else
     211                    filter[5][f] = 0.0;
     212            }
     213        } else {
     214            cutoff = (30*N)/srate;
     215            for (unsigned f=0;f<=halfN;f++) {           
     216                if (f<cutoff)
     217                    filter[5][f] = 0.5*sqrt(0.5);
     218                else
     219                    filter[5][f] = 0.0;
     220            }
    201221        }
    202222    }
    203223
     
    237257    }
    238258
    239259private:
     260    bool isAC3upmix;
    240261    // polar <-> cartesian coodinates conversion
    241262    static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); }
    242263    static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); }
     
    290311
    291312        // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field
    292313        //    but dont do DC or N/2 component
    293         for (unsigned f=2;f<halfN;f++) {           
     314        unsigned start_f = isAC3upmix ? 0:2;
     315        for (unsigned f=start_f;f<halfN;f++) {           
    294316            // get left/right amplitudes/phases
    295317            float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]);
    296318            float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]);
     
    357379                float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
    358380                float volume[5] = {
    359381                    front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),  // left
    360                     front * center_level*((1-abs(xfs[f])) * (1-center_width)),          // center
     382                    front * (isAC3upmix ? center_level_upmix : center_level) *((1-abs(xfs[f])) * (1-center_width)),          // center
    361383                    front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right
    362384                    back * surround_level * left,                                       // left surround
    363385                    back * surround_level * right                                       // right surround
     
    402424                float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
    403425                float volume[5] = {
    404426                    front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),      // left
    405                     front * center_level*((1-abs(xfs[f])) * (1-center_width)),              // center
     427                    front * (isAC3upmix ? center_level_upmix : center_level) *((1-abs(xfs[f])) * (1-center_width)),          // center
    406428                    front * (right * center_width + max(0, xfs[f]) * (1-center_width)),     // right
    407429                    back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))),  // left surround
    408430                    back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2)))   // right surround
     
    613635
    614636// implementation of the shell class
    615637
    616 fsurround_decoder::fsurround_decoder(unsigned blocksize): impl(new decoder_impl(blocksize)) { }
     638fsurround_decoder::fsurround_decoder(unsigned blocksize, bool AC3upmix): impl(new decoder_impl(blocksize,AC3upmix)) { }
    617639
    618640fsurround_decoder::~fsurround_decoder() { delete impl; }
    619641
  • trunk/mythtv/libs/libmythfreesurround/freesurround.cpp

     
    6363const unsigned default_block_size = 8192;
    6464// there will be a slider for this in the future
    6565//const float master_gain = 1.0;
    66 //#define MASTER_GAIN * master_gain
     66//#define MASTER_GAIN * master_gain 
    6767#define MASTER_GAIN
    6868//const float master_gain = 1.0/(1<<15);
    6969//const float inv_master_gain = (1<<15);
     
    163163
    164164// construction methods
    165165void *new_decoder() { return new fsurround_decoder(block_size); }
     166void *new_decoder_upmix() { return new fsurround_decoder(block_size,true); }
    166167void *new_buffers() { return new buffers(block_size/2); }
    167168void *new_int16buffers() { return new int16buffers(block_size/2); }
    168169
    169170object_pool dp(&new_decoder);
     171object_pool dp_upmix(&new_decoder_upmix);
    170172//object_pool bp(&new_buffers);
    171173object_pool bp16(&new_int16buffers);
    172174
     
    175177int channel_select = -1;
    176178#endif
    177179
    178 FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode) :
     180FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode, bool AC3upmix) :
    179181        srate(srate),
    180182        open_(false),
    181183        initialized_(false),
     
    186188        out_count(0),
    187189        processed(true),
    188190        processed_size(0),
    189         surround_mode(smode)
     191        surround_mode(smode),
     192        isAC3upmix(AC3upmix)
    190193{
    191194    VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode));
    192195    if (moviemode)
    193196    {
    194197        params.phasemode = 1;
    195         params.center_width = 0;
    196         params.gain = 1.0;
     198        if (!isAC3upmix) {
     199            params.center_width = 0;
     200            params.gain = 1.0;
     201        } else {
     202            params.center_width = 25;
     203            params.dimension = 0.5;
     204        }
    197205    }
    198206    else
    199207    {
    200         params.center_width = 70;
    201         // for 50, gain should be about 1.9, c/lr about 2.7
    202         // for 70, gain should be about 3.1, c/lr about 1.5
    203         params.gain = 3.1;
     208        if (!isAC3upmix) {
     209            params.center_width = 70;
     210            // for 50, gain should be about 1.9, c/lr about 2.7
     211            // for 70, gain should be about 3.1, c/lr about 1.5
     212            params.gain = 3.1;
     213        } else {
     214            params.center_width = 65;
     215            params.dimension = 0.3;
     216        }
    204217    }
    205218    switch (surround_mode)
    206219    {
     
    236249        decoder->phase_mode(params.phasemode);
    237250        decoder->surround_coefficients(params.coeff_a, params.coeff_b);                         
    238251        decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
    239         decoder->gain(params.gain);
     252        if (!isAC3upmix)
     253            decoder->gain(params.gain);
    240254    }
    241255}
    242256
     
    655669    {
    656670        if (decoder)
    657671        {
    658             // actually these params need only be set when they change... but it doesn't hurt
    659 #if 0
    660             decoder->steering_mode(params.steering);
    661             decoder->phase_mode(params.phasemode);
    662             decoder->surround_coefficients(params.coeff_a, params.coeff_b);                             
    663             decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
    664 #endif
    665             // decode the bufs->block
    666             //decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0);
    667             //decoder->decode(output,params.center_width/100.0,params.dimension/100.0);
    668672            decoder->decode(params.center_width/100.0,params.dimension/100.0);
    669673        }
    670674    }
     
    694698{               
    695699    if (!decoder)
    696700    {
    697         decoder = (fsurround_decoder*)dp.acquire((void*)1);
     701        if (!isAC3upmix)
     702            decoder = (fsurround_decoder*)dp.acquire((void*)1);
     703        else
     704            decoder = (fsurround_decoder*)dp_upmix.acquire((void*)1);
    698705        decoder->flush();
    699706        //if (bufs)
    700707        //    bufs->clear();
     
    709716{
    710717    if (decoder)
    711718    {
    712         dp.release(this);
     719        if (!isAC3upmix)
     720            dp.release(this);
     721        else
     722            dp_upmix.release(this);
    713723        decoder = 0;
    714724    }
    715725}
  • trunk/mythtv/libs/libmythfreesurround/el_processor.h

     
    2424public:
    2525        // create an instance of the decoder
    2626        //  blocksize is fixed over the lifetime of this object for performance reasons
    27         fsurround_decoder(unsigned blocksize=8192);
     27        fsurround_decoder(unsigned blocksize=8192, bool AC3upmix=false);
    2828        // destructor
    2929        ~fsurround_decoder();
    3030       
     
    5151        void gain(float gain);
    5252
    5353        // set the phase shifting mode for decoding
    54         // 0 = (+0°,+0°)   - music mode
    55         // 1 = (+0°,+180°) - PowerDVD compatibility
    56         // 2 = (+180°,+0°) - BeSweet compatibility
    57         // 3 = (-90°,+90°) - This seems to work. I just don't know why.
     54        // 0 = (+0,+0)   - music mode
     55        // 1 = (+0,+180) - PowerDVD compatibility
     56        // 2 = (+180,+0) - BeSweet compatibility
     57        // 3 = (-90,+90) - This seems to work. I just don't know why.
    5858        void phase_mode(unsigned mode);
    5959
    6060        // override the steering mode
     
    7171
    7272private:
    7373        class decoder_impl *impl; // private implementation (details hidden)
     74        bool isAC3upmix;
    7475};
    7576
    7677
  • trunk/mythtv/libs/libmythfreesurround/freesurround.h

     
    3131        SurroundModeActiveLinear
    3232    } SurroundMode;
    3333public:
    34     FreeSurround(uint srate, bool moviemode, SurroundMode mode);
     34    FreeSurround(uint srate, bool moviemode, SurroundMode mode, bool AC3upmix=false);
    3535    ~FreeSurround();
    3636
    3737    // put samples in buffer, returns number of samples used
     
    8888    bool processed;             // whether processing is enabled or not for latency calc
    8989    int processed_size;         // amount processed
    9090    SurroundMode surround_mode; // 1 of 3 surround modes supported
     91    bool isAC3upmix;
    9192
    9293};
    9394
  • trunk/mythtv/programs/mythfrontend/globalsettings.cpp

     
    119119    return gc;
    120120}
    121121
     122static HostCheckBox *AC3Upmix()
     123{
     124    HostCheckBox *gc = new HostCheckBox("MythAC3Upmix");
     125    gc->setLabel(QObject::tr("AC3 audio upmixer"));
     126    gc->setValue(false);
     127    gc->setHelpText(QObject::tr("Enable AC3 upmixer and digital software volume control."));
     128    return gc;
     129}
     130
     131static HostComboBox *SRCQuality()
     132{
     133    HostComboBox *gc = new HostComboBox("SRCQuality", false);
     134    gc->setLabel(QObject::tr("Sample Rate Conversion"));
     135    gc->addSelection(QObject::tr("Best"), "3", true); // default
     136    gc->addSelection(QObject::tr("Medium"), "2");
     137    gc->addSelection(QObject::tr("Fastest"), "1");
     138    gc->addSelection(QObject::tr("Disabled"), "0");
     139    gc->setHelpText(
     140            QObject::tr(
     141                "Set the quality of audio sample rate conversion. "
     142                "This only affects non 48000Hz PCM audio. "
     143                "All three options offer a worst-case SNR of 97dB. "
     144                "'Best' at a bandwidth of 97%. "
     145                "'Medium' at a bandwidth of 90%. "
     146                "'Fastest' at a bandwidth of 80%. "
     147                "Set 'Disabled' only if you know what you are doing."));
     148    return gc;
     149}
     150
     151
    122152static HostComboBox *PassThroughOutputDevice()
    123153{
    124154    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
     
    34313461    return gs;
    34323462}
    34333463
    3434 class AudioSystemSettingsGroup : public VerticalConfigurationGroup
     3464class AudioSystemSettingsGroup : public TriggeredConfigurationGroup
    34353465{
    34363466  public:
    34373467    AudioSystemSettingsGroup() :
    3438         VerticalConfigurationGroup(false, true, false, false)
     3468        TriggeredConfigurationGroup(false, true, false, false)
    34393469    {
    34403470        setLabel(QObject::tr("Audio System"));
    34413471        setUseLabel(false);
     
    34503480        addChild(AC3PassThrough());
    34513481        addChild(DTSPassThrough());
    34523482        addChild(AggressiveBuffer());
     3483
     3484        Setting* ac3upmix = AC3Upmix();
     3485        addChild(ac3upmix);
     3486        setTrigger(ac3upmix);
     3487        addTarget("1", SRCQuality());
     3488        addTarget("0", new VerticalConfigurationGroup(false,false));
     3489
    34533490    }
    34543491};
    34553492
  • trunk/mythtv/programs/mythtranscode/transcode.cpp

     
    222222        // Do nothing
    223223        return kMuteOff;
    224224    }
     225    virtual bool ToggleUpmix(void)
     226    {
     227        // Do nothing
     228        return false;
     229    }
    225230
    226231    //  These are pure virtual in AudioOutput, but we don't need them here
    227232    virtual void bufferOutputData(bool){ return; }