upgrade ffmpeg to 3.4.2, add proxy popup, undo/redo deadlock fix, rework nested edl
authorGood Guy <[email protected]>
Thu, 15 Mar 2018 00:34:45 +0000 (18:34 -0600)
committerGood Guy <[email protected]>
Thu, 15 Mar 2018 00:34:45 +0000 (18:34 -0600)
32 files changed:
cinelerra-5.1/cinelerra/Makefile
cinelerra-5.1/cinelerra/awindowgui.C
cinelerra-5.1/cinelerra/awindowgui.h
cinelerra-5.1/cinelerra/clipedls.C
cinelerra-5.1/cinelerra/clippopup.C
cinelerra-5.1/cinelerra/edl.C
cinelerra-5.1/cinelerra/edl.h
cinelerra-5.1/cinelerra/localsession.C
cinelerra-5.1/cinelerra/localsession.h
cinelerra-5.1/cinelerra/mainundo.C
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/mwindowedit.C
cinelerra-5.1/cinelerra/proxypopup.C [new file with mode: 0644]
cinelerra-5.1/cinelerra/proxypopup.h [new file with mode: 0644]
cinelerra-5.1/cinelerra/proxypopup.inc [new file with mode: 0644]
cinelerra-5.1/cinelerra/versioninfo.h
cinelerra-5.1/cinelerra/vwindow.C
cinelerra-5.1/configure.ac
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch1 [deleted file]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch2 [deleted file]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch3 [deleted file]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch4 [deleted file]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.patch5 [deleted file]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.1.tar.xz [deleted file]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch1 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch2 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch3 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch4 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.patch5 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.tar.xz [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch3

index 755e42987d03f608031873ac38c96d9f69f3d1ec..c341abcbc1dbdcbe8a3f4b94c295cf220f9357b9 100644 (file)
@@ -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 \
index 0ed6b1ce0fd3da31afd2e4b1ada67f50711be173..42672233ec775b5fe10e0273db3573e232c62f94 100644 (file)
@@ -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();
index 4bc256423dd1c67e73bce4e4a5b2aa7639cc7503..440b4019c41df7bf804b2a891c8a15f1db741fd6 100644 (file)
@@ -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
index 65dd58e2c23fc3b36d038189d3bfff46dd5ada7b..52dd7678ea168d41c7d9cc64ad8e434f7292d226 100644 (file)
@@ -38,6 +38,10 @@ void ClipEDLs::remove_clip(EDL *clip)
 EDL* ClipEDLs::get_copy(EDL *src)
 {
        if( !src ) return 0;
+       for( int i=0; i<size(); ++i ) {
+               EDL *dst = get(i);
+               if( src == dst || src->id == dst->id ) return dst;
+       }
        for( int i=0; i<size(); ++i ) {
                EDL *dst = get(i);
                if( !strcmp(dst->path, src->path) ) return dst;
index 677b9bedf4ff4a6cb17b859492f2ba6b03d7ea30..ef291f195c3c58e2cc56ac88a4028e9c314412cb 100644 (file)
@@ -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();
index 49d4cecfc72a14b6197c6eef62e887b8ad09ec9a..55ca9a2947b4d933b5f8edfd305eece56cd88b47 100644 (file)
@@ -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; i<nested_edls.size(); ++i ) {
+               EDL *dst = nested_edls[i];
+               if( !strcmp(path, dst->path) ) 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;
index 60784dcf1ebbd53c1f1c46b8272e2b19f9455a07..d523779b8f4637d6e4b8eabcc71926e6b33a8667 100644 (file)
@@ -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,
index eace821b2c7d67c43983d58c045f18b6a71afc75..8e691310ba06040a93e35cb5bf9300aa6b514aa4 100644 (file)
@@ -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);
-}
-
-
index bf1ddeeb7570056dc0bb2cff9db3566149293702..cd948aa323176e059895bbf8b20ebc18bc6a76b7 100644 (file)
@@ -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);
 
index 4a921cf4e082191a7065f80397eb3e0866204525..3bc8d7cfde8af8135574fc4d1f2acadb13a8dbbc 100644 (file)
@@ -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;
 }
 
index 4245e8725cb4f6ffed21178d9887bf0d478175a5..56059c677d499b4414b576dda027a793b7e0953f 100644 (file)
@@ -1288,35 +1288,53 @@ void MWindow::close_mixers()
        }
 }
 
+ZWindow *MWindow::create_mixer(Indexable *indexable)
+{
+       ArrayList<Indexable*> 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);
        ArrayList<ZWindow *>new_mixers;
 
-       for( int i=0; i<session->drag_assets->total; ++i ) {
-               Indexable *indexable = session->drag_assets->values[i];
-               ArrayList<Indexable*> 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; i<session->drag_assets->size(); ++i ) {
+               Indexable *indexable = session->drag_assets->get(i);
+               ZWindow *zwindow = create_mixer(indexable);
+               new_mixers.append(zwindow);
+       }
+       for( int i=0; i<session->drag_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 {
index 69781804c9830a31730471e4fa9acb3568a7c01f..0dfd24cef96bb3c466d1d6147a3ebe9dd3344d2d 100644 (file)
@@ -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();
index 2366c3884cb17aa3b1b1739ecd3228fde98d56a6..51f1b4214730aabdcd9cd6e6140b897212153f5e 100644 (file)
@@ -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 (file)
index 0000000..225b21b
--- /dev/null
@@ -0,0 +1,271 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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; i<mwindow->session->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; i<mwindow->session->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 (file)
index 0000000..3a07980
--- /dev/null
@@ -0,0 +1,142 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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 (file)
index 0000000..e0a544a
--- /dev/null
@@ -0,0 +1,33 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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
index 21621aec005e657f06dfd9e9041de8c2f18a4f38..19a9189defe28b96e7924381301e5efd4b841463 100644 (file)
@@ -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
index 451c71320e3be4f4794fb9483b9c89f1abbed6a4..98858289849a63660bd850ae3388a57057613851 100644 (file)
@@ -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();
 }
 
index d54d490547e7dcd79c14b83353fd1d7cc010454b..557aae3cda02b6ddabed47b9914d8c6454f5e0a4 100644 (file)
@@ -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 (file)
index daa9953..0000000
+++ /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 (file)
index bb628d9..0000000
+++ /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 (file)
index a96cf1c..0000000
+++ /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 (file)
index e218ae5..0000000
+++ /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 (file)
index f7db4c3..0000000
+++ /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 (file)
index 8970943..0000000
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 (file)
index 0000000..daa9953
--- /dev/null
@@ -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 (file)
index 0000000..bb628d9
--- /dev/null
@@ -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 (file)
index 0000000..36699ee
--- /dev/null
@@ -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 (file)
index 0000000..8c7cddb
--- /dev/null
@@ -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 (file)
index 0000000..f7db4c3
--- /dev/null
@@ -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 (file)
index 0000000..e1acc97
Binary files /dev/null and b/cinelerra-5.1/thirdparty/src/ffmpeg-3.4.2.tar.xz differ
index a96cf1cd88fd92cff3222797586c201e3d29285c..36699eea10294925b64d1535c27d52515cf13a8a 100644 (file)
@@ -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);
      }