From: Good Guy Date: Thu, 15 Mar 2018 00:34:45 +0000 (-0600) Subject: upgrade ffmpeg to 3.4.2, add proxy popup, undo/redo deadlock fix, rework nested edl X-Git-Url: https://git.cinelerra-gg.org/git/?a=commitdiff_plain;h=f007a674187f11ab58a5aebfe1eec27a90398bcb;p=goodguy%2Fhistory.git upgrade ffmpeg to 3.4.2, add proxy popup, undo/redo deadlock fix, rework nested edl --- diff --git a/cinelerra-5.1/cinelerra/Makefile b/cinelerra-5.1/cinelerra/Makefile index 755e4298..c341abcb 100644 --- a/cinelerra-5.1/cinelerra/Makefile +++ b/cinelerra-5.1/cinelerra/Makefile @@ -234,6 +234,7 @@ OBJS = \ $(OBJDIR)/presets.o \ $(OBJDIR)/probeprefs.o \ $(OBJDIR)/proxy.o \ + $(OBJDIR)/proxypopup.o \ $(OBJDIR)/question.o \ $(OBJDIR)/quit.o \ $(OBJDIR)/recconfirmdelete.o \ diff --git a/cinelerra-5.1/cinelerra/awindowgui.C b/cinelerra-5.1/cinelerra/awindowgui.C index 0ed6b1ce..42672233 100644 --- a/cinelerra-5.1/cinelerra/awindowgui.C +++ b/cinelerra-5.1/cinelerra/awindowgui.C @@ -57,6 +57,7 @@ #include "newfolder.h" #include "preferences.h" #include "proxy.h" +#include "proxypopup.h" #include "renderengine.h" #include "samples.h" #include "theme.h" @@ -833,6 +834,7 @@ AWindowGUI::AWindowGUI(MWindow *mwindow, AWindow *awindow) effectlist_menu = 0; assetlist_menu = 0; cliplist_menu = 0; + proxylist_menu = 0; labellist_menu = 0; folderlist_menu = 0; temp_picon = 0; @@ -860,14 +862,6 @@ AWindowGUI::~AWindowGUI() delete vicon_audio; delete newfolder_thread; - delete asset_menu; - delete clip_menu; - delete label_menu; - delete effectlist_menu; - delete assetlist_menu; - delete cliplist_menu; - delete labellist_menu; - delete folderlist_menu; delete search_text; delete temp_picon; delete remove_plugin; @@ -1060,6 +1054,8 @@ void AWindowGUI::create_objects() clip_menu->create_objects(); add_subwindow(label_menu = new LabelPopup(mwindow, this)); label_menu->create_objects(); + add_subwindow(proxy_menu = new ProxyPopup(mwindow, this)); + proxy_menu->create_objects(); add_subwindow(effectlist_menu = new EffectListMenu(mwindow, this)); effectlist_menu->create_objects(); @@ -1069,6 +1065,8 @@ void AWindowGUI::create_objects() cliplist_menu->create_objects(); add_subwindow(labellist_menu = new LabelListMenu(mwindow, this)); labellist_menu->create_objects(); + add_subwindow(proxylist_menu = new ProxyListMenu(mwindow, this)); + proxylist_menu->create_objects(); add_subwindow(folderlist_menu = new FolderListMenu(mwindow, this)); folderlist_menu->create_objects(); @@ -1584,6 +1582,7 @@ EDL *AWindowGUI::collect_proxy(Indexable *indexable) EDL *proxy_edl = new EDL(mwindow->edl); proxy_edl->create_objects(); FileSystem fs; fs.extract_name(path, proxy_asset->path); + proxy_edl->set_path(path); strcpy(proxy_edl->local_session->clip_title, path); strcpy(proxy_edl->local_session->clip_notes, _("Proxy clip")); proxy_edl->session->video_tracks = proxy_asset->layers; @@ -1999,8 +1998,11 @@ int AWindowAssets::button_press_event() gui->cliplist_menu->update(); gui->cliplist_menu->activate_menu(); break; - case AW_MEDIA_FOLDER: case AW_PROXY_FOLDER: + gui->proxylist_menu->update(); + gui->proxylist_menu->activate_menu(); + break; + case AW_MEDIA_FOLDER: gui->assetlist_menu->update_titles(folder==AW_MEDIA_FOLDER); gui->assetlist_menu->activate_menu(); break; @@ -2057,6 +2059,11 @@ int AWindowAssets::selection_changed() gui->clip_menu->update(); gui->clip_menu->activate_menu(); break; + case AW_PROXY_FOLDER: + if( !item->indexable && !item->edl ) break; + gui->proxy_menu->update(); + gui->proxy_menu->activate_menu(); + break; default: if( !item->indexable && !item->edl ) break; gui->asset_menu->update(); diff --git a/cinelerra-5.1/cinelerra/awindowgui.h b/cinelerra-5.1/cinelerra/awindowgui.h index 4bc25642..440b4019 100644 --- a/cinelerra-5.1/cinelerra/awindowgui.h +++ b/cinelerra-5.1/cinelerra/awindowgui.h @@ -42,6 +42,7 @@ #include "mwindow.inc" #include "newfolder.inc" #include "pluginserver.inc" +#include "proxypopup.inc" #include "renderengine.inc" #include "samples.inc" #include "vicon.h" @@ -264,10 +265,12 @@ public: AssetPopup *asset_menu; ClipPopup *clip_menu; LabelPopup *label_menu; + ProxyPopup *proxy_menu; EffectListMenu *effectlist_menu; AssetListMenu *assetlist_menu; ClipListMenu *cliplist_menu; LabelListMenu *labellist_menu; + ProxyListMenu *proxylist_menu; FolderListMenu *folderlist_menu; AddTools *add_tools; // Temporary for reading picons from files diff --git a/cinelerra-5.1/cinelerra/clipedls.C b/cinelerra-5.1/cinelerra/clipedls.C index 65dd58e2..52dd7678 100644 --- a/cinelerra-5.1/cinelerra/clipedls.C +++ b/cinelerra-5.1/cinelerra/clipedls.C @@ -38,6 +38,10 @@ void ClipEDLs::remove_clip(EDL *clip) EDL* ClipEDLs::get_copy(EDL *src) { if( !src ) return 0; + for( int i=0; iid == dst->id ) return dst; + } for( int i=0; ipath, src->path) ) return dst; diff --git a/cinelerra-5.1/cinelerra/clippopup.C b/cinelerra-5.1/cinelerra/clippopup.C index 677b9bed..ef291f19 100644 --- a/cinelerra-5.1/cinelerra/clippopup.C +++ b/cinelerra-5.1/cinelerra/clippopup.C @@ -432,11 +432,9 @@ int ClipPopupNest::handle_event() if( mwindow->session->drag_clips->total > 0 ) { EDL *edl = mwindow->edl; EDL *clip = mwindow->session->drag_clips->values[0]; - EDL *clip_edl = new EDL; // no parent for nested clip - clip_edl->create_objects(); - clip_edl->copy_all(clip); EDL *new_clip = new EDL(edl); new_clip->create_objects(); + new_clip->copy_all(clip); new_clip->awindow_folder = AW_CLIP_FOLDER; snprintf(new_clip->local_session->clip_title, sizeof(new_clip->local_session->clip_title), @@ -445,27 +443,25 @@ int ClipPopupNest::handle_event() clip->local_session->clip_notes); time_t dt; time(&dt); struct tm dtm; localtime_r(&dt, &dtm); - char path[BCSTRLEN]; - sprintf(path, _("Nested_%02d%02d%02d-%02d%02d%02d"), - dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, - dtm.tm_hour, dtm.tm_min, dtm.tm_sec); - clip_edl->set_path(path); sprintf(new_clip->local_session->clip_icon, "clip_%02d%02d%02d-%02d%02d%02d.png", dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, dtm.tm_hour, dtm.tm_min, dtm.tm_sec); - new_clip->set_path(path); - new_clip->to_nested(clip_edl); + char path[BCSTRLEN]; + sprintf(path, _("Nested_%02d%02d%02d-%02d%02d%02d"), + dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, + dtm.tm_hour, dtm.tm_min, dtm.tm_sec); + EDL *clip_edl = edl->new_nested(new_clip, path); + new_clip->remove_user(); int idx = edl->clips.number_of(clip); if( idx >= 0 ) { - edl->clips[idx] = new_clip; + edl->clips[idx] = clip_edl; clip->remove_user(); } else - edl->clips.append(new_clip); + edl->clips.append(clip_edl); mwindow->mainindexes->add_next_asset(0, clip_edl); mwindow->mainindexes->start_build(); - clip_edl->remove_user(); popup->gui->async_update_assets(); } gui->unlock_window(); diff --git a/cinelerra-5.1/cinelerra/edl.C b/cinelerra-5.1/cinelerra/edl.C index 49d4cecf..55ca9a29 100644 --- a/cinelerra-5.1/cinelerra/edl.C +++ b/cinelerra-5.1/cinelerra/edl.C @@ -580,21 +580,38 @@ int EDL::copy(double start, double end, int all, return 0; } -int EDL::to_nested(EDL *nested_edl) +EDL *EDL::get_nested(EDL *nested_edl, const char *path) { -// Keep frame rate, sample rate, and output size unchanged. -// These parameters would revert the project if VWindow displayed an asset -// of different size than the project. + for( int i=0; ipath) ) return dst; + } + return new_nested(nested_edl, path); +} + +EDL *EDL::new_nested(EDL *nested_edl, const char *path) +{ + EDL *new_edl = new EDL; // no parent for nested clip + new_edl->create_objects(); + new_edl->copy_session(this); + new_edl->create_nested(nested_edl, path); + return new_edl; +} +void EDL::create_nested(EDL *nested_edl, const char *path) +{ + set_path(path); + strcpy(local_session->clip_title, path); +// save a ref to nested edl for garbage delete + EDL *nest = clips.get_copy(nested_edl); +// Keep frame rate, sample rate, and output size unchanged. // Nest all video & audio outputs session->video_tracks = 1; - session->audio_tracks = nested_edl->session->audio_channels; + session->audio_tracks = nest->session->audio_channels; create_default_tracks(); - insert_asset(0, nested_edl, 0, 0, 0); - return 0; + insert_asset(0, nest, 0, 0, 0); } - void EDL::retrack() { int min_w = session->output_w, min_h = session->output_h; diff --git a/cinelerra-5.1/cinelerra/edl.h b/cinelerra-5.1/cinelerra/edl.h index 60784dcf..d523779b 100644 --- a/cinelerra-5.1/cinelerra/edl.h +++ b/cinelerra-5.1/cinelerra/edl.h @@ -181,7 +181,9 @@ public: int copy(double start, double end, int all, const char *closer, FileXML *file, const char *output_path, int rewind_it); - int to_nested(EDL *nested_edl); + EDL *get_nested(EDL *nested_edl, const char *path); + EDL *new_nested(EDL *nested_edl, const char *path); + void create_nested(EDL *nested_edl, const char *path); void paste_silence(double start, double end, int edit_labels /* = 1 */, int edit_plugins, diff --git a/cinelerra-5.1/cinelerra/localsession.C b/cinelerra-5.1/cinelerra/localsession.C index eace821b..8e691310 100644 --- a/cinelerra-5.1/cinelerra/localsession.C +++ b/cinelerra-5.1/cinelerra/localsession.C @@ -507,12 +507,3 @@ int LocalSession::outpoint_valid() return out_point >= 0; } -void LocalSession::set_clip_path(Indexable *indexable) -{ - char string[BCTEXTLEN]; - FileSystem fs; - fs.extract_name(string, indexable->path); - strcpy(clip_title, string); -} - - diff --git a/cinelerra-5.1/cinelerra/localsession.h b/cinelerra-5.1/cinelerra/localsession.h index bf1ddeeb..cd948aa3 100644 --- a/cinelerra-5.1/cinelerra/localsession.h +++ b/cinelerra-5.1/cinelerra/localsession.h @@ -63,7 +63,6 @@ public: void load_xml(FileXML *file, unsigned long load_flags); int load_defaults(BC_Hash *defaults); int save_defaults(BC_Hash *defaults); - void set_clip_path(Indexable *indexable); // Used to copy parameters that affect rendering. void synchronize_params(LocalSession *that); diff --git a/cinelerra-5.1/cinelerra/mainundo.C b/cinelerra-5.1/cinelerra/mainundo.C index 4a921cf4..3bc8d7cf 100644 --- a/cinelerra-5.1/cinelerra/mainundo.C +++ b/cinelerra-5.1/cinelerra/mainundo.C @@ -200,14 +200,14 @@ int MainUndo::undo() mwindow->gui->mainmenu->redo-> update_caption(next ? next->get_description() : ""); } - FileXML file; char *current_data = current->get_data(); if( current_data ) { + FileXML file; file.read_from_string(current_data); + delete [] current_data; load_from_undo(&file, current->get_flags()); //printf("MainUndo::undo %d %s\n", __LINE__, current->get_filename()); mwindow->set_filename(current->get_filename()); - delete [] current_data; if( mwindow->gui ) { // Now update the menu with the after entry @@ -231,21 +231,18 @@ int MainUndo::redo() undo_stack->current = current; char *current_data = current->get_data(); if( current_data ) { - FileXML file; mwindow->set_filename(current->get_filename()); + FileXML file; file.read_from_string(current_data); load_from_undo(&file, current->get_flags()); delete [] current_data; - - if( mwindow->gui ) { // Update menu - mwindow->gui->mainmenu->undo-> - update_caption(current->get_description()); + mwindow->gui->mainmenu->undo-> + update_caption(current->get_description()); // Get next after entry - if( (current=NEXT) ) current = NEXT; - mwindow->gui->mainmenu->redo-> - update_caption(current ? current->get_description() : ""); - } + if( (current=NEXT) ) current = NEXT; + mwindow->gui->mainmenu->redo-> + update_caption(current ? current->get_description() : ""); } } reset_creators(); @@ -258,8 +255,11 @@ int MainUndo::redo() // Here the master EDL loads int MainUndo::load_from_undo(FileXML *file, uint32_t load_flags) { - if( load_flags & LOAD_SESSION ) + if( load_flags & LOAD_SESSION ) { + mwindow->gui->unlock_window(); mwindow->close_mixers(); + mwindow->gui->lock_window("MainUndo::load_from_undo"); + } mwindow->edl->load_xml(file, load_flags); for( Asset *asset=mwindow->edl->assets->first; asset; asset=asset->next ) { mwindow->mainindexes->add_next_asset(0, asset); @@ -270,8 +270,11 @@ int MainUndo::load_from_undo(FileXML *file, uint32_t load_flags) } mwindow->mainindexes->start_build(); mwindow->update_plugin_guis(1); - if( load_flags & LOAD_SESSION ) + if( load_flags & LOAD_SESSION ) { + mwindow->gui->unlock_window(); mwindow->open_mixers(); + mwindow->gui->lock_window("MainUndo::load_from_undo"); + } return 0; } diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 4245e872..56059c67 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -1288,35 +1288,53 @@ void MWindow::close_mixers() } } +ZWindow *MWindow::create_mixer(Indexable *indexable) +{ + ArrayList new_assets; + new_assets.append(indexable); + Track *track = edl->tracks->last; + load_assets(&new_assets, 0, LOADMODE_NEW_TRACKS, 0, 0, 0, 0, 0, 0); + track = !track ? edl->tracks->first : track->next; + Mixer *mixer = 0; + ZWindow *zwindow = get_mixer(mixer); + while( track ) { + track->play = track->record = 0; + if( track->data_type == TRACK_VIDEO ) { + sprintf(track->title, _("Mixer %d"), zwindow->idx); + } + mixer->mixer_ids.append(track->get_mixer_id()); + track = track->next; + } + if( indexable->is_asset ) { + char *path = indexable->path; + char *tp = strrchr(path, '/'); + if( !tp ) tp = path; else ++tp; + zwindow->set_title(tp); + } + else { + char *title = ((EDL*)indexable)->local_session->clip_title; + zwindow->set_title(title); + } + return zwindow; +} + void MWindow::create_mixers() { - if( !session->drag_assets->size() ) return; + if( !session->drag_assets->size() && + !session->drag_clips->size() ) return; undo->update_undo_before(); select_zwindow(0); ArrayListnew_mixers; - for( int i=0; idrag_assets->total; ++i ) { - Indexable *indexable = session->drag_assets->values[i]; - ArrayList new_assets; - new_assets.append(indexable); - Track *track = edl->tracks->last; - load_assets(&new_assets, -1, LOADMODE_NEW_TRACKS, 0, 0, 0, 0, 0, 0); - track = !track ? edl->tracks->first : track->next; - Mixer *mixer = 0; - ZWindow *zwindow = get_mixer(mixer); - while( track ) { - track->play = track->record = 0; - if( track->data_type == TRACK_VIDEO ) { - sprintf(track->title, _("Mixer %d"), zwindow->idx); - } - mixer->mixer_ids.append(track->get_mixer_id()); - track = track->next; - } - char *path = indexable->path; - char *tp = strrchr(path, '/'); - if( !tp ) tp = path; else ++tp; - zwindow->set_title(tp); + for( int i=0; idrag_assets->size(); ++i ) { + Indexable *indexable = session->drag_assets->get(i); + ZWindow *zwindow = create_mixer(indexable); + new_mixers.append(zwindow); + } + for( int i=0; idrag_clips->size(); ++i ) { + Indexable *indexable = (Indexable*)session->drag_clips->get(i); + ZWindow *zwindow = create_mixer(indexable); new_mixers.append(zwindow); } @@ -1941,11 +1959,9 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); // Load temporary EDL for nesting. EDL *nested_edl = new EDL; nested_edl->create_objects(); - nested_edl->set_path(filenames->get(i)); nested_edl->load_xml(&xml_file, LOAD_ALL); //printf("MWindow::load_filenames %p %s\n", nested_edl, nested_edl->project_path); - new_edl->to_nested(nested_edl); - new_edl->local_session->set_clip_path(nested_edl); + new_edl->create_nested(nested_edl, filenames->get(i)); nested_edl->Garbage::remove_user(); } else { diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index 69781804..0dfd24ce 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -204,6 +204,7 @@ public: void queue_mixers(EDL *edl, int command, int wait_tracking, int use_inout, int update_refresh, int toggle_audio, int loop_play); + ZWindow *create_mixer(Indexable *indexable); void create_mixers(); void refresh_mixers(int dir=1); void stop_mixers(); diff --git a/cinelerra-5.1/cinelerra/mwindowedit.C b/cinelerra-5.1/cinelerra/mwindowedit.C index 2366c388..51f1b421 100644 --- a/cinelerra-5.1/cinelerra/mwindowedit.C +++ b/cinelerra-5.1/cinelerra/mwindowedit.C @@ -1207,17 +1207,15 @@ if( debug ) printf("MWindow::load_assets %d\n", __LINE__); EDL *new_edl = new EDL; new_edl->create_objects(); new_edl->copy_session(edl); - new_edls.append(new_edl); - if( !indexable->is_asset ) { EDL *nested_edl = (EDL*)indexable; - new_edl->to_nested(nested_edl); - new_edl->local_session->set_clip_path(nested_edl); + new_edl->create_nested(nested_edl, indexable->path); } else { Asset *asset = (Asset*)indexable; asset_to_edl(new_edl, asset); } + new_edls.append(new_edl); if( labels ) { for( RecordLabel *label=labels->first; label; label=label->next ) { diff --git a/cinelerra-5.1/cinelerra/proxypopup.C b/cinelerra-5.1/cinelerra/proxypopup.C new file mode 100644 index 00000000..225b21bd --- /dev/null +++ b/cinelerra-5.1/cinelerra/proxypopup.C @@ -0,0 +1,271 @@ + +/* + * CINELERRA + * Copyright (C) 1997-2012 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "assetedit.h" +#include "proxypopup.h" +#include "awindow.h" +#include "awindowgui.h" +#include "bcsignals.h" +#include "clipedit.h" +#include "cwindow.h" +#include "cwindowgui.h" +#include "edit.h" +#include "edits.h" +#include "edl.h" +#include "filexml.h" +#include "language.h" +#include "localsession.h" +#include "mainerror.h" +#include "mainsession.h" +#include "mwindow.h" +#include "mwindowgui.h" +#include "track.h" +#include "tracks.h" +#include "vwindow.h" +#include "vwindowgui.h" + + + +ProxyPopup::ProxyPopup(MWindow *mwindow, AWindowGUI *gui) + : BC_PopupMenu(0, 0, 0, "", 0) +{ + this->mwindow = mwindow; + this->gui = gui; +} + +ProxyPopup::~ProxyPopup() +{ +} + +void ProxyPopup::create_objects() +{ + add_item(info = new ProxyPopupInfo(mwindow, this)); + add_item(format = new AWindowListFormat(mwindow, gui)); + add_item(new ProxyPopupSort(mwindow, this)); + add_item(view = new ProxyPopupView(mwindow, this)); + add_item(view_window = new ProxyPopupViewWindow(mwindow, this)); + add_item(new ProxyPopupCopy(mwindow, this)); + add_item(new ProxyPopupPaste(mwindow, this)); +} + +void ProxyPopup::paste_assets() +{ +// Collect items into the drag vectors for temporary storage + gui->lock_window("ProxyPopup::paste_assets"); + mwindow->gui->lock_window("ProxyPopup::paste_assets"); + mwindow->cwindow->gui->lock_window("ProxyPopup::paste_assets"); + + gui->collect_assets(1); + mwindow->paste_assets(mwindow->edl->local_session->get_selectionstart(1), + mwindow->edl->tracks->first, 0); // do not overwrite + + gui->unlock_window(); + mwindow->gui->unlock_window(); + mwindow->cwindow->gui->unlock_window(); +} + +int ProxyPopup::update() +{ + format->update(); + gui->collect_assets(1); + return 0; +} + + +ProxyPopupInfo::ProxyPopupInfo(MWindow *mwindow, ProxyPopup *popup) + : BC_MenuItem(_("Info...")) +{ + this->mwindow = mwindow; + this->popup = popup; +} + +ProxyPopupInfo::~ProxyPopupInfo() +{ +} + +int ProxyPopupInfo::handle_event() +{ + int cur_x, cur_y; + popup->gui->get_abs_cursor(cur_x, cur_y, 0); + + if( mwindow->session->drag_assets->total ) { + AssetEdit *asset_edit = mwindow->awindow->get_asset_editor(); + asset_edit->edit_asset( + mwindow->session->drag_assets->values[0], cur_x, cur_y); + } + else + if( mwindow->session->drag_clips->total ) { + popup->gui->awindow->clip_edit->edit_clip( + mwindow->session->drag_clips->values[0], cur_x, cur_y); + } + return 1; +} + + +ProxyPopupSort::ProxyPopupSort(MWindow *mwindow, ProxyPopup *popup) + : BC_MenuItem(_("Sort items")) +{ + this->mwindow = mwindow; + this->popup = popup; +} + +ProxyPopupSort::~ProxyPopupSort() +{ +} + +int ProxyPopupSort::handle_event() +{ + mwindow->awindow->gui->sort_assets(0); + return 1; +} + + +ProxyPopupView::ProxyPopupView(MWindow *mwindow, ProxyPopup *popup) + : BC_MenuItem(_("View")) +{ + this->mwindow = mwindow; + this->popup = popup; +} + +ProxyPopupView::~ProxyPopupView() +{ +} + +int ProxyPopupView::handle_event() +{ + VWindow *vwindow = mwindow->get_viewer(1, DEFAULT_VWINDOW); + + if( mwindow->session->drag_assets->total ) + vwindow->change_source( + mwindow->session->drag_assets->values[0]); + else + if( mwindow->session->drag_clips->total ) + vwindow->change_source( + mwindow->session->drag_clips->values[0]); + + return 1; +} + + +ProxyPopupViewWindow::ProxyPopupViewWindow(MWindow *mwindow, ProxyPopup *popup) + : BC_MenuItem(_("View in new window")) +{ + this->mwindow = mwindow; + this->popup = popup; +} + +ProxyPopupViewWindow::~ProxyPopupViewWindow() +{ +} + +int ProxyPopupViewWindow::handle_event() +{ + for( int i=0; isession->drag_assets->size(); ++i ) { + VWindow *vwindow = mwindow->get_viewer(1); + vwindow->gui->lock_window("ProxyPopupView::handle_event 1"); + vwindow->change_source(mwindow->session->drag_assets->get(i)); + vwindow->gui->unlock_window(); + } + for( int i=0; isession->drag_clips->size(); ++i ) { + VWindow *vwindow = mwindow->get_viewer(1); + vwindow->gui->lock_window("ProxyPopupView::handle_event 2"); + vwindow->change_source(mwindow->session->drag_clips->get(i)); + vwindow->gui->unlock_window(); + } + return 1; +} + + +ProxyPopupCopy::ProxyPopupCopy(MWindow *mwindow, ProxyPopup *popup) + : BC_MenuItem(_("Copy")) +{ + this->mwindow = mwindow; + this->popup = popup; +} +ProxyPopupCopy::~ProxyPopupCopy() +{ +} + +int ProxyPopupCopy::handle_event() +{ + MWindowGUI *gui = mwindow->gui; + gui->lock_window("ProxyPopupCopy::handle_event"); + if( mwindow->session->drag_clips->total > 0 ) { + EDL *edl = mwindow->session->drag_clips->values[0]; + EDL *copy_edl = new EDL; // no parent or assets wont be copied + copy_edl->create_objects(); + copy_edl->copy_all(edl); + FileXML file; + double start = 0, end = edl->tracks->total_length(); + copy_edl->copy(start, end, 1, &file, "", 1); + copy_edl->remove_user(); + const char *file_string = file.string(); + long file_length = strlen(file_string); + gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION); + gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION); + } + gui->unlock_window(); + return 1; +} + + +ProxyPopupPaste::ProxyPopupPaste(MWindow *mwindow, ProxyPopup *popup) + : BC_MenuItem(_("Paste")) +{ + this->mwindow = mwindow; + this->popup = popup; +} + +ProxyPopupPaste::~ProxyPopupPaste() +{ +} + +int ProxyPopupPaste::handle_event() +{ + popup->paste_assets(); + return 1; +} + + +ProxyListMenu::ProxyListMenu(MWindow *mwindow, AWindowGUI *gui) + : BC_PopupMenu(0, 0, 0, "", 0) +{ + this->mwindow = mwindow; + this->gui = gui; +} + +ProxyListMenu::~ProxyListMenu() +{ +} + +void ProxyListMenu::create_objects() +{ + add_item(format = new AWindowListFormat(mwindow, gui)); + add_item(new AWindowListSort(mwindow, gui)); + update(); +} + +void ProxyListMenu::update() +{ + format->update(); +} + + diff --git a/cinelerra-5.1/cinelerra/proxypopup.h b/cinelerra-5.1/cinelerra/proxypopup.h new file mode 100644 index 00000000..3a079806 --- /dev/null +++ b/cinelerra-5.1/cinelerra/proxypopup.h @@ -0,0 +1,142 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef PROXYPOPUP_H +#define PROXYPOPUP_H + +#include "assetedit.inc" +#include "awindowgui.inc" +#include "proxypopup.inc" +#include "edl.inc" +#include "guicast.h" +#include "assets.inc" +#include "mwindow.inc" + + + +class ProxyPopup : public BC_PopupMenu +{ +public: + ProxyPopup(MWindow *mwindow, AWindowGUI *gui); + ~ProxyPopup(); + + void create_objects(); +// Set mainsession with the current selections + int update(); + void paste_assets(); + + MWindow *mwindow; + AWindowGUI *gui; + + ProxyPopupInfo *info; + ProxyPopupView *view; + ProxyPopupViewWindow *view_window; + AWindowListFormat *format; +}; + +class ProxyPopupInfo : public BC_MenuItem +{ +public: + ProxyPopupInfo(MWindow *mwindow, ProxyPopup *popup); + ~ProxyPopupInfo(); + + int handle_event(); + int button_press_event(); + + MWindow *mwindow; + ProxyPopup *popup; +}; + +class ProxyPopupSort : public BC_MenuItem +{ +public: + ProxyPopupSort(MWindow *mwindow, ProxyPopup *popup); + ~ProxyPopupSort(); + + int handle_event(); + + MWindow *mwindow; + ProxyPopup *popup; +}; + +class ProxyPopupView : public BC_MenuItem +{ +public: + ProxyPopupView(MWindow *mwindow, ProxyPopup *popup); + ~ProxyPopupView(); + + int handle_event(); + + MWindow *mwindow; + ProxyPopup *popup; +}; + + +class ProxyPopupViewWindow : public BC_MenuItem +{ +public: + ProxyPopupViewWindow(MWindow *mwindow, ProxyPopup *popup); + ~ProxyPopupViewWindow(); + + int handle_event(); + + MWindow *mwindow; + ProxyPopup *popup; +}; + +class ProxyPopupCopy : public BC_MenuItem +{ +public: + ProxyPopupCopy(MWindow *mwindow, ProxyPopup *popup); + ~ProxyPopupCopy(); + + int handle_event(); + + MWindow *mwindow; + ProxyPopup *popup; +}; + +class ProxyPopupPaste : public BC_MenuItem +{ +public: + ProxyPopupPaste(MWindow *mwindow, ProxyPopup *popup); + ~ProxyPopupPaste(); + + int handle_event(); + + MWindow *mwindow; + ProxyPopup *popup; +}; + +class ProxyListMenu : public BC_PopupMenu +{ +public: + ProxyListMenu(MWindow *mwindow, AWindowGUI *gui); + ~ProxyListMenu(); + + void create_objects(); + void update(); + AWindowListFormat *format; + MWindow *mwindow; + AWindowGUI *gui; +}; + +#endif diff --git a/cinelerra-5.1/cinelerra/proxypopup.inc b/cinelerra-5.1/cinelerra/proxypopup.inc new file mode 100644 index 00000000..e0a544ad --- /dev/null +++ b/cinelerra-5.1/cinelerra/proxypopup.inc @@ -0,0 +1,33 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __PROXYPOPUP_INC__ +#define __PROXYPOPUP_INC__ + +class ProxyPopup; +class ProxyPopupInfo; +class ProxyPopupSort; +class ProxyPopupView; +class ProxyPopupViewWindow; +class ProxyPopupCopy; +class ProxyListMenu; + +#endif diff --git a/cinelerra-5.1/cinelerra/versioninfo.h b/cinelerra-5.1/cinelerra/versioninfo.h index 21621aec..19a9189d 100644 --- a/cinelerra-5.1/cinelerra/versioninfo.h +++ b/cinelerra-5.1/cinelerra/versioninfo.h @@ -3,9 +3,9 @@ #define CINELERRA_VERSION "5.1" #define REPOMAINTXT "git://git.cinelerra-cv.org/goodguy/cinelerra.git\n" -#define COPYRIGHT_DATE "2017" -#define COPYRIGHTTEXT1 "(c) 2006-2017 Heroine Virtual Ltd. by Adam Williams\n" -#define COPYRIGHTTEXT2 "(c) 2007-2017 cin5 derivative by W.P. Morrow aka goodguy\n" +#define COPYRIGHT_DATE "2018" +#define COPYRIGHTTEXT1 "(c) 2006-2018 Heroine Virtual Ltd. by Adam Williams\n" +#define COPYRIGHTTEXT2 "(c) 2007-2018 cin5 derivative by W.P. Morrow aka goodguy\n" #undef COMPILEDATE #endif diff --git a/cinelerra-5.1/cinelerra/vwindow.C b/cinelerra-5.1/cinelerra/vwindow.C index 451c7132..98858289 100644 --- a/cinelerra-5.1/cinelerra/vwindow.C +++ b/cinelerra-5.1/cinelerra/vwindow.C @@ -208,62 +208,36 @@ void VWindow::change_source(int edl_number) void VWindow::change_source(Indexable *indexable) { + if( !indexable->is_asset ) { + change_source((EDL*)indexable); + return; + } if(!running()) return; if( playback_engine->is_playing_back ) stop_playback(1); -// if(asset && this->asset && -// asset->id == this->asset->id && -// asset == this->asset) return; gui->lock_window("VWindow::change_source 2"); -//printf("VWindow::change_source %d\n", __LINE__); - char title[BCTEXTLEN]; FileSystem fs; fs.extract_name(title, indexable->path); -//printf("VWindow::change_source 1\n"); - delete_source(1, 0); -//printf("VWindow::change_source 1\n"); - -// Generate EDL off of main EDL for cutting - Asset *asset = 0; - EDL *nested_edl = 0; - if(indexable->is_asset) - { - this->indexable = asset = new Asset; - asset->copy_from((Asset*)indexable, 0); - } - else - { - this->indexable = nested_edl = new EDL; - nested_edl->create_objects(); - nested_edl->copy_all((EDL*)indexable); - } // Create EDL this->edl = new EDL(mwindow->edl); this->edl->create_objects(); mwindow->edl->append_vwindow_edl(this->edl, 1); -// mwindow->edl->vwindow_edl = new EDL(mwindow->edl); -// mwindow->edl->vwindow_edl_shared = 0; -// mwindow->edl->vwindow_edl->create_objects(); - -//printf("VWindow::change_source 1 %d %p %p\n", __LINE__, asset, nested_edl); - if(asset) - mwindow->asset_to_edl(this->edl, asset); - else - this->edl->to_nested(nested_edl); +// Generate EDL off of main EDL for cutting + Asset *asset = new Asset; + asset->copy_from((Asset*)indexable, 0); + this->indexable = asset; + mwindow->asset_to_edl(this->edl, asset); // Update GUI gui->change_source(this->edl, title); update_position(CHANGE_ALL, 1, 1, 1); - - -//printf("VWindow::change_source 2\n"); gui->unlock_window(); } diff --git a/cinelerra-5.1/configure.ac b/cinelerra-5.1/configure.ac index d54d4905..557aae3c 100644 --- a/cinelerra-5.1/configure.ac +++ b/cinelerra-5.1/configure.ac @@ -132,7 +132,7 @@ PKG_3RD([fdk],[auto], [ libAACdec/include libAACenc/include libSYS/include ]) PKG_3RD([ffmpeg],[yes], - [ffmpeg-3.4.1], + [ffmpeg-3.4.2], [ libavutil/libavutil.a \ libavcodec/libavcodec.a \ libpostproc/libpostproc.a \ diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch1 b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch1 deleted file mode 100644 index daa99538..00000000 --- a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch1 +++ /dev/null @@ -1,12 +0,0 @@ -diff -ru ffmpeg-3.0.orig/libavformat/bluray.c ffmpeg-3.0/libavformat/bluray.c ---- ffmpeg-3.0.orig/libavformat/bluray.c 2015-03-13 11:34:50.000000000 -0600 -+++ ffmpeg-3.0/libavformat/bluray.c 2016-05-09 14:07:34.758713307 -0600 -@@ -28,7 +28,7 @@ - #include "libavutil/opt.h" - - #define BLURAY_PROTO_PREFIX "bluray:" --#define MIN_PLAYLIST_LENGTH 180 /* 3 min */ -+#define MIN_PLAYLIST_LENGTH 0 - - typedef struct { - const AVClass *class; diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch2 b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch2 deleted file mode 100644 index bb628d93..00000000 --- a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch2 +++ /dev/null @@ -1,498 +0,0 @@ -diff -ur a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c ---- a/libavformat/mpegtsenc.c 2017-12-10 14:35:10.000000000 -0700 -+++ b/libavformat/mpegtsenc.c 2017-12-18 10:54:14.260167666 -0700 -@@ -56,9 +56,8 @@ - int sid; /* service ID */ - char *name; - char *provider_name; -- int pcr_pid; -- int pcr_packet_count; -- int pcr_packet_period; -+ int64_t pcr, pcr_packet_timer, pcr_packet_period; -+ int pcr_sid, pcr_pid; - AVProgram *program; - } MpegTSService; - -@@ -78,14 +77,12 @@ - MpegTSSection pat; /* MPEG-2 PAT table */ - MpegTSSection sdt; /* MPEG-2 SDT table context */ - MpegTSService **services; -- int sdt_packet_count; -- int sdt_packet_period; -- int pat_packet_count; -- int pat_packet_period; -+ int64_t sdt_packet_timer, sdt_packet_period; -+ int64_t pat_packet_timer, pat_packet_period; - int nb_services; - int onid; - int tsid; -- int64_t first_pcr; -+ int64_t pcr, first_pcr, delay; - int mux_rate; ///< set to 1 when VBR - int pes_payload_size; - -@@ -95,12 +92,14 @@ - int service_type; - - int pmt_start_pid; -+ int pcr_start_pid; - int start_pid; - int m2ts_mode; -+ int64_t ts_offset; - - int reemit_pat_pmt; // backward compatibility - -- int pcr_period; -+ double pcr_period; - #define MPEGTS_FLAG_REEMIT_PAT_PMT 0x01 - #define MPEGTS_FLAG_AAC_LATM 0x02 - #define MPEGTS_FLAG_PAT_PMT_AT_FRAMES 0x04 -@@ -111,8 +110,6 @@ - int tables_version; - double pat_period; - double sdt_period; -- int64_t last_pat_ts; -- int64_t last_sdt_ts; - - int omit_video_pes_length; - } MpegTSWrite; -@@ -222,10 +219,10 @@ - #define DEFAULT_PROVIDER_NAME "FFmpeg" - #define DEFAULT_SERVICE_NAME "Service01" - --/* we retransmit the SI info at this rate */ -+/* we retransmit the SI info at this rate (ms) */ - #define SDT_RETRANS_TIME 500 - #define PAT_RETRANS_TIME 100 --#define PCR_RETRANS_TIME 20 -+#define PCR_RETRANS_TIME 50 - - typedef struct MpegTSWriteStream { - struct MpegTSService *service; -@@ -721,6 +718,7 @@ - service->pmt.pid = ts->pmt_start_pid + ts->nb_services; - service->sid = sid; - service->pcr_pid = 0x1fff; -+ service->pcr_sid = 0x1fff; - service->provider_name = av_strdup(provider_name); - service->name = av_strdup(name); - if (!service->provider_name || !service->name) -@@ -736,18 +734,11 @@ - return NULL; - } - --static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb) --{ -- return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + -- ts->first_pcr; --} -- - static void mpegts_prefix_m2ts_header(AVFormatContext *s) - { - MpegTSWrite *ts = s->priv_data; - if (ts->m2ts_mode) { -- int64_t pcr = get_pcr(s->priv_data, s->pb); -- uint32_t tp_extra_header = pcr % 0x3fffffff; -+ uint32_t tp_extra_header = ts->pcr % 0x3fffffff; - tp_extra_header = AV_RB32(&tp_extra_header); - avio_write(s->pb, (unsigned char *) &tp_extra_header, - sizeof(tp_extra_header)); -@@ -768,6 +759,7 @@ - MpegTSService *service; - AVStream *st, *pcr_st = NULL; - AVDictionaryEntry *title, *provider; -+ double clk_rate; - int i, j; - const char *service_name; - const char *provider_name; -@@ -776,6 +768,15 @@ - - if (s->max_delay < 0) /* Not set by the caller */ - s->max_delay = 0; -+ ts->delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); -+ -+ if (ts->m2ts_mode == -1) { -+ if (av_match_ext(s->filename, "m2ts")) { -+ ts->m2ts_mode = 1; -+ } else { -+ ts->m2ts_mode = 0; -+ } -+ } - - // round up to a whole number of TS packets - ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14; -@@ -822,6 +823,8 @@ - service->program = program; - } - } -+ if (ts->m2ts_mode > 1) -+ service->pmt.pid = 0x00ff + ts->service_id; - - ts->pat.pid = PAT_PID; - /* Initialize at 15 so that it wraps and is equal to 0 for the -@@ -907,10 +910,9 @@ - ts_st->discontinuity = ts->flags & MPEGTS_FLAG_DISCONT; - /* update PCR pid by using the first video stream */ - if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && -- service->pcr_pid == 0x1fff) { -- service->pcr_pid = ts_st->pid; -+ service->pcr_sid == 0x1fff) - pcr_st = st; -- } -+ - if (st->codecpar->codec_id == AV_CODEC_ID_AAC && - st->codecpar->extradata_size > 0) { - AVStream *ast; -@@ -946,78 +948,47 @@ - av_freep(&pids); - - /* if no video stream, use the first stream as PCR */ -- if (service->pcr_pid == 0x1fff && s->nb_streams > 0) { -- pcr_st = s->streams[0]; -- ts_st = pcr_st->priv_data; -- service->pcr_pid = ts_st->pid; -- } else -- ts_st = pcr_st->priv_data; -- -- if (ts->mux_rate > 1) { -- service->pcr_packet_period = (int64_t)ts->mux_rate * ts->pcr_period / -- (TS_PACKET_SIZE * 8 * 1000); -- ts->sdt_packet_period = (int64_t)ts->mux_rate * SDT_RETRANS_TIME / -- (TS_PACKET_SIZE * 8 * 1000); -- ts->pat_packet_period = (int64_t)ts->mux_rate * PAT_RETRANS_TIME / -- (TS_PACKET_SIZE * 8 * 1000); -- -- if (ts->copyts < 1) -- ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE); -- } else { -- /* Arbitrary values, PAT/PMT will also be written on video key frames */ -- ts->sdt_packet_period = 200; -- ts->pat_packet_period = 40; -- if (pcr_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { -- int frame_size = av_get_audio_frame_duration2(pcr_st->codecpar, 0); -- if (!frame_size) { -- av_log(s, AV_LOG_WARNING, "frame size not set\n"); -- service->pcr_packet_period = -- pcr_st->codecpar->sample_rate / (10 * 512); -- } else { -- service->pcr_packet_period = -- pcr_st->codecpar->sample_rate / (10 * frame_size); -- } -- } else { -- // max delta PCR 0.1s -- // TODO: should be avg_frame_rate -- service->pcr_packet_period = -- ts_st->user_tb.den / (10 * ts_st->user_tb.num); -- } -- if (!service->pcr_packet_period) -- service->pcr_packet_period = 1; -- } -- -- ts->last_pat_ts = AV_NOPTS_VALUE; -- ts->last_sdt_ts = AV_NOPTS_VALUE; -- // The user specified a period, use only it -- if (ts->pat_period < INT_MAX/2) { -- ts->pat_packet_period = INT_MAX; -+ if (!pcr_st && s->nb_streams > 0) -+ pcr_st = s->streams[0]; -+ if (!pcr_st) { -+ av_log(s, AV_LOG_ERROR, "no streams\n"); -+ ret = AVERROR(EINVAL); -+ goto fail; - } -- if (ts->sdt_period < INT_MAX/2) { -- ts->sdt_packet_period = INT_MAX; -+ ts_st = pcr_st->priv_data; -+ if (service->pcr_sid == 0x1fff) -+ service->pcr_sid = ts_st->pid; -+ if (service->pcr_pid == 0x1fff) -+ service->pcr_pid = ts->m2ts_mode > 1 ? -+ 0x1000 + ts->service_id : service->pcr_sid ; -+ if (service->pmt.pid == service->pcr_pid) { -+ av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", service->pcr_pid); -+ ret = AVERROR(EINVAL); -+ goto fail; - } - -+ clk_rate = ts->mux_rate > 1 ? ts->mux_rate : PCR_TIME_BASE; -+ ts->sdt_packet_period = ts->sdt_period < 0 ? -1 : ts->sdt_period/1000 * clk_rate; -+ ts->pat_packet_period = ts->pat_period/1000 * clk_rate; -+ service->pcr_packet_period = ts->pcr_period/1000 * clk_rate; -+ if (service->pcr_packet_period < (TS_PACKET_SIZE*8*10)) -+ service->pcr_packet_period = (TS_PACKET_SIZE*8*10); -+ av_log(s, AV_LOG_VERBOSE, "clk_rate %f: ticks/pkt %d pcr, %d sdt, %d pmt\n", clk_rate, -+ (int)service->pcr_packet_period, (int)ts->sdt_packet_period, (int)ts->pat_packet_period); -+ -+ if (ts->copyts < 1) -+ ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE); -+ - // output a PCR as soon as possible -- service->pcr_packet_count = service->pcr_packet_period; -- ts->pat_packet_count = ts->pat_packet_period - 1; -- ts->sdt_packet_count = ts->sdt_packet_period - 1; -+ ts->pcr = 0; -+ service->pcr_packet_timer = 0; -+ ts->pat_packet_timer = 0; -+ ts->sdt_packet_timer = 0; - - if (ts->mux_rate == 1) - av_log(s, AV_LOG_VERBOSE, "muxrate VBR, "); - else - av_log(s, AV_LOG_VERBOSE, "muxrate %d, ", ts->mux_rate); -- av_log(s, AV_LOG_VERBOSE, -- "pcr every %d pkts, sdt every %d, pat/pmt every %d pkts\n", -- service->pcr_packet_period, -- ts->sdt_packet_period, ts->pat_packet_period); -- -- if (ts->m2ts_mode == -1) { -- if (av_match_ext(s->filename, "m2ts")) { -- ts->m2ts_mode = 1; -- } else { -- ts->m2ts_mode = 0; -- } -- } - - return 0; - -@@ -1032,22 +1003,12 @@ - MpegTSWrite *ts = s->priv_data; - int i; - -- if (++ts->sdt_packet_count == ts->sdt_packet_period || -- (dts != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) || -- (dts != AV_NOPTS_VALUE && dts - ts->last_sdt_ts >= ts->sdt_period*90000.0) -- ) { -- ts->sdt_packet_count = 0; -- if (dts != AV_NOPTS_VALUE) -- ts->last_sdt_ts = FFMAX(dts, ts->last_sdt_ts); -+ if ( ts->sdt_packet_period >= 0 && ts->pcr >= ts->sdt_packet_timer ) { -+ ts->sdt_packet_timer = ts->pcr + ts->sdt_packet_period; - mpegts_write_sdt(s); - } -- if (++ts->pat_packet_count == ts->pat_packet_period || -- (dts != AV_NOPTS_VALUE && ts->last_pat_ts == AV_NOPTS_VALUE) || -- (dts != AV_NOPTS_VALUE && dts - ts->last_pat_ts >= ts->pat_period*90000.0) || -- force_pat) { -- ts->pat_packet_count = 0; -- if (dts != AV_NOPTS_VALUE) -- ts->last_pat_ts = FFMAX(dts, ts->last_pat_ts); -+ if (ts->pcr >= ts->pat_packet_timer || force_pat) { -+ ts->pat_packet_timer = ts->pcr + ts->pat_packet_period; - mpegts_write_pat(s); - for (i = 0; i < ts->nb_services; i++) - mpegts_write_pmt(s, ts->services[i]); -@@ -1089,13 +1050,14 @@ - { - MpegTSWrite *ts = s->priv_data; - MpegTSWriteStream *ts_st = st->priv_data; -+ uint32_t pcr_pid = ts_st->service->pcr_pid; - uint8_t *q; - uint8_t buf[TS_PACKET_SIZE]; - - q = buf; - *q++ = 0x47; -- *q++ = ts_st->pid >> 8; -- *q++ = ts_st->pid; -+ *q++ = pcr_pid >> 8; -+ *q++ = pcr_pid; - *q++ = 0x20 | ts_st->cc; /* Adaptation only */ - /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */ - *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */ -@@ -1106,7 +1068,7 @@ - } - - /* PCR coded into 6 bytes */ -- q += write_pcr_bits(q, get_pcr(ts, s->pb)); -+ q += write_pcr_bits(q, ts->pcr); - - /* stuffing bytes */ - memset(q, 0xFF, TS_PACKET_SIZE - (q - buf)); -@@ -1175,8 +1137,6 @@ - uint8_t *q; - int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags; - int afc_len, stuffing_len; -- int64_t pcr = -1; /* avoid warning */ -- int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); - int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key; - - av_assert0(ts_st->payload != buf || st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO); -@@ -1186,28 +1146,33 @@ - - is_start = 1; - while (payload_size > 0) { -+ ts->pcr = ts->first_pcr + (ts->mux_rate == 1 ? -+ (dts == AV_NOPTS_VALUE ? 0 : (dts - ts->delay) * 300) : -+ // add 11, pcr references the last byte of program clock reference base -+ av_rescale(avio_tell(s->pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate)); -+ - retransmit_si_info(s, force_pat, dts); - force_pat = 0; - - write_pcr = 0; -- if (ts_st->pid == ts_st->service->pcr_pid) { -- if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames -- ts_st->service->pcr_packet_count++; -- if (ts_st->service->pcr_packet_count >= -- ts_st->service->pcr_packet_period) { -- ts_st->service->pcr_packet_count = 0; -+ if (ts_st->pid == ts_st->service->pcr_sid) { -+ if( ts->pcr >= ts_st->service->pcr_packet_timer ) { -+ ts_st->service->pcr_packet_timer = ts->pcr + ts_st->service->pcr_packet_period; - write_pcr = 1; - } - } -- -+ if (write_pcr && ts_st->service->pcr_sid != ts_st->service->pcr_pid) { -+ mpegts_insert_pcr_only(s, st); -+ continue; -+ } - if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE && -- (dts - get_pcr(ts, s->pb) / 300) > delay) { -- /* pcr insert gets priority over null packet insert */ -- if (write_pcr) -- mpegts_insert_pcr_only(s, st); -+ (dts - ts->pcr / 300) > ts->delay) { -+ /* pcr insert gets priority over null packet insert */ -+ if (write_pcr) -+ mpegts_insert_pcr_only(s, st); - else -- mpegts_insert_null_packet(s); -- /* recalculate write_pcr and possibly retransmit si_info */ -+ mpegts_insert_null_packet(s); -+ /* recalculate write_pcr and possibly retransimit si_info */ - continue; - } - -@@ -1217,6 +1182,10 @@ - val = ts_st->pid >> 8; - if (is_start) - val |= 0x40; -+ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && -+ st->codecpar->codec_id == AV_CODEC_ID_AC3 && -+ ts->m2ts_mode > 1) -+ val |= 0x20; - *q++ = val; - *q++ = ts_st->pid; - ts_st->cc = ts_st->cc + 1 & 0xf; -@@ -1228,7 +1197,7 @@ - } - if (key && is_start && pts != AV_NOPTS_VALUE) { - // set Random Access for key frames -- if (ts_st->pid == ts_st->service->pcr_pid) -+ if (ts_st->pid == ts_st->service->pcr_sid) - write_pcr = 1; - set_af_flag(buf, 0x40); - q = get_ts_payload_start(buf); -@@ -1236,14 +1205,10 @@ - if (write_pcr) { - set_af_flag(buf, 0x10); - q = get_ts_payload_start(buf); -- // add 11, pcr references the last byte of program clock reference base - if (ts->mux_rate > 1) -- pcr = get_pcr(ts, s->pb); -- else -- pcr = (dts - delay) * 300; -- if (dts != AV_NOPTS_VALUE && dts < pcr / 300) -+ if (dts != AV_NOPTS_VALUE && dts < ts->pcr / 300) - av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n"); -- extend_af(buf, write_pcr_bits(q, pcr)); -+ extend_af(buf, write_pcr_bits(q, ts->pcr)); - q = get_ts_payload_start(buf); - } - if (is_start) { -@@ -1344,11 +1309,13 @@ - *q++ = flags; - *q++ = header_len; - if (pts != AV_NOPTS_VALUE) { -- write_pts(q, flags >> 6, pts); -+ int64_t ts_pts = pts + ts->ts_offset; -+ write_pts(q, flags >> 6, ts_pts); - q += 5; - } - if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) { -- write_pts(q, 1, dts); -+ int64_t ts_dts = dts + ts->ts_offset; -+ write_pts(q, 1, ts_dts); - q += 5; - } - if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) { -@@ -1519,7 +1486,6 @@ - uint8_t *data = NULL; - MpegTSWrite *ts = s->priv_data; - MpegTSWriteStream *ts_st = st->priv_data; -- const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2; - int64_t dts = pkt->dts, pts = pkt->pts; - int opus_samples = 0; - int side_data_size; -@@ -1540,16 +1506,15 @@ - } - - if (ts->flags & MPEGTS_FLAG_REEMIT_PAT_PMT) { -- ts->pat_packet_count = ts->pat_packet_period - 1; -- ts->sdt_packet_count = ts->sdt_packet_period - 1; -+ ts->pat_packet_timer = ts->sdt_packet_timer = 0; - ts->flags &= ~MPEGTS_FLAG_REEMIT_PAT_PMT; - } - - if (ts->copyts < 1) { - if (pts != AV_NOPTS_VALUE) -- pts += delay; -+ pts += 2*ts->delay; - if (dts != AV_NOPTS_VALUE) -- dts += delay; -+ dts += 2*ts->delay; - } - - if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) { -@@ -1737,7 +1702,7 @@ - AVStream *st2 = s->streams[i]; - MpegTSWriteStream *ts_st2 = st2->priv_data; - if ( ts_st2->payload_size -- && (ts_st2->payload_dts == AV_NOPTS_VALUE || dts - ts_st2->payload_dts > delay/2)) { -+ && (ts_st2->payload_dts == AV_NOPTS_VALUE || dts - ts_st2->payload_dts > ts->delay)) { - mpegts_write_pes(s, st2, ts_st2->payload, ts_st2->payload_size, - ts_st2->payload_pts, ts_st2->payload_dts, - ts_st2->payload_flags & AV_PKT_FLAG_KEY, stream_id); -@@ -1908,12 +1873,18 @@ - { "mpegts_pmt_start_pid", "Set the first pid of the PMT.", - offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT, - { .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM }, -+ { "mpegts_pcr_start_pid", "Set the first pid of the PCR.", -+ offsetof(MpegTSWrite, pcr_start_pid), AV_OPT_TYPE_INT, -+ { .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM }, - { "mpegts_start_pid", "Set the first pid.", - offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT, - { .i64 = 0x0100 }, 0x0010, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM }, - { "mpegts_m2ts_mode", "Enable m2ts mode.", - offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL, -- { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM }, -+ { .i64 = -1 }, -1, 2, AV_OPT_FLAG_ENCODING_PARAM }, -+ { "mpegts_pcr_offset", "clock offset.", -+ offsetof(MpegTSWrite, ts_offset), AV_OPT_TYPE_BOOL, -+ { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, - { "muxrate", NULL, - offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, - { .i64 = 1 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, -@@ -1951,15 +1922,15 @@ - { "omit_video_pes_length", "Omit the PES packet length for video packets", - offsetof(MpegTSWrite, omit_video_pes_length), AV_OPT_TYPE_BOOL, - { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, -- { "pcr_period", "PCR retransmission time in milliseconds", -- offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_INT, -- { .i64 = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, -- { "pat_period", "PAT/PMT retransmission time limit in seconds", -+ { "pcr_period", "PCR retransmission time limit in msecs", -+ offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_DOUBLE, -+ { .dbl = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, -+ { "pat_period", "PAT/PMT retransmission time limit in msecs", - offsetof(MpegTSWrite, pat_period), AV_OPT_TYPE_DOUBLE, -- { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, -- { "sdt_period", "SDT retransmission time limit in seconds", -+ { .dbl = PAT_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, -+ { "sdt_period", "SDT retransmission time limit in msecs", - offsetof(MpegTSWrite, sdt_period), AV_OPT_TYPE_DOUBLE, -- { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, -+ { .dbl = SDT_RETRANS_TIME }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, - { NULL }, - }; - diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch3 b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch3 deleted file mode 100644 index a96cf1cd..00000000 --- a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch3 +++ /dev/null @@ -1,70 +0,0 @@ -diff -ur a/libavformat/avformat.h b/libavformat/avformat.h ---- a/libavformat/avformat.h 2017-12-10 14:35:10.000000000 -0700 -+++ b/libavformat/avformat.h 2017-12-18 11:11:31.791996302 -0700 -@@ -504,6 +504,9 @@ - The user or muxer can override this through - AVFormatContext.avoid_negative_ts - */ -+#define AVFMT_SEEK_NOSTREAMS 0x80000 /**< Stream index ignored by seek, -+ or some streams fail to seek -+ */ - - #define AVFMT_SEEK_TO_PTS 0x4000000 /**< Seeking is based on PTS */ - -@@ -664,7 +667,8 @@ - /** - * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS, - * AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH, -- * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS. -+ * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS, -+ * AVFMT_SEEK_NOSTREAMS - */ - int flags; - -diff -ur a/libavformat/dv.c b/libavformat/dv.c ---- a/libavformat/dv.c 2017-12-10 14:35:10.000000000 -0700 -+++ b/libavformat/dv.c 2017-12-18 11:11:31.792996246 -0700 -@@ -632,6 +632,7 @@ - AVInputFormat ff_dv_demuxer = { - .name = "dv", - .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), -+ .flags = AVFMT_SEEK_NOSTREAMS, - .priv_data_size = sizeof(RawDVContext), - .read_probe = dv_probe, - .read_header = dv_read_header, -diff -ur a/libavformat/matroskadec.c b/libavformat/matroskadec.c ---- a/libavformat/matroskadec.c 2017-12-10 14:35:10.000000000 -0700 -+++ b/libavformat/matroskadec.c 2017-12-18 11:11:31.793996189 -0700 -@@ -3984,6 +3984,7 @@ - AVInputFormat ff_matroska_demuxer = { - .name = "matroska,webm", - .long_name = NULL_IF_CONFIG_SMALL("Matroska / WebM"), -+ .flags = AVFMT_SEEK_NOSTREAMS, - .extensions = "mkv,mk3d,mka,mks", - .priv_data_size = sizeof(MatroskaDemuxContext), - .read_probe = matroska_probe, -@@ -3997,6 +3998,7 @@ - AVInputFormat ff_webm_dash_manifest_demuxer = { - .name = "webm_dash_manifest", - .long_name = NULL_IF_CONFIG_SMALL("WebM DASH Manifest"), -+ .flags = AVFMT_SEEK_NOSTREAMS, - .priv_data_size = sizeof(MatroskaDemuxContext), - .read_header = webm_dash_manifest_read_header, - .read_packet = webm_dash_manifest_read_packet, -diff -ur a/libavformat/utils.c ./libavformat/utils.c ---- a/libavformat/utils.c 2017-12-10 14:35:18.000000000 -0700 -+++ b/libavformat/utils.c 2017-12-18 11:11:31.795996077 -0700 -@@ -2416,6 +2416,13 @@ - return seek_frame_byte(s, stream_index, timestamp, flags); - } - -+ if (stream_index != -1 && (s->iformat->flags & AVFMT_SEEK_NOSTREAMS)) { -+ timestamp = av_rescale_q(timestamp, -+ s->streams[stream_index]->time_base, -+ AV_TIME_BASE_Q); -+ stream_index = -1; -+ } -+ - if (stream_index < 0) { - stream_index = av_find_default_stream_index(s); - if (stream_index < 0) diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch4 b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch4 deleted file mode 100644 index e218ae5a..00000000 --- a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch4 +++ /dev/null @@ -1,110 +0,0 @@ ---- a/libavcodec/libx264.c 2017-12-10 14:35:08.000000000 -0700 -+++ b/libavcodec/libx264.c 2018-02-08 16:57:46.028108824 -0700 -@@ -279,7 +279,11 @@ - - x264_picture_init( &x4->pic ); - x4->pic.img.i_csp = x4->params.i_csp; -+#if X264_BUILD >= 153 -+ if (x4->params.i_bitdepth > 8) -+#else - if (x264_bit_depth > 8) -+#endif - x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH; - x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt); - -@@ -490,6 +494,9 @@ - x4->params.p_log_private = avctx; - x4->params.i_log_level = X264_LOG_DEBUG; - x4->params.i_csp = convert_pix_fmt(avctx->pix_fmt); -+#if X264_BUILD >= 153 -+ x4->params.i_bitdepth = av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth; -+#endif - - PARSE_X264_OPT("weightp", wpredp); - -@@ -701,24 +708,8 @@ - if (x4->nal_hrd >= 0) - x4->params.i_nal_hrd = x4->nal_hrd; - -- if (x4->motion_est >= 0) { -+ if (x4->motion_est >= 0) - x4->params.analyse.i_me_method = x4->motion_est; --#if FF_API_MOTION_EST --FF_DISABLE_DEPRECATION_WARNINGS -- } else { -- if (avctx->me_method == ME_EPZS) -- x4->params.analyse.i_me_method = X264_ME_DIA; -- else if (avctx->me_method == ME_HEX) -- x4->params.analyse.i_me_method = X264_ME_HEX; -- else if (avctx->me_method == ME_UMH) -- x4->params.analyse.i_me_method = X264_ME_UMH; -- else if (avctx->me_method == ME_FULL) -- x4->params.analyse.i_me_method = X264_ME_ESA; -- else if (avctx->me_method == ME_TESA) -- x4->params.analyse.i_me_method = X264_ME_TESA; --FF_ENABLE_DEPRECATION_WARNINGS --#endif -- } - - if (x4->coder >= 0) - x4->params.b_cabac = x4->coder; -@@ -878,6 +869,24 @@ - AV_PIX_FMT_NV20, - AV_PIX_FMT_NONE - }; -+static const enum AVPixelFormat pix_fmts_all[] = { -+ AV_PIX_FMT_YUV420P, -+ AV_PIX_FMT_YUVJ420P, -+ AV_PIX_FMT_YUV422P, -+ AV_PIX_FMT_YUVJ422P, -+ AV_PIX_FMT_YUV444P, -+ AV_PIX_FMT_YUVJ444P, -+ AV_PIX_FMT_NV12, -+ AV_PIX_FMT_NV16, -+#ifdef X264_CSP_NV21 -+ AV_PIX_FMT_NV21, -+#endif -+ AV_PIX_FMT_YUV420P10, -+ AV_PIX_FMT_YUV422P10, -+ AV_PIX_FMT_YUV444P10, -+ AV_PIX_FMT_NV20, -+ AV_PIX_FMT_NONE -+}; - #if CONFIG_LIBX264RGB_ENCODER - static const enum AVPixelFormat pix_fmts_8bit_rgb[] = { - AV_PIX_FMT_BGR0, -@@ -889,12 +898,16 @@ - - static av_cold void X264_init_static(AVCodec *codec) - { -+#if X264_BUILD < 153 - if (x264_bit_depth == 8) - codec->pix_fmts = pix_fmts_8bit; - else if (x264_bit_depth == 9) - codec->pix_fmts = pix_fmts_9bit; - else if (x264_bit_depth == 10) - codec->pix_fmts = pix_fmts_10bit; -+#else -+ codec->pix_fmts = pix_fmts_all; -+#endif - } - - #define OFFSET(x) offsetof(X264Context, x) -@@ -958,6 +971,7 @@ - { "vbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_VBR}, INT_MIN, INT_MAX, VE, "nal-hrd" }, - { "cbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_CBR}, INT_MIN, INT_MAX, VE, "nal-hrd" }, - { "avcintra-class","AVC-Intra class 50/100/200", OFFSET(avcintra_class),AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 200 , VE}, -+ { "me_method", "Set motion estimation method", OFFSET(motion_est), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, X264_ME_TESA, VE, "motion-est"}, - { "motion-est", "Set motion estimation method", OFFSET(motion_est), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, X264_ME_TESA, VE, "motion-est"}, - { "dia", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_ME_DIA }, INT_MIN, INT_MAX, VE, "motion-est" }, - { "hex", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_ME_HEX }, INT_MIN, INT_MAX, VE, "motion-est" }, -@@ -1002,9 +1016,6 @@ - { "nr", "-1" }, - #endif - { "me_range", "-1" }, --#if FF_API_MOTION_EST -- { "me_method", "-1" }, --#endif - { "subq", "-1" }, - #if FF_API_PRIVATE_OPT - { "b_strategy", "-1" }, diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch5 b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch5 deleted file mode 100644 index f7db4c30..00000000 --- a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch5 +++ /dev/null @@ -1,61 +0,0 @@ ---- a/libavcodec/libx265.c 2017-12-10 14:35:08.000000000 -0700 -+++ b/libavcodec/libx265.c 2018-02-08 16:57:46.028108824 -0700 -@@ -45,6 +45,7 @@ - int forced_idr; - char *preset; - char *tune; -+ char *profile; - char *x265_opts; - } libx265Context; - -@@ -114,11 +115,11 @@ - ctx->params->sourceHeight = avctx->height; - ctx->params->bEnablePsnr = !!(avctx->flags & AV_CODEC_FLAG_PSNR); - -- if ((avctx->color_primaries <= AVCOL_PRI_BT2020 && -+ if ((avctx->color_primaries <= AVCOL_PRI_SMPTE432 && - avctx->color_primaries != AVCOL_PRI_UNSPECIFIED) || -- (avctx->color_trc <= AVCOL_TRC_BT2020_12 && -+ (avctx->color_trc <= AVCOL_TRC_ARIB_STD_B67 && - avctx->color_trc != AVCOL_TRC_UNSPECIFIED) || -- (avctx->colorspace <= AVCOL_SPC_BT2020_CL && -+ (avctx->colorspace <= AVCOL_SPC_ICTCP && - avctx->colorspace != AVCOL_SPC_UNSPECIFIED)) { - - ctx->params->vui.bEnableVideoSignalTypePresentFlag = 1; -@@ -220,6 +221,18 @@ - } - } - -+ if (ctx->profile) { -+ if (ctx->api->param_apply_profile(ctx->params, ctx->profile) < 0) { -+ int i; -+ av_log(avctx, AV_LOG_ERROR, "Invalid or incompatible profile set: %s.\n", ctx->profile); -+ av_log(avctx, AV_LOG_INFO, "Possible profiles:"); -+ for (i = 0; x265_profile_names[i]; i++) -+ av_log(avctx, AV_LOG_INFO, " %s", x265_profile_names[i]); -+ av_log(avctx, AV_LOG_INFO, "\n"); -+ return AVERROR(EINVAL); -+ } -+ } -+ - ctx->encoder = ctx->api->encoder_open(ctx->params); - if (!ctx->encoder) { - av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n"); -@@ -294,7 +307,7 @@ - for (i = 0; i < nnal; i++) - payload += nal[i].sizeBytes; - -- ret = ff_alloc_packet(pkt, payload); -+ ret = ff_alloc_packet2(avctx, pkt, payload, payload); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); - return ret; -@@ -392,6 +412,7 @@ - { "forced-idr", "if forcing keyframes, force them as IDR frames", OFFSET(forced_idr),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, - { "preset", "set the x265 preset", OFFSET(preset), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, - { "tune", "set the x265 tune parameter", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, -+ { "profile", "set the x265 profile", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, - { "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, - { NULL } - }; diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.tar.xz b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.tar.xz deleted file mode 100644 index 8970943c..00000000 Binary files a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.tar.xz and /dev/null differ diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch1 b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch1 new file mode 100644 index 00000000..daa99538 --- /dev/null +++ b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch1 @@ -0,0 +1,12 @@ +diff -ru ffmpeg-3.0.orig/libavformat/bluray.c ffmpeg-3.0/libavformat/bluray.c +--- ffmpeg-3.0.orig/libavformat/bluray.c 2015-03-13 11:34:50.000000000 -0600 ++++ ffmpeg-3.0/libavformat/bluray.c 2016-05-09 14:07:34.758713307 -0600 +@@ -28,7 +28,7 @@ + #include "libavutil/opt.h" + + #define BLURAY_PROTO_PREFIX "bluray:" +-#define MIN_PLAYLIST_LENGTH 180 /* 3 min */ ++#define MIN_PLAYLIST_LENGTH 0 + + typedef struct { + const AVClass *class; diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch2 b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch2 new file mode 100644 index 00000000..bb628d93 --- /dev/null +++ b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch2 @@ -0,0 +1,498 @@ +diff -ur a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c +--- a/libavformat/mpegtsenc.c 2017-12-10 14:35:10.000000000 -0700 ++++ b/libavformat/mpegtsenc.c 2017-12-18 10:54:14.260167666 -0700 +@@ -56,9 +56,8 @@ + int sid; /* service ID */ + char *name; + char *provider_name; +- int pcr_pid; +- int pcr_packet_count; +- int pcr_packet_period; ++ int64_t pcr, pcr_packet_timer, pcr_packet_period; ++ int pcr_sid, pcr_pid; + AVProgram *program; + } MpegTSService; + +@@ -78,14 +77,12 @@ + MpegTSSection pat; /* MPEG-2 PAT table */ + MpegTSSection sdt; /* MPEG-2 SDT table context */ + MpegTSService **services; +- int sdt_packet_count; +- int sdt_packet_period; +- int pat_packet_count; +- int pat_packet_period; ++ int64_t sdt_packet_timer, sdt_packet_period; ++ int64_t pat_packet_timer, pat_packet_period; + int nb_services; + int onid; + int tsid; +- int64_t first_pcr; ++ int64_t pcr, first_pcr, delay; + int mux_rate; ///< set to 1 when VBR + int pes_payload_size; + +@@ -95,12 +92,14 @@ + int service_type; + + int pmt_start_pid; ++ int pcr_start_pid; + int start_pid; + int m2ts_mode; ++ int64_t ts_offset; + + int reemit_pat_pmt; // backward compatibility + +- int pcr_period; ++ double pcr_period; + #define MPEGTS_FLAG_REEMIT_PAT_PMT 0x01 + #define MPEGTS_FLAG_AAC_LATM 0x02 + #define MPEGTS_FLAG_PAT_PMT_AT_FRAMES 0x04 +@@ -111,8 +110,6 @@ + int tables_version; + double pat_period; + double sdt_period; +- int64_t last_pat_ts; +- int64_t last_sdt_ts; + + int omit_video_pes_length; + } MpegTSWrite; +@@ -222,10 +219,10 @@ + #define DEFAULT_PROVIDER_NAME "FFmpeg" + #define DEFAULT_SERVICE_NAME "Service01" + +-/* we retransmit the SI info at this rate */ ++/* we retransmit the SI info at this rate (ms) */ + #define SDT_RETRANS_TIME 500 + #define PAT_RETRANS_TIME 100 +-#define PCR_RETRANS_TIME 20 ++#define PCR_RETRANS_TIME 50 + + typedef struct MpegTSWriteStream { + struct MpegTSService *service; +@@ -721,6 +718,7 @@ + service->pmt.pid = ts->pmt_start_pid + ts->nb_services; + service->sid = sid; + service->pcr_pid = 0x1fff; ++ service->pcr_sid = 0x1fff; + service->provider_name = av_strdup(provider_name); + service->name = av_strdup(name); + if (!service->provider_name || !service->name) +@@ -736,18 +734,11 @@ + return NULL; + } + +-static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb) +-{ +- return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + +- ts->first_pcr; +-} +- + static void mpegts_prefix_m2ts_header(AVFormatContext *s) + { + MpegTSWrite *ts = s->priv_data; + if (ts->m2ts_mode) { +- int64_t pcr = get_pcr(s->priv_data, s->pb); +- uint32_t tp_extra_header = pcr % 0x3fffffff; ++ uint32_t tp_extra_header = ts->pcr % 0x3fffffff; + tp_extra_header = AV_RB32(&tp_extra_header); + avio_write(s->pb, (unsigned char *) &tp_extra_header, + sizeof(tp_extra_header)); +@@ -768,6 +759,7 @@ + MpegTSService *service; + AVStream *st, *pcr_st = NULL; + AVDictionaryEntry *title, *provider; ++ double clk_rate; + int i, j; + const char *service_name; + const char *provider_name; +@@ -776,6 +768,15 @@ + + if (s->max_delay < 0) /* Not set by the caller */ + s->max_delay = 0; ++ ts->delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); ++ ++ if (ts->m2ts_mode == -1) { ++ if (av_match_ext(s->filename, "m2ts")) { ++ ts->m2ts_mode = 1; ++ } else { ++ ts->m2ts_mode = 0; ++ } ++ } + + // round up to a whole number of TS packets + ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14; +@@ -822,6 +823,8 @@ + service->program = program; + } + } ++ if (ts->m2ts_mode > 1) ++ service->pmt.pid = 0x00ff + ts->service_id; + + ts->pat.pid = PAT_PID; + /* Initialize at 15 so that it wraps and is equal to 0 for the +@@ -907,10 +910,9 @@ + ts_st->discontinuity = ts->flags & MPEGTS_FLAG_DISCONT; + /* update PCR pid by using the first video stream */ + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && +- service->pcr_pid == 0x1fff) { +- service->pcr_pid = ts_st->pid; ++ service->pcr_sid == 0x1fff) + pcr_st = st; +- } ++ + if (st->codecpar->codec_id == AV_CODEC_ID_AAC && + st->codecpar->extradata_size > 0) { + AVStream *ast; +@@ -946,78 +948,47 @@ + av_freep(&pids); + + /* if no video stream, use the first stream as PCR */ +- if (service->pcr_pid == 0x1fff && s->nb_streams > 0) { +- pcr_st = s->streams[0]; +- ts_st = pcr_st->priv_data; +- service->pcr_pid = ts_st->pid; +- } else +- ts_st = pcr_st->priv_data; +- +- if (ts->mux_rate > 1) { +- service->pcr_packet_period = (int64_t)ts->mux_rate * ts->pcr_period / +- (TS_PACKET_SIZE * 8 * 1000); +- ts->sdt_packet_period = (int64_t)ts->mux_rate * SDT_RETRANS_TIME / +- (TS_PACKET_SIZE * 8 * 1000); +- ts->pat_packet_period = (int64_t)ts->mux_rate * PAT_RETRANS_TIME / +- (TS_PACKET_SIZE * 8 * 1000); +- +- if (ts->copyts < 1) +- ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE); +- } else { +- /* Arbitrary values, PAT/PMT will also be written on video key frames */ +- ts->sdt_packet_period = 200; +- ts->pat_packet_period = 40; +- if (pcr_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { +- int frame_size = av_get_audio_frame_duration2(pcr_st->codecpar, 0); +- if (!frame_size) { +- av_log(s, AV_LOG_WARNING, "frame size not set\n"); +- service->pcr_packet_period = +- pcr_st->codecpar->sample_rate / (10 * 512); +- } else { +- service->pcr_packet_period = +- pcr_st->codecpar->sample_rate / (10 * frame_size); +- } +- } else { +- // max delta PCR 0.1s +- // TODO: should be avg_frame_rate +- service->pcr_packet_period = +- ts_st->user_tb.den / (10 * ts_st->user_tb.num); +- } +- if (!service->pcr_packet_period) +- service->pcr_packet_period = 1; +- } +- +- ts->last_pat_ts = AV_NOPTS_VALUE; +- ts->last_sdt_ts = AV_NOPTS_VALUE; +- // The user specified a period, use only it +- if (ts->pat_period < INT_MAX/2) { +- ts->pat_packet_period = INT_MAX; ++ if (!pcr_st && s->nb_streams > 0) ++ pcr_st = s->streams[0]; ++ if (!pcr_st) { ++ av_log(s, AV_LOG_ERROR, "no streams\n"); ++ ret = AVERROR(EINVAL); ++ goto fail; + } +- if (ts->sdt_period < INT_MAX/2) { +- ts->sdt_packet_period = INT_MAX; ++ ts_st = pcr_st->priv_data; ++ if (service->pcr_sid == 0x1fff) ++ service->pcr_sid = ts_st->pid; ++ if (service->pcr_pid == 0x1fff) ++ service->pcr_pid = ts->m2ts_mode > 1 ? ++ 0x1000 + ts->service_id : service->pcr_sid ; ++ if (service->pmt.pid == service->pcr_pid) { ++ av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", service->pcr_pid); ++ ret = AVERROR(EINVAL); ++ goto fail; + } + ++ clk_rate = ts->mux_rate > 1 ? ts->mux_rate : PCR_TIME_BASE; ++ ts->sdt_packet_period = ts->sdt_period < 0 ? -1 : ts->sdt_period/1000 * clk_rate; ++ ts->pat_packet_period = ts->pat_period/1000 * clk_rate; ++ service->pcr_packet_period = ts->pcr_period/1000 * clk_rate; ++ if (service->pcr_packet_period < (TS_PACKET_SIZE*8*10)) ++ service->pcr_packet_period = (TS_PACKET_SIZE*8*10); ++ av_log(s, AV_LOG_VERBOSE, "clk_rate %f: ticks/pkt %d pcr, %d sdt, %d pmt\n", clk_rate, ++ (int)service->pcr_packet_period, (int)ts->sdt_packet_period, (int)ts->pat_packet_period); ++ ++ if (ts->copyts < 1) ++ ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE); ++ + // output a PCR as soon as possible +- service->pcr_packet_count = service->pcr_packet_period; +- ts->pat_packet_count = ts->pat_packet_period - 1; +- ts->sdt_packet_count = ts->sdt_packet_period - 1; ++ ts->pcr = 0; ++ service->pcr_packet_timer = 0; ++ ts->pat_packet_timer = 0; ++ ts->sdt_packet_timer = 0; + + if (ts->mux_rate == 1) + av_log(s, AV_LOG_VERBOSE, "muxrate VBR, "); + else + av_log(s, AV_LOG_VERBOSE, "muxrate %d, ", ts->mux_rate); +- av_log(s, AV_LOG_VERBOSE, +- "pcr every %d pkts, sdt every %d, pat/pmt every %d pkts\n", +- service->pcr_packet_period, +- ts->sdt_packet_period, ts->pat_packet_period); +- +- if (ts->m2ts_mode == -1) { +- if (av_match_ext(s->filename, "m2ts")) { +- ts->m2ts_mode = 1; +- } else { +- ts->m2ts_mode = 0; +- } +- } + + return 0; + +@@ -1032,22 +1003,12 @@ + MpegTSWrite *ts = s->priv_data; + int i; + +- if (++ts->sdt_packet_count == ts->sdt_packet_period || +- (dts != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) || +- (dts != AV_NOPTS_VALUE && dts - ts->last_sdt_ts >= ts->sdt_period*90000.0) +- ) { +- ts->sdt_packet_count = 0; +- if (dts != AV_NOPTS_VALUE) +- ts->last_sdt_ts = FFMAX(dts, ts->last_sdt_ts); ++ if ( ts->sdt_packet_period >= 0 && ts->pcr >= ts->sdt_packet_timer ) { ++ ts->sdt_packet_timer = ts->pcr + ts->sdt_packet_period; + mpegts_write_sdt(s); + } +- if (++ts->pat_packet_count == ts->pat_packet_period || +- (dts != AV_NOPTS_VALUE && ts->last_pat_ts == AV_NOPTS_VALUE) || +- (dts != AV_NOPTS_VALUE && dts - ts->last_pat_ts >= ts->pat_period*90000.0) || +- force_pat) { +- ts->pat_packet_count = 0; +- if (dts != AV_NOPTS_VALUE) +- ts->last_pat_ts = FFMAX(dts, ts->last_pat_ts); ++ if (ts->pcr >= ts->pat_packet_timer || force_pat) { ++ ts->pat_packet_timer = ts->pcr + ts->pat_packet_period; + mpegts_write_pat(s); + for (i = 0; i < ts->nb_services; i++) + mpegts_write_pmt(s, ts->services[i]); +@@ -1089,13 +1050,14 @@ + { + MpegTSWrite *ts = s->priv_data; + MpegTSWriteStream *ts_st = st->priv_data; ++ uint32_t pcr_pid = ts_st->service->pcr_pid; + uint8_t *q; + uint8_t buf[TS_PACKET_SIZE]; + + q = buf; + *q++ = 0x47; +- *q++ = ts_st->pid >> 8; +- *q++ = ts_st->pid; ++ *q++ = pcr_pid >> 8; ++ *q++ = pcr_pid; + *q++ = 0x20 | ts_st->cc; /* Adaptation only */ + /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */ + *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */ +@@ -1106,7 +1068,7 @@ + } + + /* PCR coded into 6 bytes */ +- q += write_pcr_bits(q, get_pcr(ts, s->pb)); ++ q += write_pcr_bits(q, ts->pcr); + + /* stuffing bytes */ + memset(q, 0xFF, TS_PACKET_SIZE - (q - buf)); +@@ -1175,8 +1137,6 @@ + uint8_t *q; + int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags; + int afc_len, stuffing_len; +- int64_t pcr = -1; /* avoid warning */ +- int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); + int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key; + + av_assert0(ts_st->payload != buf || st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO); +@@ -1186,28 +1146,33 @@ + + is_start = 1; + while (payload_size > 0) { ++ ts->pcr = ts->first_pcr + (ts->mux_rate == 1 ? ++ (dts == AV_NOPTS_VALUE ? 0 : (dts - ts->delay) * 300) : ++ // add 11, pcr references the last byte of program clock reference base ++ av_rescale(avio_tell(s->pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate)); ++ + retransmit_si_info(s, force_pat, dts); + force_pat = 0; + + write_pcr = 0; +- if (ts_st->pid == ts_st->service->pcr_pid) { +- if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames +- ts_st->service->pcr_packet_count++; +- if (ts_st->service->pcr_packet_count >= +- ts_st->service->pcr_packet_period) { +- ts_st->service->pcr_packet_count = 0; ++ if (ts_st->pid == ts_st->service->pcr_sid) { ++ if( ts->pcr >= ts_st->service->pcr_packet_timer ) { ++ ts_st->service->pcr_packet_timer = ts->pcr + ts_st->service->pcr_packet_period; + write_pcr = 1; + } + } +- ++ if (write_pcr && ts_st->service->pcr_sid != ts_st->service->pcr_pid) { ++ mpegts_insert_pcr_only(s, st); ++ continue; ++ } + if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE && +- (dts - get_pcr(ts, s->pb) / 300) > delay) { +- /* pcr insert gets priority over null packet insert */ +- if (write_pcr) +- mpegts_insert_pcr_only(s, st); ++ (dts - ts->pcr / 300) > ts->delay) { ++ /* pcr insert gets priority over null packet insert */ ++ if (write_pcr) ++ mpegts_insert_pcr_only(s, st); + else +- mpegts_insert_null_packet(s); +- /* recalculate write_pcr and possibly retransmit si_info */ ++ mpegts_insert_null_packet(s); ++ /* recalculate write_pcr and possibly retransimit si_info */ + continue; + } + +@@ -1217,6 +1182,10 @@ + val = ts_st->pid >> 8; + if (is_start) + val |= 0x40; ++ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && ++ st->codecpar->codec_id == AV_CODEC_ID_AC3 && ++ ts->m2ts_mode > 1) ++ val |= 0x20; + *q++ = val; + *q++ = ts_st->pid; + ts_st->cc = ts_st->cc + 1 & 0xf; +@@ -1228,7 +1197,7 @@ + } + if (key && is_start && pts != AV_NOPTS_VALUE) { + // set Random Access for key frames +- if (ts_st->pid == ts_st->service->pcr_pid) ++ if (ts_st->pid == ts_st->service->pcr_sid) + write_pcr = 1; + set_af_flag(buf, 0x40); + q = get_ts_payload_start(buf); +@@ -1236,14 +1205,10 @@ + if (write_pcr) { + set_af_flag(buf, 0x10); + q = get_ts_payload_start(buf); +- // add 11, pcr references the last byte of program clock reference base + if (ts->mux_rate > 1) +- pcr = get_pcr(ts, s->pb); +- else +- pcr = (dts - delay) * 300; +- if (dts != AV_NOPTS_VALUE && dts < pcr / 300) ++ if (dts != AV_NOPTS_VALUE && dts < ts->pcr / 300) + av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n"); +- extend_af(buf, write_pcr_bits(q, pcr)); ++ extend_af(buf, write_pcr_bits(q, ts->pcr)); + q = get_ts_payload_start(buf); + } + if (is_start) { +@@ -1344,11 +1309,13 @@ + *q++ = flags; + *q++ = header_len; + if (pts != AV_NOPTS_VALUE) { +- write_pts(q, flags >> 6, pts); ++ int64_t ts_pts = pts + ts->ts_offset; ++ write_pts(q, flags >> 6, ts_pts); + q += 5; + } + if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) { +- write_pts(q, 1, dts); ++ int64_t ts_dts = dts + ts->ts_offset; ++ write_pts(q, 1, ts_dts); + q += 5; + } + if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) { +@@ -1519,7 +1486,6 @@ + uint8_t *data = NULL; + MpegTSWrite *ts = s->priv_data; + MpegTSWriteStream *ts_st = st->priv_data; +- const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2; + int64_t dts = pkt->dts, pts = pkt->pts; + int opus_samples = 0; + int side_data_size; +@@ -1540,16 +1506,15 @@ + } + + if (ts->flags & MPEGTS_FLAG_REEMIT_PAT_PMT) { +- ts->pat_packet_count = ts->pat_packet_period - 1; +- ts->sdt_packet_count = ts->sdt_packet_period - 1; ++ ts->pat_packet_timer = ts->sdt_packet_timer = 0; + ts->flags &= ~MPEGTS_FLAG_REEMIT_PAT_PMT; + } + + if (ts->copyts < 1) { + if (pts != AV_NOPTS_VALUE) +- pts += delay; ++ pts += 2*ts->delay; + if (dts != AV_NOPTS_VALUE) +- dts += delay; ++ dts += 2*ts->delay; + } + + if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) { +@@ -1737,7 +1702,7 @@ + AVStream *st2 = s->streams[i]; + MpegTSWriteStream *ts_st2 = st2->priv_data; + if ( ts_st2->payload_size +- && (ts_st2->payload_dts == AV_NOPTS_VALUE || dts - ts_st2->payload_dts > delay/2)) { ++ && (ts_st2->payload_dts == AV_NOPTS_VALUE || dts - ts_st2->payload_dts > ts->delay)) { + mpegts_write_pes(s, st2, ts_st2->payload, ts_st2->payload_size, + ts_st2->payload_pts, ts_st2->payload_dts, + ts_st2->payload_flags & AV_PKT_FLAG_KEY, stream_id); +@@ -1908,12 +1873,18 @@ + { "mpegts_pmt_start_pid", "Set the first pid of the PMT.", + offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT, + { .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM }, ++ { "mpegts_pcr_start_pid", "Set the first pid of the PCR.", ++ offsetof(MpegTSWrite, pcr_start_pid), AV_OPT_TYPE_INT, ++ { .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM }, + { "mpegts_start_pid", "Set the first pid.", + offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT, + { .i64 = 0x0100 }, 0x0010, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM }, + { "mpegts_m2ts_mode", "Enable m2ts mode.", + offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL, +- { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM }, ++ { .i64 = -1 }, -1, 2, AV_OPT_FLAG_ENCODING_PARAM }, ++ { "mpegts_pcr_offset", "clock offset.", ++ offsetof(MpegTSWrite, ts_offset), AV_OPT_TYPE_BOOL, ++ { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, + { "muxrate", NULL, + offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, + { .i64 = 1 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, +@@ -1951,15 +1922,15 @@ + { "omit_video_pes_length", "Omit the PES packet length for video packets", + offsetof(MpegTSWrite, omit_video_pes_length), AV_OPT_TYPE_BOOL, + { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, +- { "pcr_period", "PCR retransmission time in milliseconds", +- offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_INT, +- { .i64 = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, +- { "pat_period", "PAT/PMT retransmission time limit in seconds", ++ { "pcr_period", "PCR retransmission time limit in msecs", ++ offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_DOUBLE, ++ { .dbl = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, ++ { "pat_period", "PAT/PMT retransmission time limit in msecs", + offsetof(MpegTSWrite, pat_period), AV_OPT_TYPE_DOUBLE, +- { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, +- { "sdt_period", "SDT retransmission time limit in seconds", ++ { .dbl = PAT_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, ++ { "sdt_period", "SDT retransmission time limit in msecs", + offsetof(MpegTSWrite, sdt_period), AV_OPT_TYPE_DOUBLE, +- { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, ++ { .dbl = SDT_RETRANS_TIME }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, + { NULL }, + }; + diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch3 b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch3 new file mode 100644 index 00000000..36699eea --- /dev/null +++ b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch3 @@ -0,0 +1,70 @@ +diff -ur a/libavformat/avformat.h b/libavformat/avformat.h +--- a/libavformat/avformat.h 2018-02-11 17:29:06.000000000 -0700 ++++ b/libavformat/avformat.h 2018-03-13 09:45:00.061310268 -0600 +@@ -504,6 +504,9 @@ + The user or muxer can override this through + AVFormatContext.avoid_negative_ts + */ ++#define AVFMT_SEEK_NOSTREAMS 0x80000 /**< Stream index ignored by seek, ++ or some streams fail to seek ++ */ + + #define AVFMT_SEEK_TO_PTS 0x4000000 /**< Seeking is based on PTS */ + +@@ -664,7 +667,8 @@ + /** + * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS, + * AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH, +- * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS. ++ * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS, ++ * AVFMT_SEEK_NOSTREAMS + */ + int flags; + +diff -ur a/libavformat/dv.c b/ffmpeg-3.4.2/libavformat/dv.c +--- a/libavformat/dv.c 2018-02-11 17:29:06.000000000 -0700 ++++ b/libavformat/dv.c 2018-03-13 09:45:00.061310268 -0600 +@@ -632,6 +632,7 @@ + AVInputFormat ff_dv_demuxer = { + .name = "dv", + .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), ++ .flags = AVFMT_SEEK_NOSTREAMS, + .priv_data_size = sizeof(RawDVContext), + .read_probe = dv_probe, + .read_header = dv_read_header, +diff -ur a/libavformat/matroskadec.c b/libavformat/matroskadec.c +--- a/libavformat/matroskadec.c 2018-02-11 17:29:18.000000000 -0700 ++++ b/libavformat/matroskadec.c 2018-03-13 09:45:00.061310268 -0600 +@@ -3992,6 +3992,7 @@ + AVInputFormat ff_matroska_demuxer = { + .name = "matroska,webm", + .long_name = NULL_IF_CONFIG_SMALL("Matroska / WebM"), ++ .flags = AVFMT_SEEK_NOSTREAMS, + .extensions = "mkv,mk3d,mka,mks", + .priv_data_size = sizeof(MatroskaDemuxContext), + .read_probe = matroska_probe, +@@ -4005,6 +4006,7 @@ + AVInputFormat ff_webm_dash_manifest_demuxer = { + .name = "webm_dash_manifest", + .long_name = NULL_IF_CONFIG_SMALL("WebM DASH Manifest"), ++ .flags = AVFMT_SEEK_NOSTREAMS, + .priv_data_size = sizeof(MatroskaDemuxContext), + .read_header = webm_dash_manifest_read_header, + .read_packet = webm_dash_manifest_read_packet, +diff -ur a/libavformat/utils.c b/libavformat/utils.c +--- a/libavformat/utils.c 2018-02-11 17:29:06.000000000 -0700 ++++ b/libavformat/utils.c 2018-03-13 09:45:00.062310270 -0600 +@@ -2416,6 +2416,13 @@ + return seek_frame_byte(s, stream_index, timestamp, flags); + } + ++ if (stream_index != -1 && (s->iformat->flags & AVFMT_SEEK_NOSTREAMS)) { ++ timestamp = av_rescale_q(timestamp, ++ s->streams[stream_index]->time_base, ++ AV_TIME_BASE_Q); ++ stream_index = -1; ++ } ++ + if (stream_index < 0) { + stream_index = av_find_default_stream_index(s); + if (stream_index < 0) diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch4 b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch4 new file mode 100644 index 00000000..8c7cddb7 --- /dev/null +++ b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch4 @@ -0,0 +1,16 @@ +diff -ur a/libavcodec/libx264.c b/libavcodec/libx264.c +--- a/libavcodec/libx264.c 2018-02-11 17:29:18.000000000 -0700 ++++ b/libavcodec/libx264.c 2018-03-13 09:38:03.241861794 -0600 +@@ -280,7 +280,11 @@ + + x264_picture_init( &x4->pic ); + x4->pic.img.i_csp = x4->params.i_csp; +- if (desc->comp[0].depth > 8) ++#if X264_BUILD >= 153 ++ if (x4->params.i_bitdepth > 8) ++#else ++ if (x264_bit_depth > 8) ++#endif + x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH; + x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt); + diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch5 b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch5 new file mode 100644 index 00000000..f7db4c30 --- /dev/null +++ b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch5 @@ -0,0 +1,61 @@ +--- a/libavcodec/libx265.c 2017-12-10 14:35:08.000000000 -0700 ++++ b/libavcodec/libx265.c 2018-02-08 16:57:46.028108824 -0700 +@@ -45,6 +45,7 @@ + int forced_idr; + char *preset; + char *tune; ++ char *profile; + char *x265_opts; + } libx265Context; + +@@ -114,11 +115,11 @@ + ctx->params->sourceHeight = avctx->height; + ctx->params->bEnablePsnr = !!(avctx->flags & AV_CODEC_FLAG_PSNR); + +- if ((avctx->color_primaries <= AVCOL_PRI_BT2020 && ++ if ((avctx->color_primaries <= AVCOL_PRI_SMPTE432 && + avctx->color_primaries != AVCOL_PRI_UNSPECIFIED) || +- (avctx->color_trc <= AVCOL_TRC_BT2020_12 && ++ (avctx->color_trc <= AVCOL_TRC_ARIB_STD_B67 && + avctx->color_trc != AVCOL_TRC_UNSPECIFIED) || +- (avctx->colorspace <= AVCOL_SPC_BT2020_CL && ++ (avctx->colorspace <= AVCOL_SPC_ICTCP && + avctx->colorspace != AVCOL_SPC_UNSPECIFIED)) { + + ctx->params->vui.bEnableVideoSignalTypePresentFlag = 1; +@@ -220,6 +221,18 @@ + } + } + ++ if (ctx->profile) { ++ if (ctx->api->param_apply_profile(ctx->params, ctx->profile) < 0) { ++ int i; ++ av_log(avctx, AV_LOG_ERROR, "Invalid or incompatible profile set: %s.\n", ctx->profile); ++ av_log(avctx, AV_LOG_INFO, "Possible profiles:"); ++ for (i = 0; x265_profile_names[i]; i++) ++ av_log(avctx, AV_LOG_INFO, " %s", x265_profile_names[i]); ++ av_log(avctx, AV_LOG_INFO, "\n"); ++ return AVERROR(EINVAL); ++ } ++ } ++ + ctx->encoder = ctx->api->encoder_open(ctx->params); + if (!ctx->encoder) { + av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n"); +@@ -294,7 +307,7 @@ + for (i = 0; i < nnal; i++) + payload += nal[i].sizeBytes; + +- ret = ff_alloc_packet(pkt, payload); ++ ret = ff_alloc_packet2(avctx, pkt, payload, payload); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); + return ret; +@@ -392,6 +412,7 @@ + { "forced-idr", "if forcing keyframes, force them as IDR frames", OFFSET(forced_idr),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, + { "preset", "set the x265 preset", OFFSET(preset), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, + { "tune", "set the x265 tune parameter", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, ++ { "profile", "set the x265 profile", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, + { "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, + { NULL } + }; diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.tar.xz b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.tar.xz new file mode 100644 index 00000000..e1acc976 Binary files /dev/null and b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.tar.xz differ diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch3 b/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch3 index a96cf1cd..36699eea 100644 --- a/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch3 +++ b/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch3 @@ -1,6 +1,6 @@ diff -ur a/libavformat/avformat.h b/libavformat/avformat.h ---- a/libavformat/avformat.h 2017-12-10 14:35:10.000000000 -0700 -+++ b/libavformat/avformat.h 2017-12-18 11:11:31.791996302 -0700 +--- a/libavformat/avformat.h 2018-02-11 17:29:06.000000000 -0700 ++++ b/libavformat/avformat.h 2018-03-13 09:45:00.061310268 -0600 @@ -504,6 +504,9 @@ The user or muxer can override this through AVFormatContext.avoid_negative_ts @@ -21,9 +21,9 @@ diff -ur a/libavformat/avformat.h b/libavformat/avformat.h */ int flags; -diff -ur a/libavformat/dv.c b/libavformat/dv.c ---- a/libavformat/dv.c 2017-12-10 14:35:10.000000000 -0700 -+++ b/libavformat/dv.c 2017-12-18 11:11:31.792996246 -0700 +diff -ur a/libavformat/dv.c b/ffmpeg-3.4.2/libavformat/dv.c +--- a/libavformat/dv.c 2018-02-11 17:29:06.000000000 -0700 ++++ b/libavformat/dv.c 2018-03-13 09:45:00.061310268 -0600 @@ -632,6 +632,7 @@ AVInputFormat ff_dv_demuxer = { .name = "dv", @@ -33,9 +33,9 @@ diff -ur a/libavformat/dv.c b/libavformat/dv.c .read_probe = dv_probe, .read_header = dv_read_header, diff -ur a/libavformat/matroskadec.c b/libavformat/matroskadec.c ---- a/libavformat/matroskadec.c 2017-12-10 14:35:10.000000000 -0700 -+++ b/libavformat/matroskadec.c 2017-12-18 11:11:31.793996189 -0700 -@@ -3984,6 +3984,7 @@ +--- a/libavformat/matroskadec.c 2018-02-11 17:29:18.000000000 -0700 ++++ b/libavformat/matroskadec.c 2018-03-13 09:45:00.061310268 -0600 +@@ -3992,6 +3992,7 @@ AVInputFormat ff_matroska_demuxer = { .name = "matroska,webm", .long_name = NULL_IF_CONFIG_SMALL("Matroska / WebM"), @@ -43,7 +43,7 @@ diff -ur a/libavformat/matroskadec.c b/libavformat/matroskadec.c .extensions = "mkv,mk3d,mka,mks", .priv_data_size = sizeof(MatroskaDemuxContext), .read_probe = matroska_probe, -@@ -3997,6 +3998,7 @@ +@@ -4005,6 +4006,7 @@ AVInputFormat ff_webm_dash_manifest_demuxer = { .name = "webm_dash_manifest", .long_name = NULL_IF_CONFIG_SMALL("WebM DASH Manifest"), @@ -51,9 +51,9 @@ diff -ur a/libavformat/matroskadec.c b/libavformat/matroskadec.c .priv_data_size = sizeof(MatroskaDemuxContext), .read_header = webm_dash_manifest_read_header, .read_packet = webm_dash_manifest_read_packet, -diff -ur a/libavformat/utils.c ./libavformat/utils.c ---- a/libavformat/utils.c 2017-12-10 14:35:18.000000000 -0700 -+++ b/libavformat/utils.c 2017-12-18 11:11:31.795996077 -0700 +diff -ur a/libavformat/utils.c b/libavformat/utils.c +--- a/libavformat/utils.c 2018-02-11 17:29:06.000000000 -0700 ++++ b/libavformat/utils.c 2018-03-13 09:45:00.062310270 -0600 @@ -2416,6 +2416,13 @@ return seek_frame_byte(s, stream_index, timestamp, flags); }