Ticket #5900: audioencoding-trunk-jya14.patch
File audioencoding-trunk-jya14.patch, 90.1 KB (added by , 15 years ago) |
---|
-
trunk/mythplugins/mythmusic/mythmusic/playbackbox.cpp
367 367 changeSpeed(true); 368 368 else if (action == "MUTE") 369 369 toggleMute(); 370 else if (action == "TOGGLEUPMIX") 371 toggleUpmix(); 370 372 else if (action == "MENU" && visualizer_status != 2) 371 373 { 372 374 menufilters = false; … … 1202 1204 } 1203 1205 } 1204 1206 1207 void PlaybackBoxMusic::toggleUpmix() 1208 { 1209 if (gPlayer->getOutput()) 1210 gPlayer->getOutput()->ToggleUpmix(); 1211 } 1212 1213 1205 1214 void PlaybackBoxMusic::showProgressBar() 1206 1215 { 1207 1216 if (progress_bar && visualizer_status != 2) -
trunk/mythplugins/mythmusic/mythmusic/main.cpp
367 367 REG_KEY("Music", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 368 368 REG_KEY("Music", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 369 369 REG_KEY("Music", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 370 REG_KEY("Music", "TOGGLEUPMIX","Toggle upmixer", "Ctrl+U"); 370 371 REG_KEY("Music", "CYCLEVIS", "Cycle visualizer mode", "6"); 371 372 REG_KEY("Music", "BLANKSCR", "Blank screen", "5"); 372 373 REG_KEY("Music", "THMBUP", "Increase rating", "9"); -
trunk/mythplugins/mythmusic/mythmusic/musicplayer.cpp
348 348 349 349 void MusicPlayer::openOutputDevice(void) 350 350 { 351 QString adevice; 351 QString adevice, pdevice; 352 bool isAC3upmix = gContext->GetNumSetting("MythAC3Upmix", 0); 352 353 353 354 if (gContext->GetSetting("MusicAudioDevice") == "default") 354 355 adevice = gContext->GetSetting("AudioOutputDevice"); 355 356 else 356 357 adevice = gContext->GetSetting("MusicAudioDevice"); 357 358 359 if (!isAC3upmix) 360 pdevice = "default"; 361 else 362 pdevice = gContext->GetSetting("PassThruOutputDevice"); 363 358 364 // TODO: Error checking that device is opened correctly! 359 m_output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100,360 AUDIOOUTPUT_MUSIC, true, false);365 m_output = AudioOutput::OpenAudio(adevice, pdevice, 16, 2, 44100, 366 AUDIOOUTPUT_MUSIC, true, false, isAC3upmix); 361 367 m_output->setBufferSize(256 * 1024); 362 368 m_output->SetBlocking(false); 363 369 -
trunk/mythplugins/mythmusic/mythmusic/playbackbox.h
69 69 void changeVolume(bool up_or_down); 70 70 void changeSpeed(bool up_or_down); 71 71 void toggleMute(); 72 void toggleUpmix(); 72 73 void resetTimer(); 73 74 void hideVolume(){showVolume(false);} 74 75 void showVolume(bool on_or_off); -
trunk/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
868 868 869 869 no_audio_in = false; 870 870 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 871 879 if (!audioOutput && !using_null_videoout && player_ctx->IsAudioNeeded()) 872 880 { 873 881 bool setVolume = gContext->GetNumSetting("MythControlsVolume", 1); … … 876 884 audio_bits, audio_channels, 877 885 audio_samplerate, 878 886 AUDIOOUTPUT_VIDEO, 879 setVolume, audio_passthru );887 setVolume, audio_passthru, isAC3upmix); 880 888 if (!audioOutput) 881 889 errMsg = QObject::tr("Unable to create AudioOutput."); 882 890 else … … 906 914 audio_bits, audio_channels, audio_samplerate, 907 915 audio_passthru, audio_codec); 908 916 audioOutput->Reconfigure(settings); 917 if (audioOutput->isAC3upmix && audio_passthru) 918 audio_channels = 2; 909 919 errMsg = audioOutput->GetError(); 910 920 if (!errMsg.isEmpty()) 911 921 audioOutput->SetStretchFactor(audio_stretchfactor); … … 5274 5284 } 5275 5285 } 5276 5286 5287 bool NuppelVideoPlayer::GetisAC3upmix() 5288 { 5289 if (audioOutput) 5290 return audioOutput->isAC3upmix; 5291 return false; 5292 } 5293 5294 bool NuppelVideoPlayer::ToggleUpmix() 5295 { 5296 if (audioOutput) 5297 return audioOutput->ToggleUpmix(); 5298 return false; 5299 } 5300 5277 5301 void NuppelVideoPlayer::Zoom(ZoomDirection direction) 5278 5302 { 5279 5303 if (videoOutput) -
trunk/mythtv/libs/libmythtv/avformatdecoder.cpp
430 430 audioSamples(NULL), 431 431 allow_ac3_passthru(false), allow_dts_passthru(false), 432 432 disable_passthru(false), max_channels(2), 433 dummy_frame(NULL),433 last_ac3_channels(0), dummy_frame(NULL), 434 434 // DVD 435 435 lastdvdtitle(-1), 436 436 decodeStillFrame(false), … … 451 451 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 452 452 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 453 453 max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2); 454 isAC3upmix = gContext->GetNumSetting("MythAC3Upmix", 0); 454 455 455 456 audioIn.sample_size = -32; // force SetupAudioStream to run once 456 457 itv = GetNVP()->GetInteractiveTV(); … … 2975 2976 { 2976 2977 int idx = atracks[i].av_stream_index; 2977 2978 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));2984 2979 AudioInfo item(codec_ctx->codec_id, 2985 2980 codec_ctx->sample_rate, codec_ctx->channels, 2986 do_ac3_passthru || do_dts_passthru);2981 DoPassThrough(codec_ctx)); 2987 2982 VERBOSE(VB_AUDIO, LOC + " * " + item.toString()); 2988 2983 } 2989 2984 #endif … … 3117 3112 bool AvFormatDecoder::GetFrame(int onlyvideo) 3118 3113 { 3119 3114 AVPacket *pkt = NULL; 3115 AC3HeaderInfo hdr; 3120 3116 int len; 3121 3117 unsigned char *ptr; 3122 3118 int data_size = 0; … … 3313 3309 pts = 0; 3314 3310 3315 3311 AVStream *curstream = ic->streams[pkt->stream_index]; 3312 AVCodecContext *ctx = curstream->codec; 3316 3313 3317 3314 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3318 3315 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 3319 3316 3320 if (ringBuffer->isDVD() && 3321 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3317 if (ringBuffer->isDVD() && 3318 ctx->codec_type == CODEC_TYPE_VIDEO) 3322 3319 { 3323 3320 MpegPreProcessPkt(curstream, pkt); 3324 3321 … … 3340 3337 3341 3338 if (!d->HasMPEG2Dec()) 3342 3339 { 3343 int current_width = c urstream->codec->width;3340 int current_width = ctx->width; 3344 3341 int video_width = GetNVP()->GetVideoSize().width(); 3345 3342 if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput()) 3346 3343 { … … 3381 3378 } 3382 3379 3383 3380 if (storevideoframes && 3384 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3381 ctx->codec_type == CODEC_TYPE_VIDEO) 3385 3382 { 3386 3383 av_dup_packet(pkt); 3387 3384 storedPackets.append(pkt); … … 3389 3386 continue; 3390 3387 } 3391 3388 3392 if (len > 0 && c urstream->codec->codec_type == CODEC_TYPE_VIDEO &&3389 if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO && 3393 3390 pkt->stream_index == selectedVideoIndex) 3394 3391 { 3395 AVCodecContext *context = curstream->codec;3396 3392 3397 if (c ontext->codec_id == CODEC_ID_MPEG1VIDEO ||3398 c ontext->codec_id == CODEC_ID_MPEG2VIDEO ||3399 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||3400 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||3401 c ontext->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) 3402 3398 { 3403 3399 if (!ringBuffer->isDVD()) 3404 3400 MpegPreProcessPkt(curstream, pkt); 3405 3401 } 3406 else if (c ontext->codec_id == CODEC_ID_H264 ||3407 c ontext->codec_id == CODEC_ID_H264_VDPAU)3402 else if (ctx->codec_id == CODEC_ID_H264 || 3403 ctx->codec_id == CODEC_ID_H264_VDPAU) 3408 3404 { 3409 3405 H264PreProcessPkt(curstream, pkt); 3410 3406 } … … 3449 3445 } 3450 3446 3451 3447 if (len > 0 && 3452 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3453 c urstream->codec->codec_id == CODEC_ID_MPEG2VBI)3448 ctx->codec_type == CODEC_TYPE_DATA && 3449 ctx->codec_id == CODEC_ID_MPEG2VBI) 3454 3450 { 3455 3451 ProcessVBIDataPacket(curstream, pkt); 3456 3452 … … 3459 3455 } 3460 3456 3461 3457 if (len > 0 && 3462 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3463 c urstream->codec->codec_id == CODEC_ID_DVB_VBI)3458 ctx->codec_type == CODEC_TYPE_DATA && 3459 ctx->codec_id == CODEC_ID_DVB_VBI) 3464 3460 { 3465 3461 ProcessDVBDataPacket(curstream, pkt); 3466 3462 … … 3470 3466 3471 3467 #ifdef USING_MHEG 3472 3468 if (len > 0 && 3473 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3474 c urstream->codec->codec_id == CODEC_ID_DSMCC_B)3469 ctx->codec_type == CODEC_TYPE_DATA && 3470 ctx->codec_id == CODEC_ID_DSMCC_B) 3475 3471 { 3476 3472 ProcessDSMCCPacket(curstream, pkt); 3477 3473 … … 3492 3488 #endif // USING_MHEG 3493 3489 3494 3490 // we don't care about other data streams 3495 if (c urstream->codec->codec_type == CODEC_TYPE_DATA)3491 if (ctx->codec_type == CODEC_TYPE_DATA) 3496 3492 { 3497 3493 av_free_packet(pkt); 3498 3494 continue; 3499 3495 } 3500 3496 3501 if (!c urstream->codec->codec)3497 if (!ctx->codec) 3502 3498 { 3503 3499 VERBOSE(VB_PLAYBACK, LOC + 3504 3500 QString("No codec for stream index %1, type(%2) id(%3:%4)") 3505 3501 .arg(pkt->stream_index) 3506 .arg(codec_type_string(c urstream->codec->codec_type))3507 .arg(codec_id_string(c urstream->codec->codec_id))3508 .arg(c urstream->codec->codec_id));3502 .arg(codec_type_string(ctx->codec_type)) 3503 .arg(codec_id_string(ctx->codec_id)) 3504 .arg(ctx->codec_id)); 3509 3505 av_free_packet(pkt); 3510 3506 continue; 3511 3507 } … … 3514 3510 have_err = false; 3515 3511 3516 3512 avcodeclock.lock(); 3517 int ctype = c urstream->codec->codec_type;3513 int ctype = ctx->codec_type; 3518 3514 int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; 3519 3515 int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; 3520 3516 int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; … … 3539 3535 3540 3536 // detect switches between stereo and dual languages 3541 3537 bool wasDual = audSubIdx != -1; 3542 bool isDual = c urstream->codec->avcodec_dual_language;3538 bool isDual = ctx->avcodec_dual_language; 3543 3539 if ((wasDual && !isDual) || (!wasDual && isDual)) 3544 3540 { 3545 3541 SetupAudioStreamSubIndexes(audIdx); 3546 3542 reselectAudioTrack = true; 3547 3543 } 3548 3544 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 3557 3545 // detect channels on streams that need 3558 3546 // to be decoded before we can know this 3559 3547 bool already_decoded = false; 3560 if (!c urstream->codec->channels)3548 if (!ctx->channels) 3561 3549 { 3562 3550 QMutexLocker locker(&avcodeclock); 3563 3551 VERBOSE(VB_IMPORTANT, LOC + 3564 3552 QString("Setting channels to %1") 3565 3553 .arg(audioOut.channels)); 3566 3554 3567 if ( using_passthru)3555 if (DoPassThrough(ctx)) 3568 3556 { 3569 3557 // for passthru let it select the max number 3570 3558 // of channels 3571 c urstream->codec->channels = 0;3572 c urstream->codec->request_channels = 0;3559 ctx->channels = 0; 3560 ctx->request_channels = 0; 3573 3561 } 3574 3562 else 3575 3563 { 3576 c urstream->codec->channels = audioOut.channels;3577 c urstream->codec->request_channels =3564 ctx->channels = audioOut.channels; 3565 ctx->request_channels = 3578 3566 audioOut.channels; 3579 3567 } 3568 3580 3569 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); 3584 3572 already_decoded = true; 3585 3573 3586 reselectAudioTrack |= c urstream->codec->channels;3574 reselectAudioTrack |= ctx->channels; 3587 3575 } 3588 3576 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 3589 3591 if (reselectAudioTrack) 3590 3592 { 3591 3593 QMutexLocker locker(&avcodeclock); … … 3599 3601 .av_stream_index; 3600 3602 audSubIdx = selectedTrack[kTrackTypeAudio] 3601 3603 .av_substream_index; 3604 ctx = curstream->codec; 3602 3605 } 3603 3606 3604 3607 if ((onlyvideo > 0) || (pkt->stream_index != audIdx)) … … 3630 3633 if (audioOut.do_passthru) 3631 3634 { 3632 3635 data_size = pkt->size; 3633 bool dts = CODEC_ID_DTS == c urstream->codec->codec_id;3636 bool dts = CODEC_ID_DTS == ctx->codec_id; 3634 3637 ret = encode_frame(dts, ptr, len, 3635 3638 audioSamples, data_size); 3636 3639 } 3637 3640 else 3638 3641 { 3639 AVCodecContext *ctx = curstream->codec;3640 3641 3642 if ((ctx->channels == 0) || 3642 3643 (ctx->channels > audioOut.channels)) 3643 3644 { … … 3646 3647 3647 3648 if (!already_decoded) 3648 3649 { 3649 curstream->codec->request_channels =3650 audioOut.channels;3651 3650 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, 3653 3653 &data_size, ptr, len); 3654 3654 } 3655 3655 … … 3665 3665 audIdx = -1; 3666 3666 AutoSelectAudioTrack(); 3667 3667 data_size = 0; 3668 ctx = curstream->codec; 3668 3669 } 3669 3670 } 3670 3671 avcodeclock.unlock(); … … 3682 3683 3683 3684 // calc for next frame 3684 3685 lastapts += (long long)((double)(data_size * 1000) / 3685 (curstream->codec->channels * 2) / 3686 curstream->codec->sample_rate); 3686 (ctx->channels * 2) / ctx->sample_rate); 3687 3687 3688 3688 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, 3689 3689 LOC + QString("audio timecode %1 %2 %3 %4") … … 3751 3751 continue; 3752 3752 } 3753 3753 3754 AVCodecContext *context = curstream->codec;3755 3754 AVFrame mpa_pic; 3756 3755 bzero(&mpa_pic, sizeof(AVFrame)); 3757 3756 … … 3766 3765 // HACK 3767 3766 while (!gotpicture && count < 5) 3768 3767 { 3769 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3768 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3770 3769 &gotpicture, ptr, len); 3771 3770 count++; 3772 3771 } 3773 3772 } 3774 3773 else 3775 3774 { 3776 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3775 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3777 3776 &gotpicture, ptr, len); 3778 3777 } 3779 3778 } 3780 3779 else 3781 3780 { 3782 ret = avcodec_decode_video(c ontext, &mpa_pic,3781 ret = avcodec_decode_video(ctx, &mpa_pic, 3783 3782 &gotpicture, ptr, len); 3784 3783 // Reparse it to not drop the DVD still frame 3785 3784 if (decodeStillFrame) 3786 ret = avcodec_decode_video(c ontext, &mpa_pic,3785 ret = avcodec_decode_video(ctx, &mpa_pic, 3787 3786 &gotpicture, ptr, len); 3788 3787 } 3789 3788 avcodeclock.unlock(); … … 3855 3854 #endif 3856 3855 &tmppicture, PIX_FMT_YUV420P, 3857 3856 (AVPicture *)&mpa_pic, 3858 c ontext->pix_fmt,3859 c ontext->width,3860 c ontext->height);3857 ctx->pix_fmt, 3858 ctx->width, 3859 ctx->height); 3861 3860 3862 3861 if (xf) 3863 3862 { … … 3880 3879 (temppts + 10000 > lastvpts || temppts < 0)) 3881 3880 { 3882 3881 temppts = lastvpts; 3883 temppts += (long long)(1000 * av_q2d(c ontext->time_base));3882 temppts += (long long)(1000 * av_q2d(ctx->time_base)); 3884 3883 // MPEG2 frames can be repeated, update pts accordingly 3885 3884 temppts += (long long)(mpa_pic.repeat_pict * 500 3886 * av_q2d(c urstream->codec->time_base));3885 * av_q2d(ctx->time_base)); 3887 3886 } 3888 3887 3889 3888 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + … … 3919 3918 picframe->frameNumber = framesPlayed; 3920 3919 GetNVP()->ReleaseNextVideoFrame(picframe, temppts); 3921 3920 if (d->HasMPEG2Dec() && mpa_pic.data[3]) 3922 c ontext->release_buffer(context, &mpa_pic);3921 ctx->release_buffer(ctx, &mpa_pic); 3923 3922 3924 3923 decoded_video_frame = picframe; 3925 3924 gotvideo = 1; … … 3975 3974 } 3976 3975 default: 3977 3976 { 3978 AVCodecContext *enc = curstream->codec;3979 3977 VERBOSE(VB_IMPORTANT, LOC_ERR + 3980 3978 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))); 3983 3981 have_err = true; 3984 3982 break; 3985 3983 } … … 4128 4126 } 4129 4127 } 4130 4128 4129 bool 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 4131 4158 /** \fn AvFormatDecoder::SetupAudioStream(void) 4132 4159 * \brief Reinitializes audio if it needs to be reinitialized. 4133 4160 * … … 4155 4182 codec_ctx = curstream->codec; 4156 4183 if (codec_ctx) 4157 4184 { 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); 4166 4193 } 4167 4194 } 4168 4195 … … 4179 4206 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4180 4207 4181 4208 audioOut = audioIn = info; 4209 4210 if (!isAC3upmix) { 4182 4211 AudioInfo tmpAudioOut = audioOut; 4183 4212 4184 4213 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card … … 4214 4243 4215 4244 // allow the audio stuff to reencode 4216 4245 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()->SetAudioCodec(codec_ctx); 4262 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 4263 audioOut.sample_rate, audioOut.do_passthru); 4264 4265 } 4217 4266 GetNVP()->ReinitAudio(); 4218 4267 4219 4268 return true; -
trunk/mythtv/libs/libmythtv/tv_play.h
418 418 ARBSEEK_FORWARD, 419 419 ARBSEEK_END 420 420 }; 421 421 422 void DoArbSeek(PlayerContext*, ArbSeekWhence whence); 422 423 void NormalSpeed(PlayerContext*); 423 424 void ChangeSpeed(PlayerContext*, int direction); … … 426 427 bool TimeStretchHandleAction(PlayerContext*, 427 428 const QStringList &actions); 428 429 430 void ToggleUpmix(PlayerContext*); 429 431 void ChangeAudioSync(PlayerContext*, int dir, bool allowEdit = true); 430 432 bool AudioSyncHandleAction(PlayerContext*, const QStringList &actions); 431 433 -
trunk/mythtv/libs/libmythtv/NuppelVideoPlayer.h
182 182 // Toggle Sets 183 183 void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle); 184 184 void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle); 185 bool GetisAC3upmix(void); 186 bool ToggleUpmix(void); 185 187 186 188 // Gets 187 189 QSize GetVideoBufferSize(void) const { return video_dim; } -
trunk/mythtv/libs/libmythtv/tv_play.cpp
491 491 REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 492 492 REG_KEY("TV Playback", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 493 493 REG_KEY("TV Playback", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 494 REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U"); 494 495 REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture view", 495 496 "V"); 496 497 REG_KEY("TV Playback", "TOGGLEPBPMODE", "Toggle Picture-by-Picture view", … … 630 631 Teletext F2,F3,F4,F5,F6,F7,F8 631 632 ITV F2,F3,F4,F5,F6,F7,F12 632 633 633 Playback: Ctrl-B,Ctrl-G,Ctrl-Y 634 Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U 634 635 */ 635 636 } 636 637 … … 4341 4342 DoTogglePictureAttribute(ctx, kAdjustingPicture_Playback); 4342 4343 else if (has_action("TOGGLESTRETCH", actions)) 4343 4344 ToggleTimeStretch(ctx); 4345 else if (has_action("TOGGLEUPMIX", actions)) 4346 ToggleUpmix(ctx); 4344 4347 else if (has_action("TOGGLESLEEP", actions)) 4345 4348 ToggleSleepTimer(ctx); 4346 4349 else if (has_action("TOGGLERECORD", actions) && islivetv) … … 8003 8006 SetSpeedChangeTimer(0, __LINE__); 8004 8007 } 8005 8008 8009 void TV::ToggleUpmix(PlayerContext *ctx) 8010 { 8011 if (!ctx->nvp || !ctx->nvp->HasAudioOut()) 8012 return; 8013 QString text; 8014 if(!ctx->nvp->GetisAC3upmix()) { 8015 text = tr("Upmixer disabled !"); 8016 } else { 8017 if (ctx->nvp->ToggleUpmix()) 8018 text = tr("Upmixer On"); 8019 else 8020 text = tr("Upmixer Off"); 8021 } 8022 8023 if (ctx->nvp->GetOSD() && !browsemode) 8024 ctx->nvp->GetOSD()->SetSettingsText(text, 5); 8025 } 8026 8006 8027 // dir in 10ms jumps 8007 8028 void TV::ChangeAudioSync(PlayerContext *ctx, int dir, bool allowEdit) 8008 8029 { … … 9637 9658 SetManualZoom(actx, true, tr("Zoom Mode ON")); 9638 9659 else if (action == "TOGGLESTRETCH") 9639 9660 ToggleTimeStretch(actx); 9661 else if (action == "TOGGLEUPMIX") 9662 ToggleUpmix(actx); 9640 9663 else if (action.left(13) == "ADJUSTSTRETCH") 9641 9664 { 9642 9665 bool floatRead; … … 9990 10013 9991 10014 if (category == "AUDIOSYNC") 9992 10015 new OSDGenericTree(treeMenu, tr("Adjust Audio Sync"), "TOGGLEAUDIOSYNC"); 10016 else if ((category == "TOGGLEUPMIX") && ctx->nvp && ctx->nvp->GetisAC3upmix()) 10017 new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX"); 9993 10018 else if (category == "TIMESTRETCH") 9994 10019 FillMenuTimeStretch(ctx, treeMenu); 9995 10020 else if (category == "VIDEOSCAN") -
trunk/mythtv/libs/libmythtv/tvosdmenuentry.cpp
232 232 curMenuEntries.append( 233 233 new TVOSDMenuEntry("AUDIOSYNC", 1, 1, 1, 1 , "Audio Sync")); 234 234 curMenuEntries.append( 235 new TVOSDMenuEntry("TOGGLEUPMIX", 1, 1, 1, 1, "Toggle Upmixer")); 236 curMenuEntries.append( 235 237 new TVOSDMenuEntry("TIMESTRETCH", 1, 1, 1, 1, "Time Stretch")); 236 238 curMenuEntries.append( 237 239 new TVOSDMenuEntry("VIDEOSCAN", 1, 1, 1, 1, "Video Scan")); -
trunk/mythtv/libs/libmythtv/avformatdecoder.h
200 200 201 201 void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames); 202 202 203 bool DoPassThrough(const AVCodecContext *ctx); 203 204 bool SetupAudioStream(void); 204 205 void SetupAudioStreamSubIndexes(int streamIndex); 205 206 void RemoveAudioStreams(); … … 272 273 bool allow_dts_passthru; 273 274 bool disable_passthru; 274 275 uint max_channels; 276 uint last_ac3_channels; 277 bool isAC3upmix; 275 278 276 279 VideoFrame *dummy_frame; 277 280 -
trunk/mythtv/libs/libmythsamplerate/samplerate.c
452 452 { len -- ; 453 453 454 454 scaled_value = in [len] * (8.0 * 0x10000000) ; 455 if ( CPU_CLIPS_POSITIVE == 0 &&scaled_value >= (1.0 * 0x7FFFFFFF))455 if (scaled_value >= (1.0 * 0x7FFFFFFF)) 456 456 { out [len] = 32767 ; 457 457 continue ; 458 458 } ; 459 if ( CPU_CLIPS_NEGATIVE == 0 &&scaled_value <= (-8.0 * 0x10000000))459 if (scaled_value <= (-8.0 * 0x10000000)) 460 460 { out [len] = -32768 ; 461 461 continue ; 462 462 } ; -
trunk/mythtv/libs/libmyth/audiosettings.cpp
16 16 set_initial_vol(false), 17 17 use_passthru(false), 18 18 codec(NULL), 19 source(AUDIOOUTPUT_UNKNOWN) 19 source(AUDIOOUTPUT_UNKNOWN), 20 isAC3upmix(false) 20 21 { 21 22 } 22 23 … … 29 30 set_initial_vol(other.set_initial_vol), 30 31 use_passthru(other.use_passthru), 31 32 codec(other.codec), 32 source(other.source) 33 source(other.source), 34 isAC3upmix(other.isAC3upmix) 33 35 { 34 36 } 35 37 … … 42 44 AudioOutputSource audio_source, 43 45 bool audio_set_initial_vol, 44 46 bool audio_use_passthru, 45 void *audio_codec) : 47 void *audio_codec, 48 bool AC3upmix) : 46 49 main_device(audio_main_device), 47 50 passthru_device(audio_passthru_device), 48 51 bits(audio_bits), … … 51 54 set_initial_vol(audio_set_initial_vol), 52 55 use_passthru(audio_use_passthru), 53 56 codec(audio_codec), 54 source(audio_source) 57 source(audio_source), 58 isAC3upmix(AC3upmix) 55 59 { 56 60 } 57 61 … … 60 64 int audio_channels, 61 65 int audio_samplerate, 62 66 bool audio_use_passthru, 63 void *audio_codec) : 67 void *audio_codec, 68 bool AC3upmix) : 64 69 main_device(QString::null), 65 70 passthru_device(QString::null), 66 71 bits(audio_bits), … … 69 74 set_initial_vol(false), 70 75 use_passthru(audio_use_passthru), 71 76 codec(audio_codec), 72 source(AUDIOOUTPUT_UNKNOWN) 77 source(AUDIOOUTPUT_UNKNOWN), 78 isAC3upmix(AC3upmix) 73 79 { 74 80 } 75 81 -
trunk/mythtv/libs/libmyth/audiooutputbase.h
43 43 44 44 virtual void SetStretchFactor(float factor); 45 45 virtual float GetStretchFactor(void) const; 46 virtual bool ToggleUpmix(void); 46 47 47 48 virtual void Reset(void); 48 49 … … 132 133 QString audio_passthru_device; 133 134 134 135 bool audio_passthru; 136 bool audio_enc; 137 bool audio_reenc; 135 138 136 139 float audio_stretchfactor; 137 140 AVCodecContext *audio_codec; … … 144 147 bool buffer_output_data_for_use; // used by AudioOutputNULL 145 148 146 149 int configured_audio_channels; 150 int orig_config_channels; 151 int src_quality; 152 int source_audio_channels; 147 153 148 154 private: 149 155 // resampler … … 155 161 AudioOutputDigitalEncoder *encoder; 156 162 FreeSurround *upmixer; 157 163 158 int source_audio_ channels;164 int source_audio_samplerate; 159 165 int source_audio_bytes_per_sample; 160 166 bool needs_upmix; 161 167 int surround_mode; 168 bool allow_ac3_passthru; 169 float old_audio_stretchfactor; 162 170 163 171 bool blocking; // do AddSamples calls block? 164 172 -
trunk/mythtv/libs/libmyth/audiooutputalsa.cpp
8 8 9 9 #include "mythcontext.h" 10 10 #include "audiooutputalsa.h" 11 #include "audiooutputdigitalencoder.h" 11 12 12 13 #define LOC QString("ALSA: ") 13 14 #define LOC_WARN QString("ALSA, Warning: ") … … 32 33 AudioOutputALSA::~AudioOutputALSA() 33 34 { 34 35 KillAudio(); 36 if (isAC3upmix) 37 SetIECStatus(true); 35 38 } 36 39 40 void AudioOutputALSA::SetIECStatus(bool audio) { 41 42 snd_ctl_t *ctl; 43 const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT); 44 int spdif_index = -1; 45 snd_ctl_elem_list_t *clist; 46 snd_ctl_elem_id_t *cid; 47 snd_ctl_elem_value_t *cval; 48 snd_aes_iec958_t iec958; 49 int cidx, controls; 50 51 VERBOSE(VB_AUDIO, QString("Setting IEC958 status: %1") 52 .arg(audio ? "audio" : "non-audio")); 53 54 int err; 55 if ((err = snd_ctl_open(&ctl, "default", 0)) < 0) 56 { 57 Error(QString("AudioOutputALSA::SetIECStatus: snd_ctl_open(default): %1") 58 .arg(snd_strerror(err))); 59 return; 60 } 61 snd_ctl_elem_list_alloca(&clist); 62 snd_ctl_elem_list(ctl, clist); 63 snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist)); 64 snd_ctl_elem_list(ctl, clist); 65 controls = snd_ctl_elem_list_get_used(clist); 66 for (cidx = 0; cidx < controls; cidx++) { 67 if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str)) 68 if (spdif_index < 0 || 69 snd_ctl_elem_list_get_index(clist, cidx) == (uint)spdif_index) 70 break; 71 } 72 73 if (cidx >= controls) 74 return; 75 76 snd_ctl_elem_id_alloca(&cid); 77 snd_ctl_elem_list_get_id(clist, cidx, cid); 78 snd_ctl_elem_value_alloca(&cval); 79 snd_ctl_elem_value_set_id(cval, cid); 80 snd_ctl_elem_read(ctl,cval); 81 snd_ctl_elem_value_get_iec958(cval, &iec958); 82 83 if (!audio) 84 iec958.status[0] |= IEC958_AES0_NONAUDIO; 85 else 86 iec958.status[0] &= ~IEC958_AES0_NONAUDIO; 87 88 snd_ctl_elem_value_set_iec958(cval, &iec958); 89 snd_ctl_elem_write(ctl, cval); 90 91 } 92 37 93 bool AudioOutputALSA::OpenDevice() 38 94 { 39 95 snd_pcm_format_t format; 40 96 unsigned int buffer_time, period_time; 41 97 int err; 98 QString real_device; 42 99 43 100 if (pcm_handle != NULL) 44 101 CloseDevice(); 45 102 46 103 pcm_handle = NULL; 47 104 numbadioctls = 0; 105 106 if (!isAC3upmix) { 107 real_device = (audio_passthru) ? 108 audio_passthru_device : audio_main_device; 109 } 110 else 111 if (audio_passthru || audio_enc) 112 { 113 real_device = audio_passthru_device; 114 SetIECStatus(false); 115 } 116 else 117 { 118 real_device = audio_main_device; 119 SetIECStatus(true); 120 } 48 121 49 QString real_device = (audio_passthru) ?50 audio_passthru_device : audio_main_device;51 52 122 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 53 123 .arg(real_device)); 54 124 … … 147 217 } 148 218 149 219 220 void AudioOutputALSA::reorder_6ch_ac3(void *buf, unsigned int len) { 221 unsigned short *src = (unsigned short *)buf; 222 unsigned short tmp; 223 unsigned int samples = len >> 1; 224 225 for (uint i = 0; i < samples; i += 6) { 226 tmp = src[i+1]; 227 src[i+1] = src[i+2]; 228 src[i+2] = src[i+3]; 229 src[i+3] = src[i+4]; 230 src[i+4] = tmp; 231 } 232 } 233 150 234 void AudioOutputALSA::WriteAudio(unsigned char *aubuf, int size) 151 235 { 152 236 unsigned char *tmpbuf; … … 159 243 return; 160 244 } 161 245 246 // Re-Order channels mapping if analog output is used and source is AC3 multi-channels 247 if (isAC3upmix && !audio_passthru 248 && audio_codec && (audio_codec->codec_id == CODEC_ID_AC3) 249 && (source_audio_channels > 2)) { 250 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 251 QString("WriteAudio: Re-ordering audio channels %1 bytes (%2 frames)") 252 .arg(size).arg(frames)); 253 reorder_6ch_ac3(aubuf, size); 254 } 162 255 tmpbuf = aubuf; 163 256 164 257 VERBOSE(VB_AUDIO+VB_TIMESTAMP, -
trunk/mythtv/libs/libmyth/audiooutputbase.cpp
28 28 29 29 audio_main_device(settings.GetMainDevice()), 30 30 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), 32 33 33 34 audio_codec(NULL), 34 35 source(settings.source), killaudio(false), … … 47 48 pSoundStretch(NULL), 48 49 encoder(NULL), 49 50 upmixer(NULL), 51 50 52 source_audio_channels(-1), 53 source_audio_samplerate(0), 51 54 source_audio_bytes_per_sample(0), 52 55 needs_upmix(false), 53 56 surround_mode(FreeSurround::SurroundModePassive), 57 old_audio_stretchfactor(1.0), 54 58 55 59 blocking(false), 56 60 … … 79 83 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 80 84 memset(audiobuffer, 0, sizeof(char) * kAudioRingBufferSize); 81 85 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; 82 90 83 91 // You need to call Reconfigure from your concrete class. 84 92 // Reconfigure(laudio_bits, laudio_channels, … … 110 118 void AudioOutputBase::SetStretchFactorLocked(float laudio_stretchfactor) 111 119 { 112 120 effdspstretched = (int)((float)effdsp / laudio_stretchfactor); 113 if ((audio_stretchfactor != laudio_stretchfactor) || 121 if ((audio_stretchfactor != laudio_stretchfactor) || !pSoundStretch) 114 122 { 115 123 audio_stretchfactor = laudio_stretchfactor; 116 124 if (pSoundStretch) … … 124 132 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 125 133 .arg(audio_stretchfactor)); 126 134 pSoundStretch = new soundtouch::SoundTouch(); 127 if (audio_codec) 128 { 129 if (!encoder) 135 if (!isAC3upmix) { 136 if (audio_codec) 130 137 { 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) 142 139 { 143 // eeks144 delete encoder;145 encoder = NULL;146 140 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 } 148 158 } 149 159 } 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 { 158 171 pSoundStretch->setSampleRate(audio_samplerate); 159 pSoundStretch->setChannels(audio_channels); 172 pSoundStretch->setChannels(upmixer ? 173 configured_audio_channels : source_audio_channels); 160 174 } 161 162 175 pSoundStretch->setTempo(audio_stretchfactor); 163 176 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); 164 177 165 178 // dont need these with only tempo change 166 179 //pSoundStretch->setPitch(1.0); 167 180 //pSoundStretch->setRate(1.0); 168 169 181 //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true); 170 182 //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false); 171 183 } … … 183 195 return audio_stretchfactor; 184 196 } 185 197 198 bool 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 186 214 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 187 215 { 188 216 AudioSettings settings = orig_settings; … … 193 221 int cchannels = 0; 194 222 int lsource_audio_channels = settings.channels; 195 223 bool lneeds_upmix = false; 224 bool laudio_reenc = false; 196 225 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 } 206 236 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 } 212 242 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 } 263 if (settings.codec) 264 audio_codec = (AVCodecContext*)settings.codec; 219 265 } 220 266 221 267 ClearError(); … … 224 270 settings.samplerate == audio_samplerate && !need_resampler && 225 271 settings.use_passthru == audio_passthru && 226 272 lneeds_upmix == needs_upmix && 227 lcodec_id == codec_id && lcchannels == cchannels); 273 (isAC3upmix ? (laudio_reenc == audio_reenc) : (lcodec_id == codec_id && lcchannels == cchannels)) 274 ); 228 275 bool upmix_deps = 229 276 (lsource_audio_channels == source_audio_channels); 230 277 if (general_deps && upmix_deps) … … 255 302 audio_channels = settings.channels; 256 303 source_audio_channels = lsource_audio_channels; 257 304 audio_bits = settings.bits; 258 audio_samplerate = settings.samplerate; 259 audio_codec = (AVCodecContext*)settings.codec; 305 if (!isAC3upmix) { 306 audio_samplerate = settings.samplerate; 307 audio_codec = (AVCodecContext*)settings.codec; 308 } else { 309 source_audio_samplerate = audio_samplerate = settings.samplerate; 310 audio_reenc = laudio_reenc; 311 } 260 312 audio_passthru = settings.use_passthru; 261 313 needs_upmix = lneeds_upmix; 262 314 … … 265 317 Error("AudioOutput only supports 8 or 16bit audio."); 266 318 return; 267 319 } 268 audio_bytes_per_sample = audio_channels * audio_bits / 8;269 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;270 320 271 321 need_resampler = false; 272 322 killaudio = false; … … 275 325 internal_vol = gContext->GetNumSetting("MythControlsVolume", 0); 276 326 277 327 numlowbuffer = 0; 328 329 if (!isAC3upmix) { 330 audio_bytes_per_sample = audio_channels * audio_bits / 8; 331 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 332 } else { 333 // Encode to AC-3 if not passing thru, there's more than 2 channels 334 // and we're allowed to passthru AC-3 335 if (!audio_passthru && audio_channels > 2 && allow_ac3_passthru) 336 { 337 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); 338 int srate = src_quality == 0 ? audio_samplerate : 48000; 339 encoder = new AudioOutputDigitalEncoder(isAC3upmix); 340 if (!encoder->Init(CODEC_ID_AC3, 448000, srate, 341 configured_audio_channels, audio_reenc)) 342 { 343 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 344 delete encoder; 345 encoder = NULL; 346 } 347 348 audio_enc = true; 349 } 350 351 if(audio_passthru || audio_enc) 352 // AC-3 output - soundcard expects a 2ch 48k stream 353 audio_channels = 2; 354 355 audio_bytes_per_sample = audio_channels * audio_bits / 8; 356 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 278 357 358 // Always resample to 48k - many cards can't do anything else 359 // and ALSA will do it with linear interpolation (yuk) if we don't anyway 360 if (src_quality != 0 && audio_samplerate != 48000) 361 { 362 int error; 363 audio_samplerate = 48000; 364 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2") 365 .arg(settings.samplerate).arg(audio_samplerate)); 366 src_ctx = src_new(3-src_quality, audio_channels, &error); 367 if (error) 368 { 369 Error(QString("Error creating resampler, the error was: %1") 370 .arg(src_strerror(error)) ); 371 src_ctx = NULL; 372 return; 373 } 374 src_data.src_ratio = (double) audio_samplerate / settings.samplerate; 375 src_data.data_in = src_in; 376 src_data.data_out = src_out; 377 src_data.output_frames = 16384*6; 378 need_resampler = true; 379 } 380 } 279 381 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 280 382 .arg(audio_main_device).arg(audio_channels) 281 383 .arg(source_audio_channels).arg(audio_samplerate)); … … 309 411 current_seconds = -1; 310 412 source_bitrate = -1; 311 413 414 if (!isAC3upmix) { 312 415 // NOTE: this won't do anything as above samplerate vars are set equal 313 416 // Check if we need the resampler 314 417 if (audio_samplerate != settings.samplerate) … … 329 432 src_data.output_frames = 16384*6; 330 433 need_resampler = true; 331 434 } 332 435 } 333 436 if (needs_upmix) 334 437 { 335 438 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); … … 341 444 upmixer = new FreeSurround( 342 445 audio_samplerate, 343 446 source == AUDIOOUTPUT_VIDEO, 344 (FreeSurround::SurroundMode)surround_mode );447 (FreeSurround::SurroundMode)surround_mode,isAC3upmix); 345 448 346 449 VERBOSE(VB_AUDIO, LOC + 347 450 QString("create upmixer done with surround mode %1") … … 350 453 351 454 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 352 455 .arg(audio_stretchfactor)); 353 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 354 .arg((audio_codec) ? 456 if (!isAC3upmix) { 457 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 458 .arg((audio_codec) ? 355 459 codec_id_string(audio_codec->codec_id) : "not set")); 356 460 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) 461 if (redo_stretch) 367 462 { 368 // if its passthru then we need to reencode 369 if (audio_codec) 463 delete pSoundStretch; 464 pSoundStretch = NULL; 465 SetStretchFactorLocked(audio_stretchfactor); 466 } 467 else 468 { 469 SetStretchFactorLocked(audio_stretchfactor); 470 if (pSoundStretch) 370 471 { 371 if (!encoder) 472 // if its passthru then we need to reencode 473 if (audio_codec) 372 474 { 373 VERBOSE(VB_AUDIO, LOC + 374 QString("Creating Encoder for codec %1") 375 .arg(audio_codec->codec_id)); 475 if (!encoder) 476 { 477 VERBOSE(VB_AUDIO, LOC + 478 QString("Creating Encoder for codec %1") 479 .arg(audio_codec->codec_id)); 376 480 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"); 481 encoder = new AudioOutputDigitalEncoder(isAC3upmix); 482 if (!encoder->Init(audio_codec->codec_id, 483 audio_codec->bit_rate, 484 audio_codec->sample_rate, 485 audio_codec->channels 486 )) 487 { 488 // eeks 489 delete encoder; 490 encoder = NULL; 491 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder"); 492 } 388 493 } 389 494 } 495 if (audio_codec && encoder) 496 { 497 pSoundStretch->setSampleRate(audio_codec->sample_rate); 498 pSoundStretch->setChannels(audio_codec->channels); 499 } 500 else 501 { 502 pSoundStretch->setSampleRate(audio_samplerate); 503 pSoundStretch->setChannels(audio_channels); 504 } 390 505 } 391 if (audio_codec && encoder)392 {393 pSoundStretch->setSampleRate(audio_codec->sample_rate);394 pSoundStretch->setChannels(audio_codec->channels);395 }396 else397 {398 pSoundStretch->setSampleRate(audio_samplerate);399 pSoundStretch->setChannels(audio_channels);400 }401 506 } 507 } else { 508 SetStretchFactorLocked(old_audio_stretchfactor); 402 509 } 403 404 510 // Setup visualisations, zero the visualisations buffers 405 511 prepareVisuals(); 406 512 … … 437 543 killaudio = true; 438 544 StopOutputThread(); 439 545 546 if (isAC3upmix) 547 QMutexLocker lock1(&audio_buflock); 548 440 549 // Close resampler? 441 if (src_ctx) 550 if (src_ctx) { 442 551 src_delete(src_ctx); 552 if (isAC3upmix) 553 src_ctx = NULL; 554 } 443 555 need_resampler = false; 444 556 445 557 // close sound stretcher … … 447 559 { 448 560 delete pSoundStretch; 449 561 pSoundStretch = NULL; 562 if (isAC3upmix) { 563 old_audio_stretchfactor = audio_stretchfactor; 564 audio_stretchfactor = 1.0; 565 } 450 566 } 451 567 452 568 if (encoder) … … 461 577 upmixer = NULL; 462 578 } 463 579 needs_upmix = false; 580 if (isAC3upmix) 581 audio_enc = false; 464 582 465 583 CloseDevice(); 466 584 … … 612 730 // include algorithmic latencies 613 731 if (pSoundStretch) 614 732 { 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); 733 if (!isAC3upmix) { 734 // add the effect of any unused but processed samples, 735 // AC3 reencode does this 736 totalbuffer += (int)(pSoundStretch->numSamples() * 737 audio_bytes_per_sample); 738 } 619 739 // add the effect of unprocessed samples in time stretch algo 620 740 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 621 741 audio_bytes_per_sample) / audio_stretchfactor); … … 626 746 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 627 747 } 628 748 749 if (isAC3upmix && encoder) 750 totalbuffer += encoder->Buffered(); 751 629 752 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 630 753 (audio_bytes_per_sample * effdspstretched)); 631 754 … … 681 804 return false; // would overflow 682 805 } 683 806 807 if (isAC3upmix) 808 QMutexLocker lock1(&audio_buflock); 809 684 810 // resample input if necessary 685 811 if (need_resampler && src_ctx) 686 812 { … … 725 851 int abps = (encoder) ? 726 852 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 727 853 int len = samples * abps; 854 855 if (isAC3upmix) { 856 // Give original samples to mythmusic visualisation 857 dispatchVisual((unsigned char *)buffer, len, timecode, 858 source_audio_channels, audio_bits); 859 } 728 860 729 861 // Check we have enough space to write the data 730 862 if (need_resampler && src_ctx) … … 749 881 return false; // would overflow 750 882 } 751 883 884 if (isAC3upmix) 885 QMutexLocker lock1(&audio_buflock); 886 752 887 // resample input if necessary 753 888 if (need_resampler && src_ctx) 754 889 { … … 808 943 if (src_ctx) 809 944 { 810 945 int error = src_reset(src_ctx); 811 if (error) 946 if (error) 947 { 812 948 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 813 949 "Error occured while resetting resampler: %1") 814 950 .arg(src_strerror(error))); 951 if (isAC3upmix) 952 src_ctx = NULL; 953 } 815 954 } 816 955 } 817 956 } … … 821 960 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 822 961 long long timecode) 823 962 { 824 audio_buflock.lock(); 963 if (!isAC3upmix) 964 audio_buflock.lock(); 825 965 826 966 int len; // = samples * audio_bytes_per_sample; 827 967 int audio_bytes = audio_bits / 8; … … 839 979 .arg(samples * abps) 840 980 .arg(kAudioRingBufferSize-afree).arg(afree).arg(timecode) 841 981 .arg(needs_upmix)); 842 982 983 if (isAC3upmix) 984 len = WaitForFreeSpace(samples); 985 843 986 if (upmixer && needs_upmix) 844 987 { 845 988 int out_samples = 0; 846 989 int step = (interleaved)?source_audio_channels:1; 847 len = WaitForFreeSpace(samples); // test 990 991 if (!isAC3upmix) { 992 len = WaitForFreeSpace(samples); 993 } 848 994 for (int itemp = 0; itemp < samples; ) 849 995 { 850 996 // just in case it does a processing cycle, release the lock 851 997 // to allow the output loop to do output 852 audio_buflock.unlock(); 998 if (!isAC3upmix) 999 audio_buflock.unlock(); 853 1000 if (audio_bytes == 2) 854 1001 { 855 1002 itemp += upmixer->putSamples( … … 866 1013 source_audio_channels, 867 1014 (interleaved) ? 0 : samples); 868 1015 } 869 audio_buflock.lock(); 1016 if (!isAC3upmix) 1017 audio_buflock.lock(); 870 1018 871 1019 int copy_samples = upmixer->numSamples(); 872 1020 if (copy_samples) … … 900 1048 } 901 1049 else 902 1050 { 903 len = WaitForFreeSpace(samples);904 1051 if (!isAC3upmix) 1052 len = WaitForFreeSpace(samples); 905 1053 if (interleaved) 906 1054 { 907 1055 char *mybuf = (char*)buffer; … … 936 1084 } 937 1085 } 938 1086 1087 if (!isAC3upmix) { 939 1088 if (samples > 0) 940 1089 { 941 1090 if (pSoundStretch) … … 993 1142 continue; 994 1143 995 1144 //len = WaitForFreeSpace(amount); 996 c har *ob = encoder->GetOutBuff();1145 const char *ob = encoder->GetOutBuff(); 997 1146 if (amount >= bdiff) 998 1147 { 999 1148 memcpy(audiobuffer + org_waud, ob, bdiff); … … 1068 1217 } 1069 1218 1070 1219 audio_buflock.unlock(); 1220 } else { 1221 if (samples <= 0) 1222 return; 1223 1224 if (pSoundStretch) 1225 { 1226 // does not change the timecode, only the number of samples 1227 // back to orig pos 1228 org_waud = waud; 1229 int bdiff = kAudioRingBufferSize - org_waud; 1230 int nSamplesToEnd = bdiff/abps; 1231 if (bdiff < len) 1232 { 1233 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 1234 (audiobuffer + 1235 org_waud), nSamplesToEnd); 1236 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 1237 (len - bdiff) / abps); 1238 } 1239 else 1240 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 1241 (audiobuffer + org_waud), 1242 len / abps); 1243 1244 int nSamples = pSoundStretch->numSamples(); 1245 len = WaitForFreeSpace(nSamples); 1246 1247 while ((nSamples = pSoundStretch->numSamples())) 1248 { 1249 if (nSamples > nSamplesToEnd) 1250 nSamples = nSamplesToEnd; 1251 1252 nSamples = pSoundStretch->receiveSamples( 1253 (soundtouch::SAMPLETYPE*) 1254 (audiobuffer + org_waud), nSamples 1255 ); 1256 1257 if (nSamples == nSamplesToEnd) { 1258 org_waud = 0; 1259 nSamplesToEnd = kAudioRingBufferSize/abps; 1260 } 1261 else { 1262 org_waud += nSamples * abps; 1263 nSamplesToEnd -= nSamples; 1264 } 1265 1266 } 1267 1268 } 1269 1270 // Encode to AC-3? 1271 if (encoder) 1272 { 1273 1274 org_waud = waud; 1275 int bdiff = kAudioRingBufferSize - org_waud; 1276 int to_get = 0; 1277 1278 if (bdiff < len) 1279 { 1280 encoder->EncodeUpmix(audiobuffer + org_waud, bdiff); 1281 to_get = encoder->EncodeUpmix(audiobuffer, len - bdiff); 1282 } 1283 else 1284 to_get = encoder->EncodeUpmix(audiobuffer + org_waud, len); 1285 1286 if (to_get > 0) 1287 { 1288 1289 if (to_get >= bdiff) 1290 { 1291 encoder->GetFrames(audiobuffer + org_waud, bdiff); 1292 to_get -= bdiff; 1293 org_waud = 0; 1294 } 1295 if (to_get > 0) 1296 encoder->GetFrames(audiobuffer + org_waud, to_get); 1297 1298 org_waud += to_get; 1299 1300 } 1301 1302 } 1303 1304 waud = org_waud; 1305 lastaudiolen = audiolen(false); 1306 1307 if (timecode < 0) 1308 // mythmusic doesn't give timestamps.. 1309 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1310 1311 samples_buffered += samples; 1312 1313 /* we want the time at the end -- but the file format stores 1314 time at the start of the chunk. */ 1315 // even with timestretch, timecode is still calculated from original 1316 // sample count 1317 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 1318 } // End AC3 upmiz 1071 1319 } 1072 1320 1073 1321 void AudioOutputBase::Status() -
trunk/mythtv/libs/libmyth/audiooutput.cpp
35 35 const QString &passthru_device, 36 36 int audio_bits, int audio_channels, int audio_samplerate, 37 37 AudioOutputSource source, 38 bool set_initial_vol, bool audio_passthru )38 bool set_initial_vol, bool audio_passthru, bool AC3upmix) 39 39 { 40 40 AudioSettings settings( 41 41 main_device, passthru_device, audio_bits, 42 42 audio_channels, audio_samplerate, source, 43 set_initial_vol, audio_passthru );43 set_initial_vol, audio_passthru, NULL, AC3upmix); 44 44 45 45 settings.FixPassThrough(); 46 46 -
trunk/mythtv/libs/libmyth/audiosettings.h
33 33 AudioOutputSource audio_source, 34 34 bool audio_set_initial_vol, 35 35 bool audio_use_passthru, 36 void *audio_codec = NULL); 36 void *audio_codec = NULL, 37 bool AC3upmix = false); 37 38 38 39 AudioSettings(int audio_bits, 39 40 int audio_channels, 40 41 int audio_samplerate, 41 42 bool audio_use_passthru, 42 void *audio_codec = NULL); 43 void *audio_codec = NULL, 44 bool AC3upmix = false); 43 45 44 46 void FixPassThrough(void); 45 47 void TrimDeviceType(void); … … 59 61 bool use_passthru; 60 62 void *codec; 61 63 AudioOutputSource source; 64 bool isAC3upmix; 62 65 }; 63 66 64 67 #endif // _AUDIO_SETTINGS_H_ -
trunk/mythtv/libs/libmyth/audiooutputdigitalencoder.cpp
29 29 AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) : 30 30 audio_bytes_per_sample(0), 31 31 av_context(NULL), 32 outbuf(NULL),33 outbuf_size(0),34 32 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) 36 38 { 37 39 } 38 40 41 AudioOutputDigitalEncoder::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 39 53 AudioOutputDigitalEncoder::~AudioOutputDigitalEncoder() 40 54 { 41 55 Dispose(); … … 50 64 av_context = NULL; 51 65 } 52 66 53 if ( outbuf)67 if (!isAC3upmix && frame_buffer) 54 68 { 55 delete [] outbuf;56 outbuf = NULL;57 outbuf_size = 0;58 }59 60 if (frame_buffer)61 {62 69 delete [] frame_buffer; 63 70 frame_buffer = NULL; 64 71 one_frame_bytes = 0; … … 67 74 68 75 //CODEC_ID_AC3 69 76 bool AudioOutputDigitalEncoder::Init( 70 CodecID codec_id, int bitrate, int samplerate, int channels )77 CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding) 71 78 { 72 79 AVCodec *codec; 73 80 int ret; 74 81 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") 76 83 .arg(codec_id_string(codec_id)) 77 84 .arg(bitrate) 78 85 .arg(samplerate) 79 .arg(channels)); 86 .arg(channels) 87 .arg(reencoding)); 88 89 reorder = !reencoding; 80 90 91 // We need to do this when called from mythmusic 92 if (isAC3upmix) { 93 avcodec_init(); 94 avcodec_register_all(); 95 } 81 96 //codec = avcodec_find_encoder(codec_id); 82 97 // always AC3 as there is no DTS encoder at the moment 2005/1/9 83 98 codec = avcodec_find_encoder(CODEC_ID_AC3); … … 107 122 audio_bytes_per_sample = bytes_per_frame; 108 123 one_frame_bytes = bytes_per_frame * av_context->frame_size; 109 124 110 outbuf_size = 16384; // ok for AC3 but DTS?111 outbuf = new char [outbuf_size];112 125 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 113 126 .arg(av_context->frame_size) 114 127 .arg(bytes_per_frame) … … 253 266 254 267 } AESHeader; 255 268 269 void 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 256 283 static int encode_frame( 257 284 bool dts, 258 285 unsigned char *data, 259 size_t &len )286 size_t &len, bool AC3upmix) 260 287 { 261 288 unsigned char *payload = data + 8; // skip header, currently 52 or 54bits 262 size_t enc_len;289 size_t enc_len = len; 263 290 int flags, sample_rate, bit_rate; 264 291 265 292 // we don't do any length/crc validation of the AC3 frame here; presumably … … 270 297 // ignore, and if so, may as well just assume that it will ignore 271 298 // anything with a bad CRC... 272 299 273 uint nr_samples = 0, block_len; 300 uint nr_samples = 0, block_len = 0; 301 274 302 if (dts) 275 303 { 276 304 enc_len = dts_syncinfo(payload, &flags, &sample_rate, &bit_rate); … … 305 333 #endif 306 334 } 307 335 308 if ( enc_len == 0 || enc_len > len)336 if (!AC3upmix && (enc_len == 0 || enc_len > len)) 309 337 { 310 338 int l = len; 311 339 len = 0; … … 364 392 data[6] = (enc_len << 3) & 0xFF; 365 393 data[7] = (enc_len >> 5) & 0xFF; 366 394 memset(payload + enc_len, 0, block_len - 8 - enc_len); 367 len = block_len; 395 if (!AC3upmix) 396 len = block_len; 368 397 369 398 return enc_len; 370 399 } … … 377 406 378 407 // put data in the correct spot for encode frame 379 408 outsize = avcodec_encode_audio( 380 av_context, ((uchar*)outbuf) + 8, outbuf_size- 8, buff);409 av_context, ((uchar*)outbuf) + 8, OUTBUFSIZE - 8, buff); 381 410 382 411 size_t tmpsize = outsize; 383 412 384 413 outsize = MAX_AC3_FRAME_SIZE; 385 414 encsize = encode_frame( 386 415 /*av_context->codec_id==CODEC_ID_DTS*/ false, 387 (unsigned char*)outbuf, outsize );416 (unsigned char*)outbuf, outsize, false); 388 417 389 418 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 390 419 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") … … 392 421 393 422 return outsize; 394 423 } 424 425 size_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 456 void 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
17 17 const QString &passthrudevice, 18 18 int audio_bits, int audio_channels, int audio_samplerate, 19 19 AudioOutputSource source, 20 bool set_initial_vol, bool audio_passthru );20 bool set_initial_vol, bool audio_passthru, bool AC3upmix=false); 21 21 22 22 AudioOutput() : 23 23 VolumeBase(), OutputListeners(), 24 isAC3upmix(false), 24 25 lastError(QString::null), lastWarn(QString::null) {} 25 26 26 27 virtual ~AudioOutput() { }; … … 69 70 virtual void bufferOutputData(bool y) = 0; 70 71 virtual int readOutputData(unsigned char *read_buffer, int max_length) = 0; 71 72 73 // Audio AC3 Upmixer 74 virtual bool ToggleUpmix(void) = 0; 75 bool isAC3upmix; 76 72 77 protected: 73 78 void Error(const QString &msg); 74 79 void Warn(const QString &msg); -
trunk/mythtv/libs/libmyth/audiooutputdigitalencoder.h
5 5 #include "libavcodec/avcodec.h" 6 6 }; 7 7 8 #define INBUFSIZE 131072 9 #define OUTBUFSIZE 98304 10 8 11 class AudioOutputDigitalEncoder 9 12 { 10 13 public: 11 14 AudioOutputDigitalEncoder(void); 15 AudioOutputDigitalEncoder(bool AC3upmix); 12 16 ~AudioOutputDigitalEncoder(); 13 17 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); 15 20 void Dispose(void); 16 21 size_t Encode(short * buff); 17 22 18 23 inline char *GetFrameBuffer(void); 19 24 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; } 21 30 22 31 public: 23 32 size_t audio_bytes_per_sample; 24 33 25 34 private: 26 35 AVCodecContext *av_context; 27 char *outbuf; 28 int outbuf_size; 36 char outbuf[OUTBUFSIZE]; 29 37 char *frame_buffer; 30 38 size_t one_frame_bytes; 39 // AC3 upmix 40 char inbuf[INBUFSIZE]; 41 int outbuflen; 42 int inbuflen; 43 bool reorder; 44 bool isAC3upmix; 31 45 }; 32 46 33 47 inline char *AudioOutputDigitalEncoder::GetFrameBuffer(void) -
trunk/mythtv/libs/libmyth/audiooutputalsa.h
67 67 virtual int GetBufferedOnSoundcard(void) const; 68 68 69 69 private: 70 void SetIECStatus(bool audio); 70 71 inline int SetParameters(snd_pcm_t *handle, 71 72 snd_pcm_format_t format, unsigned int channels, 72 73 unsigned int rate, unsigned int buffer_time, … … 79 80 void CloseMixer(void); 80 81 void SetupMixer(void); 81 82 ALSAVolumeInfo GetVolumeRange(snd_mixer_elem_t *elem) const; 83 void reorder_6ch_ac3(void *buf, unsigned int len); 82 84 83 85 private: 84 86 snd_pcm_t *pcm_handle; -
trunk/mythtv/libs/libmythfreesurround/el_processor.cpp
40 40 41 41 const float PI = 3.141592654; 42 42 const float epsilon = 0.000001; 43 const float center_level_upmix = 0.5*sqrt(0.5); 43 44 //const float center_level = 0.5*sqrt(0.5); // gain of the center channel 44 45 //const float center_level = sqrt(0.5); // gain of the center channel 45 46 const float center_level = 1.0; // gain of the center channel … … 57 58 public: 58 59 // create an instance of the decoder 59 60 // 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) { 61 62 #ifdef USE_FFTW3 62 63 // create FFTW buffers 63 64 lt = (float*)fftwf_malloc(sizeof(float)*N); … … 99 100 filter[c].resize(N); 100 101 } 101 102 // 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); 107 122 } 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 scaling112 // also add a gain factor of *2 due to processing gain in algo (see center_level)113 surround_gain(1.0);114 123 current_buf = 0; 115 124 // set the default coefficients 116 125 surround_coefficients(0.8165,0.5774); … … 192 201 // set lfe filter params 193 202 void sample_rate(unsigned int srate) { 194 203 // 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 } 201 221 } 202 222 } 203 223 … … 237 257 } 238 258 239 259 private: 260 bool isAC3upmix; 240 261 // polar <-> cartesian coodinates conversion 241 262 static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); } 242 263 static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); } … … 290 311 291 312 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 292 313 // 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++) { 294 316 // get left/right amplitudes/phases 295 317 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]); 296 318 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]); … … 357 379 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 358 380 float volume[5] = { 359 381 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 360 front * center_level*((1-abs(xfs[f])) * (1-center_width)), // center382 front * (isAC3upmix ? center_level_upmix : center_level) *((1-abs(xfs[f])) * (1-center_width)), // center 361 383 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 362 384 back * surround_level * left, // left surround 363 385 back * surround_level * right // right surround … … 402 424 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 403 425 float volume[5] = { 404 426 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 405 front * center_level*((1-abs(xfs[f])) * (1-center_width)),// center427 front * (isAC3upmix ? center_level_upmix : center_level) *((1-abs(xfs[f])) * (1-center_width)), // center 406 428 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 407 429 back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))), // left surround 408 430 back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2))) // right surround … … 613 635 614 636 // implementation of the shell class 615 637 616 fsurround_decoder::fsurround_decoder(unsigned blocksize ): impl(new decoder_impl(blocksize)) { }638 fsurround_decoder::fsurround_decoder(unsigned blocksize, bool AC3upmix): impl(new decoder_impl(blocksize,AC3upmix)) { } 617 639 618 640 fsurround_decoder::~fsurround_decoder() { delete impl; } 619 641 -
trunk/mythtv/libs/libmythfreesurround/freesurround.cpp
63 63 const unsigned default_block_size = 8192; 64 64 // there will be a slider for this in the future 65 65 //const float master_gain = 1.0; 66 //#define MASTER_GAIN * master_gain 66 //#define MASTER_GAIN * master_gain 67 67 #define MASTER_GAIN 68 68 //const float master_gain = 1.0/(1<<15); 69 69 //const float inv_master_gain = (1<<15); … … 163 163 164 164 // construction methods 165 165 void *new_decoder() { return new fsurround_decoder(block_size); } 166 void *new_decoder_upmix() { return new fsurround_decoder(block_size,true); } 166 167 void *new_buffers() { return new buffers(block_size/2); } 167 168 void *new_int16buffers() { return new int16buffers(block_size/2); } 168 169 169 170 object_pool dp(&new_decoder); 171 object_pool dp_upmix(&new_decoder_upmix); 170 172 //object_pool bp(&new_buffers); 171 173 object_pool bp16(&new_int16buffers); 172 174 … … 175 177 int channel_select = -1; 176 178 #endif 177 179 178 FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode ) :180 FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode, bool AC3upmix) : 179 181 srate(srate), 180 182 open_(false), 181 183 initialized_(false), … … 186 188 out_count(0), 187 189 processed(true), 188 190 processed_size(0), 189 surround_mode(smode) 191 surround_mode(smode), 192 isAC3upmix(AC3upmix) 190 193 { 191 194 VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode)); 192 195 if (moviemode) 193 196 { 194 197 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 } 197 205 } 198 206 else 199 207 { 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 } 204 217 } 205 218 switch (surround_mode) 206 219 { … … 236 249 decoder->phase_mode(params.phasemode); 237 250 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 238 251 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); 240 254 } 241 255 } 242 256 … … 655 669 { 656 670 if (decoder) 657 671 { 658 // actually these params need only be set when they change... but it doesn't hurt659 #if 0660 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 #endif665 // decode the bufs->block666 //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);668 672 decoder->decode(params.center_width/100.0,params.dimension/100.0); 669 673 } 670 674 } … … 694 698 { 695 699 if (!decoder) 696 700 { 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); 698 705 decoder->flush(); 699 706 //if (bufs) 700 707 // bufs->clear(); … … 709 716 { 710 717 if (decoder) 711 718 { 712 dp.release(this); 719 if (!isAC3upmix) 720 dp.release(this); 721 else 722 dp_upmix.release(this); 713 723 decoder = 0; 714 724 } 715 725 } -
trunk/mythtv/libs/libmythfreesurround/el_processor.h
24 24 public: 25 25 // create an instance of the decoder 26 26 // 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); 28 28 // destructor 29 29 ~fsurround_decoder(); 30 30 … … 51 51 void gain(float gain); 52 52 53 53 // set the phase shifting mode for decoding 54 // 0 = (+0 °,+0°) - music mode55 // 1 = (+0 °,+180°) - PowerDVD compatibility56 // 2 = (+180 °,+0°) - BeSweet compatibility57 // 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. 58 58 void phase_mode(unsigned mode); 59 59 60 60 // override the steering mode … … 71 71 72 72 private: 73 73 class decoder_impl *impl; // private implementation (details hidden) 74 bool isAC3upmix; 74 75 }; 75 76 76 77 -
trunk/mythtv/libs/libmythfreesurround/freesurround.h
31 31 SurroundModeActiveLinear 32 32 } SurroundMode; 33 33 public: 34 FreeSurround(uint srate, bool moviemode, SurroundMode mode );34 FreeSurround(uint srate, bool moviemode, SurroundMode mode, bool AC3upmix=false); 35 35 ~FreeSurround(); 36 36 37 37 // put samples in buffer, returns number of samples used … … 88 88 bool processed; // whether processing is enabled or not for latency calc 89 89 int processed_size; // amount processed 90 90 SurroundMode surround_mode; // 1 of 3 surround modes supported 91 bool isAC3upmix; 91 92 92 93 }; 93 94 -
trunk/mythtv/programs/mythfrontend/globalsettings.cpp
119 119 return gc; 120 120 } 121 121 122 static 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 131 static 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 122 151 static HostComboBox *PassThroughOutputDevice() 123 152 { 124 153 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3432 3461 return gs; 3433 3462 } 3434 3463 3435 class AudioSystemSettingsGroup : public VerticalConfigurationGroup3464 class AudioSystemSettingsGroup : public TriggeredConfigurationGroup 3436 3465 { 3437 3466 public: 3438 3467 AudioSystemSettingsGroup() : 3439 VerticalConfigurationGroup(false, true, false, false)3468 TriggeredConfigurationGroup(false, true, false, false) 3440 3469 { 3441 3470 setLabel(QObject::tr("Audio System")); 3442 3471 setUseLabel(false); … … 3451 3480 addChild(AC3PassThrough()); 3452 3481 addChild(DTSPassThrough()); 3453 3482 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 3454 3490 } 3455 3491 }; 3456 3492 -
trunk/mythtv/programs/mythtranscode/transcode.cpp
222 222 // Do nothing 223 223 return kMuteOff; 224 224 } 225 virtual bool ToggleUpmix(void) 226 { 227 // Do nothing 228 return false; 229 } 225 230 226 231 // These are pure virtual in AudioOutput, but we don't need them here 227 232 virtual void bufferOutputData(bool){ return; }