$(OBJDIR)/presets.o \
$(OBJDIR)/probeprefs.o \
$(OBJDIR)/proxy.o \
+ $(OBJDIR)/proxypopup.o \
$(OBJDIR)/question.o \
$(OBJDIR)/quit.o \
$(OBJDIR)/recconfirmdelete.o \
#include "newfolder.h"
#include "preferences.h"
#include "proxy.h"
+#include "proxypopup.h"
#include "renderengine.h"
#include "samples.h"
#include "theme.h"
effectlist_menu = 0;
assetlist_menu = 0;
cliplist_menu = 0;
+ proxylist_menu = 0;
labellist_menu = 0;
folderlist_menu = 0;
temp_picon = 0;
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;
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();
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();
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;
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;
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();
#include "mwindow.inc"
#include "newfolder.inc"
#include "pluginserver.inc"
+#include "proxypopup.inc"
#include "renderengine.inc"
#include "samples.inc"
#include "vicon.h"
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
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;
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),
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();
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;
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,
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);
-}
-
-
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);
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
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();
// 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);
}
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;
}
}
}
+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);
}
// 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 {
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();
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 ) {
--- /dev/null
+
+/*
+ * 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();
+}
+
+
--- /dev/null
+
+/*
+ * 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
--- /dev/null
+
+/*
+ * 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
#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
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();
}
[ 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 \
+++ /dev/null
-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;
+++ /dev/null
-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 },
- };
-
+++ /dev/null
-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)
+++ /dev/null
---- 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" },
+++ /dev/null
---- 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 }
- };
--- /dev/null
+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;
--- /dev/null
+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 },
+ };
+
--- /dev/null
+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)
--- /dev/null
+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);
+
--- /dev/null
+--- 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 -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
*/
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",
.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"),
.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"),
.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);
}