for( int aidx=0; aidx<ffaudio.size(); ++aidx )
ffaudio[aidx]->nudge = 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; i<npgrms; ++i ) {
AVProgram *pgrm = fmt_ctx->programs[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];
}
}
// 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; i<nstreams; ++i ) {
AVStream *st = fmt_ctx->streams[i];
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; vidx<ffvideo.size(); ++vidx ) {
- if( ffvideo[vidx]->nudge != AV_NOPTS_VALUE ) continue;
- ffvideo[vidx]->nudge = nudge;
+ if( ffvideo[vidx]->nudge == AV_NOPTS_VALUE )
+ ffvideo[vidx]->nudge = nudge;
}
for( int aidx=0; aidx<ffaudio.size(); ++aidx ) {
- if( ffaudio[aidx]->nudge != AV_NOPTS_VALUE ) continue;
- ffaudio[aidx]->nudge = nudge;
+ if( ffaudio[aidx]->nudge == AV_NOPTS_VALUE )
+ ffaudio[aidx]->nudge = nudge;
}
decoding = 1;
}
}
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);
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;
float *samples;
int len = aud->get_samples(samples,
&frame->extended_data[0], frame->nb_samples);
- for( int i=0; i<nch; ++i )
- index_state->put_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; i<nch; ++i )
+ index_state->put_data(ch+i,nch,samples+i,len);
+ }
}
pkt.data += ret;
pkt.size -= ret;
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));
}
-
-
-
-
-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"))
{
class KeyframesFollowEdits;
class CursorOnFrames;
class TypelessKeyframes;
+class SetBRenderActive;
class LoopPlayback;
class Redo;
KeyframesFollowEdits *keyframes_follow_edits;
CursorOnFrames *cursor_on_frames;
TypelessKeyframes *typeless_keyframes;
+ SetBRenderActive *brender_active;
LoopPlayback *loop_playback;
ShowAssets *show_assets;
ShowTitles *show_titles;
MWindow *mwindow;
};
-class SetBRenderRange : public BC_MenuItem
+class SetBRenderActive : public BC_MenuItem
{
public:
- SetBRenderRange(MWindow *mwindow);
+ SetBRenderActive(MWindow *mwindow);
int handle_event();
MWindow *mwindow;
};
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) -
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));
//
mainindexes = 0;
mainprogress = 0;
brender = 0;
+ brender_active = 0;
channeldb_buz = new ChannelDB;
channeldb_v4l2jpeg = new ChannelDB;
//file_server = 0;
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);
}
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;
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();
}
MainIndexes *mainindexes;
MainProgress *mainprogress;
BRender *brender;
+ int brender_active;
const char *default_standard;
static Commercials *commercials;
int commercial_active;
// 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();
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 /
--- /dev/null
+ogg libvorbis
+cin_quality=5
--- /dev/null
+ogg libtheora
+cin_quality=7
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,
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;
}
}
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();