Ticket #5900: audioencoding-trunk.patch
File audioencoding-trunk.patch, 61.8 KB (added by , 15 years ago) |
---|
-
libs/libmythtv/NuppelVideoPlayer.cpp
212 212 audio_passthru_device(QString::null), 213 213 audio_channels(2), audio_bits(-1), 214 214 audio_samplerate(44100), audio_stretchfactor(1.0f), 215 audio_codec(NULL),216 215 // Picture-in-Picture 217 216 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 218 217 // Preview window support … … 885 884 if (audioOutput) 886 885 { 887 886 const AudioSettings settings( 888 audio_bits, audio_channels, audio_samplerate, 889 audio_passthru, audio_codec); 887 audio_bits, audio_channels, audio_samplerate, audio_passthru); 890 888 audioOutput->Reconfigure(settings); 889 if (audio_passthru) 890 audio_channels = 2; 891 891 errMsg = audioOutput->GetError(); 892 892 if (!errMsg.isEmpty()) 893 893 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3822 3822 audio_passthru = passthru; 3823 3823 } 3824 3824 3825 void NuppelVideoPlayer::SetAudioCodec(void *ac)3826 {3827 audio_codec = ac;3828 }3829 3830 3825 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3831 3826 { 3832 3827 if (audioOutput) … … 5039 5034 } 5040 5035 } 5041 5036 5037 bool NuppelVideoPlayer::ToggleUpmix() 5038 { 5039 if (audioOutput) 5040 return audioOutput->ToggleUpmix(); 5041 return false; 5042 } 5043 5042 5044 void NuppelVideoPlayer::Zoom(ZoomDirection direction) 5043 5045 { 5044 5046 if (videoOutput) -
libs/libmythtv/avformatdecoder.cpp
415 415 audioSamples(NULL), 416 416 allow_ac3_passthru(false), allow_dts_passthru(false), 417 417 disable_passthru(false), max_channels(2), 418 dummy_frame(NULL),418 last_ac3_channels(0), dummy_frame(NULL), 419 419 // DVD 420 420 lastdvdtitle(-1), 421 421 decodeStillFrame(false), … … 3000 3000 bool AvFormatDecoder::GetFrame(int onlyvideo) 3001 3001 { 3002 3002 AVPacket *pkt = NULL; 3003 AC3HeaderInfo hdr; 3003 3004 int len; 3004 3005 unsigned char *ptr; 3005 3006 int data_size = 0; … … 3193 3194 pts = 0; 3194 3195 3195 3196 AVStream *curstream = ic->streams[pkt->stream_index]; 3197 AVCodecContext *ctx = curstream->codec; 3196 3198 3197 3199 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3198 3200 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 3199 3201 3200 3202 if (ringBuffer->isDVD() && 3201 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3203 ctx->codec_type == CODEC_TYPE_VIDEO) 3202 3204 { 3203 3205 MpegPreProcessPkt(curstream, pkt); 3204 3206 … … 3220 3222 3221 3223 if (!d->HasMPEG2Dec()) 3222 3224 { 3223 int current_width = c urstream->codec->width;3225 int current_width = ctx->width; 3224 3226 int video_width = GetNVP()->GetVideoSize().width(); 3225 3227 if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput()) 3226 3228 { … … 3261 3263 } 3262 3264 3263 3265 if (storevideoframes && 3264 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3266 ctx->codec_type == CODEC_TYPE_VIDEO) 3265 3267 { 3266 3268 av_dup_packet(pkt); 3267 3269 storedPackets.append(pkt); … … 3269 3271 continue; 3270 3272 } 3271 3273 3272 if (len > 0 && c urstream->codec->codec_type == CODEC_TYPE_VIDEO &&3274 if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO && 3273 3275 pkt->stream_index == selectedVideoIndex) 3274 3276 { 3275 AVCodecContext *context = curstream->codec;3276 3277 3277 if (c ontext->codec_id == CODEC_ID_MPEG1VIDEO ||3278 c ontext->codec_id == CODEC_ID_MPEG2VIDEO ||3279 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||3280 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD)3278 if (ctx->codec_id == CODEC_ID_MPEG1VIDEO || 3279 ctx->codec_id == CODEC_ID_MPEG2VIDEO || 3280 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC || 3281 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD) 3281 3282 { 3282 3283 if (!ringBuffer->isDVD()) 3283 3284 MpegPreProcessPkt(curstream, pkt); 3284 3285 } 3285 else if (c ontext->codec_id == CODEC_ID_H264)3286 else if (ctx->codec_id == CODEC_ID_H264) 3286 3287 { 3287 3288 H264PreProcessPkt(curstream, pkt); 3288 3289 } … … 3327 3328 } 3328 3329 3329 3330 if (len > 0 && 3330 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3331 c urstream->codec->codec_id == CODEC_ID_MPEG2VBI)3331 ctx->codec_type == CODEC_TYPE_DATA && 3332 ctx->codec_id == CODEC_ID_MPEG2VBI) 3332 3333 { 3333 3334 ProcessVBIDataPacket(curstream, pkt); 3334 3335 … … 3337 3338 } 3338 3339 3339 3340 if (len > 0 && 3340 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3341 c urstream->codec->codec_id == CODEC_ID_DVB_VBI)3341 ctx->codec_type == CODEC_TYPE_DATA && 3342 ctx->codec_id == CODEC_ID_DVB_VBI) 3342 3343 { 3343 3344 ProcessDVBDataPacket(curstream, pkt); 3344 3345 … … 3348 3349 3349 3350 #ifdef USING_MHEG 3350 3351 if (len > 0 && 3351 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3352 c urstream->codec->codec_id == CODEC_ID_DSMCC_B)3352 ctx->codec_type == CODEC_TYPE_DATA && 3353 ctx->codec_id == CODEC_ID_DSMCC_B) 3353 3354 { 3354 3355 ProcessDSMCCPacket(curstream, pkt); 3355 3356 … … 3370 3371 #endif // USING_MHEG 3371 3372 3372 3373 // we don't care about other data streams 3373 if (c urstream->codec->codec_type == CODEC_TYPE_DATA)3374 if (ctx->codec_type == CODEC_TYPE_DATA) 3374 3375 { 3375 3376 av_free_packet(pkt); 3376 3377 continue; 3377 3378 } 3378 3379 3379 if (!c urstream->codec->codec)3380 if (!ctx->codec) 3380 3381 { 3381 3382 VERBOSE(VB_PLAYBACK, LOC + 3382 3383 QString("No codec for stream index %1, type(%2) id(%3:%4)") 3383 3384 .arg(pkt->stream_index) 3384 .arg(codec_type_string(c urstream->codec->codec_type))3385 .arg(codec_id_string(c urstream->codec->codec_id))3386 .arg(c urstream->codec->codec_id));3385 .arg(codec_type_string(ctx->codec_type)) 3386 .arg(codec_id_string(ctx->codec_id)) 3387 .arg(ctx->codec_id)); 3387 3388 av_free_packet(pkt); 3388 3389 continue; 3389 3390 } … … 3392 3393 have_err = false; 3393 3394 3394 3395 avcodeclock.lock(); 3395 int ctype = c urstream->codec->codec_type;3396 int ctype = ctx->codec_type; 3396 3397 int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; 3397 3398 int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; 3398 3399 int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; … … 3417 3418 3418 3419 // detect switches between stereo and dual languages 3419 3420 bool wasDual = audSubIdx != -1; 3420 bool isDual = c urstream->codec->avcodec_dual_language;3421 bool isDual = ctx->avcodec_dual_language; 3421 3422 if ((wasDual && !isDual) || (!wasDual && isDual)) 3422 3423 { 3423 3424 SetupAudioStreamSubIndexes(audIdx); … … 3425 3426 } 3426 3427 3427 3428 bool do_ac3_passthru = 3428 (allow_ac3_passthru && !transcoding && 3429 (curstream->codec->codec_id == CODEC_ID_AC3)); 3429 (allow_ac3_passthru && !transcoding && 3430 ctx->channels >= (int)max_channels && 3431 (ctx->codec_id == CODEC_ID_AC3)); 3430 3432 bool do_dts_passthru = 3431 3433 (allow_dts_passthru && !transcoding && 3432 (c urstream->codec->codec_id == CODEC_ID_DTS));3434 (ctx->codec_id == CODEC_ID_DTS)); 3433 3435 bool using_passthru = do_ac3_passthru || do_dts_passthru; 3434 3436 3435 3437 // detect channels on streams that need 3436 3438 // to be decoded before we can know this 3437 3439 bool already_decoded = false; 3438 if (!c urstream->codec->channels)3440 if (!ctx->channels) 3439 3441 { 3440 3442 QMutexLocker locker(&avcodeclock); 3441 3443 VERBOSE(VB_IMPORTANT, LOC + … … 3446 3448 { 3447 3449 // for passthru let it select the max number 3448 3450 // of channels 3449 c urstream->codec->channels = 0;3450 c urstream->codec->request_channels = 0;3451 ctx->channels = 0; 3452 ctx->request_channels = 0; 3451 3453 } 3452 3454 else 3453 3455 { 3454 c urstream->codec->channels = audioOut.channels;3455 c urstream->codec->request_channels =3456 ctx->channels = audioOut.channels; 3457 ctx->request_channels = 3456 3458 audioOut.channels; 3457 3459 } 3458 3460 ret = avcodec_decode_audio( 3459 c urstream->codec, audioSamples,3461 ctx, audioSamples, 3460 3462 &data_size, ptr, len); 3461 3463 already_decoded = true; 3462 3464 3463 reselectAudioTrack |= c urstream->codec->channels;3465 reselectAudioTrack |= ctx->channels; 3464 3466 } 3465 3467 3468 if (ctx->codec_id == CODEC_ID_AC3) 3469 { 3470 GetBitContext gbc; 3471 init_get_bits(&gbc, ptr, len * 8); 3472 if (!ff_ac3_parse_header(&gbc, &hdr)) 3473 { 3474 if (hdr.channels != last_ac3_channels) 3475 { 3476 last_ac3_channels = ctx->channels = hdr.channels; 3477 SetupAudioStream(); 3478 } 3479 } 3480 } 3481 3466 3482 if (reselectAudioTrack) 3467 3483 { 3468 3484 QMutexLocker locker(&avcodeclock); … … 3476 3492 .av_stream_index; 3477 3493 audSubIdx = selectedTrack[kTrackTypeAudio] 3478 3494 .av_substream_index; 3495 ctx = curstream->codec; 3479 3496 } 3480 3497 3481 3498 if (firstloop && pkt->pts != (int64_t)AV_NOPTS_VALUE) … … 3507 3524 if (audioOut.do_passthru) 3508 3525 { 3509 3526 data_size = pkt->size; 3510 bool dts = CODEC_ID_DTS == c urstream->codec->codec_id;3527 bool dts = CODEC_ID_DTS == ctx->codec_id; 3511 3528 ret = encode_frame(dts, ptr, len, 3512 3529 audioSamples, data_size); 3513 3530 } 3514 3531 else 3515 3532 { 3516 AVCodecContext *ctx = curstream->codec;3517 3518 3533 if ((ctx->channels == 0) || 3519 3534 (ctx->channels > audioOut.channels)) 3520 3535 { … … 3523 3538 3524 3539 if (!already_decoded) 3525 3540 { 3526 curstream->codec->request_channels = 3527 audioOut.channels; 3541 ctx->request_channels = audioOut.channels; 3528 3542 ret = avcodec_decode_audio( 3529 3543 ctx, audioSamples, &data_size, ptr, len); 3530 3544 } … … 3541 3555 audIdx = -1; 3542 3556 AutoSelectAudioTrack(); 3543 3557 data_size = 0; 3558 ctx = curstream->codec; 3544 3559 } 3545 3560 } 3546 3561 avcodeclock.unlock(); … … 3558 3573 3559 3574 // calc for next frame 3560 3575 lastapts += (long long)((double)(data_size * 1000) / 3561 (curstream->codec->channels * 2) / 3562 curstream->codec->sample_rate); 3576 (ctx->channels * 2) / ctx->sample_rate); 3563 3577 3564 3578 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, 3565 3579 LOC + QString("audio timecode %1 %2 %3 %4") … … 3627 3641 continue; 3628 3642 } 3629 3643 3630 AVCodecContext *context = curstream->codec;3631 3644 AVFrame mpa_pic; 3632 3645 bzero(&mpa_pic, sizeof(AVFrame)); 3633 3646 … … 3642 3655 // HACK 3643 3656 while (!gotpicture && count < 5) 3644 3657 { 3645 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3658 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3646 3659 &gotpicture, ptr, len); 3647 3660 count++; 3648 3661 } 3649 3662 } 3650 3663 else 3651 3664 { 3652 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3665 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3653 3666 &gotpicture, ptr, len); 3654 3667 } 3655 3668 } 3656 3669 else 3657 3670 { 3658 ret = avcodec_decode_video(c ontext, &mpa_pic,3671 ret = avcodec_decode_video(ctx, &mpa_pic, 3659 3672 &gotpicture, ptr, len); 3660 3673 // Reparse it to not drop the DVD still frame 3661 3674 if (decodeStillFrame) 3662 ret = avcodec_decode_video(c ontext, &mpa_pic,3675 ret = avcodec_decode_video(ctx, &mpa_pic, 3663 3676 &gotpicture, ptr, len); 3664 3677 } 3665 3678 avcodeclock.unlock(); … … 3726 3739 3727 3740 img_convert(&tmppicture, PIX_FMT_YUV420P, 3728 3741 (AVPicture *)&mpa_pic, 3729 c ontext->pix_fmt,3730 c ontext->width,3731 c ontext->height);3742 ctx->pix_fmt, 3743 ctx->width, 3744 ctx->height); 3732 3745 3733 3746 if (xf) 3734 3747 { … … 3751 3764 (temppts + 10000 > lastvpts || temppts < 0)) 3752 3765 { 3753 3766 temppts = lastvpts; 3754 temppts += (long long)(1000 * av_q2d(c ontext->time_base));3767 temppts += (long long)(1000 * av_q2d(ctx->time_base)); 3755 3768 // MPEG2 frames can be repeated, update pts accordingly 3756 3769 temppts += (long long)(mpa_pic.repeat_pict * 500 3757 * av_q2d(c urstream->codec->time_base));3770 * av_q2d(ctx->time_base)); 3758 3771 } 3759 3772 3760 3773 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + … … 3790 3803 picframe->frameNumber = framesPlayed; 3791 3804 GetNVP()->ReleaseNextVideoFrame(picframe, temppts); 3792 3805 if (d->HasMPEG2Dec() && mpa_pic.data[3]) 3793 c ontext->release_buffer(context, &mpa_pic);3806 ctx->release_buffer(ctx, &mpa_pic); 3794 3807 3795 3808 decoded_video_frame = picframe; 3796 3809 gotvideo = 1; … … 3846 3859 } 3847 3860 default: 3848 3861 { 3849 AVCodecContext *enc = curstream->codec;3850 3862 VERBOSE(VB_IMPORTANT, LOC_ERR + 3851 3863 QString("Decoding - id(%1) type(%2)") 3852 .arg(codec_id_string( enc->codec_id))3853 .arg(codec_type_string( enc->codec_type)));3864 .arg(codec_id_string(ctx->codec_id)) 3865 .arg(codec_type_string(ctx->codec_type))); 3854 3866 have_err = true; 3855 3867 break; 3856 3868 } … … 4008 4020 AVStream *curstream = NULL; 4009 4021 AVCodecContext *codec_ctx = NULL; 4010 4022 AudioInfo old_in = audioIn; 4011 AudioInfo old_out = audioOut;4012 4023 bool using_passthru = false; 4013 4024 4014 4025 if ((currentTrack[kTrackTypeAudio] >= 0) && … … 4023 4034 if (codec_ctx) 4024 4035 { 4025 4036 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 4037 codec_ctx->channels >= (int)max_channels && 4026 4038 (codec_ctx->codec_id == CODEC_ID_AC3)); 4027 4039 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 4028 4040 (codec_ctx->codec_id == CODEC_ID_DTS)); … … 4046 4058 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4047 4059 4048 4060 audioOut = audioIn = info; 4049 AudioInfo tmpAudioOut = audioOut;4050 4061 4051 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card4052 if (using_passthru && !disable_passthru)4053 {4054 tmpAudioOut.channels = 2;4055 tmpAudioOut.sample_rate = 48000;4056 tmpAudioOut.sample_size = 4;4057 }4058 4059 if (audioOut.channels > (int) max_channels)4060 {4061 audioOut.channels = (int) max_channels;4062 audioOut.sample_size = audioOut.channels * 2;4063 codec_ctx->channels = audioOut.channels;4064 }4065 4066 if (!using_passthru)4067 tmpAudioOut = audioOut;4068 4069 4062 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4070 QString("%1%2\n\t\t\tfrom %3 ; %4\n\t\t\tto %5 ; %6") 4071 .arg((using_passthru) ? "digital passthrough " : "") 4072 .arg((using_passthru) ? tmpAudioOut.toString() : QString("")) 4073 .arg(old_in.toString()).arg(old_out.toString()) 4074 .arg(audioIn.toString()).arg(audioOut.toString())); 4063 QString("\n\t\t\tfrom %1 to %2") 4064 .arg(old_in.toString()).arg(audioOut.toString())); 4075 4065 4076 if ( tmpAudioOut.sample_rate > 0)4077 GetNVP()->SetEffDsp( tmpAudioOut.sample_rate * 100);4066 if (audioOut.sample_rate > 0) 4067 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4078 4068 4079 GetNVP()->SetAudioParams( tmpAudioOut.bps(), tmpAudioOut.channels,4080 tmpAudioOut.sample_rate, audioIn.do_passthru);4069 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 4070 audioOut.sample_rate, audioOut.do_passthru); 4081 4071 4082 // allow the audio stuff to reencode4083 GetNVP()->SetAudioCodec((using_passthru) ? codec_ctx : NULL);4084 4072 GetNVP()->ReinitAudio(); 4085 4073 4086 4074 return true; -
libs/libmythtv/tv_play.h
333 333 void ChangeSpeed(int direction); 334 334 void ToggleTimeStretch(void); 335 335 void ChangeTimeStretch(int dir, bool allowEdit = true); 336 void ToggleUpmix(void); 336 337 void ChangeAudioSync(int dir, bool allowEdit = true); 337 338 float StopFFRew(void); 338 339 void ChangeFFRew(int direction); -
libs/libmythtv/NuppelVideoPlayer.h
178 178 // Toggle Sets 179 179 void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle); 180 180 void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle); 181 bool ToggleUpmix(void); 181 182 182 183 // Gets 183 184 QSize GetVideoBufferSize(void) const { return video_dim; } … … 690 691 int audio_bits; 691 692 int audio_samplerate; 692 693 float audio_stretchfactor; 693 void *audio_codec;694 694 bool audio_passthru; 695 695 696 696 // Picture-in-Picture -
libs/libmythtv/tv_play.cpp
378 378 REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 379 379 REG_KEY("TV Playback", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 380 380 REG_KEY("TV Playback", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 381 REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U"); 381 382 REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture mode", 382 383 "V"); 383 384 REG_KEY("TV Playback", "TOGGLEPIPWINDOW", "Toggle active PiP window", "B"); … … 510 511 Teletext F2,F3,F4,F5,F6,F7,F8 511 512 ITV F2,F3,F4,F5,F6,F7,F12 512 513 513 Playback: Ctrl-B,Ctrl-G,Ctrl-Y 514 Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U 514 515 */ 515 516 } 516 517 … … 2776 2777 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2777 2778 action == "STRETCHINC" || action == "STRETCHDEC" || 2778 2779 action == "MUTE" || action == "TOGGLEASPECT" || 2779 action == "TOGGLEFILL" )2780 action == "TOGGLEFILL" || action == "TOGGLEUPMIX") 2780 2781 { 2781 2782 passThru = 1; 2782 2783 handled = false; … … 2831 2832 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2832 2833 action == "STRETCHINC" || action == "STRETCHDEC" || 2833 2834 action == "MUTE" || action == "PAUSE" || 2834 action == "CLEAROSD" )2835 action == "CLEAROSD" || action == "TOGGLEUPMIX") 2835 2836 { 2836 2837 passThru = 1; 2837 2838 handled = false; … … 3159 3160 ChangeTimeStretch(0); // just display 3160 3161 else if (action == "TOGGLESTRETCH") 3161 3162 ToggleTimeStretch(); 3163 else if (action == "TOGGLEUPMIX") 3164 ToggleUpmix(); 3162 3165 else if (action == "CYCLECOMMSKIPMODE") { 3163 3166 SetAutoCommercialSkip((enum commSkipMode) 3164 3167 ((autoCommercialSkip + 1) % CommSkipModes)); … … 6062 6065 } 6063 6066 } 6064 6067 6068 void TV::ToggleUpmix() 6069 { 6070 if (!activenvp || !activenvp->HasAudioOut()) 6071 return; 6072 QString text; 6073 if (activenvp->ToggleUpmix()) 6074 text = tr("Upmixer On"); 6075 else 6076 text = tr("Upmixer Off"); 6077 6078 if (GetOSD() && !browsemode) 6079 GetOSD()->SetSettingsText(text, 5); 6080 } 6081 6065 6082 // dir in 10ms jumps 6066 6083 void TV::ChangeAudioSync(int dir, bool allowEdit) 6067 6084 { … … 7375 7392 7376 7393 ChangeTimeStretch(0, !floatRead); // just display 7377 7394 } 7395 else if (action == "TOGGLEUPMIX") 7396 ToggleUpmix(); 7378 7397 else if (action.left(11) == "SELECTSCAN_") 7379 7398 activenvp->SetScanType((FrameScanType) action.right(1).toInt()); 7380 7399 else if (action.left(15) == "TOGGLEAUDIOSYNC") … … 7629 7648 new OSDGenericTree(ats_item, tr("1.5X"), "ADJUSTSTRETCH1.5", 7630 7649 (speedX100 == 150) ? 1 : 0, NULL, 7631 7650 "STRETCHGROUP"); 7651 7652 new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX"); 7632 7653 7633 7654 // add scan mode override settings to menu 7634 7655 FrameScanType scan_type = kScan_Ignore; -
libs/libmythtv/avformatdecoder.h
268 268 bool allow_dts_passthru; 269 269 bool disable_passthru; 270 270 uint max_channels; 271 uint last_ac3_channels; 271 272 272 273 VideoFrame *dummy_frame; 273 274 -
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
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 AVCodecContext *audio_codec;138 140 AudioOutputSource source; 139 141 140 142 bool killaudio; … … 156 158 FreeSurround *upmixer; 157 159 158 160 int source_audio_channels; 161 int source_audio_samplerate; 159 162 int source_audio_bytes_per_sample; 160 163 bool needs_upmix; 161 164 int surround_mode; 165 float old_audio_stretchfactor; 162 166 163 167 bool blocking; // do AddSamples calls block? 164 168 -
libs/libmyth/audiosettings.cpp
15 15 samplerate(-1), 16 16 set_initial_vol(false), 17 17 use_passthru(false), 18 codec(NULL),19 18 source(AUDIOOUTPUT_UNKNOWN) 20 19 { 21 20 } … … 28 27 samplerate(other.samplerate), 29 28 set_initial_vol(other.set_initial_vol), 30 29 use_passthru(other.use_passthru), 31 codec(other.codec),32 30 source(other.source) 33 31 { 34 32 } … … 41 39 int audio_samplerate, 42 40 AudioOutputSource audio_source, 43 41 bool audio_set_initial_vol, 44 bool audio_use_passthru, 45 void *audio_codec) : 42 bool audio_use_passthru) : 46 43 main_device(audio_main_device), 47 44 passthru_device(audio_passthru_device), 48 45 bits(audio_bits), … … 50 47 samplerate(audio_samplerate), 51 48 set_initial_vol(audio_set_initial_vol), 52 49 use_passthru(audio_use_passthru), 53 codec(audio_codec),54 50 source(audio_source) 55 51 { 56 52 } … … 59 55 int audio_bits, 60 56 int audio_channels, 61 57 int audio_samplerate, 62 bool audio_use_passthru, 63 void *audio_codec) : 58 bool audio_use_passthru) : 64 59 main_device(QString::null), 65 60 passthru_device(QString::null), 66 61 bits(audio_bits), … … 68 63 samplerate(audio_samplerate), 69 64 set_initial_vol(false), 70 65 use_passthru(audio_use_passthru), 71 codec(audio_codec),72 66 source(AUDIOOUTPUT_UNKNOWN) 73 67 { 74 68 } 75 69 76 70 void AudioSettings::FixPassThrough(void) 77 71 { 78 if (passthru_device. isEmpty() || passthru_device.toLower() == "default")72 if (passthru_device.toLower() == "default") 79 73 passthru_device = GetMainDevice(); 80 74 } 81 75 -
libs/libmyth/audiooutputalsa.cpp
34 34 KillAudio(); 35 35 } 36 36 37 void SetIECBits(bool audio) { 38 39 snd_ctl_t *ctl; 40 const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT); 41 int spdif_index = -1; 42 snd_ctl_elem_list_t *clist; 43 snd_ctl_elem_id_t *cid; 44 snd_ctl_elem_value_t *cval; 45 snd_aes_iec958_t iec958; 46 int cidx, controls; 47 48 VERBOSE(VB_GENERAL, QString("Setting IEC958 status bits")); 49 50 snd_ctl_open(&ctl, "default", 0); 51 snd_ctl_elem_list_alloca(&clist); 52 snd_ctl_elem_list(ctl, clist); 53 snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist)); 54 snd_ctl_elem_list(ctl, clist); 55 controls = snd_ctl_elem_list_get_used(clist); 56 for (cidx = 0; cidx < controls; cidx++) { 57 if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str)) 58 if (spdif_index < 0 || 59 snd_ctl_elem_list_get_index(clist, cidx) == spdif_index) 60 break; 61 } 62 snd_ctl_elem_id_alloca(&cid); 63 snd_ctl_elem_list_get_id(clist, cidx, cid); 64 snd_ctl_elem_value_alloca(&cval); 65 snd_ctl_elem_value_set_id(cval, cid); 66 snd_ctl_elem_read(ctl,cval); 67 snd_ctl_elem_value_get_iec958(cval, &iec958); 68 69 if (!audio) 70 iec958.status[0] |= IEC958_AES0_NONAUDIO; 71 else 72 iec958.status[0] &= ~IEC958_AES0_NONAUDIO; 73 74 snd_ctl_elem_value_set_iec958(cval, &iec958); 75 snd_ctl_elem_write(ctl, cval); 76 77 } 78 37 79 bool AudioOutputALSA::OpenDevice() 38 80 { 39 81 snd_pcm_format_t format; 40 82 unsigned int buffer_time, period_time; 41 83 int err; 84 QString real_device; 42 85 43 86 if (pcm_handle != NULL) 44 87 CloseDevice(); 45 88 46 89 pcm_handle = NULL; 47 90 numbadioctls = 0; 91 92 if (audio_passthru || audio_enc) 93 { 94 real_device = audio_passthru_device; 95 SetIECBits(false); 96 } 97 else 98 { 99 real_device = audio_main_device; 100 SetIECBits(true); 101 } 48 102 49 QString real_device = (audio_passthru) ?50 audio_passthru_device : audio_main_device;51 52 103 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 53 104 .arg(real_device)); 54 105 -
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 audio_codec(NULL),34 34 source(settings.source), killaudio(false), 35 35 36 36 pauseaudio(false), audio_actually_paused(false), … … 48 48 encoder(NULL), 49 49 upmixer(NULL), 50 50 source_audio_channels(-1), 51 source_audio_samplerate(0), 51 52 source_audio_bytes_per_sample(0), 52 53 needs_upmix(false), 53 54 surround_mode(FreeSurround::SurroundModePassive), 55 old_audio_stretchfactor(1.0), 54 56 55 57 blocking(false), 56 58 … … 124 126 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 125 127 .arg(audio_stretchfactor)); 126 128 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)); 129 pSoundStretch->setSampleRate(audio_samplerate); 130 pSoundStretch->setChannels(upmixer ? 131 configured_audio_channels : source_audio_channels); 135 132 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 133 pSoundStretch->setTempo(audio_stretchfactor); 163 134 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); 164 135 165 136 // dont need these with only tempo change 166 137 //pSoundStretch->setPitch(1.0); 167 138 //pSoundStretch->setRate(1.0); 168 169 139 //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true); 170 140 //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false); 171 141 } … … 183 153 return audio_stretchfactor; 184 154 } 185 155 156 bool AudioOutputBase::ToggleUpmix(void) 157 { 158 if (audio_passthru) 159 return false; 160 if (configured_audio_channels == 6) 161 configured_audio_channels = 2; 162 else 163 configured_audio_channels = 6; 164 165 const AudioSettings settings(audio_bits, source_audio_channels, 166 source_audio_samplerate, audio_passthru); 167 Reconfigure(settings); 168 return (configured_audio_channels == 6); 169 } 170 171 186 172 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 187 173 { 188 174 AudioSettings settings = orig_settings; 189 175 190 int codec_id = CODEC_ID_NONE;191 int lcodec_id = CODEC_ID_NONE;192 int lcchannels = 0;193 int cchannels = 0;194 176 int lsource_audio_channels = settings.channels; 195 177 bool lneeds_upmix = false; 178 bool laudio_reenc = false; 196 179 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 } 180 // Are we reencoding a (previously) timestretched bitstream? 181 if (settings.channels > 2 && !settings.use_passthru) 182 laudio_reenc = true; 206 183 207 if (audio_codec) 184 // Enough channels? Upmix if not 185 if (settings.channels < configured_audio_channels && 186 !settings.use_passthru) 208 187 { 209 codec_id = audio_codec->codec_id;210 cchannels = ((AVCodecContext*)audio_codec)->channels;211 }212 213 if ((configured_audio_channels == 6) &&214 !(settings.codec || audio_codec))215 {216 188 settings.channels = configured_audio_channels; 217 189 lneeds_upmix = true; 218 190 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); … … 224 196 settings.samplerate == audio_samplerate && !need_resampler && 225 197 settings.use_passthru == audio_passthru && 226 198 lneeds_upmix == needs_upmix && 227 l codec_id == codec_id && lcchannels == cchannels);199 laudio_reenc == audio_reenc); 228 200 bool upmix_deps = 229 201 (lsource_audio_channels == source_audio_channels); 230 202 if (general_deps && upmix_deps) … … 251 223 waud = raud = 0; 252 224 audio_actually_paused = false; 253 225 254 bool redo_stretch = (pSoundStretch && audio_channels != settings.channels);255 226 audio_channels = settings.channels; 256 227 source_audio_channels = lsource_audio_channels; 257 228 audio_bits = settings.bits; 258 audio_samplerate = settings.samplerate;259 audio_ codec = (AVCodecContext*)settings.codec;229 source_audio_samplerate = audio_samplerate = settings.samplerate; 230 audio_reenc = laudio_reenc; 260 231 audio_passthru = settings.use_passthru; 261 232 needs_upmix = lneeds_upmix; 262 233 … … 265 236 Error("AudioOutput only supports 8 or 16bit audio."); 266 237 return; 267 238 } 268 audio_bytes_per_sample = audio_channels * audio_bits / 8;269 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;270 239 271 240 need_resampler = false; 272 241 killaudio = false; … … 275 244 internal_vol = gContext->GetNumSetting("MythControlsVolume", 0); 276 245 277 246 numlowbuffer = 0; 247 248 // Encode to AC-3 if not passing thru , there's > 2 channels 249 // and a passthru device is defined 250 if (!audio_passthru && audio_channels > 2 && 251 !audio_passthru_device.isEmpty()) 252 { 253 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); 254 encoder = new AudioOutputDigitalEncoder(); 255 if (!encoder->Init(CODEC_ID_AC3, 448000, 48000, 256 configured_audio_channels, audio_reenc)) 257 { 258 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 259 delete encoder; 260 encoder = NULL; 261 } 262 audio_channels = 2; 263 audio_enc = true; 264 } 265 266 if(audio_passthru) 267 // Soundcard expects a 2ch 48k stream 268 audio_channels = 2; 269 270 audio_bytes_per_sample = audio_channels * audio_bits / 8; 271 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 278 272 273 // Always resample to 48k - many cards can't do anything else 274 // and ALSA will do it with linear interpolation (yuk) if we don't anyway 275 if (audio_samplerate != 48000) 276 { 277 int error; 278 audio_samplerate = 48000; 279 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2") 280 .arg(settings.samplerate).arg(audio_samplerate)); 281 src_ctx = src_new (SRC_SINC_BEST_QUALITY, audio_channels, &error); 282 if (error) 283 { 284 Error(QString("Error creating resampler, the error was: %1") 285 .arg(src_strerror(error)) ); 286 src_ctx = NULL; 287 return; 288 } 289 src_data.src_ratio = (double) audio_samplerate / settings.samplerate; 290 src_data.data_in = src_in; 291 src_data.data_out = src_out; 292 src_data.output_frames = 16384*6; 293 need_resampler = true; 294 } 295 279 296 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 280 297 .arg(audio_main_device).arg(audio_channels) 281 298 .arg(source_audio_channels).arg(audio_samplerate)); … … 309 326 current_seconds = -1; 310 327 source_bitrate = -1; 311 328 312 // NOTE: this won't do anything as above samplerate vars are set equal313 // Check if we need the resampler314 if (audio_samplerate != settings.samplerate)315 {316 int error;317 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")318 .arg(settings.samplerate).arg(audio_samplerate));319 src_ctx = src_new (SRC_SINC_BEST_QUALITY, audio_channels, &error);320 if (error)321 {322 Error(QString("Error creating resampler, the error was: %1")323 .arg(src_strerror(error)) );324 return;325 }326 src_data.src_ratio = (double) audio_samplerate / settings.samplerate;327 src_data.data_in = src_in;328 src_data.data_out = src_out;329 src_data.output_frames = 16384*6;330 need_resampler = true;331 }332 333 329 if (needs_upmix) 334 330 { 335 331 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); … … 344 340 (FreeSurround::SurroundMode)surround_mode); 345 341 346 342 VERBOSE(VB_AUDIO, LOC + 347 QString(" create upmixer done with surround mode %1")343 QString("Create upmixer done with surround mode %1") 348 344 .arg(surround_mode)); 349 345 } 350 346 351 347 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 352 348 .arg(audio_stretchfactor)); 353 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")354 .arg((audio_codec) ?355 codec_id_string(audio_codec->codec_id) : "not set"));356 349 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) 367 { 368 // if its passthru then we need to reencode 369 if (audio_codec) 370 { 371 if (!encoder) 372 { 373 VERBOSE(VB_AUDIO, LOC + 374 QString("Creating Encoder for codec %1") 375 .arg(audio_codec->codec_id)); 376 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"); 388 } 389 } 390 } 391 if (audio_codec && encoder) 392 { 393 pSoundStretch->setSampleRate(audio_codec->sample_rate); 394 pSoundStretch->setChannels(audio_codec->channels); 395 } 396 else 397 { 398 pSoundStretch->setSampleRate(audio_samplerate); 399 pSoundStretch->setChannels(audio_channels); 400 } 401 } 402 } 403 350 SetStretchFactorLocked(old_audio_stretchfactor); 351 404 352 // Setup visualisations, zero the visualisations buffers 405 353 prepareVisuals(); 406 354 … … 436 384 VERBOSE(VB_AUDIO, LOC + "Killing AudioOutputDSP"); 437 385 killaudio = true; 438 386 StopOutputThread(); 387 QMutexLocker lock1(&audio_buflock); 439 388 440 389 // Close resampler? 441 390 if (src_ctx) 391 { 442 392 src_delete(src_ctx); 393 src_ctx = NULL; 394 } 395 443 396 need_resampler = false; 444 397 445 398 // close sound stretcher … … 447 400 { 448 401 delete pSoundStretch; 449 402 pSoundStretch = NULL; 403 old_audio_stretchfactor = audio_stretchfactor; 404 audio_stretchfactor = 1.0; 450 405 } 451 406 452 407 if (encoder) … … 461 416 upmixer = NULL; 462 417 } 463 418 needs_upmix = false; 419 audio_enc = false; 464 420 465 421 CloseDevice(); 466 422 … … 562 518 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 563 519 ret = (long long)(ret * audio_stretchfactor); 564 520 565 #if 1566 521 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 567 522 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 568 523 .arg(now.tv_sec).arg(now.tv_usec) … … 571 526 .arg(audiotime) 572 527 .arg(audio_stretchfactor) 573 528 ); 574 #endif575 529 576 530 ret += audiotime; 577 531 … … 611 565 612 566 // include algorithmic latencies 613 567 if (pSoundStretch) 614 {615 // add the effect of any unused but processed samples,616 // AC3 reencode does this617 totalbuffer += (int)(pSoundStretch->numSamples() *618 audio_bytes_per_sample);619 // add the effect of unprocessed samples in time stretch algo620 568 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 621 569 audio_bytes_per_sample) / audio_stretchfactor); 622 }623 570 624 571 if (upmixer && needs_upmix) 625 {626 572 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 627 }628 573 574 if (encoder) 575 totalbuffer += encoder->Buffered(); 576 629 577 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 630 578 (audio_bytes_per_sample * effdspstretched)); 631 579 632 580 gettimeofday(&audiotime_updated, NULL); 633 #if 1 581 634 582 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 635 583 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 " 636 584 "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") … … 642 590 .arg(effdspstretched) 643 591 .arg(audio_bytes_per_sample) 644 592 .arg(audio_stretchfactor)); 645 #endif646 593 } 647 594 648 595 int AudioOutputBase::GetAudioBufferedTime(void) … … 681 628 return false; // would overflow 682 629 } 683 630 631 QMutexLocker lock1(&audio_buflock); 632 684 633 // resample input if necessary 685 634 if (need_resampler && src_ctx) 686 635 { … … 749 698 return false; // would overflow 750 699 } 751 700 701 QMutexLocker lock1(&audio_buflock); 702 752 703 // resample input if necessary 753 704 if (need_resampler && src_ctx) 754 705 { … … 808 759 if (src_ctx) 809 760 { 810 761 int error = src_reset(src_ctx); 811 if (error) 762 if (error) 763 { 812 764 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 813 765 "Error occured while resetting resampler: %1") 814 766 .arg(src_strerror(error))); 767 src_ctx = NULL; 768 } 815 769 } 816 770 } 817 771 } … … 821 775 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 822 776 long long timecode) 823 777 { 824 audio_buflock.lock();825 826 778 int len; // = samples * audio_bytes_per_sample; 827 779 int audio_bytes = audio_bits / 8; 828 780 int org_waud = waud; … … 843 795 if (upmixer && needs_upmix) 844 796 { 845 797 int out_samples = 0; 798 org_waud = waud; 846 799 int step = (interleaved)?source_audio_channels:1; 847 800 len = WaitForFreeSpace(samples); // test 801 848 802 for (int itemp = 0; itemp < samples; ) 849 803 { 850 // just in case it does a processing cycle, release the lock851 // to allow the output loop to do output852 audio_buflock.unlock();853 804 if (audio_bytes == 2) 854 805 { 855 806 itemp += upmixer->putSamples( … … 866 817 source_audio_channels, 867 818 (interleaved) ? 0 : samples); 868 819 } 869 audio_buflock.lock();870 820 871 821 int copy_samples = upmixer->numSamples(); 872 822 if (copy_samples) … … 940 890 { 941 891 if (pSoundStretch) 942 892 { 943 944 893 // does not change the timecode, only the number of samples 945 894 // back to orig pos 946 895 org_waud = waud; … … 961 910 len / abps); 962 911 } 963 912 964 if (encoder) 913 int nSamples = pSoundStretch->numSamples(); 914 len = WaitForFreeSpace(nSamples); 915 916 while ((nSamples = pSoundStretch->numSamples())) 965 917 { 966 // pull out a packet's worth and reencode it until we 967 // don't have enough for any more packets 968 soundtouch::SAMPLETYPE *temp_buff = 969 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 970 size_t frameSize = encoder->FrameSize()/abps; 971 972 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 973 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 974 .arg(frameSize) 975 .arg(encoder->FrameSize()) 976 .arg(pSoundStretch->numSamples())); 977 978 // process the same number of samples as it creates 979 // a full encoded buffer just like before 980 while (pSoundStretch->numSamples() >= frameSize) 981 { 982 int got = pSoundStretch->receiveSamples( 983 temp_buff, frameSize); 984 int amount = encoder->Encode(temp_buff); 985 986 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 987 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 988 .arg(amount) 989 .arg(got) 990 .arg(pSoundStretch->numSamples())); 991 992 if (!amount) 993 continue; 994 995 //len = WaitForFreeSpace(amount); 996 char *ob = encoder->GetOutBuff(); 997 if (amount >= bdiff) 998 { 999 memcpy(audiobuffer + org_waud, ob, bdiff); 1000 ob += bdiff; 1001 amount -= bdiff; 1002 org_waud = 0; 1003 } 1004 if (amount > 0) 1005 memcpy(audiobuffer + org_waud, ob, amount); 1006 1007 bdiff = kAudioRingBufferSize - amount; 1008 org_waud = (org_waud + amount) % kAudioRingBufferSize; 918 if (nSamples > nSamplesToEnd) 919 nSamples = nSamplesToEnd; 920 921 nSamples = pSoundStretch->receiveSamples( 922 (soundtouch::SAMPLETYPE*) 923 (audiobuffer + org_waud), nSamples 924 ); 925 926 if (nSamples == nSamplesToEnd) { 927 org_waud = 0; 928 nSamplesToEnd = kAudioRingBufferSize/abps; 1009 929 } 930 else { 931 org_waud += nSamples * abps; 932 nSamplesToEnd -= nSamples; 933 } 934 1010 935 } 1011 else 936 937 } 938 939 // Encode to AC-3? 940 if (encoder) 941 { 942 943 org_waud = waud; 944 int bdiff = kAudioRingBufferSize - org_waud; 945 int to_get = 0; 946 947 if (bdiff < len) 1012 948 { 1013 int newLen = 0; 1014 int nSamples; 1015 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1016 audio_bytes_per_sample); 1017 do 949 encoder->Encode(audiobuffer + org_waud, bdiff); 950 to_get = encoder->Encode(audiobuffer, len - bdiff); 951 } 952 else 953 to_get = encoder->Encode(audiobuffer + org_waud, len); 954 955 if (to_get > 0) 956 { 957 958 if (to_get >= bdiff) 1018 959 { 1019 int samplesToGet = len/audio_bytes_per_sample; 1020 if (samplesToGet > nSamplesToEnd) 1021 { 1022 samplesToGet = nSamplesToEnd; 1023 } 1024 1025 nSamples = pSoundStretch->receiveSamples( 1026 (soundtouch::SAMPLETYPE*) 1027 (audiobuffer + org_waud), samplesToGet); 1028 if (nSamples == nSamplesToEnd) 1029 { 1030 org_waud = 0; 1031 nSamplesToEnd = kAudioRingBufferSize/audio_bytes_per_sample; 1032 } 1033 else 1034 { 1035 int bufsz = nSamples * audio_bytes_per_sample; 1036 org_waud = (org_waud + bufsz) % kAudioRingBufferSize; 1037 nSamplesToEnd -= nSamples; 1038 } 1039 1040 newLen += nSamples * audio_bytes_per_sample; 1041 len -= nSamples * audio_bytes_per_sample; 1042 } while (nSamples > 0); 960 encoder->GetFrames(audiobuffer + org_waud, bdiff); 961 to_get -= bdiff; 962 org_waud = 0; 963 } 964 if (to_get > 0) 965 encoder->GetFrames(audiobuffer + org_waud, to_get); 966 967 org_waud += to_get; 968 1043 969 } 970 1044 971 } 1045 972 1046 973 waud = org_waud; 1047 974 lastaudiolen = audiolen(false); 1048 975 1049 976 if (timecode < 0) 1050 {1051 977 // mythmusic doesn't give timestamps.. 1052 978 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1053 }1054 979 1055 980 samples_buffered += samples; 1056 981 … … 1061 986 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 1062 987 1063 988 if (interleaved) 1064 { 989 // Give original samples to mythmusic visualisation 1065 990 dispatchVisual((unsigned char *)buffer, len, timecode, 1066 991 source_audio_channels, audio_bits); 1067 }1068 992 } 1069 993 1070 audio_buflock.unlock();1071 994 } 1072 995 1073 996 void AudioOutputBase::Status() -
libs/libmyth/audiosettings.h
32 32 int audio_samplerate, 33 33 AudioOutputSource audio_source, 34 34 bool audio_set_initial_vol, 35 bool audio_use_passthru, 36 void *audio_codec = NULL); 35 bool audio_use_passthru); 37 36 38 37 AudioSettings(int audio_bits, 39 38 int audio_channels, 40 39 int audio_samplerate, 41 bool audio_use_passthru, 42 void *audio_codec = NULL); 40 bool audio_use_passthru); 43 41 44 42 void FixPassThrough(void); 45 43 void TrimDeviceType(void); … … 57 55 int samplerate; 58 56 bool set_initial_vol; 59 57 bool use_passthru; 60 void *codec;61 58 AudioOutputSource source; 62 59 }; 63 60 -
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 frame_buffer(NULL),35 one_frame_bytes(0)32 outbuflen(0), 33 inbuflen(0), 34 one_frame_bytes(0), 35 reorder(true) 36 36 { 37 37 } 38 38 … … 49 49 av_free(av_context); 50 50 av_context = NULL; 51 51 } 52 53 if (outbuf)54 {55 delete [] outbuf;56 outbuf = NULL;57 outbuf_size = 0;58 }59 60 if (frame_buffer)61 {62 delete [] frame_buffer;63 frame_buffer = NULL;64 one_frame_bytes = 0;65 }66 52 } 67 53 68 54 //CODEC_ID_AC3 69 55 bool AudioOutputDigitalEncoder::Init( 70 CodecID codec_id, int bitrate, int samplerate, int channels )56 CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding) 71 57 { 72 58 AVCodec *codec; 73 59 int ret; 74 60 75 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 ")61 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 re=%5") 76 62 .arg(codec_id_string(codec_id)) 77 63 .arg(bitrate) 78 64 .arg(samplerate) 79 .arg(channels)); 65 .arg(channels) 66 .arg(reencoding)); 67 68 reorder = !reencoding; 80 69 81 //codec = avcodec_find_encoder(codec_id); 70 // We need to do this when called from mythmusic 71 avcodec_init(); 72 avcodec_register_all(); 82 73 // always AC3 as there is no DTS encoder at the moment 2005/1/9 83 74 codec = avcodec_find_encoder(CODEC_ID_AC3); 84 75 if (!codec) … … 107 98 audio_bytes_per_sample = bytes_per_frame; 108 99 one_frame_bytes = bytes_per_frame * av_context->frame_size; 109 100 110 outbuf_size = 16384; // ok for AC3 but DTS?111 outbuf = new char [outbuf_size];112 101 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 113 102 .arg(av_context->frame_size) 114 103 .arg(bytes_per_frame) … … 253 242 254 243 } AESHeader; 255 244 245 void reorder_6ch_ac3(void *buf, unsigned int len) { 246 unsigned short *src = (unsigned short *)buf; 247 unsigned short tmp; 248 unsigned int samples = len >> 1; 249 250 for (uint i = 0; i < samples; i += 6) { 251 tmp = src[i+4]; 252 src[i+4] = src[i+3]; 253 src[i+3] = src[i+2]; 254 src[i+2] = src[i+1]; 255 src[i+1] = tmp; 256 } 257 } 258 256 259 static int encode_frame( 257 260 bool dts, 258 261 unsigned char *data, 259 size_t &len)262 size_t enc_len) 260 263 { 261 264 unsigned char *payload = data + 8; // skip header, currently 52 or 54bits 262 size_t enc_len;263 265 int flags, sample_rate, bit_rate; 264 266 265 267 // we don't do any length/crc validation of the AC3 frame here; presumably … … 270 272 // ignore, and if so, may as well just assume that it will ignore 271 273 // anything with a bad CRC... 272 274 273 uint nr_samples = 0, block_len; 275 uint nr_samples = 0, block_len = 0; 276 274 277 if (dts) 275 278 { 276 279 enc_len = dts_syncinfo(payload, &flags, &sample_rate, &bit_rate); … … 305 308 #endif 306 309 } 307 310 308 if (enc_len == 0 || enc_len > len)309 {310 int l = len;311 len = 0;312 return l;313 }314 315 311 enc_len = std::min((uint)enc_len, block_len - 8); 316 312 317 313 //uint32_t x = *(uint32_t*)payload; … … 364 360 data[6] = (enc_len << 3) & 0xFF; 365 361 data[7] = (enc_len >> 5) & 0xFF; 366 362 memset(payload + enc_len, 0, block_len - 8 - enc_len); 367 len = block_len;368 363 369 364 return enc_len; 370 365 } 371 366 372 367 // must have exactly 1 frames worth of data 373 size_t AudioOutputDigitalEncoder::Encode( short *buff)368 size_t AudioOutputDigitalEncoder::Encode(void *buf, int len) 374 369 { 375 int encsize = 0;376 370 size_t outsize = 0; 377 371 378 // put data in the correct spot for encode frame 379 outsize = avcodec_encode_audio( 380 av_context, ((uchar*)outbuf) + 8, outbuf_size - 8, buff); 372 int fs = FrameSize(); 373 memcpy(inbuf+inbuflen, buf, len); 374 inbuflen += len; 375 int frames = inbuflen / fs; 381 376 382 size_t tmpsize = outsize; 377 while (frames--) 378 { 379 if (reorder) 380 reorder_6ch_ac3(inbuf, fs); 381 382 // put data in the correct spot for encode frame 383 outsize = avcodec_encode_audio( 384 av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf); 385 386 encode_frame( 387 /*av_context->codec_id==CODEC_ID_DTS*/ false, 388 (unsigned char*)outbuf + outbuflen, outsize 389 ); 383 390 384 outsize = MAX_AC3_FRAME_SIZE; 385 encsize = encode_frame( 386 /*av_context->codec_id==CODEC_ID_DTS*/ false, 387 (unsigned char*)outbuf, outsize); 391 outbuflen += MAX_AC3_FRAME_SIZE; 392 inbuflen -= fs; 393 memmove(inbuf, inbuf+fs, inbuflen); 394 } 395 396 return outbuflen; 397 } 388 398 389 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 390 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 391 .arg(tmpsize).arg(encsize).arg(outsize)); 392 393 return outsize; 399 void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen) 400 { 401 int len = (maxlen < outbuflen ? maxlen : outbuflen); 402 memcpy(ptr, outbuf, len); 403 outbuflen -= len; 404 memmove(outbuf, outbuf+len, outbuflen); 394 405 } -
libs/libmyth/audiooutput.h
68 68 69 69 virtual void bufferOutputData(bool y) = 0; 70 70 virtual int readOutputData(unsigned char *read_buffer, int max_length) = 0; 71 virtual bool ToggleUpmix(void) = 0; 71 72 72 73 protected: 73 74 void Error(const QString &msg); -
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/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 … … 192 191 if (moviemode) 193 192 { 194 193 params.phasemode = 1; 195 params.center_width = 0; 196 params.gain = 1.0; 194 params.center_width = 40; 195 params.gain = 3.0; 196 params.dimension = 0.5; 197 197 } 198 198 else 199 199 { 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 200 params.center_width = 80; 203 201 params.gain = 3.1; 202 params.dimension = 0.3; 204 203 } 205 204 switch (surround_mode) 206 205 { -
programs/mythtranscode/transcode.cpp
216 216 // Do nothing 217 217 return kMuteOff; 218 218 } 219 virtual bool ToggleUpmix(void) 220 { 221 // Do nothing 222 return false; 223 } 219 224 220 225 // These are pure virtual in AudioOutput, but we don't need them here 221 226 virtual void bufferOutputData(bool){ return; }