From d0f9735ae263eebd484a22d1e49bd3e1cd16cf70 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Wed, 5 Apr 2017 14:25:22 -0600 Subject: [PATCH] ffmpeg audio tracking alignment, bluebanana fixes, bg render hotkey, ogg format --- cinelerra-5.1/cinelerra/ffmpeg.C | 73 +++++++++++++------ cinelerra-5.1/cinelerra/mainmenu.C | 22 ++---- cinelerra-5.1/cinelerra/mainmenu.h | 6 +- cinelerra-5.1/cinelerra/mtimebar.C | 16 +--- cinelerra-5.1/cinelerra/mwindow.C | 33 ++++++--- cinelerra-5.1/cinelerra/mwindow.h | 3 +- cinelerra-5.1/cinelerra/trackcanvas.C | 4 +- cinelerra-5.1/ffmpeg/audio/ogg.dfl | 1 + cinelerra-5.1/ffmpeg/audio/ogg.ogg | 2 + cinelerra-5.1/ffmpeg/video/ogg.dfl | 1 + cinelerra-5.1/ffmpeg/video/ogg.ogg | 2 + .../plugins/bluebanana/bluebananaconfig.C | 2 + .../plugins/bluebanana/bluebananaengine.C | 19 ----- .../plugins/bluebanana/bluebananawindow.C | 7 +- 14 files changed, 106 insertions(+), 85 deletions(-) create mode 100644 cinelerra-5.1/ffmpeg/audio/ogg.dfl create mode 100644 cinelerra-5.1/ffmpeg/audio/ogg.ogg create mode 100644 cinelerra-5.1/ffmpeg/video/ogg.dfl create mode 100644 cinelerra-5.1/ffmpeg/video/ogg.ogg diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index 4239bc5d..44a337e6 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -1930,30 +1930,33 @@ int FFMPEG::decode_activate() for( int aidx=0; aidxnudge = AV_NOPTS_VALUE; // set nudges for each program stream set + const int64_t min_nudge = INT64_MIN+1; int npgrms = fmt_ctx->nb_programs; for( int i=0; iprograms[i]; // first start time video stream - int64_t vstart_time = -1, astart_time = -1; + int64_t vstart_time = min_nudge, astart_time = min_nudge; for( int j=0; j<(int)pgrm->nb_stream_indexes; ++j ) { int fidx = pgrm->stream_index[j]; AVStream *st = fmt_ctx->streams[fidx]; AVCodecContext *avctx = st->codec; if( avctx->codec_type == AVMEDIA_TYPE_VIDEO ) { if( st->start_time == AV_NOPTS_VALUE ) continue; - if( vstart_time > st->start_time ) continue; - vstart_time = st->start_time; + if( vstart_time < st->start_time ) + vstart_time = st->start_time; continue; } - if( avctx->codec_type == AVMEDIA_TYPE_VIDEO ) { + if( avctx->codec_type == AVMEDIA_TYPE_AUDIO ) { if( st->start_time == AV_NOPTS_VALUE ) continue; - if( astart_time > st->start_time ) continue; - astart_time = st->start_time; + if( astart_time < st->start_time ) + astart_time = st->start_time; continue; } } - // match program streams to max start_time - int64_t nudge = vstart_time > astart_time ? vstart_time : astart_time; + //since frame rate is much more grainy than sample rate, it is better to + // align using video, so that total absolute error is minimized. + int64_t nudge = vstart_time > min_nudge ? vstart_time : + astart_time > min_nudge ? astart_time : AV_NOPTS_VALUE; for( int j=0; j<(int)pgrm->nb_stream_indexes; ++j ) { int fidx = pgrm->stream_index[j]; AVStream *st = fmt_ctx->streams[fidx]; @@ -1975,7 +1978,7 @@ int FFMPEG::decode_activate() } } // set nudges for any streams not yet set - int64_t vstart_time = 0, astart_time = 0; + int64_t vstart_time = min_nudge, astart_time = min_nudge; int nstreams = fmt_ctx->nb_streams; for( int i=0; istreams[i]; @@ -1986,28 +1989,29 @@ int FFMPEG::decode_activate() int vidx = ffvideo.size(); while( --vidx >= 0 && ffvideo[vidx]->fidx != i ); if( vidx >= 0 && ffvideo[vidx]->nudge != AV_NOPTS_VALUE ) continue; - if( vstart_time >= st->start_time ) continue; - vstart_time = st->start_time; + if( vstart_time < st->start_time ) + vstart_time = st->start_time; break; } case AVMEDIA_TYPE_AUDIO: { if( st->start_time == AV_NOPTS_VALUE ) continue; int aidx = ffaudio.size(); while( --aidx >= 0 && ffaudio[aidx]->fidx != i ); if( aidx >= 0 && ffaudio[aidx]->nudge != AV_NOPTS_VALUE ) continue; - if( astart_time >= st->start_time ) continue; - astart_time = st->start_time; + if( astart_time < st->start_time ) + astart_time = st->start_time; break; } default: break; } } - int64_t nudge = vstart_time > astart_time ? vstart_time : astart_time; + int64_t nudge = vstart_time > min_nudge ? vstart_time : + astart_time > min_nudge ? astart_time : AV_NOPTS_VALUE; for( int vidx=0; vidxnudge != AV_NOPTS_VALUE ) continue; - ffvideo[vidx]->nudge = nudge; + if( ffvideo[vidx]->nudge == AV_NOPTS_VALUE ) + ffvideo[vidx]->nudge = nudge; } for( int aidx=0; aidxnudge != AV_NOPTS_VALUE ) continue; - ffaudio[aidx]->nudge = nudge; + if( ffaudio[aidx]->nudge == AV_NOPTS_VALUE ) + ffaudio[aidx]->nudge = nudge; } decoding = 1; } @@ -2593,6 +2597,23 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled) } av_dict_free(&copts); } + + decode_activate(); + for( int i=0; i<(int)fmt_ctx->nb_streams; ++i ) { + AVStream *st = fmt_ctx->streams[i]; + AVCodecContext *avctx = st->codec; + if( avctx->codec_type != AVMEDIA_TYPE_AUDIO ) continue; + int64_t tstmp = st->start_time; + if( tstmp == AV_NOPTS_VALUE ) continue; + int aidx = ffaudio.size(); + while( --aidx>=0 && ffaudio[aidx]->fidx != i ); + if( aidx < 0 ) continue; + FFAudioStream *aud = ffaudio[aidx]; + tstmp -= aud->nudge; + double secs = to_secs(tstmp, st->time_base); + aud->curr_pos = secs * aud->sample_rate + 0.5; + } + int errs = 0; for( int64_t count=0; !*canceled; ++count ) { av_packet_unref(&pkt); @@ -2652,8 +2673,8 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled) if( aud->nudge != AV_NOPTS_VALUE ) tstmp -= aud->nudge; double secs = to_secs(tstmp, st->time_base); int64_t sample = secs * aud->sample_rate + 0.5; - if( sample < 0 ) sample = 0; - index_state->put_audio_mark(aidx, sample, pkt.pos); + if( sample >= 0 ) + index_state->put_audio_mark(aidx, sample, pkt.pos); } while( pkt.size > 0 ) { int ch = aud->channel0, nch = aud->channels; @@ -2671,9 +2692,15 @@ printf("audio%d pad %jd %jd (%jd)\n", aud->idx, pos, aud->curr_pos, pos-aud->cur float *samples; int len = aud->get_samples(samples, &frame->extended_data[0], frame->nb_samples); - for( int i=0; iput_data(ch+i,nch,samples+i,len); - aud->curr_pos += len; + pos = aud->curr_pos; + if( (aud->curr_pos += len) >= 0 ) { + if( pos < 0 ) { + samples += -pos * nch; + len = aud->curr_pos; + } + for( int i=0; iput_data(ch+i,nch,samples+i,len); + } } pkt.data += ret; pkt.size -= ret; diff --git a/cinelerra-5.1/cinelerra/mainmenu.C b/cinelerra-5.1/cinelerra/mainmenu.C index cf119d61..1b75ddfc 100644 --- a/cinelerra-5.1/cinelerra/mainmenu.C +++ b/cinelerra-5.1/cinelerra/mainmenu.C @@ -212,7 +212,7 @@ void MainMenu::create_objects() settingsmenu->add_item(new BC_MenuItem("-")); settingsmenu->add_item(new SaveSettingsNow(mwindow)); settingsmenu->add_item(loop_playback = new LoopPlayback(mwindow)); - settingsmenu->add_item(new SetBRenderRange(mwindow)); + settingsmenu->add_item(brender_active = new SetBRenderActive(mwindow)); // set scrubbing speed // ScrubSpeed *scrub_speed; // settingsmenu->add_item(scrub_speed = new ScrubSpeed(mwindow)); @@ -1237,28 +1237,22 @@ int PasteSubttl::handle_event() } - - - - -SetBRenderRange::SetBRenderRange(MWindow *mwindow) - : BC_MenuItem(_("Set background rendering")) +SetBRenderActive::SetBRenderActive(MWindow *mwindow) + : BC_MenuItem(_("Toggle background rendering"),_("Shift-G"),'G') { this->mwindow = mwindow; + set_shift(1); } -int SetBRenderRange::handle_event() +int SetBRenderActive::handle_event() { - mwindow->set_brender_range(); + int v = mwindow->brender_active ? 0 : 1; + set_checked(v); + mwindow->set_brender_active(v); return 1; } - - - - - LabelsFollowEdits::LabelsFollowEdits(MWindow *mwindow) : BC_MenuItem(_("Edit labels")) { diff --git a/cinelerra-5.1/cinelerra/mainmenu.h b/cinelerra-5.1/cinelerra/mainmenu.h index ebbd208b..6e277aed 100644 --- a/cinelerra-5.1/cinelerra/mainmenu.h +++ b/cinelerra-5.1/cinelerra/mainmenu.h @@ -28,6 +28,7 @@ class PluginsFollowEdits; class KeyframesFollowEdits; class CursorOnFrames; class TypelessKeyframes; +class SetBRenderActive; class LoopPlayback; class Redo; @@ -120,6 +121,7 @@ public: KeyframesFollowEdits *keyframes_follow_edits; CursorOnFrames *cursor_on_frames; TypelessKeyframes *typeless_keyframes; + SetBRenderActive *brender_active; LoopPlayback *loop_playback; ShowAssets *show_assets; ShowTitles *show_titles; @@ -554,10 +556,10 @@ public: MWindow *mwindow; }; -class SetBRenderRange : public BC_MenuItem +class SetBRenderActive : public BC_MenuItem { public: - SetBRenderRange(MWindow *mwindow); + SetBRenderActive(MWindow *mwindow); int handle_event(); MWindow *mwindow; }; diff --git a/cinelerra-5.1/cinelerra/mtimebar.C b/cinelerra-5.1/cinelerra/mtimebar.C index 5ab4eb12..5fa6e4c8 100644 --- a/cinelerra-5.1/cinelerra/mtimebar.C +++ b/cinelerra-5.1/cinelerra/mtimebar.C @@ -426,9 +426,8 @@ void MTimeBar::draw_time() void MTimeBar::draw_range() { int x1 = 0, x2 = 0; - if(mwindow->edl->tracks->total_playable_vtracks() && - mwindow->preferences->use_brender) - { + if( mwindow->brender_active && mwindow->preferences->use_brender && + mwindow->edl->tracks->total_playable_vtracks() ) { double time_per_pixel = (double)mwindow->edl->local_session->zoom_sample / mwindow->edl->session->sample_rate; x1 = (int)(mwindow->edl->session->brender_start / time_per_pixel) - @@ -437,22 +436,15 @@ void MTimeBar::draw_range() mwindow->edl->local_session->view_start[pane->number]; } - if(x2 > x1 && - x1 < get_w() && - x2 > 0) - { + if(x2 > x1 && x1 < get_w() && x2 > 0) { draw_top_background(get_parent(), 0, 0, x1, get_h()); - draw_3segmenth(x1, 0, x2 - x1, mwindow->theme->get_image("timebar_brender")); - draw_top_background(get_parent(), x2, 0, get_w() - x2, get_h()); } - else - { + else { draw_top_background(get_parent(), 0, 0, get_w(), get_h()); } - // int64_t pixel = position_to_pixel( // mwindow->edl->local_session->get_selectionstart(1)); // diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 27aa6dfa..577f229e 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -200,6 +200,7 @@ MWindow::MWindow() mainindexes = 0; mainprogress = 0; brender = 0; + brender_active = 0; channeldb_buz = new ChannelDB; channeldb_v4l2jpeg = new ChannelDB; //file_server = 0; @@ -1163,12 +1164,14 @@ void MWindow::init_brender() session->brender_end = 0; brender_lock->unlock(); } - if(brender) brender->restart(edl); + brender_active = 0; + stop_brender(); } void MWindow::restart_brender() { //printf("MWindow::restart_brender 1\n"); + if(!brender_active || !preferences->use_brender) return; if(brender) brender->restart(edl); } @@ -1200,21 +1203,28 @@ int MWindow::brender_available(int position) return result; } -void MWindow::set_brender_range() +void MWindow::set_brender_active(int v, int update) { - edl->session->brender_start = edl->local_session->get_selectionstart(1); - edl->session->brender_end = edl->local_session->get_selectionend(1); + if( !preferences->use_brender ) v = 0; + brender_active = v; + gui->mainmenu->brender_active->set_checked(v); + if( v != 0 ) { + edl->session->brender_start = edl->local_session->get_selectionstart(1); + edl->session->brender_end = edl->local_session->get_selectionend(1); - if(EQUIV(edl->session->brender_end, edl->session->brender_start)) - { - edl->session->brender_end = edl->tracks->total_video_length(); + if(EQUIV(edl->session->brender_end, edl->session->brender_start)) { + edl->session->brender_end = edl->tracks->total_video_length(); + } + restart_brender(); + } + else + stop_brender(); + if( update ) { + gui->update_timebar(0); + gui->draw_overlays(1); } - - restart_brender(); - gui->draw_overlays(1); } - int MWindow::has_commercials() { return theme->use_commercials; @@ -1742,6 +1752,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); edl->local_session->loop_playback = 0; edl->local_session->set_selectionstart(0); edl->local_session->set_selectionend(0); + set_brender_active(0, 0); fit_selection(); goto_start(); } diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index a0ec37f3..b294bd39 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -528,6 +528,7 @@ public: MainIndexes *mainindexes; MainProgress *mainprogress; BRender *brender; + int brender_active; const char *default_standard; static Commercials *commercials; int commercial_active; @@ -621,7 +622,7 @@ public: // This one happens asynchronously of the others. Used by playback to // see what frame is background rendered. int brender_available(int position); - void set_brender_range(); + void set_brender_active(int v, int update=1); int put_commercial(); void activate_commercial() { commercial_active = 1; } void commit_commercial(); diff --git a/cinelerra-5.1/cinelerra/trackcanvas.C b/cinelerra-5.1/cinelerra/trackcanvas.C index b7f25ca6..e79654d4 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.C +++ b/cinelerra-5.1/cinelerra/trackcanvas.C @@ -1854,7 +1854,9 @@ void TrackCanvas::draw_loop_points() void TrackCanvas::draw_brender_range() { - if(mwindow->preferences->use_brender) + if( !mwindow->preferences->use_brender || !mwindow->brender_active ) return; + if( mwindow->edl->session->brender_start >= mwindow->edl->session->brender_end ) return; + if( mwindow->edl->session->brender_end > 0 ) { int64_t x1 = Units::round(mwindow->edl->session->brender_start * mwindow->edl->session->sample_rate / diff --git a/cinelerra-5.1/ffmpeg/audio/ogg.dfl b/cinelerra-5.1/ffmpeg/audio/ogg.dfl new file mode 100644 index 00000000..e87bd307 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/ogg.dfl @@ -0,0 +1 @@ +ogg.ogg diff --git a/cinelerra-5.1/ffmpeg/audio/ogg.ogg b/cinelerra-5.1/ffmpeg/audio/ogg.ogg new file mode 100644 index 00000000..1fa55073 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/ogg.ogg @@ -0,0 +1,2 @@ +ogg libvorbis +cin_quality=5 diff --git a/cinelerra-5.1/ffmpeg/video/ogg.dfl b/cinelerra-5.1/ffmpeg/video/ogg.dfl new file mode 100644 index 00000000..e87bd307 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/ogg.dfl @@ -0,0 +1 @@ +ogg.ogg diff --git a/cinelerra-5.1/ffmpeg/video/ogg.ogg b/cinelerra-5.1/ffmpeg/video/ogg.ogg new file mode 100644 index 00000000..17565ef0 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/ogg.ogg @@ -0,0 +1,2 @@ +ogg libtheora +cin_quality=7 diff --git a/cinelerra-5.1/plugins/bluebanana/bluebananaconfig.C b/cinelerra-5.1/plugins/bluebanana/bluebananaconfig.C index 74ecf1b4..330af41c 100644 --- a/cinelerra-5.1/plugins/bluebanana/bluebananaconfig.C +++ b/cinelerra-5.1/plugins/bluebanana/bluebananaconfig.C @@ -212,6 +212,8 @@ void BluebananaConfig::copy_from(BluebananaConfig &that) { Oadj_active = that.Oadj_active; Oadj_val = that.Oadj_val; + Aadj_active = that.Aadj_active; + Aadj_val = that.Aadj_val; } void BluebananaConfig::interpolate(BluebananaConfig &prev, diff --git a/cinelerra-5.1/plugins/bluebanana/bluebananaengine.C b/cinelerra-5.1/plugins/bluebanana/bluebananaengine.C index 34037de1..1026deb9 100644 --- a/cinelerra-5.1/plugins/bluebanana/bluebananaengine.C +++ b/cinelerra-5.1/plugins/bluebanana/bluebananaengine.C @@ -478,25 +478,6 @@ void BluebananaUnit::process_package(LoadPackage *package){ if(!use_mask && !invert_selection && selection_test < SELECT_THRESH){ /* skip processing this fragment */ - /* we're using a mask; if the mask is set to capture, we - need to restore alpha before skipping */ - if(capture_mask){ - switch(frame->get_color_model()) { - case BC_RGBA8888: - unmask_rgba8(row_fragment,todo); - break; - case BC_RGBA_FLOAT: - unmask_rgbaF((float *)row_fragment,todo); - break; - case BC_YUVA8888: - unmask_yuva8(row_fragment,todo); - break; - } - pthread_mutex_lock(&engine->copylock); - memcpy(row,row_fragment,byte_advance); - pthread_mutex_unlock(&engine->copylock); - } - row+=byte_advance; continue; } diff --git a/cinelerra-5.1/plugins/bluebanana/bluebananawindow.C b/cinelerra-5.1/plugins/bluebanana/bluebananawindow.C index 504957e9..32ac6781 100644 --- a/cinelerra-5.1/plugins/bluebanana/bluebananawindow.C +++ b/cinelerra-5.1/plugins/bluebanana/bluebananawindow.C @@ -1839,8 +1839,11 @@ public: } void update(){ if(active != plugin->config.active){ - plugin->config.active = active; - this->BC_CheckBox::update(plugin->config.active,1); + if(active>=0) + plugin->config.active = active; + else + active = plugin->config.active; + this->BC_CheckBox::update(active,1); gui->enter_config_change(); gui->Hadj_slider->update(); gui->Sadj_slider->update(); -- 2.26.2