Ticket #5900: audioencoding-fixes.patch
File audioencoding-fixes.patch, 62.6 KB (added by , 15 years ago) |
---|
-
libs/libmythtv/NuppelVideoPlayer.cpp
209 209 audio_passthru_device(QString::null), 210 210 audio_channels(2), audio_bits(-1), 211 211 audio_samplerate(44100), audio_stretchfactor(1.0f), 212 audio_codec(NULL),213 212 // Picture-in-Picture 214 213 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 215 214 // Preview window support … … 804 803 if (audioOutput) 805 804 { 806 805 audioOutput->Reconfigure(audio_bits, audio_channels, 807 audio_samplerate, audio_passthru, 808 audio_codec); 806 audio_samplerate, audio_passthru); 807 if (audio_passthru) 808 audio_channels = 2; 809 809 errMsg = audioOutput->GetError(); 810 810 if (!errMsg.isEmpty()) 811 811 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3718 3718 audio_passthru = passthru; 3719 3719 } 3720 3720 3721 void NuppelVideoPlayer::SetAudioCodec(void *ac)3722 {3723 audio_codec = ac;3724 }3725 3726 3721 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3727 3722 { 3728 3723 if (audioOutput) -
libs/libmythtv/avformatdecoder.cpp
411 411 audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]), 412 412 allow_ac3_passthru(false), allow_dts_passthru(false), 413 413 disable_passthru(false), max_channels(2), 414 dummy_frame(NULL),414 last_ac3_channels(0), dummy_frame(NULL), 415 415 // DVD 416 416 lastdvdtitle(-1), 417 417 decodeStillFrame(false), … … 2971 2971 bool AvFormatDecoder::GetFrame(int onlyvideo) 2972 2972 { 2973 2973 AVPacket *pkt = NULL; 2974 AC3HeaderInfo hdr; 2974 2975 int len; 2975 2976 unsigned char *ptr; 2976 2977 int data_size = 0; … … 3157 3158 pts = 0; 3158 3159 3159 3160 AVStream *curstream = ic->streams[pkt->stream_index]; 3161 AVCodecContext *ctx = curstream->codec; 3160 3162 3161 3163 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3162 3164 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 3163 3165 3164 3166 if (ringBuffer->isDVD() && 3165 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3167 ctx->codec_type == CODEC_TYPE_VIDEO) 3166 3168 { 3167 3169 MpegPreProcessPkt(curstream, pkt); 3168 3170 … … 3190 3192 3191 3193 if (!d->HasMPEG2Dec()) 3192 3194 { 3193 int current_width = c urstream->codec->width;3195 int current_width = ctx->width; 3194 3196 int video_width = GetNVP()->GetVideoSize().width(); 3195 3197 if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput()) 3196 3198 { … … 3231 3233 } 3232 3234 3233 3235 if (storevideoframes && 3234 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3236 ctx->codec_type == CODEC_TYPE_VIDEO) 3235 3237 { 3236 3238 av_dup_packet(pkt); 3237 3239 storedPackets.append(pkt); … … 3239 3241 continue; 3240 3242 } 3241 3243 3242 if (len > 0 && c urstream->codec->codec_type == CODEC_TYPE_VIDEO &&3244 if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO && 3243 3245 pkt->stream_index == selectedVideoIndex) 3244 3246 { 3245 AVCodecContext *context = curstream->codec;3246 3247 3247 if (c ontext->codec_id == CODEC_ID_MPEG1VIDEO ||3248 c ontext->codec_id == CODEC_ID_MPEG2VIDEO ||3249 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||3250 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD)3248 if (ctx->codec_id == CODEC_ID_MPEG1VIDEO || 3249 ctx->codec_id == CODEC_ID_MPEG2VIDEO || 3250 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC || 3251 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD) 3251 3252 { 3252 3253 if (!ringBuffer->isDVD()) 3253 3254 MpegPreProcessPkt(curstream, pkt); 3254 3255 } 3255 else if (c ontext->codec_id == CODEC_ID_H264)3256 else if (ctx->codec_id == CODEC_ID_H264) 3256 3257 { 3257 3258 H264PreProcessPkt(curstream, pkt); 3258 3259 } … … 3298 3299 } 3299 3300 3300 3301 if (len > 0 && 3301 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3302 c urstream->codec->codec_id == CODEC_ID_MPEG2VBI)3302 ctx->codec_type == CODEC_TYPE_DATA && 3303 ctx->codec_id == CODEC_ID_MPEG2VBI) 3303 3304 { 3304 3305 ProcessVBIDataPacket(curstream, pkt); 3305 3306 … … 3308 3309 } 3309 3310 3310 3311 if (len > 0 && 3311 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3312 c urstream->codec->codec_id == CODEC_ID_DVB_VBI)3312 ctx->codec_type == CODEC_TYPE_DATA && 3313 ctx->codec_id == CODEC_ID_DVB_VBI) 3313 3314 { 3314 3315 ProcessDVBDataPacket(curstream, pkt); 3315 3316 … … 3318 3319 } 3319 3320 3320 3321 if (len > 0 && 3321 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3322 c urstream->codec->codec_id == CODEC_ID_DSMCC_B)3322 ctx->codec_type == CODEC_TYPE_DATA && 3323 ctx->codec_id == CODEC_ID_DSMCC_B) 3323 3324 { 3324 3325 ProcessDSMCCPacket(curstream, pkt); 3325 3326 … … 3339 3340 } 3340 3341 3341 3342 // we don't care about other data streams 3342 if (c urstream->codec->codec_type == CODEC_TYPE_DATA)3343 if (ctx->codec_type == CODEC_TYPE_DATA) 3343 3344 { 3344 3345 av_free_packet(pkt); 3345 3346 continue; 3346 3347 } 3347 3348 3348 if (!c urstream->codec->codec)3349 if (!ctx->codec) 3349 3350 { 3350 3351 VERBOSE(VB_PLAYBACK, LOC + 3351 3352 QString("No codec for stream index %1, type(%2) id(%3:%4)") 3352 3353 .arg(pkt->stream_index) 3353 .arg(codec_type_string(c urstream->codec->codec_type))3354 .arg(codec_id_string(c urstream->codec->codec_id))3355 .arg(c urstream->codec->codec_id));3354 .arg(codec_type_string(ctx->codec_type)) 3355 .arg(codec_id_string(ctx->codec_id)) 3356 .arg(ctx->codec_id)); 3356 3357 av_free_packet(pkt); 3357 3358 continue; 3358 3359 } … … 3361 3362 have_err = false; 3362 3363 3363 3364 avcodeclock.lock(); 3364 int ctype = c urstream->codec->codec_type;3365 int ctype = ctx->codec_type; 3365 3366 int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; 3366 3367 int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; 3367 3368 int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; … … 3386 3387 3387 3388 // detect switches between stereo and dual languages 3388 3389 bool wasDual = audSubIdx != -1; 3389 bool isDual = c urstream->codec->avcodec_dual_language;3390 bool isDual = ctx->avcodec_dual_language; 3390 3391 if ((wasDual && !isDual) || (!wasDual && isDual)) 3391 3392 { 3392 3393 SetupAudioStreamSubIndexes(audIdx); … … 3394 3395 } 3395 3396 3396 3397 bool do_ac3_passthru = 3397 (allow_ac3_passthru && !transcoding && 3398 (curstream->codec->codec_id == CODEC_ID_AC3)); 3398 (allow_ac3_passthru && !transcoding && 3399 ctx->channels >= (int)max_channels && 3400 (ctx->codec_id == CODEC_ID_AC3)); 3399 3401 bool do_dts_passthru = 3400 3402 (allow_dts_passthru && !transcoding && 3401 (c urstream->codec->codec_id == CODEC_ID_DTS));3403 (ctx->codec_id == CODEC_ID_DTS)); 3402 3404 bool using_passthru = do_ac3_passthru || do_dts_passthru; 3403 3405 3404 3406 // detect channels on streams that need 3405 3407 // to be decoded before we can know this 3406 3408 bool already_decoded = false; 3407 if (!c urstream->codec->channels)3409 if (!ctx->channels) 3408 3410 { 3409 3411 QMutexLocker locker(&avcodeclock); 3410 3412 VERBOSE(VB_IMPORTANT, LOC + … … 3415 3417 { 3416 3418 // for passthru let it select the max number 3417 3419 // of channels 3418 c urstream->codec->channels = 0;3419 c urstream->codec->request_channels = 0;3420 ctx->channels = 0; 3421 ctx->request_channels = 0; 3420 3422 } 3421 3423 else 3422 3424 { 3423 c urstream->codec->channels = audioOut.channels;3424 c urstream->codec->request_channels =3425 ctx->channels = audioOut.channels; 3426 ctx->request_channels = 3425 3427 audioOut.channels; 3426 3428 } 3427 3429 ret = avcodec_decode_audio( 3428 c urstream->codec, audioSamples,3430 ctx, audioSamples, 3429 3431 &data_size, ptr, len); 3430 3432 already_decoded = true; 3431 3433 3432 reselectAudioTrack |= c urstream->codec->channels;3434 reselectAudioTrack |= ctx->channels; 3433 3435 } 3434 3436 3437 if (ctx->codec_id == CODEC_ID_AC3 && 3438 !ff_ac3_parse_header(ptr, &hdr)) 3439 { 3440 if (hdr.channels != last_ac3_channels) 3441 { 3442 last_ac3_channels = ctx->channels = hdr.channels; 3443 SetupAudioStream(); 3444 } 3445 } 3446 3435 3447 if (reselectAudioTrack) 3436 3448 { 3437 3449 QMutexLocker locker(&avcodeclock); … … 3445 3457 .av_stream_index; 3446 3458 audSubIdx = selectedTrack[kTrackTypeAudio] 3447 3459 .av_substream_index; 3460 ctx = curstream->codec; 3448 3461 } 3449 3462 3450 3463 if (firstloop && pkt->pts != (int64_t)AV_NOPTS_VALUE) … … 3476 3489 if (audioOut.do_passthru) 3477 3490 { 3478 3491 data_size = pkt->size; 3479 bool dts = CODEC_ID_DTS == c urstream->codec->codec_id;3492 bool dts = CODEC_ID_DTS == ctx->codec_id; 3480 3493 ret = encode_frame(dts, ptr, len, 3481 3494 audioSamples, data_size); 3482 3495 } 3483 3496 else 3484 3497 { 3485 AVCodecContext *ctx = curstream->codec;3486 3487 3498 if ((ctx->channels == 0) || 3488 3499 (ctx->channels > audioOut.channels)) 3489 3500 { … … 3492 3503 3493 3504 if (!already_decoded) 3494 3505 { 3495 curstream->codec->request_channels = 3496 audioOut.channels; 3506 ctx->request_channels = audioOut.channels; 3497 3507 ret = avcodec_decode_audio( 3498 3508 ctx, audioSamples, &data_size, ptr, len); 3499 3509 } … … 3510 3520 audIdx = -1; 3511 3521 AutoSelectAudioTrack(); 3512 3522 data_size = 0; 3523 ctx = curstream->codec; 3513 3524 } 3514 3525 } 3515 3526 avcodeclock.unlock(); … … 3527 3538 3528 3539 // calc for next frame 3529 3540 lastapts += (long long)((double)(data_size * 1000) / 3530 (curstream->codec->channels * 2) / 3531 curstream->codec->sample_rate); 3541 (ctx->channels * 2) / ctx->sample_rate); 3532 3542 3533 3543 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, 3534 3544 LOC + QString("audio timecode %1 %2 %3 %4") … … 3588 3598 continue; 3589 3599 } 3590 3600 3591 AVCodecContext *context = curstream->codec;3592 3601 AVFrame mpa_pic; 3593 3602 bzero(&mpa_pic, sizeof(AVFrame)); 3594 3603 … … 3603 3612 // HACK 3604 3613 while (!gotpicture && count < 5) 3605 3614 { 3606 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3615 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3607 3616 &gotpicture, ptr, len); 3608 3617 count++; 3609 3618 } 3610 3619 } 3611 3620 else 3612 3621 { 3613 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3622 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3614 3623 &gotpicture, ptr, len); 3615 3624 } 3616 3625 } 3617 3626 else 3618 3627 { 3619 ret = avcodec_decode_video(c ontext, &mpa_pic,3628 ret = avcodec_decode_video(ctx, &mpa_pic, 3620 3629 &gotpicture, ptr, len); 3621 3630 // Reparse it to not drop the DVD still frame 3622 3631 if (decodeStillFrame) 3623 ret = avcodec_decode_video(c ontext, &mpa_pic,3632 ret = avcodec_decode_video(ctx, &mpa_pic, 3624 3633 &gotpicture, ptr, len); 3625 3634 } 3626 3635 avcodeclock.unlock(); … … 3687 3696 3688 3697 img_convert(&tmppicture, PIX_FMT_YUV420P, 3689 3698 (AVPicture *)&mpa_pic, 3690 c ontext->pix_fmt,3691 c ontext->width,3692 c ontext->height);3699 ctx->pix_fmt, 3700 ctx->width, 3701 ctx->height); 3693 3702 3694 3703 if (xf) 3695 3704 { … … 3712 3721 (temppts + 10000 > lastvpts || temppts < 0)) 3713 3722 { 3714 3723 temppts = lastvpts; 3715 temppts += (long long)(1000 * av_q2d(c ontext->time_base));3724 temppts += (long long)(1000 * av_q2d(ctx->time_base)); 3716 3725 // MPEG2 frames can be repeated, update pts accordingly 3717 3726 temppts += (long long)(mpa_pic.repeat_pict * 500 3718 * av_q2d(c urstream->codec->time_base));3727 * av_q2d(ctx->time_base)); 3719 3728 } 3720 3729 3721 3730 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + … … 3751 3760 picframe->frameNumber = framesPlayed; 3752 3761 GetNVP()->ReleaseNextVideoFrame(picframe, temppts); 3753 3762 if (d->HasMPEG2Dec() && mpa_pic.data[3]) 3754 c ontext->release_buffer(context, &mpa_pic);3763 ctx->release_buffer(ctx, &mpa_pic); 3755 3764 3756 3765 decoded_video_frame = picframe; 3757 3766 gotvideo = 1; … … 3810 3819 } 3811 3820 default: 3812 3821 { 3813 AVCodecContext *enc = curstream->codec;3814 3822 VERBOSE(VB_IMPORTANT, LOC_ERR + 3815 3823 QString("Decoding - id(%1) type(%2)") 3816 .arg(codec_id_string( enc->codec_id))3817 .arg(codec_type_string( enc->codec_type)));3824 .arg(codec_id_string(ctx->codec_id)) 3825 .arg(codec_type_string(ctx->codec_type))); 3818 3826 have_err = true; 3819 3827 break; 3820 3828 } … … 3972 3980 AVStream *curstream = NULL; 3973 3981 AVCodecContext *codec_ctx = NULL; 3974 3982 AudioInfo old_in = audioIn; 3975 AudioInfo old_out = audioOut;3976 3983 bool using_passthru = false; 3977 3984 3978 3985 if ((currentTrack[kTrackTypeAudio] >= 0) && … … 3985 3992 assert(curstream->codec); 3986 3993 codec_ctx = curstream->codec; 3987 3994 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3995 codec_ctx->channels >= (int)max_channels && 3988 3996 (codec_ctx->codec_id == CODEC_ID_AC3)); 3989 3997 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3990 3998 (codec_ctx->codec_id == CODEC_ID_DTS)); … … 4002 4010 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4003 4011 4004 4012 audioOut = audioIn = info; 4005 if (using_passthru) 4006 { 4007 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 4008 AudioInfo digInfo = audioOut; 4009 if (!disable_passthru) 4010 { 4011 digInfo.channels = 2; 4012 digInfo.sample_rate = 48000; 4013 digInfo.sample_size = 4; 4014 } 4015 if (audioOut.channels > (int) max_channels) 4016 { 4017 audioOut.channels = (int) max_channels; 4018 audioOut.sample_size = audioOut.channels * 2; 4019 codec_ctx->channels = audioOut.channels; 4020 } 4021 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 4022 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 4023 .arg(digInfo.toString()) 4024 .arg(old_in.toString()).arg(old_out.toString()) 4025 .arg(audioIn.toString()).arg(audioOut.toString())); 4026 4027 if (digInfo.sample_rate > 0) 4028 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 4029 4030 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 4031 digInfo.sample_rate, audioIn.do_passthru); 4032 // allow the audio stuff to reencode 4033 GetNVP()->SetAudioCodec(codec_ctx); 4034 GetNVP()->ReinitAudio(); 4035 return true; 4036 } 4037 else 4038 { 4039 if (audioOut.channels > (int) max_channels) 4040 { 4041 audioOut.channels = (int) max_channels; 4042 audioOut.sample_size = audioOut.channels * 2; 4043 codec_ctx->channels = audioOut.channels; 4044 } 4045 } 4046 4013 4047 4014 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4048 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") 4049 .arg(old_in.toString()).arg(old_out.toString()) 4050 .arg(audioIn.toString()).arg(audioOut.toString())); 4015 QString("\n\t\t\tfrom %1 to %2") 4016 .arg(old_in.toString()).arg(audioOut.toString())); 4051 4017 4052 4018 if (audioOut.sample_rate > 0) 4053 4019 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4054 4020 4055 GetNVP()->SetAudioParams(audioOut.bps(), audio Out.channels,4021 GetNVP()->SetAudioParams(audioOut.bps(), audioIn.channels, 4056 4022 audioOut.sample_rate, 4057 audio In.do_passthru);4023 audioOut.do_passthru); 4058 4024 4059 // allow the audio stuff to reencode4060 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);4061 4025 QString errMsg = GetNVP()->ReinitAudio(); 4062 bool audiook = errMsg.isEmpty();4063 4026 4064 4027 return true; 4065 4028 } -
libs/libmythtv/tv_play.h
314 314 void ChangeSpeed(int direction); 315 315 void ToggleTimeStretch(void); 316 316 void ChangeTimeStretch(int dir, bool allowEdit = true); 317 void ToggleUpmix(void); 317 318 void ChangeAudioSync(int dir, bool allowEdit = true); 318 319 float StopFFRew(void); 319 320 void ChangeFFRew(int direction); -
libs/libmythtv/NuppelVideoPlayer.h
685 685 int audio_bits; 686 686 int audio_samplerate; 687 687 float audio_stretchfactor; 688 void *audio_codec;689 688 bool audio_passthru; 690 689 691 690 // Picture-in-Picture -
libs/libmythtv/tv_play.cpp
348 348 REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 349 349 REG_KEY("TV Playback", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 350 350 REG_KEY("TV Playback", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 351 REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U"); 351 352 REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture mode", 352 353 "V"); 353 354 REG_KEY("TV Playback", "TOGGLEPIPWINDOW", "Toggle active PiP window", "B"); … … 480 481 Teletext F2,F3,F4,F5,F6,F7,F8 481 482 ITV F2,F3,F4,F5,F6,F7,F12 482 483 483 Playback: Ctrl-B,Ctrl-G,Ctrl-Y 484 Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U 484 485 */ 485 486 } 486 487 … … 2710 2711 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2711 2712 action == "STRETCHINC" || action == "STRETCHDEC" || 2712 2713 action == "MUTE" || action == "TOGGLEASPECT" || 2713 action == "TOGGLEFILL" )2714 action == "TOGGLEFILL" || action == "TOGGLEUPMIX") 2714 2715 { 2715 2716 passThru = 1; 2716 2717 handled = false; … … 2725 2726 else 2726 2727 handled = false; 2727 2728 } 2728 2729 2729 2730 if (!passThru) 2730 2731 return; 2731 2732 } 2732 2733 2733 2734 if (zoomMode) 2734 2735 { 2735 2736 int passThru = 0; … … 2765 2766 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2766 2767 action == "STRETCHINC" || action == "STRETCHDEC" || 2767 2768 action == "MUTE" || action == "PAUSE" || 2768 action == "CLEAROSD" )2769 action == "CLEAROSD" || action == "TOGGLEUPMIX") 2769 2770 { 2770 2771 passThru = 1; 2771 2772 handled = false; … … 2777 2778 if (!passThru) 2778 2779 return; 2779 2780 } 2780 2781 2781 2782 if (dialogname != "" && GetOSD() && GetOSD()->DialogShowing(dialogname)) 2782 2783 { 2783 2784 for (unsigned int i = 0; i < actions.size() && !handled; i++) … … 3036 3037 return; 3037 3038 } 3038 3039 } 3039 3040 3040 3041 for (unsigned int i = 0; i < actions.size() && !handled; i++) 3041 3042 { 3042 3043 QString action = actions[i]; … … 3070 3071 ChangeTimeStretch(0); // just display 3071 3072 else if (action == "TOGGLESTRETCH") 3072 3073 ToggleTimeStretch(); 3074 else if (action == "TOGGLEUPMIX") 3075 ToggleUpmix(); 3073 3076 else if (action == "CYCLECOMMSKIPMODE") { 3074 3077 SetAutoCommercialSkip((enum commSkipMode) 3075 3078 ((autoCommercialSkip + 1) % CommSkipModes)); … … 6054 6057 } 6055 6058 } 6056 6059 6060 void TV::ToggleUpmix() 6061 { 6062 AudioOutput *aud = nvp->getAudioOutput(); 6063 if (!aud) 6064 return; 6065 QString text; 6066 if (aud->ToggleUpmix()) 6067 text = tr("Upmixer On"); 6068 else 6069 text = tr("Upmixer Off"); 6070 6071 if (GetOSD() && !browsemode) 6072 GetOSD()->SetSettingsText(text, 5); 6073 } 6074 6075 6057 6076 // dir in 10ms jumps 6058 6077 void TV::ChangeAudioSync(int dir, bool allowEdit) 6059 6078 { … … 7300 7319 7301 7320 ChangeTimeStretch(0, !floatRead); // just display 7302 7321 } 7322 else if (action == "TOGGLEUPMIX") 7323 ToggleUpmix(); 7303 7324 else if (action.left(11) == "SELECTSCAN_") 7304 7325 activenvp->SetScanType((FrameScanType) action.right(1).toInt()); 7305 7326 else if (action.left(15) == "TOGGLEAUDIOSYNC") … … 7547 7568 subitem = new OSDGenericTree(item, tr("1.5X"), "ADJUSTSTRETCH1.5", 7548 7569 (speedX100 == 150) ? 1 : 0, NULL, 7549 7570 "STRETCHGROUP"); 7571 7572 item = new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX"); 7550 7573 7551 7574 // add scan mode override settings to menu 7552 7575 FrameScanType scan_type = kScan_Ignore; -
libs/libmythtv/avformatdecoder.h
264 264 bool allow_dts_passthru; 265 265 bool disable_passthru; 266 266 uint max_channels; 267 uint last_ac3_channels; 267 268 268 269 VideoFrame *dummy_frame; 269 270 -
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 } ; -
libs/libmyth/audiooutputbase.h
48 48 virtual void Reconfigure(int audio_bits, 49 49 int audio_channels, 50 50 int audio_samplerate, 51 bool audio_passthru, 52 void *audio_codec = NULL); 51 bool audio_passthru); 53 52 54 53 // do AddSamples calls block? 55 54 virtual void SetBlocking(bool blocking); … … 59 58 60 59 virtual void SetStretchFactor(float factor); 61 60 virtual float GetStretchFactor(void); 61 virtual bool ToggleUpmix(void); 62 62 63 63 virtual void Reset(void); 64 64 … … 139 139 QString audio_passthru_device; 140 140 141 141 bool audio_passthru; 142 bool audio_enc; 143 bool audio_reenc; 142 144 143 145 float audio_stretchfactor; 144 AVCodecContext *audio_codec;145 146 AudioOutputSource source; 146 147 147 148 bool killaudio; … … 167 168 FreeSurround *upmixer; 168 169 169 170 int source_audio_channels; 171 int source_audio_samplerate; 170 172 int source_audio_bytes_per_sample; 171 173 bool needs_upmix; 172 174 int surround_mode; 175 float old_audio_stretchfactor; 173 176 174 177 bool blocking; // do AddSamples calls block? 175 178 -
libs/libmyth/audiooutputalsa.cpp
37 37 KillAudio(); 38 38 } 39 39 40 void SetIECBits(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_GENERAL, QString("Setting IEC958 status bits")); 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) == spdif_index) 63 break; 64 } 65 snd_ctl_elem_id_alloca(&cid); 66 snd_ctl_elem_list_get_id(clist, cidx, cid); 67 snd_ctl_elem_value_alloca(&cval); 68 snd_ctl_elem_value_set_id(cval, cid); 69 snd_ctl_elem_read(ctl,cval); 70 snd_ctl_elem_value_get_iec958(cval, &iec958); 71 72 if (!audio) 73 iec958.status[0] |= IEC958_AES0_NONAUDIO; 74 else 75 iec958.status[0] &= ~IEC958_AES0_NONAUDIO; 76 77 snd_ctl_elem_value_set_iec958(cval, &iec958); 78 snd_ctl_elem_write(ctl, cval); 79 80 } 81 40 82 bool AudioOutputALSA::OpenDevice() 41 83 { 42 84 snd_pcm_format_t format; 43 85 unsigned int buffer_time, period_time; 44 86 int err; 87 QString real_device; 45 88 46 89 if (pcm_handle != NULL) 47 90 CloseDevice(); 48 91 49 92 pcm_handle = NULL; 50 93 numbadioctls = 0; 94 95 if (audio_passthru || audio_enc) 96 { 97 real_device = audio_passthru_device; 98 SetIECBits(false); 99 } 100 else 101 { 102 real_device = audio_main_device; 103 SetIECBits(true); 104 } 51 105 52 QString real_device = (audio_passthru) ?53 audio_passthru_device : audio_main_device;54 55 106 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 56 107 .arg(real_device)); 57 108 -
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); 12 15 ~AudioOutputDigitalEncoder(); 13 16 14 bool Init(CodecID codec_id, int bitrate, int samplerate, int channels); 17 bool Init(CodecID codec_id, int bitrate, int samplerate, 18 int channels, bool reencoding); 15 19 void Dispose(void); 16 size_t Encode(short * buff); 17 18 inline char *GetFrameBuffer(void); 20 size_t Encode(void *buf, int len); 21 void GetFrames(void *ptr, int maxlen); 19 22 size_t FrameSize(void) const { return one_frame_bytes; } 20 char *GetOutBuff(void) const { return outbuf;}23 int Buffered(void) const { return inbuflen; } 21 24 22 25 public: 23 26 size_t audio_bytes_per_sample; 24 27 25 28 private: 26 29 AVCodecContext *av_context; 27 char *outbuf; 28 int outbuf_size; 29 char *frame_buffer; 30 char outbuf[OUTBUFSIZE]; 31 char inbuf[INBUFSIZE]; 32 int outbuflen; 33 int inbuflen; 30 34 size_t one_frame_bytes; 35 bool reorder; 31 36 }; 32 37 33 inline char *AudioOutputDigitalEncoder::GetFrameBuffer(void)34 {35 if (!frame_buffer && av_context)36 frame_buffer = new char [one_frame_bytes];37 38 return frame_buffer;39 }40 41 38 #endif -
libs/libmyth/audiooutputbase.cpp
37 37 38 38 audio_main_device(QDeepCopy<QString>(laudio_main_device)), 39 39 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 40 audio_passthru(false), audio_stretchfactor(1.0f), 40 audio_passthru(false), audio_enc(false), 41 audio_reenc(false), audio_stretchfactor(1.0f), 41 42 42 audio_codec(NULL),43 43 source(lsource), killaudio(false), 44 44 45 45 pauseaudio(false), audio_actually_paused(false), … … 54 54 pSoundStretch(NULL), 55 55 encoder(NULL), 56 56 upmixer(NULL), 57 57 58 source_audio_channels(-1), 59 source_audio_samplerate(0), 58 60 source_audio_bytes_per_sample(0), 59 61 needs_upmix(false), 60 62 surround_mode(FreeSurround::SurroundModePassive), 63 old_audio_stretchfactor(1.0), 61 64 62 65 blocking(false), 63 66 … … 124 127 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 125 128 .arg(audio_stretchfactor)); 126 129 pSoundStretch = new soundtouch::SoundTouch(); 127 if (audio_codec) 128 { 129 if (!encoder) 130 { 131 VERBOSE(VB_AUDIO, LOC + 132 QString("Creating Encoder for codec %1 origfs %2") 133 .arg(audio_codec->codec_id) 134 .arg(audio_codec->frame_size)); 130 pSoundStretch->setSampleRate(audio_samplerate); 131 pSoundStretch->setChannels(upmixer ? 132 configured_audio_channels : source_audio_channels); 135 133 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->channels141 ))142 {143 // eeks144 delete encoder;145 encoder = NULL;146 VERBOSE(VB_AUDIO, LOC +147 QString("Failed to Create Encoder"));148 }149 }150 }151 if (audio_codec && encoder)152 {153 pSoundStretch->setSampleRate(audio_codec->sample_rate);154 pSoundStretch->setChannels(audio_codec->channels);155 }156 else157 {158 pSoundStretch->setSampleRate(audio_samplerate);159 pSoundStretch->setChannels(audio_channels);160 }161 162 134 pSoundStretch->setTempo(audio_stretchfactor); 163 135 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); 164 136 165 137 // dont need these with only tempo change 166 138 //pSoundStretch->setPitch(1.0); 167 139 //pSoundStretch->setRate(1.0); 168 169 140 //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true); 170 141 //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false); 171 142 } … … 184 155 return audio_stretchfactor; 185 156 } 186 157 158 bool AudioOutputBase::ToggleUpmix(void) 159 { 160 if (audio_passthru) 161 return false; 162 if (configured_audio_channels == 6) 163 configured_audio_channels = 2; 164 else 165 configured_audio_channels = 6; 166 167 Reconfigure(audio_bits, source_audio_channels, 168 source_audio_samplerate, audio_passthru); 169 return (configured_audio_channels == 6); 170 } 171 187 172 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 188 int laudio_samplerate, bool laudio_passthru, 189 void *laudio_codec) 173 int laudio_samplerate, bool laudio_passthru) 190 174 { 191 int codec_id = CODEC_ID_NONE;192 int lcodec_id = CODEC_ID_NONE;193 int lcchannels = 0;194 int cchannels = 0;195 175 int lsource_audio_channels = laudio_channels; 196 176 bool lneeds_upmix = false; 197 198 if (laudio_codec) 177 bool laudio_reenc = false; 178 179 // Are we reencoding a (previously) timestretched bitstream? 180 if (laudio_channels > 2 && !laudio_passthru) 181 laudio_reenc = true; 182 183 // Enough channels? Upmix if not 184 if (laudio_channels < configured_audio_channels && !laudio_passthru) 199 185 { 200 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;201 laudio_bits = 16;202 laudio_channels = 2;203 lsource_audio_channels = laudio_channels;204 laudio_samplerate = 48000;205 lcchannels = ((AVCodecContext*)laudio_codec)->channels;206 }207 208 if (audio_codec)209 {210 codec_id = audio_codec->codec_id;211 cchannels = ((AVCodecContext*)audio_codec)->channels;212 }213 214 if ((configured_audio_channels == 6) &&215 !(laudio_codec || audio_codec))216 {217 186 laudio_channels = configured_audio_channels; 218 187 lneeds_upmix = true; 219 188 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); … … 225 194 laudio_samplerate == audio_samplerate && !need_resampler && 226 195 laudio_passthru == audio_passthru && 227 196 lneeds_upmix == needs_upmix && 228 l codec_id == codec_id && lcchannels == cchannels);197 laudio_reenc == audio_reenc); 229 198 bool upmix_deps = 230 199 (lsource_audio_channels == source_audio_channels); 231 200 if (general_deps && upmix_deps) … … 252 221 waud = raud = 0; 253 222 audio_actually_paused = false; 254 223 255 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);256 224 audio_channels = laudio_channels; 257 225 source_audio_channels = lsource_audio_channels; 258 226 audio_bits = laudio_bits; 259 audio_samplerate = laudio_samplerate;260 audio_ codec = (AVCodecContext*)laudio_codec;227 source_audio_samplerate = audio_samplerate = laudio_samplerate; 228 audio_reenc = laudio_reenc; 261 229 audio_passthru = laudio_passthru; 262 230 needs_upmix = lneeds_upmix; 263 231 … … 268 236 Error("AudioOutput only supports 8 or 16bit audio."); 269 237 return; 270 238 } 271 audio_bytes_per_sample = audio_channels * audio_bits / 8;272 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;273 239 274 240 need_resampler = false; 275 241 killaudio = false; … … 278 244 internal_vol = gContext->GetNumSetting("MythControlsVolume", 0); 279 245 280 246 numlowbuffer = 0; 247 248 // Encode to AC-3 if not passing thru, there's more than 2 channels 249 // and a passhru device is defined 250 // This won't reencode timestretched 2ch AC-3 but there's no point doing so 251 if (!audio_passthru && audio_channels > 2 && 252 !audio_passthru_device.isEmpty()) 253 { 254 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); 255 encoder = new AudioOutputDigitalEncoder(); 256 if (!encoder->Init(CODEC_ID_AC3, 448000, 48000, 257 audio_channels, audio_reenc)) 258 { 259 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 260 delete encoder; 261 encoder = NULL; 262 } 263 audio_channels = 2; 264 audio_enc = true; 265 } 266 267 if(audio_passthru) 268 // Soundcard expects a 2ch 48k stream 269 audio_channels = 2; 270 271 audio_bytes_per_sample = audio_channels * audio_bits / 8; 272 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 281 273 274 // Always resample to 48k - many cards can't do anything else 275 // and ALSA will do it with linear interpolation (yuk) if we don't anyway 276 if (audio_samplerate != 48000) 277 { 278 int error; 279 audio_samplerate = 48000; 280 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2") 281 .arg(laudio_samplerate).arg(audio_samplerate)); 282 src_ctx = src_new (SRC_SINC_BEST_QUALITY, audio_channels, &error); 283 if (error) 284 { 285 Error(QString("Error creating resampler, the error was: %1") 286 .arg(src_strerror(error)) ); 287 pthread_mutex_unlock(&avsync_lock); 288 pthread_mutex_unlock(&audio_buflock); 289 src_ctx = NULL; 290 return; 291 } 292 src_data.src_ratio = (double) audio_samplerate / laudio_samplerate; 293 src_data.data_in = src_in; 294 src_data.data_out = src_out; 295 src_data.output_frames = 16384*6; 296 need_resampler = true; 297 } 298 282 299 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 283 300 .arg(audio_main_device).arg(audio_channels) 284 301 .arg(source_audio_channels).arg(audio_samplerate)); … … 314 331 current_seconds = -1; 315 332 source_bitrate = -1; 316 333 317 // NOTE: this won't do anything as above samplerate vars are set equal318 // Check if we need the resampler319 if (audio_samplerate != laudio_samplerate)320 {321 int error;322 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")323 .arg(laudio_samplerate).arg(audio_samplerate));324 src_ctx = src_new (SRC_SINC_BEST_QUALITY, audio_channels, &error);325 if (error)326 {327 Error(QString("Error creating resampler, the error was: %1")328 .arg(src_strerror(error)) );329 pthread_mutex_unlock(&avsync_lock);330 pthread_mutex_unlock(&audio_buflock);331 return;332 }333 src_data.src_ratio = (double) audio_samplerate / laudio_samplerate;334 src_data.data_in = src_in;335 src_data.data_out = src_out;336 src_data.output_frames = 16384*6;337 need_resampler = true;338 }339 340 334 if (needs_upmix) 341 335 { 342 336 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); … … 351 345 (FreeSurround::SurroundMode)surround_mode); 352 346 353 347 VERBOSE(VB_AUDIO, LOC + 354 QString(" create upmixer done with surround mode %1")348 QString("Create upmixer done with surround mode %1") 355 349 .arg(surround_mode)); 356 350 } 357 351 358 352 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 359 353 .arg(audio_stretchfactor)); 360 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")361 .arg((audio_codec) ?362 codec_id_string(audio_codec->codec_id) : "not set"));363 354 364 if (redo_stretch) 365 { 366 float laudio_stretchfactor = audio_stretchfactor; 367 delete pSoundStretch; 368 pSoundStretch = NULL; 369 audio_stretchfactor = 0.0f; 370 SetStretchFactorLocked(laudio_stretchfactor); 371 } 372 else 373 { 374 SetStretchFactorLocked(audio_stretchfactor); 375 if (pSoundStretch) 376 { 377 // if its passthru then we need to reencode 378 if (audio_codec) 379 { 380 if (!encoder) 381 { 382 VERBOSE(VB_AUDIO, LOC + 383 QString("Creating Encoder for codec %1") 384 .arg(audio_codec->codec_id)); 355 SetStretchFactorLocked(old_audio_stretchfactor); 385 356 386 encoder = new AudioOutputDigitalEncoder();387 if (!encoder->Init(audio_codec->codec_id,388 audio_codec->bit_rate,389 audio_codec->sample_rate,390 audio_codec->channels391 ))392 {393 // eeks394 delete encoder;395 encoder = NULL;396 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");397 }398 }399 }400 if (audio_codec && encoder)401 {402 pSoundStretch->setSampleRate(audio_codec->sample_rate);403 pSoundStretch->setChannels(audio_codec->channels);404 }405 else406 {407 pSoundStretch->setSampleRate(audio_samplerate);408 pSoundStretch->setChannels(audio_channels);409 }410 }411 }412 413 357 // Setup visualisations, zero the visualisations buffers 414 358 prepareVisuals(); 415 359 … … 455 399 VERBOSE(VB_AUDIO, LOC + "Killing AudioOutputDSP"); 456 400 killaudio = true; 457 401 StopOutputThread(); 402 403 pthread_mutex_lock(&audio_buflock); 458 404 459 405 // Close resampler? 460 406 if (src_ctx) 407 { 461 408 src_delete(src_ctx); 409 src_ctx = NULL; 410 } 411 462 412 need_resampler = false; 463 413 464 414 // close sound stretcher … … 466 416 { 467 417 delete pSoundStretch; 468 418 pSoundStretch = NULL; 419 old_audio_stretchfactor = audio_stretchfactor; 420 audio_stretchfactor = 1.0; 469 421 } 470 422 471 423 if (encoder) … … 480 432 upmixer = NULL; 481 433 } 482 434 needs_upmix = false; 435 audio_enc = false; 483 436 484 437 CloseDevice(); 485 438 439 pthread_mutex_unlock(&audio_buflock); 486 440 killAudioLock.unlock(); 487 441 } 488 442 … … 591 545 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 592 546 ret = (long long)(ret * audio_stretchfactor); 593 547 594 #if 1595 548 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 596 549 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 597 550 .arg(now.tv_sec).arg(now.tv_usec) … … 600 553 .arg(audiotime) 601 554 .arg(audio_stretchfactor) 602 555 ); 603 #endif604 556 605 557 ret += audiotime; 606 558 … … 638 590 639 591 soundcard_buffer = getBufferedOnSoundcard(); // bytes 640 592 totalbuffer = audiolen(false) + soundcard_buffer; 641 593 642 594 // include algorithmic latencies 643 595 if (pSoundStretch) 644 {645 // add the effect of any unused but processed samples,646 // AC3 reencode does this647 totalbuffer += (int)(pSoundStretch->numSamples() *648 audio_bytes_per_sample);649 // add the effect of unprocessed samples in time stretch algo650 596 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 651 597 audio_bytes_per_sample) / audio_stretchfactor); 652 }653 598 654 599 if (upmixer && needs_upmix) 655 {656 600 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 657 }658 601 602 if (encoder) 603 totalbuffer += encoder->Buffered(); 604 659 605 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 660 606 (audio_bytes_per_sample * effdspstretched)); 661 607 662 608 gettimeofday(&audiotime_updated, NULL); 663 #if 1 609 664 610 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 665 611 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 " 666 612 "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") … … 672 618 .arg(effdspstretched) 673 619 .arg(audio_bytes_per_sample) 674 620 .arg(audio_stretchfactor)); 675 #endif676 621 677 622 pthread_mutex_unlock(&avsync_lock); 678 623 pthread_mutex_unlock(&audio_buflock); … … 708 653 709 654 return false; // would overflow 710 655 } 656 657 pthread_mutex_lock(&audio_buflock); 711 658 712 659 // resample input if necessary 713 660 if (need_resampler && src_ctx) … … 741 688 // Call our function to do the work 742 689 _AddSamples(buffers, false, samples, timecode); 743 690 } 691 692 pthread_mutex_unlock(&audio_buflock); 744 693 745 694 return true; 746 695 } … … 776 725 .arg(timecode)); 777 726 return false; // would overflow 778 727 } 728 729 pthread_mutex_lock(&audio_buflock); 779 730 780 731 // resample input if necessary 781 732 if (need_resampler && src_ctx) … … 804 755 // Call our function to do the work 805 756 _AddSamples(buffer, true, samples, timecode); 806 757 } 758 759 pthread_mutex_unlock(&audio_buflock); 807 760 808 761 return true; 809 762 } … … 836 789 if (src_ctx) 837 790 { 838 791 int error = src_reset(src_ctx); 839 if (error) 792 if (error) 793 { 840 794 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 841 795 "Error occured while resetting resampler: %1") 842 796 .arg(src_strerror(error))); 797 src_ctx = NULL; 798 } 843 799 } 844 800 } 845 801 } … … 849 805 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 850 806 long long timecode) 851 807 { 852 pthread_mutex_lock(&audio_buflock);853 854 808 int len; // = samples * audio_bytes_per_sample; 855 809 int audio_bytes = audio_bits / 8; 856 810 int org_waud = waud; … … 871 825 if (upmixer && needs_upmix) 872 826 { 873 827 int out_samples = 0; 828 org_waud = waud; 874 829 int step = (interleaved)?source_audio_channels:1; 875 830 len = WaitForFreeSpace(samples); // test 831 876 832 for (int itemp = 0; itemp < samples; ) 877 833 { 878 // just in case it does a processing cycle, release the lock879 // to allow the output loop to do output880 pthread_mutex_unlock(&audio_buflock);881 834 if (audio_bytes == 2) 882 835 { 883 836 itemp += upmixer->putSamples( … … 894 847 source_audio_channels, 895 848 (interleaved) ? 0 : samples); 896 849 } 897 pthread_mutex_lock(&audio_buflock);898 850 899 851 int copy_samples = upmixer->numSamples(); 900 852 if (copy_samples) … … 913 865 (short*)(audiobuffer), (copy_samples - bdiff_samples)); 914 866 } 915 867 else 916 {917 868 upmixer->receiveSamples( 918 869 (short*)(audiobuffer + org_waud), copy_samples); 919 }870 920 871 org_waud = (org_waud + copy_len) % AUDBUFSIZE; 921 872 } 922 873 } … … 969 920 { 970 921 if (pSoundStretch) 971 922 { 972 973 923 // does not change the timecode, only the number of samples 974 924 // back to orig pos 975 925 org_waud = waud; … … 984 934 (len - bdiff) / abps); 985 935 } 986 936 else 987 {988 937 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 989 938 (audiobuffer + org_waud), 990 939 len / abps); 991 }992 940 993 if (encoder) 941 int nSamples = pSoundStretch->numSamples(); 942 len = WaitForFreeSpace(nSamples); 943 944 while ((nSamples = pSoundStretch->numSamples())) 994 945 { 995 // pull out a packet's worth and reencode it until we 996 // don't have enough for any more packets 997 soundtouch::SAMPLETYPE *temp_buff = 998 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 999 size_t frameSize = encoder->FrameSize()/abps; 946 if (nSamples > nSamplesToEnd) 947 nSamples = nSamplesToEnd; 948 949 nSamples = pSoundStretch->receiveSamples( 950 (soundtouch::SAMPLETYPE*) 951 (audiobuffer + org_waud), nSamples 952 ); 953 954 if (nSamples == nSamplesToEnd) { 955 org_waud = 0; 956 nSamplesToEnd = AUDBUFSIZE/abps; 957 } 958 else { 959 org_waud += nSamples * abps; 960 nSamplesToEnd -= nSamples; 961 } 962 963 } 964 965 } 1000 966 1001 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1002 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 1003 .arg(frameSize) 1004 .arg(encoder->FrameSize()) 1005 .arg(pSoundStretch->numSamples())); 967 // Encode to AC-3? 968 if (encoder) 969 { 970 971 org_waud = waud; 972 int bdiff = AUDBUFSIZE - org_waud; 973 int to_get = 0; 1006 974 1007 // process the same number of samples as it creates 1008 // a full encoded buffer just like before 1009 while (pSoundStretch->numSamples() >= frameSize) 1010 { 1011 int got = pSoundStretch->receiveSamples( 1012 temp_buff, frameSize); 1013 int amount = encoder->Encode(temp_buff); 1014 1015 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1016 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 1017 .arg(amount) 1018 .arg(got) 1019 .arg(pSoundStretch->numSamples())); 1020 1021 if (!amount) 1022 continue; 1023 1024 //len = WaitForFreeSpace(amount); 1025 char *ob = encoder->GetOutBuff(); 1026 if (amount >= bdiff) 1027 { 1028 memcpy(audiobuffer + org_waud, ob, bdiff); 1029 ob += bdiff; 1030 amount -= bdiff; 1031 org_waud = 0; 1032 } 1033 if (amount > 0) 1034 memcpy(audiobuffer + org_waud, ob, amount); 1035 1036 bdiff = AUDBUFSIZE - amount; 1037 org_waud += amount; 1038 } 975 if (bdiff < len) 976 { 977 encoder->Encode(audiobuffer + org_waud, bdiff); 978 to_get = encoder->Encode(audiobuffer, len - bdiff); 1039 979 } 1040 else 980 else 981 to_get = encoder->Encode(audiobuffer + org_waud, len); 982 983 if (to_get > 0) 1041 984 { 1042 int newLen = 0; 1043 int nSamples; 1044 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1045 audio_bytes_per_sample); 1046 do 985 986 if (to_get >= bdiff) 1047 987 { 1048 int samplesToGet = len/audio_bytes_per_sample; 1049 if (samplesToGet > nSamplesToEnd) 1050 { 1051 samplesToGet = nSamplesToEnd; 1052 } 988 encoder->GetFrames(audiobuffer + org_waud, bdiff); 989 to_get -= bdiff; 990 org_waud = 0; 991 } 992 if (to_get > 0) 993 encoder->GetFrames(audiobuffer + org_waud, to_get); 1053 994 1054 nSamples = pSoundStretch->receiveSamples( 1055 (soundtouch::SAMPLETYPE*) 1056 (audiobuffer + org_waud), samplesToGet); 1057 if (nSamples == nSamplesToEnd) 1058 { 1059 org_waud = 0; 1060 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1061 } 1062 else 1063 { 1064 org_waud += nSamples * audio_bytes_per_sample; 1065 nSamplesToEnd -= nSamples; 1066 } 995 org_waud += to_get; 1067 996 1068 newLen += nSamples * audio_bytes_per_sample;1069 len -= nSamples * audio_bytes_per_sample;1070 } while (nSamples > 0);1071 997 } 998 1072 999 } 1073 1000 1074 1001 waud = org_waud; 1075 1002 lastaudiolen = audiolen(false); 1076 1003 1077 1004 if (timecode < 0) 1078 {1079 1005 // mythmusic doesn't give timestamps.. 1080 1006 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1081 }1082 1007 1083 1008 samples_buffered += samples; 1084 1009 … … 1090 1015 1091 1016 if (interleaved) 1092 1017 { 1018 // Give original samples to mythmusic visualisation 1093 1019 dispatchVisual((unsigned char *)buffer, len, timecode, 1094 1020 source_audio_channels, audio_bits); 1095 1021 } 1096 1022 } 1097 1023 1098 pthread_mutex_unlock(&audio_buflock);1099 1024 } 1100 1025 1101 1026 void AudioOutputBase::Status() -
libs/libmyth/audiooutputdigitalencoder.cpp
27 27 28 28 AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) : 29 29 av_context(NULL), 30 outbuf (NULL),31 outbuf_size(0),32 frame_buffer(NULL),33 one_frame_bytes(0)30 outbuflen(0), 31 inbuflen(0), 32 one_frame_bytes(0), 33 reorder(true) 34 34 { 35 35 } 36 36 … … 47 47 av_free(av_context); 48 48 av_context = NULL; 49 49 } 50 51 if (outbuf)52 {53 delete [] outbuf;54 outbuf = NULL;55 outbuf_size = 0;56 }57 58 if (frame_buffer)59 {60 delete [] frame_buffer;61 frame_buffer = NULL;62 one_frame_bytes = 0;63 }64 50 } 65 51 66 52 //CODEC_ID_AC3 67 53 bool AudioOutputDigitalEncoder::Init( 68 CodecID codec_id, int bitrate, int samplerate, int channels )54 CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding) 69 55 { 70 56 AVCodec *codec; 71 57 int ret; 72 58 73 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 ")59 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 re=%5") 74 60 .arg(codec_id_string(codec_id)) 75 61 .arg(bitrate) 76 62 .arg(samplerate) 77 .arg(channels)); 63 .arg(channels) 64 .arg(reencoding)); 65 66 reorder = !reencoding; 78 67 79 //codec = avcodec_find_encoder(codec_id); 68 // We need to do this when called from mythmusic 69 avcodec_init(); 70 avcodec_register_all(); 80 71 // always AC3 as there is no DTS encoder at the moment 2005/1/9 81 72 codec = avcodec_find_encoder(CODEC_ID_AC3); 82 73 if (!codec) … … 105 96 audio_bytes_per_sample = bytes_per_frame; 106 97 one_frame_bytes = bytes_per_frame * av_context->frame_size; 107 98 108 outbuf_size = 16384; // ok for AC3 but DTS?109 outbuf = new char [outbuf_size];110 99 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 111 100 .arg(av_context->frame_size) 112 101 .arg(bytes_per_frame) … … 256 245 257 246 } AESHeader; 258 247 248 249 void reorder_6ch_ac3(void *buf, unsigned int len) { 250 unsigned short *src = (unsigned short *)buf; 251 unsigned short tmp; 252 unsigned int samples = len >> 1; 253 254 for (uint i = 0; i < samples; i += 6) { 255 tmp = src[i+4]; 256 src[i+4] = src[i+3]; 257 src[i+3] = src[i+2]; 258 src[i+2] = src[i+1]; 259 src[i+1] = tmp; 260 } 261 } 262 259 263 static int encode_frame( 260 264 bool dts, 261 265 unsigned char *data, 262 size_t &len)266 size_t enc_len) 263 267 { 264 size_t enc_len;265 268 int flags, sample_rate, bit_rate; 266 269 267 270 // we don't do any length/crc validation of the AC3 frame here; presumably … … 273 276 // anything with a bad CRC... 274 277 275 278 uint nr_samples = 0, block_len; 279 276 280 if (dts) 277 281 { 278 282 enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate); … … 293 297 #endif 294 298 } 295 299 296 if (enc_len == 0 || enc_len > len)297 {298 int l = len;299 len = 0;300 return l;301 }302 303 300 enc_len = min((uint)enc_len, block_len - 8); 304 301 305 302 //uint32_t x = *(uint32_t*)(data+8); 306 303 // in place swab 307 304 swab((const char *)data + 8, (char *)data + 8, enc_len); … … 348 345 break; 349 346 } 350 347 } 351 data[5] = 0 x00;348 data[5] = 0; 352 349 data[6] = (enc_len << 3) & 0xFF; 353 350 data[7] = (enc_len >> 5) & 0xFF; 354 351 memset(data + 8 + enc_len, 0, block_len - 8 - enc_len); 355 len = block_len;356 352 357 353 return enc_len; 358 354 } 359 355 360 // must have exactly 1 frames worth of data 361 size_t AudioOutputDigitalEncoder::Encode(short *buff) 356 size_t AudioOutputDigitalEncoder::Encode(void *buf, int len) 362 357 { 363 int encsize = 0;364 358 size_t outsize = 0; 365 359 366 // put data in the correct spot for encode frame 367 outsize = avcodec_encode_audio( 368 av_context, ((uchar*)outbuf) + 8, outbuf_size - 8, buff); 360 int fs = FrameSize(); 361 memcpy(inbuf+inbuflen, buf, len); 362 inbuflen += len; 363 int frames = inbuflen / fs; 369 364 370 size_t tmpsize = outsize; 365 while (frames--) 366 { 367 if (reorder) 368 reorder_6ch_ac3(inbuf, fs); 369 370 // put data in the correct spot for encode frame 371 outsize = avcodec_encode_audio( 372 av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf); 371 373 372 outsize = MAX_AC3_FRAME_SIZE;373 encsize = encode_frame(374 /*av_context->codec_id==CODEC_ID_DTS*/ false,375 (unsigned char*)outbuf, outsize);374 encode_frame( 375 /*av_context->codec_id==CODEC_ID_DTS*/ false, 376 (unsigned char*)outbuf + outbuflen, outsize 377 ); 376 378 377 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 378 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 379 .arg(tmpsize).arg(encsize).arg(outsize)); 379 outbuflen += MAX_AC3_FRAME_SIZE; 380 inbuflen -= fs; 381 memmove(inbuf, inbuf+fs, inbuflen); 382 } 380 383 381 return out size;384 return outbuflen; 382 385 } 386 387 void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen) 388 { 389 int len = (maxlen < outbuflen ? maxlen : outbuflen); 390 memcpy(ptr, outbuf, len); 391 outbuflen -= len; 392 memmove(outbuf, outbuf+len, outbuflen); 393 } -
libs/libmyth/audiooutput.h
34 34 virtual void Reconfigure(int audio_bits, 35 35 int audio_channels, 36 36 int audio_samplerate, 37 bool audio_passthru, 38 void* audio_codec = NULL) = 0; 37 bool audio_passthru) = 0; 39 38 40 39 virtual void SetStretchFactor(float factor); 41 40 virtual float GetStretchFactor(void) { return 1.0f; } 41 virtual bool ToggleUpmix(void) = 0; 42 42 43 43 // do AddSamples calls block? 44 44 virtual void SetBlocking(bool blocking) = 0; -
libs/libmythfreesurround/el_processor.cpp
192 192 // set lfe filter params 193 193 void sample_rate(unsigned int srate) { 194 194 // lfe filter is just straight through band limited 195 unsigned int cutoff = ( 250*N)/srate;195 unsigned int cutoff = (50*N)/srate; 196 196 for (unsigned f=0;f<=halfN;f++) { 197 197 if ((f>=2) && (f<cutoff)) 198 198 filter[5][f] = 1.0; -
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 //const float master_gain = 1.0/(1<<15); 69 //const float inv_master_gain = (1<<15); 68 //const float inv_master_gain = 1.0; 70 69 //#define INV_MASTER_GAIN * inv_master_gain 71 70 #define INV_MASTER_GAIN 72 71 … … 191 190 if (moviemode) 192 191 { 193 192 params.phasemode = 1; 194 params.center_width = 0; 195 params.gain = 1.0; 193 params.center_width = 40; 194 params.gain = 3.0; 195 params.dimension = 0.5; 196 196 } 197 197 else 198 198 { 199 params.center_width = 70; 200 // for 50, gain should be about 1.9, c/lr about 2.7 201 // for 70, gain should be about 3.1, c/lr about 1.5 199 params.center_width = 80; 202 200 params.gain = 3.1; 201 params.dimension = 0.3; 203 202 } 204 203 switch (surround_mode) 205 204 { -
programs/mythtranscode/transcode.cpp
55 55 56 56 // reconfigure sound out for new params 57 57 virtual void Reconfigure(int audio_bits, int audio_channels, 58 int audio_samplerate, bool audio_passthru, 59 void *audio_codec = NULL) 58 int audio_samplerate, bool audio_passthru) 60 59 { 61 60 (void)audio_samplerate; 62 61 (void)audio_passthru; 63 (void)audio_codec;64 62 65 63 ClearError(); 66 64 bits = audio_bits; … … 218 216 // Do nothing 219 217 return MUTE_OFF; 220 218 } 219 virtual bool ToggleUpmix(void) 220 { 221 // Do nothing 222 return false; 223 } 221 224 222 225 // These are pure virtual in AudioOutput, but we don't need them here 223 226 virtual void bufferOutputData(bool){ return; }