$(OBJDIR)/vdevicempeg.o \
$(OBJDIR)/vdevicev4l2mpeg.o \
$(OBJDIR)/wwindow.o \
+ $(OBJDIR)/pluginfclient.o \
# $(OBJDIR)/renderfarmfsclient.o \
# $(OBJDIR)/renderfarmfsserver.o \
$(THEME_DATA) \
LIBS = $(LIBRARIES)
-LIBS += $(thirdparty_libraries)
-LIBS += $(thirdparty_libraries)
-LIBS += $(thirdparty_libraries)
LIBS += \
-lX11 \
-lXext \
-llzma \
-lfontconfig \
-lfreetype \
- $(EXTRA_LIBS)
+
+LIBS += -Wl,--start-group $(thirdparty_libraries) -Wl,--end-group
+LIBS += $(EXTRA_LIBS)
CUTADS = $(OBJDIR)/cutads
CUTOBJ = $(OBJDIR)/cutads.o
if(plugin_server->multichannel)
{
// Test against previous parameters for reuse of previous data
- if(is_processed &&
- this->start_position == start_position &&
- this->len == len &&
- this->sample_rate == sample_rate)
- {
- memcpy(output->get_data(),
- buffer_vector[buffer_number]->get_data(),
- sizeof(double) * len);
- return;
- }
-
+ if( !is_processed || this->start_position != start_position ||
+ this->len != len || this->sample_rate != sample_rate ) {
// Update status
- this->start_position = start_position;
- this->len = len;
- this->sample_rate = sample_rate;
- is_processed = 1;
+ this->start_position = start_position;
+ this->len = len;
+ this->sample_rate = sample_rate;
+ is_processed = 1;
// Allocate buffer vector
- new_buffer_vector(virtual_plugins.total, len);
-
-// Create temporary buffer vector with output argument substituted in
- Samples **output_temp = new Samples*[virtual_plugins.total];
- for(int i = 0; i < virtual_plugins.total; i++)
- {
- if(i == buffer_number)
- output_temp[i] = output;
- else
- output_temp[i] = buffer_vector[i];
- }
+ new_buffer_vector(virtual_plugins.total, len);
// Process plugin
- plugin_servers.values[0]->process_buffer(output_temp,
- start_position,
- len,
- sample_rate,
- plugin->length *
- sample_rate /
- renderengine->get_edl()->session->sample_rate,
- renderengine->command->get_direction());
-
-// Delete temporary buffer vector
- delete [] output_temp;
+ plugin_servers.values[0]->process_buffer(
+ buffer_vector, start_position, len, sample_rate,
+ plugin->length * sample_rate /
+ renderengine->get_edl()->session->sample_rate,
+ renderengine->command->get_direction());
+ }
+ memcpy(output->get_data(),
+ buffer_vector[buffer_number]->get_data(),
+ sizeof(double) * len);
}
else
{
clip_edit = new ClipEdit(mwindow, this, 0);
}
+int AWindow::save_defaults(BC_Hash *defaults)
+{
+ return gui->save_defaults(defaults);
+}
+int AWindow::load_defaults(BC_Hash *defaults)
+{
+ return gui->load_defaults(defaults);
+}
+
void AWindow::run()
{
#include "assetedit.inc"
#include "assetremove.inc"
#include "awindowgui.inc"
+#include "bchash.inc"
#include "bcwindowbase.inc"
#include "clipedit.inc"
#include "mwindow.inc"
void run();
void create_objects();
+ int load_defaults(BC_Hash *defaults);
+ int save_defaults(BC_Hash *defaults);
char current_folder[BCTEXTLEN];
#include "awindow.h"
#include "awindowmenu.h"
#include "bcsignals.h"
+#include "bchash.h"
#include "cache.h"
#include "bccmodels.h"
#include "cursors.h"
#include "vwindow.h"
#include "data/lad_picon_png.h"
+#include "data/ff_audio_png.h"
+#include "data/ff_video_png.h"
#include<stdio.h>
#include<unistd.h>
icon = gui->atransition_icon;
icon_vframe = gui->atransition_vframe;
}
- else if( !plugin->is_ladspa() ) {
- icon = gui->aeffect_icon;
- icon_vframe = gui->aeffect_vframe;
+ else if( plugin->is_ffmpeg() ) {
+ icon = gui->ff_aud_icon;
+ icon_vframe = gui->ff_aud_vframe;
}
- else {
+ else if( plugin->is_ladspa() ) {
icon = gui->ladspa_icon;
icon_vframe = gui->ladspa_vframe;
}
+ else {
+ icon = gui->aeffect_icon;
+ icon_vframe = gui->aeffect_vframe;
+ }
}
else if( plugin->video ) {
if( plugin->transition ) {
icon = gui->vtransition_icon;
icon_vframe = gui->vtransition_vframe;
}
+ else if( plugin->is_ffmpeg() ) {
+ icon = gui->ff_vid_icon;
+ icon_vframe = gui->ff_vid_vframe;
+ }
else {
icon = gui->veffect_icon;
icon_vframe = gui->veffect_vframe;
aeffect_icon = 0; aeffect_vframe = 0;
ladspa_icon = 0; ladspa_vframe = 0;
veffect_icon = 0; veffect_vframe = 0;
+ ff_aud_icon = 0; ff_aud_vframe = 0;
+ ff_vid_icon = 0; ff_vid_vframe = 0;
+ plugin_visibility = ((uint64_t)1<<(8*sizeof(uint64_t)-1))-1;
newfolder_thread = 0;
asset_menu = 0;
assetlist_menu = 0;
folderlist_menu = 0;
temp_picon = 0;
remove_plugin = 0;
- plugin_visibility = ~0;
}
AWindowGUI::~AWindowGUI()
atransitions.remove_all_objects();
vtransitions.remove_all_objects();
displayed_assets[1].remove_all_objects();
+
delete file_icon;
delete audio_icon;
delete video_icon;
delete aeffect_icon;
delete ladspa_icon;
delete ladspa_vframe;
+ delete ff_aud_icon;
+ delete ff_aud_vframe;
+ delete ff_vid_icon;
+ delete ff_vid_vframe;
delete veffect_icon;
delete newfolder_thread;
delete asset_menu;
bool AWindowGUI::protected_pixmap(BC_Pixmap *icon)
{
return icon == file_icon ||
- icon == audio_icon ||
icon == folder_icon ||
- icon == clip_icon ||
+ icon == audio_icon ||
icon == video_icon ||
- icon == veffect_icon ||
+ icon == clip_icon ||
icon == vtransition_icon ||
+ icon == atransition_icon ||
+ icon == veffect_icon ||
icon == aeffect_icon ||
icon == ladspa_icon ||
- icon == atransition_icon;
+ icon == ff_aud_icon ||
+ icon == ff_vid_icon;
}
void AWindowGUI::create_objects()
aeffect_icon = new BC_Pixmap(this, aeffect_vframe, PIXMAP_ALPHA);
ladspa_vframe = new VFrame(lad_picon_png);
ladspa_icon = new BC_Pixmap(this, ladspa_vframe, PIXMAP_ALPHA);
+ ff_aud_vframe = new VFrame(ff_audio_png);
+ ff_aud_icon = new BC_Pixmap(this, ff_aud_vframe, PIXMAP_ALPHA);
+ ff_vid_vframe = new VFrame(ff_video_png);
+ ff_vid_icon = new BC_Pixmap(this, ff_vid_vframe, PIXMAP_ALPHA);
veffect_vframe = mwindow->theme->get_image("veffect_icon");
veffect_icon = new BC_Pixmap(this, veffect_vframe, PIXMAP_ALPHA);
SET_TRACE
mwindow->theme->get_awindow_sizes(this);
+ load_defaults(mwindow->defaults);
SET_TRACE
add_subwindow(asset_list = new AWindowAssets(mwindow,
flush();
}
+int AWindowGUI::save_defaults(BC_Hash *defaults)
+{
+ defaults->update("PLUGIN_VISIBILTY", plugin_visibility);
+ return 0;
+}
+
+int AWindowGUI::load_defaults(BC_Hash *defaults)
+{
+ plugin_visibility = defaults->get("PLUGIN_VISIBILTY", plugin_visibility);
+ return 0;
+}
+
+
int AWindowGUI::close_event()
{
hide_window();
mwindow->gui->unlock_window();
lock_window("AWindowGUI::close_event");
+ save_defaults(mwindow->defaults);
mwindow->save_defaults();
return 1;
}
void AddPluginsMenu::create_objects()
{
- uint32_t vis = 0;
+ uint64_t vis = 0;
+ add_item(new AddPluginItem(this, "ladspa", PLUGIN_LADSPA_ID));
+ vis |= 1 << PLUGIN_LADSPA_ID;
+ add_item(new AddPluginItem(this, "ffmpeg", PLUGIN_FFMPEG_ID));
+ vis |= 1 << PLUGIN_FFMPEG_ID;
for( int i=0; i<MWindow::plugindb->size(); ++i ) {
PluginServer *plugin = MWindow::plugindb->get(i);
if( !plugin->audio && !plugin->video ) continue;
vis |= msk;
char parent[BCTEXTLEN];
strcpy(parent, plugin->path);
- char *cp = strrchr(parent, '/');
- if( !cp ) continue;
- *cp = 0;
char *bp = strrchr(parent, '/');
+ if( bp ) { *bp = 0; bp = strrchr(parent, '/'); }
if( !bp ) bp = parent; else ++bp;
- if( !strcmp(bp, "ladspa") )
- gui->plugin_visibility &= ~(1 << idx);
add_item(new AddPluginItem(this, bp, idx));
}
-
}
AddPluginItem::AddPluginItem(AddPluginsMenu *menu, char const *text, int idx)
{
this->menu = menu;
this->idx = idx;
- uint32_t msk = 1 << idx, vis = menu->gui->plugin_visibility;
+ uint64_t msk = (uint64_t)1 << idx, vis = menu->gui->plugin_visibility;
int chk = (msk & vis) ? 1 : 0;
set_checked(chk);
}
{
int chk = get_checked() ^ 1;
set_checked(chk);
- uint32_t msk = 1 << idx, vis = menu->gui->plugin_visibility;
+ uint64_t msk = (uint64_t)1 << idx, vis = menu->gui->plugin_visibility;
menu->gui->plugin_visibility = chk ? vis | msk : vis & ~msk;
menu->gui->update_effects();
menu->gui->update_assets();
+ menu->gui->save_defaults(menu->mwindow->defaults);
return 1;
}
PluginServer* selected_plugin();
AssetPicon* selected_folder();
bool protected_pixmap(BC_Pixmap *pixmap);
+ int save_defaults(BC_Hash *defaults);
+ int load_defaults(BC_Hash *defaults);
MWindow *mwindow;
AWindow *awindow;
AWindowAssets *asset_list;
AWindowFolders *folder_list;
AWindowDivider *divider;
- uint32_t plugin_visibility;
// Store data to speed up responses
// Persistant data for listboxes
const char *asset_titles[ASSET_COLUMNS];
+ BC_Hash *defaults;
// Persistent icons
BC_Pixmap *folder_icon;
BC_Pixmap *file_icon;
BC_Pixmap *vtransition_icon; VFrame *vtransition_vframe;
BC_Pixmap *aeffect_icon; VFrame *aeffect_vframe;
BC_Pixmap *ladspa_icon; VFrame *ladspa_vframe;
+ BC_Pixmap *ff_aud_icon; VFrame *ff_aud_vframe;
+ BC_Pixmap *ff_vid_icon; VFrame *ff_vid_vframe;
BC_Pixmap *veffect_icon; VFrame *veffect_vframe;
NewFolderThread *newfolder_thread;
// Temporary for reading picons from files
VFrame *temp_picon;
+ int64_t plugin_visibility;
AWindowRemovePlugin *remove_plugin;
private:
void update_folder_list();
--- /dev/null
+#ifndef FF_AUDIO_PNG_H
+#define FF_AUDIO_PNG_H
+
+static unsigned char ff_audio_png[] =
+{
+ 0x00, 0x00, 0x0a, 0x4a,
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
+ 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x3f, 0x88,
+ 0xb1, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0,
+ 0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00,
+ 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45,
+ 0x07, 0xdf, 0x0a, 0x1a, 0x00, 0x24, 0x35, 0xfd, 0xf3, 0x8e, 0x85, 0x00, 0x00, 0x00, 0x19, 0x74,
+ 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74,
+ 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0x0e, 0x17,
+ 0x00, 0x00, 0x09, 0xb2, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xd5, 0x9a, 0x41, 0x6c, 0x5c, 0x57,
+ 0x15, 0x86, 0xbf, 0x73, 0xdf, 0x9b, 0x19, 0x7b, 0x26, 0xb6, 0x43, 0x92, 0x36, 0x4d, 0xdc, 0x26,
+ 0x6d, 0x93, 0x36, 0x69, 0x9a, 0xa8, 0x4a, 0x2c, 0x55, 0x2c, 0xba, 0x29, 0x0b, 0x04, 0x1b, 0x5a,
+ 0xa9, 0x9b, 0xac, 0x41, 0x5d, 0xb2, 0x01, 0x89, 0x45, 0x61, 0xc5, 0x16, 0x44, 0x1b, 0x09, 0x90,
+ 0xc8, 0x06, 0x8a, 0x68, 0x25, 0x54, 0x55, 0x02, 0x54, 0x84, 0x8a, 0x40, 0x08, 0x28, 0x54, 0x42,
+ 0x9d, 0xa2, 0x0a, 0x62, 0x27, 0x85, 0xaa, 0x69, 0xd4, 0x3a, 0x75, 0xe2, 0x38, 0xb6, 0x13, 0xc7,
+ 0xf6, 0xcc, 0xbc, 0x7b, 0x58, 0xdc, 0x7b, 0xdf, 0xbb, 0xf3, 0xe6, 0x8d, 0x1d, 0xbb, 0x05, 0x85,
+ 0x91, 0x46, 0xf3, 0xe6, 0xdd, 0xe7, 0x79, 0xe7, 0x3f, 0xe7, 0xfc, 0xe7, 0xfc, 0xe7, 0x3e, 0xcb,
+ 0xe9, 0xd3, 0xa7, 0x75, 0x7d, 0x7d, 0x1d, 0x91, 0x04, 0x05, 0x94, 0xff, 0x83, 0x97, 0x82, 0x08,
+ 0x18, 0x51, 0xac, 0xb5, 0x34, 0x1a, 0x0d, 0xd2, 0xd5, 0xd5, 0x55, 0x3a, 0xdd, 0x0c, 0xe8, 0x50,
+ 0x4f, 0x7a, 0xa4, 0x26, 0x03, 0xd5, 0x3b, 0x1c, 0x87, 0xa1, 0x9b, 0xa5, 0x74, 0x6d, 0x82, 0x31,
+ 0x0e, 0x4c, 0x2a, 0x62, 0x68, 0xd6, 0x56, 0x79, 0xe2, 0xc8, 0x1c, 0xa7, 0x8e, 0x74, 0xd9, 0xb9,
+ 0x6b, 0x94, 0x8c, 0xf4, 0x8e, 0x05, 0x21, 0x02, 0x74, 0x56, 0x79, 0xff, 0x52, 0x8f, 0x3f, 0x9e,
+ 0x1b, 0xe7, 0xdd, 0x8f, 0xf7, 0x60, 0x24, 0x21, 0xcd, 0x2c, 0x9c, 0x3a, 0x30, 0xcf, 0x17, 0x1e,
+ 0x5f, 0xe4, 0xe8, 0xe1, 0x04, 0x46, 0x0d, 0x90, 0xdd, 0xd9, 0x49, 0x66, 0x3b, 0x3c, 0xbc, 0x6f,
+ 0x95, 0x7a, 0xda, 0x65, 0xe1, 0xc6, 0x28, 0x8b, 0xdd, 0x06, 0xa9, 0xb5, 0x70, 0xe2, 0xe0, 0x02,
+ 0xf7, 0x4f, 0xae, 0x83, 0x18, 0xb8, 0xbe, 0x76, 0x07, 0x27, 0x95, 0x80, 0x5a, 0x48, 0x0d, 0xcd,
+ 0x31, 0xcb, 0xf1, 0x07, 0x7b, 0xfc, 0xe9, 0x9f, 0x37, 0xb8, 0x36, 0xb7, 0x9b, 0xd4, 0xaa, 0xd0,
+ 0x6c, 0x75, 0xc1, 0x2e, 0xc3, 0xad, 0x55, 0xe8, 0x28, 0x48, 0x41, 0xaa, 0xf0, 0xf7, 0x31, 0xd1,
+ 0xfa, 0xce, 0x69, 0xf5, 0xfd, 0x86, 0xae, 0x6d, 0xd1, 0xee, 0xbe, 0xfb, 0x8a, 0xff, 0xec, 0x02,
+ 0x36, 0x41, 0xcc, 0x67, 0x18, 0x69, 0x58, 0x54, 0x71, 0x64, 0xb0, 0x16, 0x34, 0x5b, 0x87, 0x44,
+ 0x21, 0xd9, 0xc4, 0x68, 0x29, 0xdd, 0xe8, 0xbf, 0x09, 0xa4, 0xea, 0xb7, 0xc2, 0x77, 0x9b, 0xa1,
+ 0xd9, 0x1a, 0x56, 0xdc, 0x89, 0x34, 0x5f, 0x95, 0x21, 0x9e, 0x88, 0x0d, 0x16, 0x98, 0x9d, 0x87,
+ 0xc9, 0xa7, 0xb7, 0x67, 0xd3, 0xc7, 0xbf, 0x82, 0xbd, 0xbb, 0xb6, 0x01, 0xa4, 0xca, 0x81, 0xa6,
+ 0xff, 0x9c, 0xe9, 0x5b, 0x94, 0x0a, 0x10, 0x25, 0x70, 0xed, 0xf3, 0xdb, 0x03, 0xb1, 0x7f, 0xf7,
+ 0x36, 0x40, 0x0c, 0x73, 0xac, 0x0e, 0x66, 0x44, 0x5a, 0xa4, 0x8c, 0x01, 0xc9, 0xfa, 0xd1, 0xcb,
+ 0xa0, 0x57, 0xda, 0xef, 0x6e, 0xcf, 0x96, 0x53, 0x47, 0x36, 0x70, 0xd2, 0x56, 0x23, 0x02, 0x60,
+ 0x04, 0x24, 0x89, 0x81, 0x84, 0x36, 0x39, 0x02, 0xa2, 0x20, 0xbd, 0xea, 0xd4, 0xe2, 0x93, 0x45,
+ 0x64, 0xcb, 0x40, 0x74, 0x48, 0x86, 0xe4, 0xe7, 0x6b, 0x20, 0x23, 0x79, 0x48, 0x22, 0x8e, 0x34,
+ 0x3d, 0x88, 0x5e, 0x35, 0x59, 0x43, 0x6a, 0x5d, 0x18, 0xbc, 0x67, 0xfb, 0xc7, 0xde, 0xd0, 0x4f,
+ 0x93, 0xec, 0x52, 0x91, 0x11, 0x7d, 0x14, 0x68, 0x38, 0x9b, 0x07, 0x81, 0xd4, 0x5d, 0xa8, 0x36,
+ 0xf0, 0xda, 0xec, 0x55, 0xb8, 0x7c, 0xad, 0xff, 0x5c, 0x3d, 0x85, 0xe3, 0x87, 0x86, 0x78, 0x5b,
+ 0xf8, 0xf4, 0x5e, 0x52, 0xfa, 0x22, 0x35, 0x07, 0x66, 0x10, 0x48, 0xcd, 0x01, 0xa9, 0xca, 0xcb,
+ 0x0d, 0x88, 0x7e, 0xe2, 0x10, 0xd4, 0x6b, 0xff, 0xc3, 0xf2, 0x9b, 0xbf, 0x52, 0x67, 0x73, 0x3f,
+ 0x10, 0x9f, 0x73, 0x71, 0x13, 0xa9, 0xe8, 0x17, 0x55, 0x69, 0x35, 0xf5, 0xc8, 0xe6, 0x95, 0xee,
+ 0x13, 0x03, 0xa9, 0x2c, 0xbf, 0x09, 0x50, 0x03, 0x7a, 0x11, 0x10, 0x1b, 0x22, 0x62, 0x86, 0x7b,
+ 0x41, 0xaa, 0x23, 0x72, 0xf6, 0x17, 0xee, 0xbd, 0x91, 0x1d, 0xd7, 0x7f, 0x07, 0x13, 0x63, 0xb7,
+ 0xd1, 0x64, 0x95, 0x0d, 0xf9, 0x59, 0x9c, 0x17, 0x90, 0xd4, 0xd1, 0x21, 0x07, 0x22, 0x80, 0x8a,
+ 0x43, 0x67, 0x4c, 0x75, 0x63, 0x0c, 0x11, 0xd9, 0x46, 0xc5, 0x3a, 0x74, 0x6f, 0x04, 0x62, 0x83,
+ 0x6a, 0x38, 0x74, 0x4d, 0x2a, 0xc0, 0x0b, 0x9e, 0x06, 0x49, 0x3e, 0x72, 0xb8, 0x10, 0x58, 0xdc,
+ 0x49, 0x31, 0xa5, 0x8b, 0xc3, 0xdb, 0x30, 0x3b, 0x6f, 0x06, 0x88, 0x7e, 0x3b, 0xaf, 0xa9, 0xa3,
+ 0xc1, 0x00, 0x89, 0x8c, 0x11, 0xaf, 0xc7, 0x37, 0x58, 0x93, 0xa0, 0xd9, 0xbd, 0xc1, 0xf1, 0x35,
+ 0x12, 0xec, 0x4d, 0x73, 0x90, 0x0e, 0x48, 0xe6, 0x23, 0x12, 0x80, 0xc8, 0x60, 0x82, 0x6c, 0xb7,
+ 0x7f, 0x4c, 0x3d, 0x12, 0x0f, 0x12, 0x32, 0xc4, 0xfb, 0x32, 0x3c, 0x4a, 0x12, 0x9a, 0x5f, 0xe9,
+ 0x8f, 0x24, 0x01, 0xad, 0xb9, 0x88, 0x48, 0xce, 0x91, 0x50, 0x05, 0xcc, 0x90, 0x1b, 0x65, 0x95,
+ 0x40, 0x9e, 0x7d, 0x1a, 0xce, 0x7e, 0xb3, 0x42, 0x39, 0x86, 0x9b, 0x6a, 0x9c, 0xec, 0x5a, 0x3a,
+ 0xae, 0x92, 0xd4, 0xa5, 0xef, 0xa2, 0xc1, 0xb8, 0x8a, 0xb4, 0x33, 0x2e, 0x2a, 0x36, 0xae, 0x5a,
+ 0xd6, 0x2f, 0x94, 0x23, 0x12, 0x75, 0xd7, 0xf6, 0xcc, 0xb0, 0x8a, 0xa5, 0x43, 0xda, 0x72, 0xd9,
+ 0x21, 0x43, 0x8c, 0xdd, 0xf0, 0xd8, 0xff, 0x7e, 0x55, 0xd5, 0x92, 0x04, 0x34, 0xf5, 0xd9, 0xe4,
+ 0x81, 0xa8, 0x1a, 0x5f, 0xca, 0xcc, 0x96, 0xa4, 0xc9, 0xd4, 0xb1, 0xa2, 0x51, 0x4e, 0x7e, 0x71,
+ 0x9b, 0x8a, 0xf8, 0x75, 0xd8, 0xbb, 0xfb, 0x36, 0x4b, 0x70, 0x19, 0x08, 0x69, 0x7f, 0x1f, 0xd1,
+ 0x2c, 0xa4, 0x96, 0xef, 0xec, 0xc6, 0xf8, 0x4c, 0x70, 0xb9, 0x39, 0x7b, 0x15, 0x2e, 0xcf, 0xf7,
+ 0xfa, 0x7e, 0xbb, 0x96, 0xc2, 0x89, 0xc3, 0x29, 0x18, 0xa1, 0x7d, 0xde, 0xfa, 0xf1, 0x78, 0x8b,
+ 0x8a, 0xf8, 0x2e, 0xd8, 0xbb, 0x27, 0x8d, 0x52, 0x51, 0x8b, 0xd4, 0xec, 0x3b, 0x8e, 0x7c, 0xac,
+ 0xd6, 0x7f, 0x49, 0x41, 0xe3, 0xd4, 0x12, 0xb0, 0x19, 0xa8, 0xfa, 0x96, 0x2f, 0xa9, 0x27, 0xbe,
+ 0x78, 0xce, 0x08, 0xed, 0xf3, 0xbd, 0xbc, 0x5e, 0x87, 0xd7, 0xf1, 0x43, 0x86, 0x46, 0xa3, 0xe9,
+ 0xa2, 0x35, 0xb3, 0xb6, 0x2d, 0x20, 0xa7, 0x8e, 0xa6, 0x5e, 0xf8, 0x05, 0x6e, 0xda, 0x22, 0x97,
+ 0xc5, 0x73, 0x4a, 0xca, 0x59, 0x62, 0x3d, 0x05, 0xea, 0xbe, 0xfc, 0x46, 0x32, 0xde, 0x5a, 0xbc,
+ 0xf1, 0x23, 0xfe, 0x5d, 0xf3, 0xf3, 0xb1, 0x01, 0x11, 0xda, 0x33, 0x2b, 0x15, 0x69, 0x55, 0xf7,
+ 0x46, 0x04, 0x20, 0xdb, 0x50, 0xc4, 0x8f, 0xd4, 0xfb, 0x81, 0x54, 0x0d, 0x1a, 0x3e, 0x5a, 0xcb,
+ 0x37, 0x2d, 0x7f, 0x7e, 0xbb, 0xcb, 0x03, 0x93, 0x29, 0xc7, 0x0e, 0xd7, 0x41, 0x1a, 0xa8, 0x26,
+ 0x58, 0xab, 0x48, 0x9e, 0x5a, 0x56, 0x50, 0x42, 0xa7, 0xac, 0x47, 0x7c, 0x71, 0xde, 0x69, 0x4f,
+ 0xdf, 0xa8, 0x20, 0x7a, 0xc3, 0x5f, 0x0b, 0xed, 0x99, 0xde, 0xa0, 0x22, 0x7e, 0xf9, 0x6e, 0x67,
+ 0x28, 0xe2, 0xab, 0x89, 0x94, 0x52, 0x26, 0xae, 0x6a, 0x61, 0xad, 0x7c, 0x9d, 0x5b, 0x3b, 0xff,
+ 0x7e, 0x97, 0xef, 0xbc, 0x78, 0x8b, 0x9f, 0xbe, 0x76, 0x8b, 0xaf, 0x9e, 0x6e, 0xf1, 0xbd, 0x6f,
+ 0x8c, 0x01, 0x75, 0x54, 0x93, 0xfc, 0xe7, 0x52, 0x09, 0x33, 0x7b, 0x00, 0x22, 0x01, 0x48, 0x94,
+ 0x5a, 0x33, 0xdd, 0x0a, 0x20, 0x2d, 0x90, 0x3a, 0xb3, 0x57, 0x7a, 0x5c, 0x9e, 0xb7, 0x83, 0x8a,
+ 0xf8, 0xa1, 0x56, 0xd1, 0x3b, 0xd4, 0x46, 0x7d, 0xc4, 0x46, 0x8d, 0xcf, 0xf3, 0x62, 0x83, 0xb5,
+ 0xdf, 0xbc, 0xb1, 0xca, 0x99, 0x97, 0x96, 0x79, 0xfd, 0xcd, 0x55, 0x00, 0xae, 0x2c, 0x04, 0x5d,
+ 0x98, 0xa2, 0x6a, 0xd0, 0xc0, 0x11, 0x71, 0x73, 0xbc, 0x0f, 0x4e, 0xcd, 0x93, 0x3e, 0x75, 0x11,
+ 0x09, 0x64, 0xff, 0xfd, 0xe1, 0x52, 0x65, 0x2c, 0xf2, 0xb7, 0x3d, 0xb3, 0x3e, 0xa8, 0x88, 0x1f,
+ 0x6a, 0x50, 0xaf, 0xd7, 0xa3, 0x4c, 0xb1, 0x11, 0x0f, 0x4a, 0xe9, 0x23, 0x5a, 0xc9, 0x11, 0x55,
+ 0xcb, 0x0f, 0x7f, 0xbe, 0xc8, 0x99, 0x97, 0x17, 0xf9, 0xd7, 0xa5, 0xc8, 0x91, 0x12, 0x2a, 0x6c,
+ 0x0d, 0x2d, 0x73, 0x44, 0x33, 0x71, 0x15, 0x40, 0x6a, 0x3e, 0x2a, 0xb5, 0x48, 0x46, 0x98, 0xa2,
+ 0x72, 0x48, 0x09, 0x08, 0x86, 0xf6, 0x4c, 0xa7, 0x82, 0x3f, 0x4d, 0xcf, 0xb9, 0x7c, 0x47, 0x6d,
+ 0x08, 0x0f, 0xca, 0x6b, 0x0e, 0xc8, 0x87, 0x73, 0x3d, 0xce, 0xbc, 0xb4, 0xc0, 0x99, 0x97, 0xae,
+ 0xd1, 0xed, 0x55, 0xd4, 0x62, 0x71, 0x40, 0xac, 0x4d, 0x3c, 0xbf, 0x21, 0x45, 0x43, 0x6a, 0x19,
+ 0x5f, 0x7e, 0x93, 0x28, 0x22, 0x9e, 0x6c, 0x12, 0xe7, 0x6d, 0x94, 0xe7, 0x46, 0x68, 0x4f, 0x0f,
+ 0x46, 0xe4, 0xec, 0xab, 0xd7, 0x39, 0xfb, 0xea, 0xf5, 0x8d, 0x15, 0xf1, 0x5f, 0x4e, 0x30, 0x31,
+ 0x66, 0xf2, 0x82, 0xb2, 0x7c, 0xd3, 0x82, 0x1a, 0xc6, 0x77, 0x24, 0x7c, 0xed, 0xbb, 0x1f, 0xf1,
+ 0xca, 0x6f, 0x17, 0x87, 0xfc, 0xb5, 0x71, 0x40, 0x4c, 0x0a, 0x48, 0x04, 0x24, 0x70, 0x44, 0x83,
+ 0x34, 0xae, 0x79, 0x31, 0x66, 0xfa, 0xc5, 0x5b, 0xdf, 0xa0, 0x55, 0x78, 0xb5, 0x3d, 0xbd, 0xba,
+ 0x75, 0x45, 0x7c, 0x5f, 0x83, 0x89, 0xf1, 0x7a, 0xfe, 0x5b, 0x2f, 0xfe, 0x72, 0x81, 0x1f, 0xbd,
+ 0x72, 0x95, 0x5d, 0x13, 0x09, 0xaf, 0xfd, 0xe0, 0xf0, 0x06, 0x20, 0x22, 0x09, 0xaf, 0xa6, 0xa8,
+ 0x07, 0x05, 0x10, 0x8d, 0x34, 0x7e, 0x2d, 0xd2, 0x5d, 0x25, 0xa1, 0xa7, 0xfd, 0x12, 0x63, 0xf6,
+ 0x6a, 0x97, 0xcb, 0xf3, 0xdd, 0xad, 0x0b, 0xc9, 0x63, 0xad, 0x68, 0xa6, 0x53, 0xa6, 0xdf, 0x5b,
+ 0xe7, 0xcd, 0x77, 0x56, 0xd8, 0x31, 0x1a, 0xf2, 0x7f, 0x93, 0x5d, 0x6c, 0x9f, 0x31, 0x6a, 0xb5,
+ 0xa8, 0x5a, 0xa1, 0xa8, 0xa8, 0x4a, 0xd1, 0x31, 0x49, 0xcb, 0x3a, 0xbe, 0x34, 0xf0, 0x38, 0xc5,
+ 0xd9, 0x3e, 0x77, 0x63, 0x7b, 0x8a, 0xf8, 0xd1, 0xb1, 0x3e, 0x20, 0x1d, 0xef, 0x8b, 0x91, 0x86,
+ 0xe9, 0x1b, 0x5a, 0x87, 0xa6, 0x16, 0x0e, 0x88, 0xcb, 0x24, 0x0a, 0xf5, 0x6b, 0x6d, 0x90, 0x23,
+ 0xa6, 0x18, 0x58, 0x90, 0xbc, 0x6a, 0xf5, 0xcf, 0x0e, 0x45, 0x44, 0xaa, 0x1a, 0xe5, 0xb3, 0xcf,
+ 0xdc, 0xc3, 0xd9, 0x6f, 0x3f, 0x5c, 0x51, 0xe5, 0xaa, 0x36, 0x72, 0xdd, 0xf1, 0xcd, 0x55, 0xed,
+ 0x97, 0xe7, 0x9b, 0x09, 0x2f, 0x49, 0xf2, 0x02, 0xd1, 0x07, 0xa4, 0x88, 0x48, 0x20, 0x7a, 0x5a,
+ 0x02, 0x21, 0xfe, 0xd6, 0xda, 0x67, 0xcf, 0x5b, 0xe7, 0x2a, 0x3a, 0xfe, 0xa3, 0xe3, 0x40, 0x82,
+ 0x22, 0x88, 0x68, 0xc5, 0x88, 0xa7, 0x03, 0x6a, 0xd0, 0xdd, 0x3b, 0x36, 0x72, 0xb3, 0xd4, 0x4a,
+ 0x7c, 0x89, 0x8e, 0x38, 0xa2, 0xa1, 0x8f, 0xa8, 0x14, 0xbd, 0x44, 0xd2, 0x88, 0xe0, 0x5e, 0xda,
+ 0x07, 0x72, 0xa1, 0x88, 0xaf, 0xf7, 0xed, 0x73, 0x37, 0x07, 0x81, 0x1c, 0xdf, 0xe9, 0x79, 0x66,
+ 0x7c, 0xaf, 0xb3, 0xde, 0xd8, 0xc4, 0x03, 0xb3, 0xae, 0x42, 0xaa, 0xe4, 0x6b, 0xad, 0x66, 0x3d,
+ 0x8a, 0x55, 0x7d, 0xf3, 0xd4, 0x92, 0x3a, 0x68, 0x8a, 0x5a, 0x9b, 0x8b, 0x81, 0x14, 0x20, 0xd3,
+ 0x30, 0xd3, 0xfb, 0x99, 0x04, 0x53, 0xf4, 0x0f, 0x1f, 0x82, 0xcc, 0x0a, 0x62, 0x52, 0x12, 0xb1,
+ 0xa0, 0x3d, 0x3e, 0x9a, 0x5b, 0xe7, 0xe3, 0xf9, 0xf5, 0x92, 0x22, 0x16, 0x4e, 0x3c, 0xbc, 0x13,
+ 0xab, 0x09, 0x56, 0x13, 0x92, 0xd4, 0x80, 0xed, 0x3a, 0xb7, 0x25, 0x75, 0xb0, 0xbd, 0xc2, 0xeb,
+ 0x62, 0x40, 0xbb, 0x80, 0xd0, 0x68, 0x38, 0x82, 0xaf, 0x75, 0x2c, 0x98, 0xfa, 0xe6, 0xa9, 0x45,
+ 0xe2, 0x1d, 0xa5, 0x79, 0x92, 0x3a, 0x66, 0x85, 0x88, 0x48, 0x12, 0x6d, 0x0b, 0x49, 0xe4, 0x01,
+ 0x97, 0x7a, 0x22, 0x89, 0x07, 0xa7, 0xbc, 0x35, 0x3d, 0x18, 0x8d, 0xe3, 0x0f, 0x8d, 0xd1, 0x68,
+ 0xd4, 0xc8, 0xac, 0x41, 0x31, 0xfe, 0xfa, 0x0c, 0x10, 0x44, 0x52, 0x3f, 0x24, 0xf9, 0x63, 0x4c,
+ 0xde, 0x00, 0xef, 0xdb, 0xd7, 0xe4, 0xfe, 0xfd, 0xa3, 0xec, 0x1c, 0xaf, 0xf9, 0xb5, 0xdb, 0xe1,
+ 0x48, 0x31, 0x85, 0x8a, 0x94, 0xfb, 0x48, 0xce, 0x91, 0xc4, 0xa7, 0x5a, 0xd1, 0x10, 0x93, 0xd4,
+ 0x20, 0xa1, 0xaf, 0x90, 0xf2, 0xf6, 0xf4, 0x72, 0x05, 0x3f, 0x76, 0x82, 0xa4, 0x18, 0x63, 0x90,
+ 0x5c, 0x76, 0xa4, 0x15, 0x24, 0x0d, 0x6a, 0xc1, 0xa5, 0xf0, 0x97, 0x9f, 0x79, 0x80, 0x2f, 0x3d,
+ 0xb9, 0xd7, 0x27, 0x80, 0xf0, 0xd8, 0x91, 0x71, 0xde, 0xb9, 0xb0, 0xbc, 0x69, 0x1f, 0x41, 0x35,
+ 0x1f, 0x4f, 0x8c, 0xe0, 0x66, 0x13, 0xcd, 0x6f, 0x94, 0x46, 0x43, 0x56, 0x9a, 0xef, 0x62, 0x18,
+ 0xe3, 0x81, 0xa8, 0x2b, 0x7f, 0x6f, 0x9f, 0x5b, 0xaa, 0x00, 0xb2, 0xdb, 0x55, 0x74, 0x63, 0x30,
+ 0x26, 0x68, 0xb5, 0xc8, 0x31, 0xb1, 0x6a, 0xc0, 0xe4, 0x6b, 0xad, 0xd1, 0x1a, 0x07, 0xef, 0x1d,
+ 0xe7, 0xc0, 0xfe, 0x31, 0x50, 0xe1, 0xf9, 0xe7, 0x1e, 0xe3, 0xa9, 0xcf, 0xed, 0x1b, 0x82, 0xc3,
+ 0xe4, 0x0e, 0x51, 0x25, 0xea, 0x23, 0x61, 0xe8, 0xd2, 0x88, 0x23, 0xa1, 0xab, 0x53, 0x4c, 0x89,
+ 0x91, 0x14, 0x72, 0x32, 0xfd, 0xdc, 0x62, 0x05, 0xd1, 0x77, 0xfb, 0x9b, 0x94, 0xb7, 0xd2, 0xa3,
+ 0x72, 0x2b, 0x1a, 0x6d, 0xb2, 0x45, 0xf5, 0x33, 0xba, 0xee, 0xc9, 0xcf, 0xee, 0xe3, 0xe0, 0xe4,
+ 0x18, 0x07, 0xf6, 0xb7, 0xf8, 0xfe, 0xcf, 0xfe, 0x5d, 0x9a, 0xe2, 0x8b, 0xa7, 0x3c, 0xaa, 0x45,
+ 0x0d, 0x8c, 0x80, 0xf8, 0x2a, 0x15, 0x6f, 0x42, 0xa8, 0x0c, 0xdd, 0xc6, 0x99, 0x7d, 0xe3, 0xa9,
+ 0xa2, 0xb2, 0x55, 0x19, 0x1b, 0x5f, 0x2c, 0x25, 0x63, 0x65, 0xc8, 0x5a, 0x74, 0xfc, 0xe0, 0x7d,
+ 0xe3, 0x3c, 0xff, 0xdc, 0x49, 0x0e, 0x4e, 0xee, 0xe0, 0x85, 0x9f, 0x5c, 0xe0, 0xc3, 0xb9, 0xd5,
+ 0xfe, 0x14, 0x2d, 0x4d, 0x8e, 0xa6, 0xaf, 0x6f, 0xe5, 0xa2, 0x31, 0x89, 0x36, 0xc6, 0xcc, 0x16,
+ 0xfb, 0xb6, 0xde, 0xc6, 0xe6, 0xf5, 0xed, 0xed, 0x6e, 0x27, 0x89, 0xe1, 0xeb, 0x5f, 0x39, 0xca,
+ 0x0b, 0xdf, 0x3a, 0xc5, 0x13, 0x53, 0x7b, 0x00, 0x68, 0x8d, 0x46, 0x3c, 0x2b, 0x6b, 0x2d, 0x57,
+ 0x8f, 0x05, 0x92, 0x9d, 0xd0, 0xf0, 0x72, 0xd8, 0x66, 0xae, 0x9c, 0x69, 0x06, 0x7a, 0x2b, 0x1f,
+ 0xf2, 0x0b, 0xaf, 0x48, 0xff, 0x93, 0x56, 0x31, 0x45, 0x9a, 0x04, 0xa5, 0x1c, 0xaf, 0xe5, 0x00,
+ 0xc3, 0x6e, 0xa6, 0x0e, 0xae, 0xf5, 0x5d, 0x17, 0x52, 0x5d, 0x79, 0xe6, 0xf3, 0x07, 0xb8, 0x7f,
+ 0x72, 0x07, 0xbf, 0xfe, 0xc3, 0x2c, 0x27, 0x8f, 0x4d, 0x40, 0x3a, 0x81, 0xda, 0x16, 0xda, 0x9b,
+ 0xcb, 0x49, 0xe2, 0xb4, 0x56, 0xaf, 0xc3, 0xea, 0xc5, 0x19, 0xb8, 0xe7, 0x71, 0x98, 0x78, 0xc0,
+ 0x1b, 0x9f, 0xf9, 0x96, 0x9f, 0xb9, 0x8d, 0x87, 0xdc, 0x30, 0x8b, 0xa2, 0x88, 0xda, 0x68, 0x1c,
+ 0xd5, 0xbc, 0x59, 0x86, 0xb7, 0x0c, 0xf1, 0xba, 0xc6, 0xe7, 0x75, 0x70, 0xa3, 0x71, 0xd8, 0x76,
+ 0xd4, 0xd4, 0xc9, 0x7d, 0x4c, 0x9d, 0x3c, 0xe6, 0x25, 0xfc, 0x18, 0xbd, 0x6b, 0x1f, 0xd0, 0xf9,
+ 0xe8, 0x1f, 0x50, 0x6b, 0x04, 0x20, 0x82, 0x66, 0x19, 0x4b, 0xef, 0xfe, 0x9d, 0xf1, 0xc6, 0x12,
+ 0xcd, 0x7b, 0xef, 0xa1, 0xd6, 0xc4, 0x3d, 0xaa, 0x56, 0x5f, 0xd2, 0xac, 0xfb, 0x54, 0x75, 0x4a,
+ 0x59, 0xad, 0xc3, 0xe8, 0xca, 0xb6, 0xbb, 0xce, 0x06, 0x25, 0x6a, 0x35, 0xd7, 0x95, 0x5a, 0xb9,
+ 0x01, 0xa9, 0x39, 0xed, 0xe2, 0x51, 0x47, 0x4c, 0xf1, 0x58, 0x30, 0x7c, 0x0f, 0x02, 0x3c, 0xee,
+ 0xd1, 0xd8, 0x84, 0xde, 0x4a, 0x97, 0x95, 0x8b, 0x17, 0x59, 0x9b, 0xbf, 0x82, 0x24, 0x87, 0x8b,
+ 0xe7, 0xec, 0xa2, 0x4a, 0x77, 0x69, 0x9e, 0xb5, 0x4b, 0x8b, 0xd4, 0x6d, 0x93, 0xda, 0x2e, 0x81,
+ 0x11, 0x75, 0xbb, 0x78, 0xbd, 0x22, 0xc3, 0x6c, 0x4f, 0xc8, 0x32, 0xd7, 0xa0, 0xb3, 0x0c, 0x7f,
+ 0x2c, 0x79, 0x26, 0x66, 0x99, 0x07, 0x67, 0x8b, 0xcf, 0x58, 0x66, 0x05, 0xa3, 0x4d, 0xe2, 0xdf,
+ 0xc6, 0x7d, 0x26, 0x49, 0x71, 0x2e, 0x49, 0xa3, 0x73, 0xfe, 0x98, 0xa8, 0x2b, 0xd0, 0x05, 0xbb,
+ 0xd0, 0xa1, 0x77, 0x75, 0x05, 0xbb, 0x3e, 0x82, 0x5a, 0xe3, 0x1a, 0xa2, 0xa8, 0xb2, 0xd0, 0x19,
+ 0xe1, 0xe6, 0x5a, 0x8d, 0x6c, 0xa5, 0x0b, 0x4b, 0xcb, 0xee, 0x0f, 0x3a, 0xe4, 0x20, 0xf0, 0xdb,
+ 0x5a, 0x9a, 0x81, 0xf6, 0x1c, 0x10, 0xdb, 0x73, 0xc6, 0x07, 0x50, 0xb6, 0x07, 0x99, 0x2d, 0x8e,
+ 0x03, 0x38, 0xb5, 0x11, 0x10, 0x53, 0x18, 0x9d, 0x78, 0xa3, 0x35, 0x29, 0xfa, 0x5b, 0xd8, 0x2e,
+ 0x08, 0xbb, 0xa1, 0xa4, 0x25, 0x10, 0x89, 0xb7, 0x63, 0x19, 0x6e, 0x2d, 0xc3, 0xfc, 0x8d, 0x51,
+ 0x6e, 0x74, 0x6a, 0xc8, 0x88, 0x92, 0x62, 0x33, 0x2e, 0xac, 0xdf, 0xc5, 0xae, 0xf9, 0x9b, 0x58,
+ 0x59, 0x62, 0xcf, 0xba, 0x52, 0x9f, 0x77, 0x37, 0xc1, 0xd3, 0x40, 0x63, 0x4f, 0xab, 0x07, 0x60,
+ 0x0b, 0x0a, 0x59, 0x2d, 0xd6, 0x34, 0xf3, 0xeb, 0x5a, 0x8a, 0x8a, 0x29, 0x80, 0x88, 0xf8, 0x68,
+ 0xf8, 0xb7, 0xc4, 0x9f, 0x51, 0x6a, 0x25, 0x3e, 0x6a, 0xf9, 0x5e, 0x61, 0xe2, 0x1c, 0x7b, 0x6b,
+ 0x05, 0xde, 0xbb, 0x3c, 0xc2, 0xdf, 0xe6, 0xee, 0xe2, 0x4a, 0xd6, 0x22, 0xb5, 0x3d, 0xd2, 0x56,
+ 0x6b, 0x94, 0x25, 0xee, 0xe6, 0xaf, 0x9d, 0x51, 0xa6, 0x3f, 0x58, 0xa6, 0x71, 0xa9, 0x8b, 0x88,
+ 0xf4, 0x17, 0x5d, 0x19, 0xfe, 0x4c, 0xb2, 0xf2, 0x41, 0xac, 0x6c, 0xb2, 0x77, 0xab, 0x54, 0xff,
+ 0x93, 0x9b, 0x6e, 0x50, 0xa0, 0xa3, 0x13, 0x3d, 0x15, 0x96, 0xa5, 0xc9, 0x42, 0x3a, 0x41, 0xd2,
+ 0x18, 0xa1, 0xd5, 0x1c, 0xe1, 0x3f, 0x89, 0x98, 0x18, 0xac, 0xd2, 0xd3, 0xb2, 0x95, 0x00, 0x00,
+ 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
+#endif
--- /dev/null
+#ifndef FF_VIDEO_PNG_H
+#define FF_VIDEO_PNG_H
+
+static unsigned char ff_video_png[] =
+{
+ 0x00, 0x00, 0x0a, 0x9d,
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
+ 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x3f, 0x88,
+ 0xb1, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0,
+ 0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00,
+ 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45,
+ 0x07, 0xdf, 0x0a, 0x1a, 0x00, 0x20, 0x02, 0x21, 0x22, 0xee, 0x8e, 0x00, 0x00, 0x00, 0x19, 0x74,
+ 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74,
+ 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0x0e, 0x17,
+ 0x00, 0x00, 0x0a, 0x05, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xd5, 0x9a, 0xdf, 0x6f, 0x1c, 0x57,
+ 0x15, 0xc7, 0x3f, 0xe7, 0xce, 0xec, 0xae, 0xbd, 0x96, 0x7f, 0xc4, 0x71, 0x7e, 0x34, 0x3f, 0x4a,
+ 0x68, 0x7e, 0x35, 0xad, 0x83, 0x50, 0x42, 0x23, 0xa8, 0x8a, 0x0a, 0x34, 0xd0, 0xa6, 0xaa, 0xd4,
+ 0x14, 0xa8, 0x08, 0x0f, 0x88, 0x17, 0xfa, 0x1f, 0xf0, 0xc6, 0x03, 0x12, 0x7f, 0x44, 0x1f, 0xf2,
+ 0xc2, 0x0b, 0x02, 0x5e, 0x2a, 0x21, 0x84, 0x10, 0x48, 0x20, 0x54, 0x54, 0x40, 0x54, 0x71, 0x01,
+ 0x15, 0xc7, 0x69, 0x50, 0xd4, 0x34, 0xa5, 0xce, 0x2f, 0x37, 0x89, 0xe3, 0x38, 0xb6, 0x77, 0x77,
+ 0xee, 0xe1, 0xe1, 0xde, 0x3b, 0x73, 0x67, 0x76, 0xd6, 0x69, 0xdc, 0x82, 0xc2, 0x48, 0xa3, 0x9d,
+ 0x9d, 0x99, 0xf5, 0x9c, 0xef, 0x3d, 0xe7, 0x7b, 0xce, 0xf7, 0x9c, 0xb1, 0x9c, 0x3a, 0x75, 0x4a,
+ 0xd7, 0xd6, 0xd6, 0x10, 0x49, 0x50, 0x40, 0xf9, 0x3f, 0xd8, 0x14, 0x44, 0xc0, 0x88, 0x62, 0xad,
+ 0xa5, 0xd5, 0x6a, 0x91, 0xae, 0xac, 0xac, 0xd0, 0xe9, 0x66, 0x40, 0x87, 0x66, 0xd2, 0x23, 0x35,
+ 0x19, 0xa8, 0x3e, 0xe0, 0x38, 0x0c, 0xdd, 0x2c, 0xa5, 0x6b, 0x13, 0x8c, 0x71, 0x60, 0x52, 0x11,
+ 0x43, 0xbb, 0xb1, 0xc2, 0x53, 0x07, 0xaf, 0x72, 0xe4, 0x60, 0x97, 0x89, 0xc9, 0x61, 0x32, 0xd2,
+ 0x07, 0x16, 0x84, 0x08, 0xd0, 0x59, 0xe1, 0xdd, 0x4b, 0x3d, 0x5e, 0x9f, 0x1d, 0xe3, 0xfc, 0x95,
+ 0x29, 0x8c, 0x24, 0xa4, 0x99, 0x85, 0x23, 0x0f, 0x2f, 0xf0, 0xdc, 0xb1, 0x5b, 0x3c, 0xba, 0x2f,
+ 0x81, 0x61, 0x03, 0x64, 0x0f, 0x76, 0x90, 0xd9, 0x0e, 0x07, 0x1e, 0x5a, 0xa1, 0x99, 0x76, 0xb9,
+ 0xb1, 0x34, 0xcc, 0xad, 0x6e, 0x8b, 0xd4, 0x5a, 0x38, 0xfc, 0xa9, 0x1b, 0xec, 0xd9, 0xb9, 0x06,
+ 0x62, 0xe0, 0xe6, 0xea, 0x03, 0x1c, 0x54, 0x02, 0x6a, 0x21, 0x35, 0xb4, 0x47, 0x2d, 0xd3, 0x8f,
+ 0xf4, 0xf8, 0xe3, 0x3f, 0x97, 0xf8, 0xf0, 0xea, 0x66, 0x52, 0xab, 0x42, 0x7b, 0xa4, 0x0b, 0xf6,
+ 0x36, 0xdc, 0x5d, 0x81, 0x8e, 0x82, 0x14, 0xa4, 0x0a, 0xbf, 0x8f, 0x89, 0x56, 0x3a, 0xa7, 0xf5,
+ 0xcf, 0x1b, 0x78, 0xed, 0x3e, 0xed, 0x2e, 0x3d, 0x57, 0xfc, 0x67, 0x17, 0xb0, 0x09, 0x62, 0x36,
+ 0x31, 0xd4, 0xb2, 0xa8, 0xe2, 0xc8, 0x60, 0x2d, 0x68, 0xb6, 0x06, 0x89, 0x42, 0x72, 0x0f, 0xa3,
+ 0xa5, 0xf2, 0xa0, 0xff, 0x26, 0x90, 0xba, 0xbf, 0x15, 0xbe, 0xdb, 0x0c, 0xcd, 0x56, 0xb1, 0xe2,
+ 0x4e, 0xa4, 0xf9, 0x55, 0x19, 0xb0, 0x12, 0xb1, 0xc1, 0x02, 0xf3, 0x0b, 0xb0, 0xf3, 0xe4, 0xc6,
+ 0x6c, 0xba, 0xf2, 0x4b, 0xd8, 0x36, 0xb9, 0x01, 0x20, 0x75, 0x0b, 0x68, 0xca, 0xe7, 0x4c, 0xe9,
+ 0xa2, 0xd4, 0x80, 0xa8, 0x80, 0x9b, 0x39, 0xb7, 0x31, 0x10, 0x3b, 0x36, 0x6f, 0x00, 0xc4, 0xa0,
+ 0x85, 0xd5, 0xfe, 0x88, 0x48, 0x8b, 0x90, 0x31, 0x20, 0x59, 0x19, 0xbd, 0xf4, 0xaf, 0xca, 0xcc,
+ 0xf9, 0x8d, 0xd9, 0x72, 0xe4, 0xe0, 0x3a, 0x8b, 0x74, 0xbf, 0x1e, 0x01, 0x30, 0x02, 0x92, 0xc4,
+ 0x40, 0x42, 0x99, 0x1c, 0x02, 0x51, 0x90, 0x5e, 0x7d, 0x68, 0xf1, 0xf1, 0x3c, 0x72, 0xdf, 0x40,
+ 0x74, 0x40, 0x84, 0xe4, 0xe7, 0x1b, 0x20, 0x43, 0xb9, 0x4b, 0x22, 0x8e, 0xb4, 0x3d, 0x88, 0x5e,
+ 0x3d, 0x59, 0x43, 0x68, 0xbd, 0xd3, 0xff, 0xcc, 0x99, 0x1f, 0x7b, 0x43, 0x3f, 0x49, 0xb2, 0x4b,
+ 0x4d, 0x44, 0x94, 0x28, 0xd0, 0x72, 0x36, 0xf7, 0x03, 0x69, 0x3a, 0x57, 0xad, 0xb3, 0x6a, 0xf3,
+ 0xd7, 0xe1, 0xf2, 0x87, 0xe5, 0x73, 0xcd, 0x14, 0xa6, 0xf7, 0x0e, 0x58, 0x6d, 0xe1, 0x93, 0xdb,
+ 0xa4, 0xf2, 0x45, 0x1a, 0x0e, 0x4c, 0x3f, 0x90, 0x86, 0x03, 0x52, 0x17, 0x97, 0xeb, 0x10, 0xfd,
+ 0xf0, 0x5e, 0x68, 0x36, 0xfe, 0x87, 0xe9, 0x37, 0xdf, 0x52, 0x67, 0x73, 0x19, 0x88, 0x8f, 0xb9,
+ 0xb8, 0x88, 0xd4, 0xd4, 0x8b, 0xba, 0xb0, 0x3a, 0x7a, 0xe8, 0xde, 0x99, 0xee, 0x63, 0x03, 0xa9,
+ 0x4d, 0xbf, 0x09, 0xd0, 0x00, 0x7a, 0x11, 0x10, 0x1b, 0x3c, 0x62, 0x06, 0xaf, 0x82, 0xd4, 0x7b,
+ 0xe4, 0xf4, 0x2f, 0xdc, 0xbe, 0x9e, 0x1d, 0x37, 0x7f, 0x07, 0xe3, 0xa3, 0x1f, 0xa1, 0xc8, 0x2a,
+ 0xeb, 0xf2, 0xb3, 0x38, 0x2f, 0x20, 0xa9, 0xa3, 0x43, 0x0e, 0x44, 0x00, 0x15, 0x87, 0xce, 0x98,
+ 0xfa, 0xc2, 0x18, 0x3c, 0xb2, 0x81, 0x8c, 0xb5, 0x77, 0x57, 0x04, 0x62, 0x9d, 0x6c, 0x38, 0xf0,
+ 0x9a, 0xd4, 0x80, 0x17, 0x3c, 0x0d, 0x92, 0xbc, 0xe5, 0x70, 0x2e, 0xb0, 0xb8, 0x93, 0x62, 0x2a,
+ 0x37, 0x87, 0xdd, 0x30, 0xbf, 0x60, 0xfa, 0x88, 0xfe, 0x51, 0xb6, 0xa3, 0x8f, 0x06, 0x03, 0x24,
+ 0x32, 0x46, 0xbc, 0x1e, 0x5f, 0xe7, 0x9a, 0x04, 0xcd, 0xee, 0x0d, 0x8e, 0xef, 0x91, 0x60, 0x6f,
+ 0x9a, 0x83, 0x74, 0x40, 0x32, 0xef, 0x91, 0x00, 0x44, 0xfa, 0x03, 0x64, 0xa3, 0xf5, 0xe3, 0xe8,
+ 0xa1, 0xb8, 0x91, 0x90, 0x01, 0xab, 0x2f, 0x83, 0xbd, 0x24, 0xa1, 0xf8, 0x55, 0x7e, 0x24, 0x09,
+ 0x68, 0xc3, 0x79, 0x44, 0x72, 0x8e, 0x84, 0x2c, 0x60, 0x06, 0x3c, 0x28, 0xab, 0x05, 0xf2, 0xca,
+ 0x49, 0x38, 0xfd, 0x83, 0x1a, 0xe5, 0x18, 0x1e, 0xaa, 0x71, 0xb0, 0x6b, 0xe5, 0xb8, 0x4e, 0x52,
+ 0x57, 0xbe, 0x8b, 0x06, 0xe3, 0x6a, 0xc2, 0xce, 0x38, 0xaf, 0xd8, 0x38, 0x6b, 0x59, 0x7f, 0xa1,
+ 0xea, 0x91, 0xa8, 0xba, 0xce, 0xcc, 0x0d, 0xca, 0x58, 0x3a, 0xa0, 0x2c, 0x57, 0x17, 0x64, 0x80,
+ 0xb1, 0xeb, 0x1e, 0xfb, 0xbf, 0x5f, 0x97, 0xb5, 0x24, 0x01, 0x4d, 0x7d, 0x34, 0x79, 0x20, 0xaa,
+ 0xc6, 0xa7, 0x32, 0x73, 0x5f, 0xd2, 0xe4, 0xe8, 0x63, 0x45, 0xa1, 0xdc, 0x79, 0x62, 0x83, 0x8a,
+ 0xf8, 0xb7, 0xb0, 0x6d, 0xf3, 0x47, 0x4c, 0xc1, 0x55, 0x20, 0xa4, 0xe5, 0x3a, 0xa2, 0x59, 0x08,
+ 0x2d, 0x5f, 0xd9, 0x8d, 0xf1, 0x91, 0xe0, 0x62, 0x73, 0xfe, 0x3a, 0x5c, 0x5e, 0xe8, 0x95, 0xfe,
+ 0x76, 0x23, 0x85, 0xc3, 0xfb, 0x52, 0x30, 0xc2, 0xcc, 0x39, 0xeb, 0xdb, 0xe3, 0xfb, 0x54, 0xc4,
+ 0x5b, 0x60, 0xdb, 0x54, 0x1a, 0x85, 0xa2, 0x16, 0xa1, 0x59, 0x3a, 0x8e, 0xd6, 0x58, 0xad, 0xff,
+ 0x92, 0x82, 0xc6, 0xa1, 0x25, 0x60, 0x33, 0x50, 0xf5, 0x25, 0x5f, 0x52, 0x4f, 0x7c, 0xf1, 0x9c,
+ 0x11, 0x66, 0xce, 0xf5, 0xf2, 0x7c, 0x1d, 0xb6, 0xe9, 0xbd, 0x86, 0x56, 0xab, 0xed, 0xbc, 0x35,
+ 0xb7, 0xba, 0x21, 0x20, 0x47, 0x1e, 0x4d, 0xbd, 0xf0, 0x0b, 0xdc, 0xb4, 0x45, 0x2c, 0x8b, 0xe7,
+ 0x94, 0x54, 0xa3, 0xc4, 0x7a, 0x0a, 0x34, 0x7d, 0xfa, 0x8d, 0x64, 0xbc, 0xb5, 0x78, 0xe3, 0x87,
+ 0xfc, 0xde, 0xf0, 0xfd, 0xb1, 0x01, 0x11, 0x66, 0xe6, 0x96, 0x6b, 0xc2, 0xaa, 0xe9, 0x8d, 0x08,
+ 0x40, 0x36, 0xa0, 0x88, 0x0f, 0x35, 0xcb, 0x40, 0xea, 0x1a, 0x8d, 0x38, 0x5b, 0xa9, 0x27, 0xb4,
+ 0x18, 0x90, 0x16, 0xaa, 0x09, 0xd6, 0x2a, 0x92, 0x87, 0x96, 0x15, 0x94, 0x50, 0x29, 0x9b, 0x11,
+ 0x5f, 0xdc, 0xea, 0xcc, 0x9c, 0x5d, 0xaa, 0x21, 0x7a, 0xcb, 0xdf, 0x0b, 0x33, 0x73, 0xbd, 0x7e,
+ 0x45, 0xfc, 0xd3, 0xad, 0xce, 0x50, 0xc4, 0x67, 0x13, 0xa9, 0x84, 0x4c, 0x9c, 0xd5, 0xc2, 0xb5,
+ 0xea, 0x7d, 0x15, 0x96, 0x1b, 0x7f, 0x8f, 0x18, 0xa0, 0x89, 0x6a, 0x92, 0xff, 0xb9, 0x54, 0x42,
+ 0xcf, 0x1e, 0x80, 0x48, 0x00, 0x12, 0x85, 0xd6, 0x5c, 0xb7, 0x06, 0xc8, 0x08, 0x48, 0x93, 0xf9,
+ 0x6b, 0x3d, 0x2e, 0x2f, 0xd8, 0x7e, 0x45, 0xbc, 0x7f, 0xa4, 0xa8, 0x1d, 0x6a, 0xa3, 0x3a, 0x62,
+ 0xa3, 0xc2, 0xe7, 0x79, 0xb1, 0xde, 0xb5, 0x52, 0x1b, 0x2e, 0x2e, 0x84, 0xc5, 0x71, 0x44, 0xd5,
+ 0xa0, 0x81, 0x23, 0xe2, 0xfa, 0x78, 0xef, 0x9c, 0x86, 0x27, 0x7d, 0xea, 0x3c, 0x12, 0xc8, 0xfe,
+ 0xfb, 0x7d, 0x95, 0xcc, 0x58, 0xc4, 0xef, 0xcc, 0xdc, 0x5a, 0xbf, 0x22, 0xde, 0xdf, 0xa2, 0xd9,
+ 0x6c, 0x46, 0x91, 0x62, 0x23, 0x1e, 0x54, 0xc2, 0x47, 0xb4, 0x9e, 0x23, 0xe1, 0x5a, 0xe0, 0x48,
+ 0xfe, 0x33, 0xe3, 0xef, 0x6f, 0xa0, 0x55, 0x8e, 0x68, 0x26, 0x2e, 0x03, 0x48, 0xc3, 0x7b, 0xa5,
+ 0x11, 0xc9, 0x08, 0x53, 0x64, 0x0e, 0xa9, 0x00, 0xc1, 0x30, 0x33, 0xd7, 0xa9, 0xe1, 0x4f, 0xdb,
+ 0x73, 0x2e, 0x9f, 0xa8, 0x0d, 0xe0, 0x01, 0xf4, 0x7a, 0x19, 0xff, 0x38, 0xdf, 0xe1, 0xd6, 0x52,
+ 0xc6, 0x67, 0xf6, 0x37, 0x99, 0xda, 0x94, 0x22, 0x62, 0x4a, 0x8b, 0x55, 0x7e, 0x76, 0x08, 0xad,
+ 0x06, 0xd6, 0x26, 0x9e, 0xdf, 0x90, 0xa2, 0x21, 0xb4, 0x8c, 0x4f, 0xbf, 0x49, 0xe4, 0x11, 0x4f,
+ 0x36, 0x89, 0xe3, 0x36, 0x8a, 0x73, 0x23, 0xcc, 0x9c, 0xed, 0xf7, 0xc8, 0xe9, 0xd7, 0x6e, 0x72,
+ 0xfa, 0xb5, 0x9b, 0xeb, 0x2b, 0xe2, 0x3f, 0x1d, 0x66, 0x7c, 0xd4, 0x70, 0x71, 0xbe, 0xcb, 0x0f,
+ 0x5f, 0xbd, 0xc6, 0xdb, 0xff, 0x5a, 0xe5, 0xf8, 0xe7, 0x47, 0xf9, 0xd6, 0xb3, 0x13, 0x7c, 0xe1,
+ 0xb3, 0x23, 0x8c, 0xb6, 0x93, 0x82, 0xec, 0xa1, 0x28, 0xe6, 0x61, 0x9a, 0x80, 0x49, 0x01, 0x89,
+ 0x80, 0x04, 0x8e, 0x68, 0x90, 0xc6, 0x0d, 0x2f, 0xc6, 0x4c, 0x59, 0xbc, 0x95, 0x1a, 0xad, 0x62,
+ 0x55, 0x67, 0xce, 0xae, 0xdc, 0xbf, 0x22, 0xde, 0xdd, 0x62, 0x7c, 0xcc, 0x25, 0x8a, 0xc5, 0x65,
+ 0xe1, 0xc2, 0xbf, 0xbb, 0xbc, 0x7f, 0xa5, 0xcb, 0x4f, 0x7e, 0x75, 0x93, 0xbf, 0xfc, 0xe3, 0x2e,
+ 0x2f, 0x3c, 0x3d, 0xce, 0x37, 0xbf, 0x36, 0xc1, 0xf4, 0xfe, 0x36, 0xed, 0xe1, 0xaa, 0x47, 0x24,
+ 0xb7, 0x4f, 0x95, 0x6a, 0xfa, 0xd5, 0x48, 0xe3, 0x37, 0x22, 0xdd, 0x55, 0x11, 0x7a, 0x5a, 0x96,
+ 0x18, 0xf3, 0xd7, 0xbb, 0x5c, 0x5e, 0xe8, 0xde, 0xbf, 0x90, 0x7c, 0x6c, 0xa4, 0x18, 0xe0, 0xa8,
+ 0xc9, 0x03, 0xae, 0xd3, 0x53, 0xe6, 0xde, 0x5d, 0xe5, 0xc2, 0xfb, 0x6b, 0xbc, 0x7e, 0xe6, 0x0e,
+ 0x2f, 0x3f, 0x3b, 0xc9, 0x4b, 0xcf, 0x4c, 0xf2, 0xc8, 0xee, 0x16, 0x92, 0xdb, 0x61, 0xf3, 0x88,
+ 0x51, 0xab, 0x45, 0xd6, 0x0a, 0xde, 0x52, 0x95, 0xa2, 0x62, 0x92, 0x56, 0x75, 0x7c, 0xa5, 0xe1,
+ 0x71, 0x8a, 0x73, 0x66, 0x76, 0x69, 0x63, 0x8a, 0xf8, 0xf1, 0xd1, 0xa8, 0x39, 0x4d, 0xfb, 0x54,
+ 0x6a, 0xa7, 0xa7, 0x9c, 0x99, 0x5d, 0xe6, 0x9d, 0x8b, 0xab, 0xfc, 0xe1, 0xcd, 0x3b, 0x7c, 0xfb,
+ 0xf9, 0x29, 0xbe, 0x72, 0x6c, 0x9c, 0xed, 0x53, 0x4d, 0x8c, 0x09, 0x36, 0x1a, 0x1f, 0x49, 0x14,
+ 0xea, 0xd7, 0xda, 0x20, 0x47, 0x4c, 0xd1, 0xb0, 0x20, 0x79, 0xd6, 0x2a, 0xf7, 0x0e, 0x85, 0x47,
+ 0xea, 0x0a, 0xe5, 0x2b, 0xdf, 0xd8, 0xce, 0xe9, 0x1f, 0x1d, 0xa8, 0xc9, 0x72, 0x75, 0x83, 0x5c,
+ 0xfa, 0x2b, 0x77, 0xa0, 0xb4, 0xc2, 0xe2, 0x9d, 0x8c, 0xdf, 0xbc, 0x71, 0x93, 0xbf, 0x9f, 0x5b,
+ 0xe6, 0xcb, 0xc7, 0x26, 0x38, 0x75, 0x62, 0x0b, 0x4f, 0x3f, 0x31, 0xc6, 0xe8, 0x58, 0x92, 0x27,
+ 0x8f, 0x12, 0x90, 0xc2, 0x23, 0x81, 0xe8, 0x69, 0x05, 0x84, 0xf8, 0x47, 0x6b, 0xc9, 0x9e, 0x33,
+ 0xb3, 0x35, 0x15, 0xff, 0xf1, 0x31, 0x20, 0x41, 0x11, 0x44, 0xb4, 0xa6, 0xc5, 0xab, 0xa8, 0x3f,
+ 0x49, 0xd6, 0x6d, 0xee, 0xad, 0xc2, 0xfc, 0xf5, 0x0e, 0x3f, 0xfb, 0xf5, 0x35, 0xfe, 0xfa, 0xf6,
+ 0x12, 0x5f, 0x3f, 0x3e, 0xc5, 0x77, 0x4e, 0xee, 0x60, 0xfa, 0x80, 0x94, 0x39, 0xa2, 0xa1, 0x8e,
+ 0xa8, 0x14, 0xb5, 0x44, 0xd2, 0x88, 0xe0, 0x5e, 0xda, 0x07, 0x72, 0xa1, 0x88, 0xcf, 0xf7, 0x33,
+ 0xb3, 0x77, 0xfa, 0x81, 0x4c, 0x4f, 0x78, 0x9e, 0x19, 0x5f, 0xeb, 0x2c, 0xa0, 0xa8, 0x26, 0x1e,
+ 0x98, 0x75, 0x19, 0x52, 0xc5, 0x5d, 0x13, 0x07, 0xfa, 0x9e, 0xaf, 0x44, 0x14, 0x2e, 0x5c, 0x5a,
+ 0xe1, 0xd5, 0x9f, 0xcf, 0xd3, 0x6c, 0x35, 0x99, 0x3e, 0x90, 0xa2, 0xd6, 0xe6, 0x62, 0x20, 0x05,
+ 0xc8, 0xf2, 0xec, 0x66, 0xa2, 0x82, 0x63, 0x4a, 0x5d, 0x5d, 0x66, 0x05, 0x31, 0x29, 0x89, 0x58,
+ 0xd0, 0x1e, 0x1f, 0x5c, 0x5d, 0xe3, 0xca, 0xc2, 0x5a, 0x45, 0x11, 0x0b, 0x87, 0x0f, 0x4c, 0x60,
+ 0x35, 0xc1, 0x6a, 0x42, 0x92, 0x1a, 0xb0, 0x5d, 0xb7, 0x6c, 0x49, 0x13, 0x6c, 0xaf, 0xf0, 0x82,
+ 0x18, 0xd0, 0x6e, 0x2d, 0x47, 0x06, 0x6d, 0x69, 0x2a, 0xec, 0x7b, 0xb8, 0xcd, 0x81, 0x3d, 0xa3,
+ 0x7e, 0xa1, 0x34, 0x0f, 0x52, 0xc7, 0xb8, 0xe0, 0x11, 0x49, 0xa2, 0xb1, 0x90, 0x14, 0x73, 0x6e,
+ 0x71, 0xa1, 0x27, 0x92, 0x78, 0x70, 0xca, 0x99, 0xb3, 0xfd, 0xde, 0x98, 0xde, 0x3f, 0x4a, 0xab,
+ 0xd5, 0x20, 0xb3, 0x06, 0xc5, 0xf8, 0xfb, 0x33, 0x40, 0x10, 0x49, 0x7d, 0x3d, 0xf0, 0xc7, 0x98,
+ 0xbc, 0xb8, 0xc9, 0x3d, 0x70, 0x24, 0x89, 0xb0, 0xfb, 0xa1, 0x61, 0x4e, 0x3c, 0xb5, 0x85, 0x53,
+ 0x27, 0x1e, 0xe2, 0x89, 0x23, 0x5b, 0x4a, 0x5d, 0xa8, 0x48, 0xb5, 0x8e, 0xe4, 0x1c, 0x49, 0x7c,
+ 0xa8, 0x15, 0x05, 0x31, 0x49, 0x0d, 0x12, 0xea, 0x0a, 0x29, 0x6f, 0x9d, 0xbd, 0x5d, 0xc3, 0x8f,
+ 0x09, 0x90, 0x14, 0x63, 0x0c, 0x92, 0xcb, 0x8e, 0xb4, 0xc2, 0x87, 0xc8, 0xdb, 0x9a, 0x56, 0x16,
+ 0xad, 0x7f, 0x4e, 0x3d, 0x39, 0xde, 0xe4, 0x99, 0x27, 0xb7, 0x72, 0xea, 0xf9, 0x5d, 0x3c, 0x75,
+ 0x74, 0x13, 0x53, 0x13, 0x0d, 0x48, 0x1b, 0x60, 0x0d, 0xa8, 0xe6, 0xed, 0x89, 0xd3, 0x5a, 0x8a,
+ 0x8b, 0xd3, 0xbc, 0xeb, 0x4a, 0xca, 0xd3, 0x0d, 0x04, 0x63, 0xc2, 0x0a, 0x38, 0x43, 0xde, 0x9a,
+ 0x5d, 0xac, 0x01, 0xb2, 0xd9, 0x65, 0x74, 0x83, 0x03, 0xa2, 0xea, 0x8b, 0x97, 0x16, 0x1e, 0x2f,
+ 0x11, 0x5d, 0x4a, 0x3d, 0x45, 0x5c, 0xf9, 0x47, 0xda, 0x09, 0xc7, 0x0e, 0x4f, 0xf2, 0xf2, 0xf3,
+ 0xbb, 0x78, 0xe1, 0x4b, 0x3b, 0xd8, 0xb5, 0x7d, 0xd8, 0x2d, 0xbf, 0x6a, 0xbe, 0x20, 0xaa, 0x44,
+ 0x75, 0x24, 0x34, 0x5d, 0x1a, 0x71, 0x24, 0x54, 0x75, 0x8a, 0x2e, 0x31, 0x97, 0x4c, 0x61, 0x7c,
+ 0x3a, 0x7b, 0xab, 0x86, 0xe8, 0x9b, 0xfd, 0x43, 0xaa, 0xa3, 0xf4, 0x38, 0xdd, 0x46, 0x72, 0x43,
+ 0xf0, 0xba, 0xaa, 0xd8, 0x86, 0x5b, 0x09, 0x87, 0xf6, 0x8e, 0xf2, 0xd2, 0x57, 0x77, 0x71, 0xf2,
+ 0xf8, 0x0e, 0x0e, 0x3e, 0x32, 0x46, 0x23, 0x8d, 0xab, 0xbb, 0xe6, 0x2d, 0x86, 0x6a, 0xb1, 0x06,
+ 0x11, 0x10, 0x9f, 0xa5, 0xe2, 0x21, 0x84, 0xca, 0xc0, 0x31, 0xce, 0xfc, 0x1b, 0x2f, 0x16, 0x99,
+ 0xad, 0xce, 0xd8, 0xf8, 0x66, 0xa9, 0x8c, 0x10, 0x23, 0x52, 0xa4, 0x0d, 0x43, 0x9a, 0x1a, 0x8c,
+ 0xc0, 0xc3, 0x3b, 0xda, 0xbc, 0xf8, 0xcc, 0x2e, 0x5e, 0x7e, 0x6e, 0x37, 0x47, 0xa7, 0x27, 0x19,
+ 0x6a, 0x99, 0x9a, 0x31, 0x90, 0x16, 0xc9, 0xa2, 0x3c, 0x09, 0x8e, 0x6c, 0x09, 0xa2, 0x31, 0x9f,
+ 0x01, 0x6f, 0x64, 0x1a, 0xad, 0xf5, 0x2f, 0x66, 0x6a, 0x5f, 0x72, 0xc0, 0x9e, 0x9d, 0x23, 0x7c,
+ 0xf7, 0xa5, 0x3d, 0x5c, 0x9a, 0xbf, 0xcb, 0xf1, 0x27, 0xb7, 0xf1, 0xc5, 0xcf, 0x6d, 0x65, 0xd3,
+ 0x78, 0x73, 0x9d, 0xe7, 0x6a, 0xc1, 0xb3, 0xaa, 0xd6, 0x72, 0xf9, 0x58, 0x20, 0x99, 0x80, 0x96,
+ 0x97, 0xc3, 0x36, 0x73, 0xe9, 0x4c, 0x33, 0xd0, 0xbb, 0x79, 0x93, 0x5f, 0x8a, 0xef, 0xb8, 0xde,
+ 0x89, 0x89, 0x1a, 0x21, 0xc9, 0x07, 0x67, 0xf9, 0xb5, 0x00, 0x10, 0x53, 0x84, 0x88, 0xc2, 0xf8,
+ 0xd8, 0x30, 0xdf, 0xff, 0xde, 0x63, 0x85, 0xd2, 0x46, 0xcb, 0xbd, 0x87, 0x68, 0x11, 0xd2, 0x21,
+ 0x24, 0xd3, 0x71, 0xd4, 0x8e, 0xa0, 0xbd, 0xab, 0x39, 0x49, 0x9c, 0xd6, 0xea, 0x75, 0x58, 0xb9,
+ 0x38, 0x07, 0xdb, 0x8f, 0xc1, 0xf8, 0xa7, 0xbd, 0xf1, 0x99, 0x2f, 0xf9, 0x99, 0x1b, 0x3c, 0xe4,
+ 0x86, 0x59, 0x14, 0x45, 0xd4, 0x46, 0xed, 0xa8, 0xe6, 0xc5, 0x32, 0xec, 0x32, 0xc0, 0x8b, 0x1a,
+ 0x9f, 0xaf, 0x69, 0xcb, 0xd7, 0x9f, 0xe6, 0xab, 0x2b, 0x0f, 0x66, 0x94, 0xde, 0x87, 0xef, 0xd1,
+ 0xf9, 0xe0, 0x6d, 0x68, 0xb4, 0x02, 0x10, 0x41, 0xb3, 0x8c, 0xc5, 0xf3, 0x7f, 0x63, 0xac, 0xb5,
+ 0x48, 0x7b, 0xd7, 0x76, 0x1a, 0x6d, 0xdc, 0xab, 0x6a, 0xf5, 0x29, 0xcd, 0xba, 0x4f, 0x55, 0xa7,
+ 0x94, 0xd5, 0x3a, 0x8c, 0x2e, 0x6d, 0xbb, 0xfb, 0x6c, 0x50, 0xa2, 0x56, 0x73, 0x5d, 0xa9, 0xb5,
+ 0x03, 0x48, 0xcd, 0x69, 0x17, 0xb7, 0x3a, 0x62, 0x8a, 0xd7, 0x82, 0xe1, 0x7b, 0x10, 0xe0, 0x71,
+ 0x8d, 0xc6, 0x26, 0xf4, 0x96, 0xbb, 0x2c, 0x5f, 0xbc, 0xc8, 0xea, 0xc2, 0x35, 0x24, 0xd9, 0x57,
+ 0xbc, 0x67, 0x17, 0x55, 0xba, 0x8b, 0x0b, 0xac, 0x5e, 0xba, 0x45, 0xd3, 0xb6, 0x69, 0x4c, 0x0a,
+ 0x0c, 0xa9, 0x9b, 0xe2, 0xf5, 0x8a, 0x08, 0xb3, 0x3d, 0x21, 0xcb, 0x5c, 0x81, 0xce, 0x32, 0xfc,
+ 0xb1, 0xe4, 0x91, 0x98, 0x65, 0x1e, 0x9c, 0x2d, 0x3e, 0x63, 0x99, 0x15, 0x8c, 0x36, 0x89, 0xdf,
+ 0x8d, 0xfb, 0x4c, 0x92, 0xe2, 0x5c, 0x92, 0x46, 0xe7, 0xfc, 0x31, 0x49, 0x24, 0xca, 0xbb, 0x60,
+ 0x6f, 0x74, 0xe8, 0x5d, 0x5f, 0xc6, 0xae, 0x0d, 0xa1, 0xd6, 0x15, 0xd4, 0x54, 0x54, 0xb9, 0xd1,
+ 0x19, 0xe2, 0xce, 0x6a, 0x83, 0x6c, 0xb9, 0x0b, 0x8b, 0xb7, 0xdd, 0x0f, 0x3a, 0xe4, 0x20, 0xf0,
+ 0x63, 0x2d, 0xcd, 0x40, 0x7b, 0x0e, 0x88, 0xed, 0x39, 0xe3, 0x03, 0x28, 0xdb, 0x83, 0xcc, 0x16,
+ 0xc7, 0x01, 0x9c, 0xda, 0x08, 0x88, 0x29, 0x8c, 0x4e, 0xbc, 0xd1, 0x9a, 0x14, 0x7d, 0x5c, 0x18,
+ 0x17, 0x84, 0x69, 0x68, 0x28, 0x69, 0xc4, 0xc7, 0x3d, 0xd0, 0xdb, 0x70, 0xf7, 0x36, 0x2c, 0x2c,
+ 0x0d, 0xb3, 0xd4, 0x69, 0x20, 0x43, 0x4a, 0x8a, 0xcd, 0x78, 0x67, 0x6d, 0x0b, 0x93, 0x0b, 0x77,
+ 0xb0, 0xb2, 0xc8, 0xd4, 0x9a, 0xd2, 0x5c, 0x70, 0x0f, 0xc1, 0xd3, 0x40, 0xe3, 0x95, 0x56, 0x0f,
+ 0xc0, 0x16, 0x14, 0xb2, 0x5a, 0x5c, 0xd3, 0xcc, 0x5f, 0xd7, 0x8a, 0x57, 0x4c, 0x01, 0x44, 0xc4,
+ 0x7b, 0xc3, 0xef, 0x12, 0x7f, 0x46, 0xa1, 0x95, 0x78, 0xaf, 0xe5, 0xb3, 0xc2, 0xc4, 0x2d, 0xec,
+ 0xdd, 0x65, 0xb8, 0x70, 0x79, 0x88, 0x37, 0xaf, 0x6e, 0xe1, 0x5a, 0x36, 0x42, 0x6a, 0x7b, 0xa4,
+ 0x23, 0x23, 0xc3, 0x2c, 0xb2, 0x95, 0x3f, 0x77, 0x86, 0x39, 0xfb, 0xde, 0x6d, 0x5a, 0x97, 0xba,
+ 0x88, 0x48, 0x79, 0x0a, 0x2c, 0x83, 0xdf, 0x49, 0xd6, 0xbe, 0x88, 0x95, 0x7b, 0xcc, 0x6e, 0x95,
+ 0xfa, 0x7f, 0x72, 0xd3, 0xc1, 0x23, 0xef, 0xf8, 0x44, 0x4f, 0x85, 0xdb, 0xd2, 0xe6, 0x46, 0x3a,
+ 0x4e, 0xd2, 0x1a, 0x62, 0xa4, 0x3d, 0xc4, 0x7f, 0x00, 0x62, 0xa3, 0x30, 0x17, 0xd8, 0xe5, 0x5f,
+ 0x89, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
+#endif
#include "asset.h"
#include "bccmodels.h"
+#include "bchash.h"
#include "fileffmpeg.h"
#include "file.h"
#include "ffmpeg.h"
frame_rate = 0;
aspect_ratio = 0;
length = 0;
- convert_ctx = 0;
}
FFVideoStream::~FFVideoStream()
{
- if( convert_ctx ) sws_freeContext(convert_ctx);
}
int FFVideoStream::decode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame)
return ret;
}
-PixelFormat FFVideoStream::color_model_to_pix_fmt(int color_model)
+PixelFormat FFVideoConvert::color_model_to_pix_fmt(int color_model)
{
switch( color_model ) {
case BC_YUV422: return AV_PIX_FMT_YUYV422;
return AV_PIX_FMT_NB;
}
-int FFVideoStream::pix_fmt_to_color_model(PixelFormat pix_fmt)
+int FFVideoConvert::pix_fmt_to_color_model(PixelFormat pix_fmt)
{
switch (pix_fmt) {
case AV_PIX_FMT_YUYV422: return BC_YUV422;
return BC_TRANSPARENCY;
}
-int FFVideoStream::convert_picture_vframe(VFrame *frame,
+int FFVideoConvert::convert_picture_vframe(VFrame *frame,
AVPicture *ip, PixelFormat ifmt, int iw, int ih)
{
AVPicture opic;
convert_ctx = sws_getCachedContext(convert_ctx, iw, ih, ifmt,
frame->get_w(), frame->get_h(), ofmt, SWS_BICUBIC, NULL, NULL, NULL);
if( !convert_ctx ) {
- fprintf(stderr, "FFVideoStream::convert_picture_frame:"
+ fprintf(stderr, "FFVideoConvert::convert_picture_frame:"
" sws_getCachedContext() failed\n");
- return 1;
+ return -1;
}
int ret = sws_scale(convert_ctx, ip->data, ip->linesize, 0, ih,
opic.data, opic.linesize);
if( ret < 0 ) {
- ff_err(ret, "FFVideoStream::convert_picture_frame: sws_scale() failed\n");
- return 1;
+ ff_err(ret, "FFVideoConvert::convert_picture_frame: sws_scale() failed\n");
+ return -1;
}
return 0;
}
-int FFVideoStream::convert_cmodel(VFrame *frame,
+int FFVideoConvert::convert_cmodel(VFrame *frame,
AVPicture *ip, PixelFormat ifmt, int iw, int ih)
{
// try direct transfer
return 1;
}
-int FFVideoStream::convert_vframe_picture(VFrame *frame,
+int FFVideoConvert::transfer_cmodel(VFrame *frame,
+ AVFrame *ifp, PixelFormat ifmt, int iw, int ih)
+{
+ int ret = convert_cmodel(frame, (AVPicture *)ifp, ifmt, iw, ih);
+ if( ret > 0 ) {
+ const AVDictionary *src = av_frame_get_metadata(ifp);
+ AVDictionaryEntry *t = NULL;
+ BC_Hash *hp = frame->get_params();
+ //hp->clear();
+ while( (t=av_dict_get(src, "", t, AV_DICT_IGNORE_SUFFIX)) )
+ hp->update(t->key, t->value);
+ }
+ return ret;
+}
+
+int FFVideoConvert::convert_vframe_picture(VFrame *frame,
AVPicture *op, PixelFormat ofmt, int ow, int oh)
{
AVPicture opic;
convert_ctx = sws_getCachedContext(convert_ctx, frame->get_w(), frame->get_h(), ifmt,
ow, oh, ofmt, SWS_BICUBIC, NULL, NULL, NULL);
if( !convert_ctx ) {
- fprintf(stderr, "FFVideoStream::convert_frame_picture:"
+ fprintf(stderr, "FFVideoConvert::convert_frame_picture:"
" sws_getCachedContext() failed\n");
- return 1;
+ return -1;
}
int ret = sws_scale(convert_ctx, opic.data, opic.linesize, 0, frame->get_h(),
op->data, op->linesize);
if( ret < 0 ) {
- ff_err(ret, "FFVideoStream::convert_frame_picture: sws_scale() failed\n");
- return 1;
+ ff_err(ret, "FFVideoConvert::convert_frame_picture: sws_scale() failed\n");
+ return -1;
}
return 0;
}
-int FFVideoStream::convert_pixfmt(VFrame *frame,
+int FFVideoConvert::convert_pixfmt(VFrame *frame,
AVPicture *op, PixelFormat ofmt, int ow, int oh)
{
// try direct transfer
- if( !convert_vframe_picture(frame, op, ofmt, ow, oh) ) return 0;
+ if( !convert_vframe_picture(frame, op, ofmt, ow, oh) ) return 1;
// use indirect transfer
int colormodel = frame->get_color_model();
int bits = BC_CModels::calculate_pixelsize(colormodel) * 8;
(bits > 8 ? BC_RGB161616: BC_RGB888) ;
VFrame vframe(frame->get_w(), frame->get_h(), icolor_model);
vframe.transfer_from(frame);
- if( convert_vframe_picture(&vframe, op, ofmt, ow, oh) ) return 1;
- return 0;
+ if( !convert_vframe_picture(&vframe, op, ofmt, ow, oh) ) return 1;
+ return -1;
+}
+
+int FFVideoConvert::transfer_pixfmt(VFrame *frame,
+ AVFrame *ofp, PixelFormat ofmt, int ow, int oh)
+{
+ int ret = convert_pixfmt(frame, (AVPicture *)ofp, ofmt, ow, oh);
+ if( ret > 0 ) {
+ BC_Hash *hp = frame->get_params();
+ AVDictionary **dict = avpriv_frame_get_metadatap(ofp);
+ //av_dict_free(dict);
+ for( int i=0; i<hp->size(); ++i ) {
+ char *key = hp->get_key(i), *val = hp->get_value(i);
+ av_dict_set(dict, key, val, 0);
+ }
+ }
+ return ret;
}
void FFVideoStream::load_markers()
snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
src_ctx->width, src_ctx->height, src_ctx->pix_fmt,
- st->time_base.num, st->time_base.den,
+ src_ctx->time_base.num, src_ctx->time_base.den,
src_ctx->sample_aspect_ratio.num, src_ctx->sample_aspect_ratio.den);
if( ret >= 0 )
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
int ret = 0; char args[BCTEXTLEN];
snprintf(args, sizeof(args),
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%jx",
- st->time_base.num, st->time_base.den, src_ctx->sample_rate,
+ src_ctx->time_base.num, src_ctx->time_base.den, src_ctx->sample_rate,
av_get_sample_fmt_name(src_ctx->sample_fmt), src_ctx->channel_layout);
if( ret >= 0 )
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
float *aud_bfr;
};
-class FFVideoStream : public FFStream {
+
+class FFVideoConvert {
+public:
+ struct SwsContext *convert_ctx;
+
+ FFVideoConvert() { convert_ctx = 0; }
+ ~FFVideoConvert() { if( convert_ctx ) sws_freeContext(convert_ctx); }
+
+ static PixelFormat color_model_to_pix_fmt(int color_model);
+ static int pix_fmt_to_color_model(PixelFormat pix_fmt);
+
+ int convert_picture_vframe(VFrame *frame,
+ AVPicture *ip, PixelFormat ifmt, int iw, int ih);
+ int convert_cmodel(VFrame *frame_out,
+ AVPicture *ip, PixelFormat ifmt, int iw, int ih);
+ int transfer_cmodel(VFrame *frame_in, //defaults->metadata
+ AVFrame *ifp, PixelFormat ifmt, int iw, int ih);
+ int convert_vframe_picture(VFrame *frame,
+ AVPicture *op, PixelFormat ofmt, int ow, int oh);
+ int convert_pixfmt(VFrame *frame_in,
+ AVPicture *op, PixelFormat ofmt, int ow, int oh);
+ int transfer_pixfmt(VFrame *frame_in, //metadata->defaults
+ AVFrame *ofp, PixelFormat ofmt, int ow, int oh);
+};
+
+class FFVideoStream : public FFStream, public FFVideoConvert {
public:
FFVideoStream(FFMPEG *ffmpeg, AVStream *strm, int idx, int fidx);
virtual ~FFVideoStream();
int64_t length;
float aspect_ratio;
- struct SwsContext *convert_ctx;
uint8_t *pkt_bfr;
int pkt_bfr_sz;
int64_t start_pts;
-
- static PixelFormat color_model_to_pix_fmt(int color_model);
- static int pix_fmt_to_color_model(PixelFormat pix_fmt);
-
- int convert_picture_vframe(VFrame *frame,
- AVPicture *ip, PixelFormat ifmt, int iw, int ih);
- int convert_cmodel(VFrame *frame_out,
- AVPicture *ip, PixelFormat ifmt, int iw, int ih);
- int convert_vframe_picture(VFrame *frame,
- AVPicture *op, PixelFormat ofmt, int ow, int oh);
- int convert_pixfmt(VFrame *frame_in,
- AVPicture *op, PixelFormat ofmt, int ow, int oh);
};
class FFMPEG : public Thread {
file->get_audio_position() : AV_NOPTS_VALUE ;
int got_packet = 0;
ret = avcodec_encode_audio2(avctx, &avpkt, frame, &got_packet);
- if( !ret ) {
- fprintf(stderr, "avcodec_encode_audio2 failed. \n%m\n");
+ if( ret < 0 ) {
+ char errmsg[BCSTRLEN];
+ av_strerror(ret, errmsg, sizeof(errmsg));
+ fprintf(stderr, "avcodec_encode_audio2 failed. \n%s\n", errmsg);
}
}
av_packet_free_side_data(&avpkt);
index_version != PLUGIN_FILE_VERSION ) ret = 1;
while( !ret && !feof(fp)) {
- char *sp = index_line, *plugin_path = 0, *plugin_title = 0;
- if( fgets(sp, BCTEXTLEN, fp) ) {
- plugin_path = PluginServer::table_quoted_field(sp);
- if( plugin_exists(plugin_path) ) continue;
- plugin_title = PluginServer::table_quoted_field(sp);
+ if( !fgets(index_line, BCTEXTLEN, fp) ) break;
+ if( index_line[0] == ';' ) continue;
+ if( index_line[0] == '#' ) continue;
+ int type = PLUGIN_TYPE_UNKNOWN;
+ char path[BCTEXTLEN], title[BCTEXTLEN];
+ if( PluginServer::scan_table(index_line, type, path, title) ) continue;
+ PluginServer *server = 0;
+ switch( type ) {
+ case PLUGIN_TYPE_BUILTIN:
+ case PLUGIN_TYPE_LADSPA:
+ server = new PluginServer(mwindow, path, type);
+ break;
+ case PLUGIN_TYPE_FFMPEG: // skip "ff_..."
+ server = new_ffmpeg_server(mwindow, path+3);
+ break;
}
- if( plugin_path && plugin_title ) {
+ if( !server ) continue;
// Create plugin server from index entry
- PluginServer *new_plugin = new PluginServer(path, mwindow);
- new_plugin->set_path(plugin_path);
- new_plugin->set_title(plugin_title);
- if( new_plugin->read_table(sp) ) {
- delete new_plugin;
- ret = 1; break;
- }
- plugindb->append(new_plugin);
+ server->set_title(title);
+ if( server->read_table(index_line) ) {
+ delete server;
+ ret = 1; break;
}
+ plugindb->append(server);
}
fclose(fp);
fs.set_filter( "[*.plugin][*.so]" );
int result = fs.update(plugin_path);
if( result || !fs.dir_list.total ) return;
- int vis_id = ++idx;
+ int vis_id = idx++;
for( int i=0; i<fs.dir_list.total; ++i ) {
char *fs_path = fs.dir_list.values[i]->path;
continue;
}
if( plugin_exists(plugin_path) ) continue;
- PluginServer *new_plugin = new PluginServer(plugin_path, mwindow);
- result = new_plugin->open_plugin(1, preferences, 0, 0);
+ PluginServer *server = new PluginServer(mwindow, plugin_path, PLUGIN_TYPE_UNKNOWN);
+ result = server->open_plugin(1, preferences, 0, 0);
if( !result ) {
- new_plugin->write_table(fp,vis_id);
- new_plugin->close_plugin();
- new_plugin->delete_this();
+ server->write_table(fp,vis_id);
+ server->close_plugin();
+ server->delete_this();
continue;
}
if( result != PLUGINSERVER_IS_LAD ) continue;
int lad_index = 0;
for(;;) {
- PluginServer *new_plugin = new PluginServer(plugin_path, mwindow);
- new_plugin->set_lad_index(lad_index++);
- result = new_plugin->open_plugin(1, preferences, 0, 0);
+ PluginServer *server = new PluginServer(mwindow, plugin_path, PLUGIN_TYPE_LADSPA);
+ server->set_lad_index(lad_index++);
+ result = server->open_plugin(1, preferences, 0, 0);
if( result ) break;
- new_plugin->write_table(fp,vis_id);
- new_plugin->close_plugin();
- new_plugin->delete_this();
+ server->write_table(fp, PLUGIN_LADSPA_ID);
+ server->close_plugin();
+ server->delete_this();
}
}
}
int MWindow::init_plugins(MWindow *mwindow, Preferences *preferences)
{
+ init_ffmpeg();
if( !plugindb ) plugindb = new ArrayList<PluginServer*>;
char index_path[BCTEXTLEN];
sprintf(index_path, "%s/%s", preferences->plugin_dir, PLUGIN_FILE);
}
fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
char *plug_path = FileSystem::basepath(preferences->plugin_dir);
- int dir_id = 0;
+ int dir_id = PLUGIN_IDS;
init_plugin_index(mwindow, preferences, fp, plug_path, ".", dir_id);
+ init_ffmpeg_index(mwindow, preferences, fp);
fclose(fp);
delete [] plug_path;
return load_plugin_index(mwindow, index_path);
if( !plugindb ) return;
for(int i = 0; i < plugindb->total; i++)
{
- fprintf(fp, "audio=%d video=%d rt=%d multi=%d"
+ fprintf(fp, "type=%d audio=%d video=%d rt=%d multi=%d"
" synth=%d transition=%d theme=%d %s\n",
+ plugindb->values[i]->plugin_type,
plugindb->values[i]->audio,
plugindb->values[i]->video,
plugindb->values[i]->realtime,
// Pointer comparison
plugin_guis->values[i]->save_defaults();
}
+ awindow->save_defaults(defaults);
defaults->save();
return 0;
#include "playback3d.inc"
#include "playbackengine.inc"
#include "plugin.inc"
+#include "pluginfclient.inc"
#include "pluginserver.inc"
#include "pluginset.inc"
#include "preferences.inc"
// Contains file descriptors for all the dlopens
static ArrayList<PluginServer*> *plugindb;
// Currently visible plugins
+ int64_t plugin_visibility;
ArrayList<PluginServer*> *plugin_guis;
// GUI Plugins to delete
ArrayList<PluginServer*> *dead_plugins;
// Keyframe editors
ArrayList<KeyFrameThread*> *keyframe_threads;
-
// Adjust sample position to line up with frames.
int fix_timing(int64_t &samples_out,
int64_t &frames_out,
static int init_plugins(MWindow *mwindow, Preferences *preferences);
static void init_plugin_index(MWindow *mwindow, Preferences *preferences,
FILE *fp, const char *plug_dir, const char *plug_path, int &dir_id);
+ static void init_ffmpeg();
+ static void init_ffmpeg_index(MWindow *mwindow, Preferences *preferences, FILE *fp);
static int load_plugin_index(MWindow *mwindow, char *path);
+ static PluginServer* new_ffmpeg_server(MWindow *mwindow, const char *name);
void init_preferences();
void init_signals();
void init_theme();
#define PRESETS_FILE "Cinelerra_presets"
#define PICTURE_FILE "Cinelerra_picture"
#define PLUGIN_FILE "Cinelerra_plugins"
-#define PLUGIN_FILE_VERSION 1
+#define PLUGIN_FILE_VERSION 2
// Behavior of region selections
#define SELECTION_SAMPLES 0
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "bcwindowbase.h"
+#include "bctitle.h"
+#include "cstrdup.h"
+#include "language.h"
+#include "mwindow.h"
+#include "pluginfclient.h"
+#include "pluginserver.h"
+#include "samples.h"
+#include "vframe.h"
+#include "filexml.h"
+
+
+static void ff_err(int ret, const char *fmt, ...)
+{
+ char msg[BCTEXTLEN];
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof(msg), fmt, ap);
+ va_end(ap);
+ char errmsg[BCSTRLEN];
+ av_strerror(ret, errmsg, sizeof(errmsg));
+ fprintf(stderr,_("%s err: %s\n"),msg, errmsg);
+}
+
+PluginFClientConfig::PluginFClientConfig()
+{
+ ffilt = 0;
+}
+
+PluginFClientConfig::~PluginFClientConfig()
+{
+ delete ffilt;
+ remove_all_objects();
+}
+
+int PluginFClientConfig::equivalent(PluginFClientConfig &that)
+{
+ PluginFClientConfig &conf = *this;
+ for( int i=0; i<that.size(); ++i ) {
+ PluginFClient_Opt *topt = conf[i], *vopt = that[i];
+ char tval[BCTEXTLEN], *tp = topt->get(tval, sizeof(tval));
+ char vval[BCTEXTLEN], *vp = vopt->get(vval, sizeof(vval));
+ int ret = tp && vp ? strcmp(tp, vp) : tp || vp ? 1 : 0;
+ if( ret ) return 0;
+ }
+ return 1;
+}
+
+void PluginFClientConfig::copy_from(PluginFClientConfig &that)
+{
+ PluginFClientConfig &conf = *this;
+ for( int i=0; i<that.size(); ++i ) {
+ PluginFClient_Opt *vp = that[i];
+ const char *nm = vp->opt->name;
+ int k = size();
+ while( --k >= 0 && strcmp(nm, conf[k]->opt->name) );
+ if( k < 0 ) continue;
+ PluginFClient_Opt *fopt = conf[k];
+ char str[BCTEXTLEN], *sp = vp->get(str, sizeof(str));
+ if( sp ) fopt->set(sp);
+ }
+}
+
+void PluginFClientConfig::interpolate(PluginFClientConfig &prev, PluginFClientConfig &next,
+ int64_t prev_frame, int64_t next_frame, int64_t current_frame)
+{
+ copy_from(prev);
+}
+
+void PluginFClientConfig::initialize(const char *name)
+{
+ ffilt = PluginFFilter::new_ffilter(name);
+ const AVOption *opt = 0;
+ void *obj = ffilt->filter_config();
+
+ const AVClass *filt_class = ffilt->filter_class();
+ if( filt_class && filt_class->option ) {
+ PluginFClientConfig &conf = *this;
+ while( (opt=av_opt_next(obj, opt)) != 0 ) {
+ if( opt->type == AV_OPT_TYPE_CONST ) continue;
+ int dupl = 0;
+ for( int i=0; !dupl && i<size(); ++i ) {
+ PluginFClient_Opt *fp = conf[i];
+ const AVOption *op = fp->opt;
+ if( op->offset != opt->offset ) continue;
+ if( op->type != opt->type ) continue;
+ dupl = 1;
+ if( strlen(op->name) < strlen(opt->name) )
+ fp->opt = opt;
+ }
+ if( dupl ) continue;
+ PluginFClient_Opt *fopt = new PluginFClient_Opt(this, opt);
+ append(fopt);
+ }
+ }
+}
+
+int PluginFClientConfig::update()
+{
+ int ret = 0;
+ PluginFClientConfig &conf = *this;
+
+ for( int i=0; i<size(); ++i ) {
+ PluginFClient_Opt *fopt = conf[i];
+ char val[BCTEXTLEN], *vp = fopt->get(val, sizeof(val));
+ if( !vp || !strcmp(val, fopt->item_value->get_text()) ) continue;
+ fopt->item_value->update();
+ ++ret;
+ }
+ return ret;
+}
+
+void PluginFClientConfig::dump(FILE *fp)
+{
+ const AVOption *opt = 0;
+ const AVClass *obj = filter_class();
+ PluginFClientConfig &conf = *this;
+
+ while( (opt=av_opt_next(&obj, opt)) != 0 ) {
+ if( opt->type == AV_OPT_TYPE_CONST ) continue;
+ int k = size();
+ while( --k >= 0 && strcmp(opt->name, conf[k]->opt->name) );
+ if( k < 0 ) continue;
+ PluginFClient_Opt *fopt = conf[k];
+ char val[BCTEXTLEN], *vp = fopt->get(val,sizeof(val));
+ fprintf(fp, " %s:=%s", opt->name, vp);
+ if( opt->unit ) {
+ char unt[BCTEXTLEN], *up = unt;
+ fopt->units(up);
+ fprintf(fp, "%s", unt);
+ }
+ fprintf(fp, "\n");
+ }
+}
+
+PluginFClientReset::
+PluginFClientReset(PluginFClientWindow *fwin, int x, int y)
+ : BC_GenericButton(x, y, _("Reset"))
+{
+ this->fwin = fwin;
+}
+
+PluginFClientReset::
+~PluginFClientReset()
+{
+}
+
+int PluginFClientReset::handle_event()
+{
+ av_opt_set_defaults(fwin->ffmpeg->config.filter_config());
+ if( fwin->ffmpeg->config.update() > 0 )
+ fwin->draw();
+ fwin->ffmpeg->plugin->send_configure_change();
+ return 1;
+}
+
+PluginFClientText::
+PluginFClientText(PluginFClientWindow *fwin, int x, int y, int w)
+ : BC_TextBox(x, y, w, 1, (char *)"")
+{
+ this->fwin = fwin;
+}
+
+PluginFClientText::
+~PluginFClientText()
+{
+}
+
+int PluginFClientText::handle_event()
+{
+ return 0;
+}
+
+PluginFClientUnits::
+PluginFClientUnits(PluginFClientWindow *fwin, int x, int y, int w)
+ : BC_PopupMenu(x, y, w, "")
+{
+ this->fwin = fwin;
+}
+
+PluginFClientUnits::
+~PluginFClientUnits()
+{
+}
+
+int PluginFClientUnits::handle_event()
+{
+ const char *text = get_text();
+ if( text && fwin->selected ) {
+ if( text ) fwin->selected->set(text);
+ fwin->selected->item_value->update();
+ fwin->draw();
+ fwin->ffmpeg->plugin->send_configure_change();
+ }
+ return 1;
+}
+
+PluginFClientApply::
+PluginFClientApply(PluginFClientWindow *fwin, int x, int y)
+ : BC_GenericButton(x, y, _("Apply"))
+{
+ this->fwin = fwin;
+}
+
+PluginFClientApply::
+~PluginFClientApply()
+{
+}
+
+int PluginFClientApply::handle_event()
+{
+ const char *text = fwin->text->get_text();
+ if( text && fwin->selected ) {
+ fwin->selected->set(text);
+ fwin->selected->item_value->update();
+ fwin->draw();
+ fwin->ffmpeg->plugin->send_configure_change();
+ }
+ return 1;
+}
+
+
+PluginFClient_OptPanel::
+PluginFClient_OptPanel(PluginFClientWindow *fwin, int x, int y, int w, int h)
+ : BC_ListBox(x, y, w, h, LISTBOX_TEXT), opts(items[0]), vals(items[1])
+{
+ this->fwin = fwin;
+ update(); // init col/wid/columns
+}
+
+PluginFClient_OptPanel::
+~PluginFClient_OptPanel()
+{
+}
+
+void PluginFClient_OptPanel::create_objects()
+{
+ PluginFClientConfig &fconfig = fwin->ffmpeg->config;
+ for( int i=0; i<fconfig.size(); ++i ) {
+ PluginFClient_Opt *opt = fconfig[i];
+ opts.append(opt->item_name);
+ vals.append(opt->item_value);
+ }
+}
+
+int PluginFClient_OptPanel::cursor_leave_event()
+{
+ hide_tooltip();
+ return 0;
+}
+
+void PluginFClientWindow::update(PluginFClient_Opt *opt)
+{
+ if( selected != opt ) {
+ if( selected ) selected->item_name->set_selected(0);
+ selected = opt;
+ if( selected ) selected->item_name->set_selected(1);
+ }
+ clear_box(0,0, 0,panel->get_y());
+ char str[BCTEXTLEN], *sp;
+ *(sp=str) = 0;
+ if( opt ) opt->types(sp);
+ type->update(str);
+ *(sp=str) = 0;
+ if( opt ) opt->ranges(sp);
+ range->update(str);
+ while( units->total_items() ) units->remove_item(0);
+ ArrayList<const AVOption *> opts;
+ int n = !opt ? 0 : opt->units(opts);
+ for( int i=0; i<n; ++i )
+ units->add_item(new BC_MenuItem(opts[i]->name, 0));
+ char unit[BCSTRLEN]; strcpy(unit, "()");
+ if( units->total_items() && opt && opt->opt->unit )
+ strcpy(unit, opt->opt->unit);
+ units->set_text(unit);
+ char val[BCTEXTLEN]; val[0] = 0;
+ if( opt ) opt->get(val, sizeof(val));
+ text->update(val);
+
+ panel->update();
+}
+
+int PluginFClient_OptPanel::selection_changed()
+{
+ PluginFClient_Opt *opt = 0;
+ BC_ListBoxItem *item = get_selection(0, 0);
+ if( item ) {
+ PluginFClient_OptName *opt_name = (PluginFClient_OptName *)item;
+ opt = opt_name->opt;
+ }
+ fwin->update(opt);
+ fwin->panel->set_tooltip(!opt ? 0 : opt->tip());
+ fwin->panel->show_tooltip();
+ return 1;
+}
+
+void *PluginFClient_Opt::filter_config()
+{
+ return conf->filter_config();
+}
+const AVClass *PluginFClient_Opt::filter_class()
+{
+ return conf->filter_class();
+}
+
+int PluginFClient_Opt::types(char *rp)
+{
+ const char *cp;
+ switch (opt->type) {
+ case AV_OPT_TYPE_FLAGS: cp = "<flags>"; break;
+ case AV_OPT_TYPE_INT: cp = "<int>"; break;
+ case AV_OPT_TYPE_INT64: cp = "<int64>"; break;
+ case AV_OPT_TYPE_DOUBLE: cp = "<double>"; break;
+ case AV_OPT_TYPE_FLOAT: cp = "<float>"; break;
+ case AV_OPT_TYPE_STRING: cp = "<string>"; break;
+ case AV_OPT_TYPE_RATIONAL: cp = "<rational>"; break;
+ case AV_OPT_TYPE_BINARY: cp = "<binary>"; break;
+ case AV_OPT_TYPE_IMAGE_SIZE: cp = "<image_size>"; break;
+ case AV_OPT_TYPE_VIDEO_RATE: cp = "<video_rate>"; break;
+ case AV_OPT_TYPE_PIXEL_FMT: cp = "<pix_fmt>"; break;
+ case AV_OPT_TYPE_SAMPLE_FMT: cp = "<sample_fmt>"; break;
+ case AV_OPT_TYPE_DURATION: cp = "<duration>"; break;
+ case AV_OPT_TYPE_COLOR: cp = "<color>"; break;
+ case AV_OPT_TYPE_CHANNEL_LAYOUT: cp = "<channel_layout>"; break;
+ default: cp = "<undef>"; break;
+ }
+ return sprintf(rp, "%s", cp);
+}
+int PluginFClient_Opt::scalar(double d, char *rp)
+{
+ const char *cp = 0;
+ if( d == INT_MAX ) cp = "INT_MAX";
+ else if( d == INT_MIN ) cp = "INT_MIN";
+ else if( d == UINT32_MAX ) cp = "UINT32_MAX";
+ else if( d == (double)INT64_MAX ) cp = "I64_MAX";
+ else if( d == INT64_MIN ) cp = "I64_MIN";
+ else if( d == FLT_MAX ) cp = "FLT_MAX";
+ else if( d == FLT_MIN ) cp = "FLT_MIN";
+ else if( d == -FLT_MAX ) cp = "-FLT_MAX";
+ else if( d == -FLT_MIN ) cp = "-FLT_MIN";
+ else if( d == DBL_MAX ) cp = "DBL_MAX";
+ else if( d == DBL_MIN ) cp = "DBL_MIN";
+ else if( d == -DBL_MAX ) cp = "-DBL_MAX";
+ else if( d == -DBL_MIN ) cp = "-DBL_MIN";
+ else if( d == 0 ) cp = signbit(d) ? "-0" : "0";
+ else if( isnan(d) ) cp = signbit(d) ? "-NAN" : "NAN";
+ else if( isinf(d) ) cp = signbit(d) ? "-INF" : "INF";
+ else return sprintf(rp, "%g", d);
+ return sprintf(rp, "%s", cp);
+}
+
+int PluginFClient_Opt::ranges(char *rp)
+{
+ const AVClass *filt_class = filter_class();
+ if( !filt_class || !filt_class->option ) return 0;
+ switch (opt->type) {
+ case AV_OPT_TYPE_INT:
+ case AV_OPT_TYPE_INT64:
+ case AV_OPT_TYPE_DOUBLE:
+ case AV_OPT_TYPE_FLOAT: break;
+ default: return 0;;
+ }
+ AVOptionRanges *r = 0;
+ void *obj = &filt_class;
+ char *cp = rp;
+ if( av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) < 0 ) return 0;
+ for( int i=0; i<r->nb_ranges; ++i ) {
+ cp += sprintf(cp, " ("); cp += scalar(r->range[i]->value_min, cp);
+ cp += sprintf(cp, ".."); cp += scalar(r->range[i]->value_max, cp);
+ cp += sprintf(cp, ")");
+ }
+ av_opt_freep_ranges(&r);
+ return cp - rp;
+}
+
+int PluginFClient_Opt::units(ArrayList<const AVOption *> &opts)
+{
+ if( !this->opt->unit ) return 0;
+ const AVClass *filt_class = filter_class();
+ if( !filt_class || !filt_class->option ) return 0;
+ void *obj = &filt_class;
+ const AVOption *opt = NULL;
+ while( (opt=av_opt_next(obj, opt)) != 0 ) {
+ if( !opt->unit ) continue;
+ if( opt->type != AV_OPT_TYPE_CONST ) continue;
+ if( strcmp(this->opt->unit, opt->unit) ) continue;
+ int i = opts.size();
+ while( --i >= 0 ) {
+ if( opts[i]->default_val.i64 != opt->default_val.i64 ) continue;
+ if( strlen(opts[i]->name) < strlen(opt->name) ) opts[i] = opt;
+ break;
+ }
+ if( i < 0 )
+ opts.append(opt);
+ }
+ return opts.size();
+}
+
+int PluginFClient_Opt::units(char *rp)
+{
+ ArrayList<const AVOption *> opts;
+ int n = units(opts);
+ if( !n ) return 0;
+ char *cp = rp;
+ cp += sprintf(cp, " [%s:", this->opt->unit);
+ for( int i=0; i<n; ++i )
+ cp += sprintf(cp, " %s", opts[i]->name);
+ cp += sprintf(cp, "]:");
+ return cp - rp;
+}
+
+const char *PluginFClient_Opt::tip()
+{
+ return opt->help;
+}
+
+int PluginFClient_OptPanel::update()
+{
+ const char *cols[] = { "option", "value", };
+ const int col1_w = 150;
+ int wids[] = { col1_w, get_w()-col1_w };
+ BC_ListBox::update(&items[0], &cols[0], &wids[0], sizeof(items)/sizeof(items[0]));
+ return 0;
+}
+
+
+PluginFClientWindow::PluginFClientWindow(PluginFClient *ffmpeg)
+ : PluginClientWindow(ffmpeg->plugin, 600, 300, 600, 300, 1)
+{
+ this->ffmpeg = ffmpeg;
+ this->selected = 0;
+}
+
+PluginFClientWindow::~PluginFClientWindow()
+{
+}
+
+void PluginFClientWindow::create_objects()
+{
+ char string[BCTEXTLEN];
+ BC_Title *title;
+ int x = 10, y = 10;
+ const char *descr = ffmpeg->config.ffilt->description();
+ if( !descr ) descr = ffmpeg->config.ffilt->filter_name();
+ add_subwindow(title = new BC_Title(x, y, descr));
+ y += title->get_h() + 10;
+ int x0 = x;
+ sprintf(string, _("Type: "));
+ add_subwindow(title = new BC_Title(x0, y, string));
+ x0 += title->get_w() + 8;
+ add_subwindow(type = new BC_Title(x0, y, (char *)""));
+ x0 = x + 150;
+ sprintf(string, _("Range: "));
+ add_subwindow(title = new BC_Title(x0, y, string));
+ x0 += title->get_w() + 8;
+ add_subwindow(range = new BC_Title(x0, y, (char *)""));
+ int x1 = get_w() - BC_GenericButton::calculate_w(this, _("Reset")) - 8;
+ add_subwindow(reset = new PluginFClientReset(this, x1, y));
+ y += title->get_h() + 10;
+ x0 = x;
+ add_subwindow(units = new PluginFClientUnits(this, x0, y, 120));
+ x0 += units->get_w() + 8;
+ x1 = get_w() - BC_GenericButton::calculate_w(this, _("Apply")) - 8;
+ add_subwindow(apply = new PluginFClientApply(this, x1, y));
+ add_subwindow(text = new PluginFClientText(this, x0, y, x1-x0 - 8));
+ y += title->get_h() + 10;
+
+ panel_x = x; panel_y = y;
+ panel_w = get_w()-10 - panel_x;
+ panel_h = get_h()-10 - panel_y;
+ panel = new PluginFClient_OptPanel(this, panel_x, panel_y, panel_w, panel_h);
+ add_subwindow(panel);
+ panel->create_objects();
+ ffmpeg->config.update();
+ draw();
+ show_window(1);
+}
+
+void PluginFClientWindow::draw()
+{
+ update(selected);
+}
+
+int PluginFClientWindow::resize_event(int w, int h)
+{
+ int x = get_w() - BC_GenericButton::calculate_w(this, _("Reset")) - 8;
+ int y = reset->get_y();
+ reset->reposition_window(x, y);
+ int x1 = get_w() - BC_GenericButton::calculate_w(this, _("Apply")) - 8;
+ int y1 = units->get_y();
+ apply->reposition_window(x1, y1);
+ int x0 = units->get_x() + units->get_w() + 8;
+ int y0 = units->get_y();
+ text->reposition_window(x0,y0, x1-x0-8);
+ panel_w = get_w()-10 - panel_x;
+ panel_h = get_h()-10 - panel_y;
+ panel->reposition_window(panel_x,panel_y, panel_w, panel_h);
+ return 1;
+}
+
+PluginFClient::PluginFClient(PluginClient *plugin, const char *name)
+{
+ this->plugin = plugin;
+ this->name = name;
+ ffilt = 0;
+ fsrc = fsink = 0;
+ plugin_position = -1;
+ filter_position = -1;
+ activated = 0;
+ sprintf(title, "F_%s", name);
+ config.initialize(name);
+ curr_config.initialize(name);
+}
+
+PluginFClient::~PluginFClient()
+{
+}
+
+bool PluginFClient::is_audio(AVFilter *fp)
+{
+ if( !fp->outputs ) return 0;
+ if( avfilter_pad_count(fp->outputs) > 1 ) return 0;
+ if( !avfilter_pad_get_name(fp->outputs, 0) ) return 0;
+ if( avfilter_pad_get_type(fp->outputs, 0) != AVMEDIA_TYPE_AUDIO ) return 0;
+ if( !fp->inputs ) return 1;
+ if( avfilter_pad_count(fp->inputs) > 1 ) return 0;
+ if( !avfilter_pad_get_name(fp->inputs, 0) ) return 0;
+ if( avfilter_pad_get_type(fp->inputs, 0) != AVMEDIA_TYPE_AUDIO ) return 0;
+ return 1;
+}
+bool PluginFClient::is_video(AVFilter *fp)
+{
+ if( !fp->outputs ) return 0;
+ if( avfilter_pad_count(fp->outputs) > 1 ) return 0;
+ if( !avfilter_pad_get_name(fp->outputs, 0) ) return 0;
+ if( avfilter_pad_get_type(fp->outputs, 0) != AVMEDIA_TYPE_VIDEO ) return 0;
+ if( !fp->inputs ) return 1;
+ if( avfilter_pad_count(fp->inputs) > 1 ) return 0;
+ if( !avfilter_pad_get_name(fp->inputs, 0) ) return 0;
+ if( avfilter_pad_get_type(fp->inputs, 0) != AVMEDIA_TYPE_VIDEO ) return 0;
+ return 1;
+}
+
+NEW_WINDOW_MACRO(PluginFClient, PluginFClientWindow)
+
+int PluginFClient::load_configuration()
+{
+ int64_t src_position = get_source_position();
+ KeyFrame *prev_keyframe = get_prev_keyframe(src_position);
+ config.copy_from(curr_config);
+ read_data(prev_keyframe);
+ int ret = !config.equivalent(curr_config) ? 1 : 0;
+ return ret;
+}
+
+
+void PluginFClient::render_gui(void *data, int size)
+{
+ PluginFClientConfig *conf = (PluginFClientConfig *)data;
+ config.copy_from(*conf);
+ KeyFrame *keyframe = plugin->server->get_keyframe();
+ save_data(keyframe);
+ update_gui();
+}
+
+void PluginFClient::update_gui()
+{
+ PluginClientThread *thread = plugin->get_thread();
+ if( !thread ) return;
+ PluginFClientWindow *window = (PluginFClientWindow*)thread->get_window();
+ window->lock_window("PluginFClient::update_gui");
+ load_configuration();
+ if( config.update() > 0 )
+ window->draw();
+ window->unlock_window();
+}
+
+const char *PluginFClient::plugin_title()
+{
+ return title;
+}
+
+char *PluginFClient::to_upper(char *cp, const char *sp)
+{
+ char *bp = cp;
+ while( *sp != 0 ) *bp++ = toupper(*sp++);
+ *bp = 0;
+ return cp;
+}
+
+void PluginFClient::save_data(KeyFrame *keyframe)
+{
+ FileXML output;
+ char string[BCTEXTLEN];
+
+// cause data to be stored directly in text
+ output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
+ output.tag.set_title(to_upper(string, plugin_title()));
+ const AVClass *filt_class = config.filter_class();
+ if( filt_class && filt_class->option ) {
+ void *obj = config.filter_config();
+ const AVOption *opt = NULL;
+ while( (opt=av_opt_next(obj, opt)) != 0 ) {
+ uint8_t *buf = 0;
+ if( av_opt_get(obj, opt->name, 0, &buf) < 0 ) continue;
+ output.tag.set_property(opt->name, (const char *)buf);
+ av_freep(&buf);
+ }
+ }
+
+ output.append_tag();
+ output.terminate_string();
+}
+
+void PluginFClient::read_data(KeyFrame *keyframe)
+{
+ FileXML input;
+ char string[BCTEXTLEN], value[BCTEXTLEN];
+ input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+
+ while( !input.read_tag() ) {
+ to_upper(string, plugin_title());
+ if( !input.tag.title_is(string) ) continue;
+ const AVClass *filt_class = config.filter_class();
+ if( filt_class && filt_class->option ) {
+ void *obj = config.filter_config();
+ const AVOption *opt = NULL;
+ while( (opt=av_opt_next(obj, opt)) != 0 ) {
+ to_upper(string, opt->name);
+ if( !input.tag.get_property(string, value) ) continue;
+ av_opt_set(obj, opt->name, value, 0);
+ }
+ }
+ }
+}
+
+int PluginFClient::activate()
+{
+ if( fsrc )
+ avfilter_link(fsrc, 0, ffilt->fctx, 0);
+ avfilter_link(ffilt->fctx, 0, fsink, 0);
+ int ret = avfilter_graph_config(ffilt->graph, NULL);
+ if( ret >= 0 ) {
+ curr_config.copy_from(config);
+ activated = 1;
+ }
+ return ret;
+}
+
+void PluginFClient::reactivate()
+{
+ delete ffilt; ffilt = 0;
+ activated = 0;
+}
+
+PluginFAClient::PluginFAClient(PluginServer *server, const char *name)
+ : PluginAClient(server), PluginFClient(this, name)
+{
+}
+
+PluginFAClient::~PluginFAClient()
+{
+}
+
+int PluginFAClient::activate()
+{
+ if( activated ) return activated;
+ ffilt = PluginFFilter::new_ffilter(name, &config);
+ if( !ffilt ) {
+ config.copy_from(curr_config);
+ send_configure_change();
+ send_render_gui(&config, sizeof(config));
+ ffilt = PluginFFilter::new_ffilter(name, &config);
+ }
+ AVSampleFormat sample_fmt = AV_SAMPLE_FMT_FLTP;
+ int channels = PluginClient::total_in_buffers;
+ uint64_t layout = (((uint64_t)1)<<channels) - 1;
+ AVFilterGraph *graph = !ffilt ? 0 : ffilt->graph;
+ int ret = !graph ? -1 : 0;
+ if( ret >= 0 && ffilt->filter->inputs ) {
+ char args[BCTEXTLEN];
+ snprintf(args, sizeof(args),
+ "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%jx",
+ 1, sample_rate, sample_rate, av_get_sample_fmt_name(sample_fmt), layout);
+ ret = avfilter_graph_create_filter(&fsrc, avfilter_get_by_name("abuffer"),
+ "in", args, NULL, graph);
+ }
+ if( ret >= 0 )
+ ret = avfilter_graph_create_filter(&fsink, avfilter_get_by_name("abuffersink"),
+ "out", NULL, NULL, graph);
+ if( ret >= 0 )
+ ret = av_opt_set_bin(fsink, "sample_fmts",
+ (uint8_t*)&sample_fmt, sizeof(sample_fmt), AV_OPT_SEARCH_CHILDREN);
+ if( ret >= 0 )
+ ret = av_opt_set_bin(fsink, "channel_layouts",
+ (uint8_t*)&layout, sizeof(layout), AV_OPT_SEARCH_CHILDREN);
+ if( ret >= 0 )
+ ret = av_opt_set_bin(fsink, "sample_rates",
+ (uint8_t*)&sample_rate, sizeof(sample_rate), AV_OPT_SEARCH_CHILDREN);
+ if( ret >= 0 )
+ ret = PluginFClient::activate();
+ if( ret < 0 && activated >= 0 ) {
+ ff_err(ret, "PluginFAClient::activate: %s failed\n", plugin_title());
+ activated = -1;
+ }
+ return activated;
+}
+
+
+static AVRational best_frame_rate(double frame_rate)
+{
+ static const int m1 = 1001*12, m2 = 1000*12;
+ static const int freqs[] = {
+ 40*m1, 48*m1, 50*m1, 60*m1, 80*m1,120*m1, 240*m1,
+ 24*m2, 30*m2, 60*m2, 12*m2, 15*m2, 48*m2, 0,
+ };
+ double max_err = 1.;
+ int freq, best_freq = 0;
+ for( int i=0; (freq = i<30*12 ? (i+1)*1001 : freqs[i-30*12]); ++i ) {
+ double framerate = (double)freq / m1;
+ double err = fabs(frame_rate/framerate - 1.);
+ if( err >= max_err ) continue;
+ max_err = err;
+ best_freq = freq;
+ }
+ return max_err < 0.0001 ?
+ (AVRational) { best_freq, m1 } :
+ (AVRational) { 0, 0 };
+}
+
+int PluginFVClient::activate(int width, int height, int color_model)
+{
+ if( activated ) return activated;
+ ffilt = PluginFFilter::new_ffilter(name, &config);
+ if( !ffilt ) {
+ config.copy_from(curr_config);
+ send_configure_change();
+ send_render_gui(&config, sizeof(config));
+ ffilt = PluginFFilter::new_ffilter(name, &config);
+ }
+ AVPixelFormat pix_fmt = color_model_to_pix_fmt(color_model);
+ AVFilterGraph *graph = !ffilt ? 0 : ffilt->graph;
+ int ret = !graph ? -1 : 0;
+ if( ret >= 0 && ffilt->filter->inputs ) {
+ curr_config.copy_from(config);
+ if( pix_fmt == AV_PIX_FMT_NB ) {
+ int bpp = BC_CModels::calculate_pixelsize(color_model) * 8;
+ int bits_per_comp = bpp / BC_CModels::components(color_model);
+ int alpha = BC_CModels::has_alpha(color_model);
+ pix_fmt = bits_per_comp > 8 ?
+ !alpha ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGBA64LE :
+ !alpha ? AV_PIX_FMT_RGB24 : AV_PIX_FMT_RGBA ;
+ }
+ int aspect_w = 1, aspect_h = 1; // XXX
+ AVRational best_rate = best_frame_rate(frame_rate);
+ char args[BCTEXTLEN];
+ snprintf(args, sizeof(args),
+ "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
+ width, height, pix_fmt, best_rate.num, best_rate.den, aspect_w, aspect_h);
+ ret = avfilter_graph_create_filter(&fsrc, avfilter_get_by_name("buffer"),
+ "in", args, NULL, graph);
+ }
+ if( ret >= 0 )
+ ret = avfilter_graph_create_filter(&fsink, avfilter_get_by_name("buffersink"),
+ "out", NULL, NULL, graph);
+ if( ret >= 0 )
+ ret = av_opt_set_bin(fsink, "pix_fmts",
+ (uint8_t*)&pix_fmt, sizeof(pix_fmt), AV_OPT_SEARCH_CHILDREN);
+ if( ret >= 0 )
+ ret = PluginFClient::activate();
+ if( ret < 0 && activated >= 0 ) {
+ ff_err(ret, "PluginFVClient::activate() %s\n", plugin_title());
+ activated = -1;
+ }
+ return activated;
+}
+
+int PluginFAClient::get_inchannels()
+{
+ AVFilterContext *fctx = ffilt->fctx;
+ AVFilterLink **links = !fctx->nb_inputs ? 0 : fctx->inputs;
+ return !links ? 0 : avfilter_link_get_channels(links[0]);
+}
+
+int PluginFAClient::get_outchannels()
+{
+ AVFilterContext *fctx = ffilt->fctx;
+ AVFilterLink **links = !fctx->nb_outputs ? 0 : fctx->outputs;
+ return !links ? 0 : avfilter_link_get_channels(links[0]);
+}
+
+int PluginFAClient::process_buffer(int64_t size, Samples **buffer, int64_t start_position, int sample_rate)
+{
+ int total_in = PluginClient::total_in_buffers;
+ int total_out = PluginClient::total_out_buffers;
+ int in_channels = 0, out_channels = 0;
+
+ if( load_configuration() )
+ plugin_position = -1;
+ if( plugin_position != start_position ) {
+ filter_position = plugin_position = start_position;
+ reactivate();
+ }
+
+ AVFrame *frame = 0;
+ int ret = activate();
+ if( ret >= 0 && !(frame = av_frame_alloc()) ) {
+ fprintf(stderr, "PluginFAClient::process_buffer: av_frame_alloc failed\n");
+ ret = AVERROR(ENOMEM);
+ }
+ if( ret >= 0 ) {
+ in_channels = get_inchannels();
+ out_channels = get_outchannels();
+ }
+
+ int retry = 10;
+ while( ret >= 0 && --retry >= 0 ) {
+ ret = av_buffersink_get_frame(fsink, frame);
+ if( ret >= 0 || ret != AVERROR(EAGAIN) ) break;
+ if( !fsrc ) { ret = AVERROR(EIO); break; }
+ for( int i=0; i<total_in; ++i )
+ read_samples(buffer[i], i, sample_rate, filter_position, size);
+ filter_position += size;
+ frame->nb_samples = size;
+ frame->format = AV_SAMPLE_FMT_FLTP;
+ frame->channel_layout = (1<<in_channels)-1;
+ frame->sample_rate = sample_rate;
+ frame->pts = local_to_edl(filter_position);
+ ret = av_frame_get_buffer(frame, 0);
+ if( ret < 0 ) break;
+ float **in_buffers = (float **)&frame->extended_data[0];
+ for(int i = 0; i < in_channels; i++) {
+ float *in_buffer = in_buffers[i];
+ int k = i < total_in ? i : 0;
+ double *in_ptr = buffer[k]->get_data();
+ for(int j = 0; j < size; j++) in_buffer[j] = in_ptr[j];
+ }
+ ret = av_buffersrc_add_frame_flags(fsrc, frame, 0);
+ }
+ if( ret >= 0 && retry < 0 )
+ ret = AVERROR(EAGAIN);
+
+ if( ret >= 0 ) {
+ int nbfrs = total_out;
+ if( out_channels < nbfrs ) nbfrs = out_channels;
+ float **out_buffers = (float **)&frame->extended_data[0];
+ int i = 0;
+ while( i < nbfrs ) {
+ float *out_buffer = out_buffers[i];
+ double *out_ptr = buffer[i++]->get_data();
+ for(int j = 0; j < size; j++) out_ptr[j] = out_buffer[j];
+ }
+ while( i < total_out ) {
+ double *out_ptr = buffer[i++]->get_data();
+ bzero(out_ptr, sizeof(double) * size);
+ }
+ }
+ if( ret < 0 ) {
+ int64_t position = PluginFClient::get_source_position();
+ double t0 = (double)position/sample_rate, dt = 1./sample_rate;
+ for( int i=0; i<total_out; ++i ) {
+ double t = t0, *out = buffer[i]->get_data();
+ for( int k=size; --k>=0; t+=dt ) {
+ double w = int(2*t) & 1 ? 2*M_PI*440 : 2*M_PI*697;
+ *out++ = sin(t * w);
+ }
+ }
+ ff_err(ret, "PluginFAClient::process_buffer() %s\n", plugin_title());
+ }
+
+ av_frame_free(&frame);
+ plugin_position += size;
+ return size;
+}
+
+
+PluginFVClient::PluginFVClient(PluginServer *server, const char *name)
+ : PluginVClient(server), PluginFClient(this, name)
+{
+}
+
+PluginFVClient::~PluginFVClient()
+{
+}
+
+int PluginFVClient::process_buffer(VFrame **frames, int64_t position, double frame_rate)
+{
+ VFrame *vframe = *frames;
+ int width = vframe->get_w();
+ int height = vframe->get_h();
+
+ if( load_configuration() )
+ plugin_position = -1;
+ if( plugin_position != position ) {
+ filter_position = plugin_position = position;
+ reactivate();
+ }
+
+ int colormodel = vframe->get_color_model();
+ int ret = activate(width, height, colormodel);
+ AVPixelFormat pix_fmt = fsrc ?
+ (AVPixelFormat) fsrc->outputs[0]->format :
+ color_model_to_pix_fmt(colormodel);
+ if( pix_fmt <= AV_PIX_FMT_NONE || pix_fmt >= AV_PIX_FMT_NB )
+ pix_fmt = AV_PIX_FMT_RGBA;
+
+ AVFrame *frame = 0;
+ if( ret >= 0 && !(frame = av_frame_alloc()) ) {
+ fprintf(stderr, "PluginFVClient::process_buffer: av_frame_alloc failed\n");
+ ret = AVERROR(ENOMEM);
+ }
+
+ int retry = 10;
+ while( ret >= 0 && --retry >= 0 ) {
+ ret = av_buffersink_get_frame(fsink, frame);
+ if( ret >= 0 || ret != AVERROR(EAGAIN) ) break;
+ if( !fsrc ) { ret = AVERROR(EIO); break; }
+ read_frame(vframe, 0, filter_position++, frame_rate, get_use_opengl());
+ frame->format = pix_fmt;
+ frame->width = width;
+ frame->height = height;
+ frame->pts = local_to_edl(position);
+ ret = av_frame_get_buffer(frame, 32);
+ if( ret < 0 ) break;
+ ret = transfer_pixfmt(vframe, frame, pix_fmt, width, height);
+ if( ret < 0 ) break;
+ ret = av_buffersrc_add_frame_flags(fsrc, frame, 0);
+ }
+ if( ret >= 0 && retry < 0 )
+ ret = AVERROR(EAGAIN);
+
+ if( ret >= 0 ) {
+ pix_fmt = (AVPixelFormat) frame->format;
+ ret = transfer_cmodel(vframe, frame, pix_fmt, width, height);
+ }
+ if( ret < 0 ) {
+ ff_err(ret, "PluginFVClient::process_buffer() %s\n", plugin_title());
+ if( position & 1 ) vframe->clear_frame();
+ }
+
+ ++plugin_position;
+ av_frame_free(&frame);
+ return ret >= 0 ? 0 : 1;
+}
+
+
+PluginFClient_OptName:: PluginFClient_OptName(PluginFClient_Opt *opt)
+{
+ this->opt = opt;
+ set_text(opt->opt->name);
+}
+
+PluginFClient_OptValue::PluginFClient_OptValue(PluginFClient_Opt *opt)
+{
+ this->opt = opt;
+ update();
+}
+
+void PluginFClient_OptValue::update()
+{
+ char val[BCTEXTLEN]; val[0] = 0;
+ opt->get(val, sizeof(val));
+ set_text(val);
+}
+
+
+PluginFClient_Opt::PluginFClient_Opt(PluginFClientConfig *conf, const AVOption *opt)
+{
+ this->conf = conf;
+ this->opt = opt;
+ item_name = new PluginFClient_OptName(this);
+ item_value = new PluginFClient_OptValue(this);
+}
+
+PluginFClient_Opt::~PluginFClient_Opt()
+{
+ delete item_name;
+ delete item_value;
+}
+
+char *PluginFClient_Opt::get(char *vp, int sz)
+{
+ char *ret = 0;
+ void *obj = filter_config();
+ uint8_t *bp = 0;
+ if( av_opt_get(obj, opt->name, 0, &bp) >= 0 && bp != 0 ) {
+ const char *val = (const char *)bp;
+ ret = sz >= 0 ? strncpy(vp,val,sz) : strcpy(vp, val);
+ if( sz > 0 ) vp[sz-1] = 0;
+ av_freep(&bp);
+ }
+ return ret;
+}
+void PluginFClient_Opt::set(const char *val)
+{
+ void *obj = filter_config();
+ av_opt_set(obj , opt->name, val, 0);
+}
+
+void PluginFFilter::uninit()
+{
+}
+
+static int get_defaults(const char *name, char *args)
+{
+ *args = 0;
+ char defaults_path[BCTEXTLEN];
+ FFMPEG::set_option_path(defaults_path, "plugin.opts");
+ FILE *fp = fopen(defaults_path,"r");
+ if( !fp ) return 0;
+ char ff_plugin[BCSTRLEN], ff_args[BCTEXTLEN], *ap = 0;
+ while( !ap && fgets(ff_args, sizeof(ff_args), fp) ) {
+ if( *(ap=ff_args) == ';' ) continue;
+ if( *(ap=ff_args) == '#' ) ++ap;
+ char *bp = ff_plugin, *ep = bp + sizeof(ff_plugin)-1;
+ while( bp < ep && *ap && *ap != '\n' && *ap != ' ' ) *bp++ = *ap++;
+ *bp = 0;
+ if( strcmp(ff_plugin, name) ) ap = 0;
+ }
+ fclose(fp);
+ if( !ap ) return 0;
+ if( ff_args[0] == '#' ) return -1;
+ while( *ap == ' ' ) ++ap;
+ while( *ap && *ap != '\n' ) *args++ = *ap++;
+ *args = 0;
+ return 1;
+}
+
+bool PluginFFilter::is_audio()
+{
+ return PluginFClient::is_audio(filter);
+}
+
+bool PluginFFilter::is_video()
+{
+ return PluginFClient::is_video(filter);
+}
+
+int PluginFFilter::init(const char *name, PluginFClientConfig *conf)
+{
+ char args[BCTEXTLEN];
+ int ret = get_defaults(name, args);
+ if( ret < 0 ) return 0;
+ PluginFLogLevel errs(AV_LOG_ERROR);
+ this->filter = avfilter_get_by_name(name);
+ if( !this->filter ) return AVERROR(ENOENT);
+ int flag_mask = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_DYNAMIC_OUTPUTS;
+ if( filter->flags & flag_mask ) return AVERROR(EPERM);
+ if( !this->is_audio() && !this->is_video() ) return AVERROR(EIO);
+ this->graph = avfilter_graph_alloc();
+ if( !this->graph ) return AVERROR(ENOMEM);
+ static int inst = 0;
+ char inst_name[BCSTRLEN];
+ sprintf(inst_name,"%s_%d", name, ++inst);
+ graph->thread_type = 0;
+ graph->nb_threads = 1;
+ fctx = avfilter_graph_alloc_filter(graph, filter, inst_name);
+ if( !fctx ) return AVERROR(ENOMEM);
+ if( conf ) {
+ AVDictionary *opts = 0;
+ for( int i=0; i<conf->size(); ++i ) {
+ PluginFClient_Opt *op = conf->get(i);
+ const char *name = op->opt->name;
+ char val[BCTEXTLEN], *vp = op->get(val, sizeof(val));
+ if( vp ) av_dict_set(&opts, name, vp, 0);
+ }
+ ret = avfilter_init_dict(fctx, &opts);
+ av_dict_free(&opts);
+ }
+ else
+ ret = avfilter_init_str(fctx, args);
+ return ret < 0 ? ret : 1;
+}
+
+
+PluginFFilter::PluginFFilter()
+{
+ filter = 0;
+ graph = 0;
+ fctx = 0;
+}
+
+PluginFFilter::~PluginFFilter()
+{
+ PluginFLogLevel errs(AV_LOG_ERROR);
+ avfilter_graph_free(&graph);
+ filter = 0; fctx = 0;
+}
+
+PluginFFilter *PluginFFilter::new_ffilter(const char *name, PluginFClientConfig *conf)
+{
+ PluginFFilter *ffilt = new PluginFFilter;
+ int ret = ffilt->init(name, conf);
+ if( ret < 0 ) ff_err(ret, "PluginFFilter::new_ffilter(%s)\n", name);
+ if( ret <= 0 ) { delete ffilt; ffilt = 0; }
+ return ffilt;
+}
+
+PluginClient *PluginServer::new_ffmpeg_plugin()
+{
+ AVFilter *filter = avfilter_get_by_name(ff_name);
+ if( !filter ) return 0;
+ PluginFClient *ffmpeg =
+ PluginFClient::is_audio(filter) ?
+ (PluginFClient *)new PluginFAClient(this, ff_name) :
+ PluginFClient::is_video(filter) ?
+ (PluginFClient *)new PluginFVClient(this, ff_name) :
+ 0;
+ if( !ffmpeg ) return 0;
+ return ffmpeg->plugin;
+}
+
+
+PluginServer* MWindow::new_ffmpeg_server(MWindow *mwindow, const char *name)
+{
+ PluginFFilter *ffilt = PluginFFilter::new_ffilter(name);
+ if( !ffilt ) return 0;
+ delete ffilt;
+ return new PluginServer(mwindow, (char*)name, PLUGIN_TYPE_FFMPEG);
+}
+
+void MWindow::init_ffmpeg_index(MWindow *mwindow, Preferences *preferences, FILE *fp)
+{
+ PluginFLogLevel errs(AV_LOG_ERROR);
+ const AVFilter *filter = 0;
+ while( (filter=avfilter_next(filter)) != 0 ) {
+ PluginServer *server = new_ffmpeg_server(mwindow, filter->name);
+ if( server ) {
+ int result = server->open_plugin(1, preferences, 0, 0);
+ if( !result ) {
+ server->write_table(fp, PLUGIN_FFMPEG_ID);
+ server->close_plugin();
+ }
+ server->delete_this();
+ if( result ) fprintf(fp, "#%s\n", filter->name);
+ }
+ }
+}
+
+void MWindow::init_ffmpeg()
+{
+ av_register_all();
+ avfilter_register_all();
+}
+
--- /dev/null
+#ifndef __PLUGINFCLIENT_H__
+#define __PLUGINFCLIENT_H__
+
+#include "arraylist.h"
+#include "bclistbox.h"
+#include "bclistboxitem.h"
+#include "bcbutton.h"
+#include "bcpopupmenu.h"
+#include "bcmenuitem.h"
+#include "bctextbox.h"
+#include "ffmpeg.h"
+#include "pluginclient.h"
+#include "pluginaclient.h"
+#include "pluginvclient.h"
+#include "pluginserver.h"
+#include "pluginfclient.inc"
+#include "preferences.inc"
+
+extern "C" {
+#include "libavfilter/buffersrc.h"
+#include "libavfilter/buffersink.h"
+#include "libavformat/avformat.h"
+#include "libavformat/avio.h"
+#include "libavcodec/avcodec.h"
+#include "libavfilter/avfilter.h"
+#include "libavutil/avutil.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "libswresample/swresample.h"
+#include "libswscale/swscale.h"
+}
+
+class PluginFClient_OptName : public BC_ListBoxItem {
+public:
+ PluginFClient_Opt *opt;
+
+ PluginFClient_OptName(PluginFClient_Opt *opt);
+};
+
+class PluginFClient_OptValue : public BC_ListBoxItem {
+public:
+ PluginFClient_Opt *opt;
+
+ void update();
+ PluginFClient_OptValue(PluginFClient_Opt *opt);
+};
+
+class PluginFClient_Opt {
+public:
+ PluginFClientConfig *conf;
+ const AVOption *opt;
+ PluginFClient_OptName *item_name;
+ PluginFClient_OptValue *item_value;
+
+ char *get(char *vp, int sz=-1);
+ void set(const char *val);
+ int types(char *rp);
+ int scalar(double d, char *rp);
+ int ranges(char *rp);
+ int units(ArrayList<const AVOption *> &opts);
+ int units(char *rp);
+ const char *tip();
+ void *filter_config();
+ const AVClass *filter_class();
+
+ PluginFClient_Opt(PluginFClientConfig *conf, const AVOption *opt);
+ ~PluginFClient_Opt();
+};
+
+class PluginFFilter {
+ PluginFFilter(PluginFFilter &that) {} //disable assign/copy
+public:
+ AVFilter *filter;
+ AVFilterGraph *graph;
+ AVFilterContext *fctx;
+
+ void *filter_config() { return fctx->priv; }
+ const AVClass *filter_class() { return filter->priv_class; }
+ const char *description() { return filter->description; }
+
+ int init(const char *name, PluginFClientConfig *conf);
+ void uninit();
+ static PluginFFilter *new_ffilter(const char *name, PluginFClientConfig *conf=0);
+
+ PluginClient* new_plugin(PluginServer*);
+ const char *filter_name() { return filter->name; }
+ bool is_audio();
+ bool is_video();
+
+ PluginFFilter();
+ ~PluginFFilter();
+};
+
+class PluginFClientConfig : public ArrayList<PluginFClient_Opt *>
+{
+public:
+ PluginFFilter *ffilt;
+ void *filter_config() { return ffilt->filter_config(); }
+ const AVClass *filter_class() { return ffilt->filter_class(); }
+
+ void copy_from(PluginFClientConfig &that);
+ int equivalent(PluginFClientConfig &that);
+ void interpolate(PluginFClientConfig &prev, PluginFClientConfig &next,
+ int64_t prev_frame, int64_t next_frame, int64_t current_frame);
+ void initialize(const char *name);
+ int update();
+ void dump(FILE *fp=stdout);
+
+ PluginFClientConfig();
+ ~PluginFClientConfig();
+};
+
+
+class PluginFClient_OptPanel : public BC_ListBox {
+public:
+ PluginFClient_OptPanel(PluginFClientWindow *fwin, int x, int y, int w, int h);
+ ~PluginFClient_OptPanel();
+ void create_objects();
+ int cursor_leave_event();
+
+ PluginFClientWindow *fwin;
+ ArrayList<BC_ListBoxItem*> items[2];
+ ArrayList<BC_ListBoxItem*> &opts;
+ ArrayList<BC_ListBoxItem*> &vals;
+
+ int selection_changed();
+ int update();
+};
+
+class PluginFClientReset : public BC_GenericButton {
+public:
+ PluginFClientWindow *fwin;
+
+ PluginFClientReset(PluginFClientWindow *fwin, int x, int y);
+ ~PluginFClientReset();
+ int handle_event();
+};
+
+class PluginFClientUnits : public BC_PopupMenu {
+public:
+ PluginFClientWindow *fwin;
+
+ PluginFClientUnits(PluginFClientWindow *fwin, int x, int y, int w);
+ ~PluginFClientUnits();
+ int handle_event();
+};
+
+class PluginFClientText : public BC_TextBox {
+public:
+ PluginFClientWindow *fwin;
+
+ PluginFClientText(PluginFClientWindow *fwin, int x, int y, int w);
+ ~PluginFClientText();
+ int handle_event();
+};
+
+class PluginFClientApply : public BC_GenericButton {
+public:
+ PluginFClientWindow *fwin;
+
+ PluginFClientApply(PluginFClientWindow *fwin, int x, int y);
+ ~PluginFClientApply();
+ int handle_event();
+};
+
+class PluginFClientWindow : public PluginClientWindow
+{
+public:
+ PluginFClientWindow(PluginFClient *ffmpeg);
+ ~PluginFClientWindow();
+
+ void create_objects();
+ void update(PluginFClient_Opt *oip);
+ void draw();
+ int resize_event(int w, int h);
+
+ PluginFClient *ffmpeg;
+ PluginFClient_OptPanel *panel;
+ int panel_x, panel_y, panel_w, panel_h;
+ BC_Title *type, *range;
+ PluginFClient_Opt *selected;
+
+ PluginFClientReset *reset;
+ PluginFClientUnits *units;
+ PluginFClientText *text;
+ PluginFClientApply *apply;
+};
+
+class PluginFLogLevel {
+ int level;
+public:
+ PluginFLogLevel(int lvl) {
+ level = av_log_get_level();
+ if( level > lvl ) av_log_set_level(lvl);
+ }
+ ~PluginFLogLevel() { av_log_set_level(level); }
+};
+
+class PluginFClient {
+public:
+ const char *name;
+ PluginClient *plugin;
+ PluginFFilter *ffilt;
+ AVFilterContext *fsrc, *fsink;
+ int64_t plugin_position, filter_position;
+ int activated;
+ char title[BCSTRLEN];
+
+ PluginFClient(PluginClient *plugin, const char *name);
+ ~PluginFClient();
+ static bool is_audio(AVFilter *fp);
+ static bool is_video(AVFilter *fp);
+
+ int64_t get_source_position() {
+ return plugin->get_source_position();
+ }
+ KeyFrame* get_prev_keyframe(int64_t position, int is_local=1) {
+ return plugin->get_prev_keyframe(position, is_local);
+ }
+ KeyFrame* get_next_keyframe(int64_t position, int is_local=1) {
+ return plugin->get_next_keyframe(position, is_local);
+ }
+ int64_t edl_to_local(int64_t position) {
+ return plugin->edl_to_local(position);
+ }
+
+ void update_gui();
+ char *to_upper(char *bp, const char *sp);
+ void save_data(KeyFrame *keyframe);
+ void read_data(KeyFrame *keyframe);
+ void render_gui(void *data, int size);
+ int activate();
+ void reactivate();
+
+ PluginFClientConfig curr_config, av_config;
+ PLUGIN_CLASS_MEMBERS(PluginFClientConfig)
+};
+
+class PluginFAClient : public PluginAClient, public PluginFClient
+{
+public:
+ PluginFAClient(PluginServer *server, const char *name);
+ ~PluginFAClient();
+ const char *plugin_title() { return PluginFClient::plugin_title(); }
+ PluginClientWindow *new_window() { return PluginFClient::new_window(); }
+ int activate();
+
+ int load_configuration() { return PluginFClient::load_configuration(); }
+ void save_data(KeyFrame *keyframe) { PluginFClient::save_data(keyframe); }
+ void read_data(KeyFrame *keyframe) { PluginFClient::read_data(keyframe); }
+ void update_gui() { PluginFClient::update_gui(); }
+ void render_gui(void *data, int size) { PluginFClient::render_gui(data, size); }
+
+ int is_realtime() { return 1; }
+ int is_multichannel() { return 1; }
+ int uses_gui() { return 1; }
+ int is_synthesis() { return 1; }
+ int get_inchannels();
+ int get_outchannels();
+ int process_buffer(int64_t size, Samples **buffer, int64_t start_position, int sample_rate);
+};
+
+class PluginFVClient : public PluginVClient, public PluginFClient, public FFVideoConvert
+{
+public:
+ PluginFVClient(PluginServer *server, const char *name);
+ ~PluginFVClient();
+ const char *plugin_title() { return PluginFClient::plugin_title(); }
+ PluginClientWindow *new_window() { return PluginFClient::new_window(); }
+ int activate(int width, int height, int color_model);
+
+ int load_configuration() { return PluginFClient::load_configuration(); }
+ void save_data(KeyFrame *keyframe) { PluginFClient::save_data(keyframe); }
+ void read_data(KeyFrame *keyframe) { PluginFClient::read_data(keyframe); }
+ void update_gui() { PluginFClient::update_gui(); }
+ void render_gui(void *data, int size) { PluginFClient::render_gui(data, size); }
+
+ int is_realtime() { return 1; }
+ int is_multichannel() { return 1; }
+ int uses_gui() { return 1; }
+ int is_synthesis() { return 1; }
+ int process_buffer(VFrame **frames, int64_t start_position, double frame_rate);
+};
+
+#endif
--- /dev/null
+#ifndef __PLUGINFCLIENT_INC__
+#define __PLUGINFCLIENT_INC__
+
+struct AVFilter;
+typedef struct AVFilter AVFilter;
+struct AVFilterGraph;
+typedef struct AVFilterGraph AVFilterGraph;
+
+class PluginFClient_Opt;
+class PluginFFilter;
+class PluginFClientConfig;
+class PluginFClient_OptName;
+class PluginFClient_OptValue;
+class PluginFClient_OptPanel;
+class PluginFClientUnits;
+class PluginFClientText;
+class PluginFClientApply;
+class PluginFClientWindow;
+class PluginFClient;
+class PluginFAClient;
+class PluginFVClient;
+
+#ifndef FLT_MAX
+#define FLT_MAX 3.40282346638528859812e+38F
+#endif
+
+#ifndef FLT_MIN
+#define FLT_MIN 1.17549435082228750797e-38F
+#endif
+
+#ifndef DBL_MAX
+#define DBL_MAX ((double)1.79769313486231570815e+308L)
+#endif
+
+#ifndef DBL_MIN
+#define DBL_MIN ((double)2.22507385850720138309e-308L)
+#endif
+
+#endif
#include "autoconf.h"
#include "bcsignals.h"
#include "cplayback.h"
+#include "cstrdup.h"
#include "cwindow.h"
#include "edl.h"
#include "edlsession.h"
#include "plugin.h"
#include "pluginaclient.h"
#include "pluginaclientlad.h"
+#include "pluginfclient.h"
#include "pluginclient.h"
#include "plugincommands.h"
#include "pluginserver.h"
#include <sys/mman.h>
-PluginServer::PluginServer()
+void PluginServer::init()
{
reset_parameters();
+ this->plugin_type = PLUGIN_TYPE_UNKNOWN;
modules = new ArrayList<Module*>;
nodes = new ArrayList<VirtualNode*>;
}
-PluginServer::PluginServer(char *path, MWindow *mwindow)
+PluginServer::PluginServer()
{
- reset_parameters();
- set_path(path);
- modules = new ArrayList<Module*>;
- nodes = new ArrayList<VirtualNode*>;
- this->mwindow = mwindow;
+ init();
}
-PluginServer::PluginServer(PluginServer &that)
+PluginServer::PluginServer(MWindow *mwindow, char *path, int type)
{
- reset_parameters();
-
- if(that.title)
- {
- title = new char[strlen(that.title) + 1];
- strcpy(title, that.title);
- }
-
- if(that.path)
- {
- path = new char[strlen(that.path) + 1];
- strcpy(path, that.path);
+ char fpath[BCTEXTLEN];
+ init();
+ this->plugin_type = type;
+ this->mwindow = mwindow;
+ if( type == PLUGIN_TYPE_FFMPEG ) {
+ ff_name = cstrdup(path);
+ sprintf(fpath, "ff_%s", path);
+ path = fpath;
}
+ set_path(path);
+}
+PluginServer::PluginServer(PluginServer &that)
+{
+ reset_parameters();
+ plugin_type = that.plugin_type;
+ title = !that.title ? 0 : cstrdup(that.title);
+ path = !that.path ? 0 : cstrdup(that.path);
+ ff_name = !that.ff_name ? 0 : cstrdup(that.ff_name);
modules = new ArrayList<Module*>;
nodes = new ArrayList<VirtualNode*>;
keyframe = that.keyframe;
new_plugin = that.new_plugin;
- is_lad = that.is_lad;
lad_descriptor = that.lad_descriptor;
lad_descriptor_function = that.lad_descriptor_function;
lad_index = that.lad_index;
PluginServer::~PluginServer()
{
close_plugin();
- if(path) delete [] path;
- if(title) delete [] title;
- if(modules) delete modules;
- if(nodes) delete nodes;
- if(picon) delete picon;
+ delete [] path;
+ delete [] ff_name;
+ delete [] title;
+ delete modules;
+ delete nodes;
+ delete picon;
}
// Done only once at creation
prompt = 0;
cleanup_plugin();
autos = 0;
- plugin = 0;
edl = 0;
+ dlobj = 0;
preferences = 0;
title = 0;
path = 0;
+ ff_name = 0;
audio = video = theme = 0;
fileio = 0;
uses_gui = 0;
nodes = 0;
picon = 0;
- is_lad = 0;
lad_index = -1;
lad_descriptor_function = 0;
lad_descriptor = 0;
return 0;
}
-
// Done every time the plugin is opened or closed
int PluginServer::cleanup_plugin()
{
int PluginServer::is_ladspa()
{
- return is_lad;
+ return plugin_type == PLUGIN_TYPE_LADSPA ? 1 : 0;
}
-int PluginServer::set_path(char *path)
+int PluginServer::is_ffmpeg()
{
- if(this->path) delete [] this->path;
- this->path = new char[strlen(path) + 1];
- strcpy(this->path, path);
- return 0;
+ return plugin_type == PLUGIN_TYPE_FFMPEG ? 1 : 0;
+}
+
+void PluginServer::set_path(const char *path)
+{
+ delete [] this->path;
+ this->path = cstrdup(path);
}
char* PluginServer::get_path()
void PluginServer::set_title(const char *string)
{
if(title) delete [] title;
- title = new char[strlen(string) + 1];
- strcpy(title, string);
+ title = cstrdup(string);
}
void PluginServer::generate_display_title(char *string)
strcpy(string, ltitle);
}
+void *PluginServer::load_obj()
+{
+ if( !dlobj ) {
+ char dlpath[BCTEXTLEN], *dp = dlpath;
+ char *cp = path;
+ if( *cp != '/' ) {
+ char *bp = preferences->plugin_dir;
+ while( *bp ) *dp++ = *bp++;
+ *dp++ = '/';
+ }
+ while( *cp ) *dp++ = *cp++;
+ *dp = 0;
+ dlobj = load(dlpath);
+ }
+ return dlobj;
+}
+
+void PluginServer::unload_obj()
+{
+ if( !dlobj ) return;
+ unload(dlobj); dlobj = 0;
+}
+
void PluginServer::delete_this()
{
- void *dlp = load_obj();
+ void *obj = dlobj;
delete this;
- unload_obj(dlp);
+ if( obj ) unload(obj);
}
// Open plugin for signal processing
this->preferences = preferences;
this->plugin = plugin;
this->edl = edl;
- if( !load_obj() ) {
- // add base path if not absolute path
- char dl_path[BCTEXTLEN], *dp = dl_path;
- char *cp = path;
- if( *cp != '/' ) {
- char *bp = preferences->plugin_dir;
- while( *bp ) *dp++ = *bp++;
- *dp++ = '/';
- }
- while( *cp ) *dp++ = *cp++;
- *dp = 0;
- if( !load_obj(dl_path) ) {
+ if( plugin_type != PLUGIN_TYPE_FFMPEG && plugin_type != PLUGIN_TYPE_EXECUTABLE && !load_obj() ) {
// If the load failed it may still be an executable tool for a specific
// file format, in which case we just store the path.
- set_title(path);
- char string[BCTEXTLEN];
- strcpy(string, load_error());
- if(!strstr(string, "executable"))
- eprintf("PluginServer::open_plugin: load_obj failure = %s\n", string);
+ set_title(path);
+ char string[BCTEXTLEN];
+ strcpy(string, load_error());
+ if( !strstr(string, "executable") ) {
+ eprintf("PluginServer::open_plugin: load_obj failure = %s\n", string);
return PLUGINSERVER_NOT_RECOGNIZED;
}
+ plugin_type = PLUGIN_TYPE_EXECUTABLE;
}
- if( !new_plugin && !lad_descriptor ) {
+ if( plugin_type == PLUGIN_TYPE_UNKNOWN || plugin_type == PLUGIN_TYPE_BUILTIN ) {
new_plugin =
(PluginClient* (*)(PluginServer*)) load_sym("new_plugin");
- if( !new_plugin ) {
- lad_descriptor_function =
- (LADSPA_Descriptor_Function) load_sym("ladspa_descriptor");
- if(!lad_descriptor_function) {
- fprintf(stderr, "PluginServer::open_plugin "
- " %d: new_plugin undefined in %s\n", __LINE__, path);
- unload_obj();
- return PLUGINSERVER_NOT_RECOGNIZED;
- }
+ if( new_plugin )
+ plugin_type = PLUGIN_TYPE_BUILTIN;
+ }
+ if( plugin_type == PLUGIN_TYPE_UNKNOWN || plugin_type == PLUGIN_TYPE_LADSPA ) {
+ lad_descriptor_function =
+ (LADSPA_Descriptor_Function) load_sym("ladspa_descriptor");
+ if( lad_descriptor_function ) {
if( lad_index < 0 ) {
unload_obj();
return PLUGINSERVER_IS_LAD;
}
lad_descriptor = lad_descriptor_function(lad_index);
- if(!lad_descriptor) {
- unload_obj();
+ if( !lad_descriptor )
return PLUGINSERVER_NOT_RECOGNIZED;
- }
- is_lad = 1;
+ plugin_type = PLUGIN_TYPE_LADSPA;
}
}
-
- client = is_lad ?
- (PluginClient *) new PluginAClientLAD(this) :
- new_plugin(this);
-
+ if( plugin_type == PLUGIN_TYPE_UNKNOWN ) {
+ fprintf(stderr, "PluginServer::open_plugin "
+ " %d: plugin undefined in %s\n", __LINE__, path);
+ unload_obj();
+ return PLUGINSERVER_NOT_RECOGNIZED;
+ }
+ switch( plugin_type ) {
+ case PLUGIN_TYPE_BUILTIN:
+ client = new_plugin(this);
+ break;
+ case PLUGIN_TYPE_LADSPA:
+ client = new PluginAClientLAD(this);
+ break;
+ case PLUGIN_TYPE_FFMPEG:
+ client = new_ffmpeg_plugin();
+ break;
+ default:
+ client = 0;
+ break;
+ }
+ if( !client )
+ return PLUGINSERVER_NOT_RECOGNIZED;
+
// Run initialization functions
realtime = client->is_realtime();
// Don't load defaults when probing the directory.
void PluginServer::write_table(FILE *fp, int idx)
{
if(!fp) return;
- fprintf(fp, "\"%s\" \"%s\" %d %d %d %d %d %d %d %d %d %d %d %d\n",
- path, title, idx, audio, video, theme, realtime, fileio,
- uses_gui, multichannel, synthesis, transition, is_lad, lad_index);
+ fprintf(fp, "%d \"%s\" \"%s\" %d %d %d %d %d %d %d %d %d %d %d\n",
+ plugin_type, path, title, idx, audio, video, theme, realtime,
+ fileio, uses_gui, multichannel, synthesis, transition, lad_index);
}
-char *PluginServer::table_quoted_field(char *&sp)
+int PluginServer::scan_table(char *text, int &type, char *path, char *title)
{
- char *cp = sp;
- while( *cp && (*cp == ' ' || *cp == '\t') ) ++cp;
- if( *cp++ != '"' ) return 0;
- char *bp = cp;
- while( *cp && *cp != '"' ) ++cp;
- if( *cp != '"' ) return 0;
- *cp++ = 0; sp = cp;
- return bp;
+ int n = sscanf(text, "%d \"%[^\"]\" \"%[^\"]\"", &type, path, title);
+ return n < 3 ? 1 : 0;
}
int PluginServer::read_table(char *text)
{
- int n = sscanf(text, "%d %d %d %d %d %d %d %d %d %d %d %d",
- &dir_idx, &audio, &video, &theme, &realtime, &fileio, &uses_gui,
- &multichannel, &synthesis, &transition, &is_lad, &lad_index);
-
- return n == 12 ? 0 : 1;
+ char path[BCTEXTLEN], title[BCTEXTLEN];
+ int n = sscanf(text, "%d \"%[^\"]\" \"%[^\"]\" %d %d %d %d %d %d %d %d %d %d %d",
+ &plugin_type, path, title, &dir_idx, &audio, &video, &theme, &realtime,
+ &fileio, &uses_gui, &multichannel, &synthesis, &transition, &lad_index);
+ if( n != 14 ) return 1;
+ this->path = cstrdup(path);
+ this->title = cstrdup(title);
+ return 0;
}
int PluginServer::init_realtime(int realtime_sched,
#include "mwindow.inc"
#include "plugin.inc"
#include "pluginaclientlad.inc"
+#include "pluginfclient.inc"
#include "pluginclient.inc"
#include "pluginserver.inc"
#include "preferences.inc"
#include <dlfcn.h>
-
-
-class PluginObj
+class PluginServer
{
+ int reset_parameters();
+ void init();
+ int cleanup_plugin();
+
void *dlobj;
-public:
- PluginObj() { dlobj = 0; }
- ~PluginObj() {}
- PluginObj(PluginObj &that) { dlobj = 0; }
-// dl interface
- void *load_obj() { return dlobj; }
- void *load_obj(const char *path) { return dlobj = dlopen(path, RTLD_NOW); }
- static void unload_obj(void *dlp) { if( dlp ) dlclose(dlp); }
- void unload_obj() { unload_obj(dlobj); }
+ void *load(const char *dlp) { return dlobj = dlopen(dlp, RTLD_NOW); }
+ void unload(void *obj) { dlclose(obj); }
void *load_sym(const char *sym) { return dlsym(dlobj, sym); }
const char *load_error() { return dlerror(); }
-};
-
-class PluginServer : public PluginObj
-{
- int reset_parameters();
- int cleanup_plugin();
+ void *load_obj();
+ void unload_obj();
// Base class created by client
PluginClient *client;
PluginClient* (*new_plugin)(PluginServer*);
// LAD support
- int is_lad;
int lad_index;
LADSPA_Descriptor_Function lad_descriptor_function;
const LADSPA_Descriptor *lad_descriptor;
int use_opengl;
+// FFMPEG support
+ const char *ff_name;
// Driver for opengl calls.
VideoDevice *vdevice;
public:
PluginServer();
- PluginServer(char *path, MWindow *mwindow=0);
+ PluginServer(MWindow *mwindow, char *path, int type);
PluginServer(PluginServer &);
virtual ~PluginServer();
-
friend class PluginAClientLAD;
friend class PluginAClientConfig;
friend class PluginAClientWindow;
+ friend class PluginFClient;
+ friend class PluginFAClient;
+ friend class PluginFVClient;
+ friend class PluginFClientConfig;
+ friend class PluginFClientWindow;
+
// open a plugin and wait for commands
// Get information for plugindb if master.
#define PLUGINSERVER_IS_LAD 2
void render_stop();
// Write entry into plugin table
void write_table(FILE *fp, int idx);
- static char *table_quoted_field(char *&sp);
+ static int scan_table(char *text, int &type, char *path, char *title);
int read_table(char *text);
// queries
void set_title(const char *string);
// Get picon png vframe image
VFrame *get_picon();
VFrame *get_plugin_images();
+
// ladspa
void set_lad_index(int i);
int get_lad_index();
int is_ladspa();
+// ffmpeg
+ int is_ffmpeg();
+ PluginClient *new_ffmpeg_plugin();
// =============================== for realtime plugins
// save configuration of plugin
void save_data(KeyFrame *keyframe);
double get_framerate(); // get framerate produced by plugin
int get_project_samplerate(); // get samplerate of project data before processing
double get_project_framerate(); // get framerate of project data before processing
- int set_path(char *path); // required first
- char* get_path();
+ void set_path(const char *path); // required first
+ char *get_path();
int get_synthesis();
void get_defaults_path(char *path);
void save_defaults();
int64_t get_written_samples(); // after samples are written, get the number written
int64_t get_written_frames(); // after frames are written, get the number written
+// client origin
+ int plugin_type;
// buffers
int64_t out_buffer_size; // size of a send buffer to the plugin
#ifndef PLUGINSERVER_INC
#define PLUGINSERVER_INC
+class PluginObj;
class PluginServer;
-class PluginGUIServer;
+
+#define PLUGIN_LADSPA_ID 0
+#define PLUGIN_FFMPEG_ID 1
+#define PLUGIN_IDS 2
+
+#define PLUGIN_TYPE_UNKNOWN -1
+#define PLUGIN_TYPE_EXECUTABLE 0
+#define PLUGIN_TYPE_BUILTIN 1
+#define PLUGIN_TYPE_LADSPA 2
+#define PLUGIN_TYPE_FFMPEG 3
+#define PLUGIN_TYPES 4
#endif
if(plugin_server->multichannel)
{
// Test against previous parameters for reuse of previous data
- if(is_processed &&
- this->start_position == start_position &&
- EQUIV(this->frame_rate, frame_rate))
- {
+ if( !is_processed || this->start_position != start_position ||
+ !EQUIV(this->frame_rate, frame_rate)) {
+ is_processed = 1;
+ this->start_position = start_position;
+ this->frame_rate = frame_rate;
+
+// Allocate buffer vector for subsequent render calls
+ new_buffer_vector(output->get_w(), output->get_h(),
+ output->get_color_model());
+// Process plugin
+//printf("VAttachmentPoint::render 1 %d\n", buffer_number);
+ if(renderengine)
+ plugin_servers.values[0]->set_use_opengl(use_opengl,
+ renderengine->video);
+ plugin_servers.values[0]->process_buffer(buffer_vector,
+ start_position, frame_rate,
+ (int64_t)Units::round(plugin->length * frame_rate /
+ renderengine->get_edl()->session->frame_rate),
+ renderengine->command->get_direction());
+ }
+//printf("VAttachmentPoint::render 3\n");
// Need to copy PBuffer if OpenGL, regardless of use_opengl
- if(buffer_vector[buffer_number]->get_opengl_state() == VFrame::RAM)
- {
- output->copy_from(buffer_vector[buffer_number]);
- output->set_opengl_state(VFrame::RAM);
- }
- else
- if(renderengine && renderengine->video)
- {
+ if( buffer_vector[buffer_number]->get_opengl_state() == VFrame::RAM ) {
+ output->copy_from(buffer_vector[buffer_number]);
+ output->set_opengl_state(VFrame::RAM);
+ }
+ else if(renderengine && renderengine->video) {
// Need to copy PBuffer to texture
// printf("VAttachmentPoint::render temp=%p output=%p\n",
// buffer_vector[buffer_number],
// output);
- VDeviceX11 *x11_device = (VDeviceX11*)renderengine->video->get_output_base();
- x11_device->copy_frame(output, buffer_vector[buffer_number]);
- }
- return;
- }
-
- is_processed = 1;
- this->start_position = start_position;
- this->frame_rate = frame_rate;
-
-// Allocate buffer vector for subsequent render calls
- new_buffer_vector(output->get_w(),
- output->get_h(),
- output->get_color_model());
-
-// Create temporary vector with output argument substituted in
- VFrame **output_temp = new VFrame*[virtual_plugins.total];
- for(int i = 0; i < virtual_plugins.total; i++)
- {
- if(i == buffer_number)
- output_temp[i] = output;
- else
- output_temp[i] = buffer_vector[i];
+ VDeviceX11 *x11_device = (VDeviceX11*)renderengine->video->get_output_base();
+ x11_device->copy_frame(output, buffer_vector[buffer_number]);
}
-
-// Process plugin
-//printf("VAttachmentPoint::render 1 %d\n", buffer_number);
- if(renderengine)
- plugin_servers.values[0]->set_use_opengl(use_opengl,
- renderengine->video);
- plugin_servers.values[0]->process_buffer(output_temp,
- start_position,
- frame_rate,
- (int64_t)Units::round(plugin->length *
- frame_rate /
- renderengine->get_edl()->session->frame_rate),
- renderengine->command->get_direction());
-//printf("VAttachmentPoint::render 2\n");
-
- delete [] output_temp;
-//printf("VAttachmentPoint::render 3\n");
}
else
// process single track
--- /dev/null
+#abuffer
+#abuffersink
+#acrossfade
+adelay delays=1
+#adrawgraph
+aeval exprs=(sin(2*PI*t*440)+sin(2*PI*t*350))/2*mod(floor(2*t),2):channel_layout=1c
+#aevalsrc
+#afifo
+#aformat
+#ainterleave
+#allrgb
+#allyuv
+#alphaextract
+#alphamerge
+#amerge
+#amix
+#amovie
+#anull
+#anullsink
+#anullsrc
+#apad
+#aperms
+#aphasemeter
+aresample sample_rate=48000
+#areverse
+#aselect
+#asendcmd
+#asetnsamples
+#asetpts
+#asetrate
+#asettb
+#ashowinfo
+#asilencedetect
+#asilenceremove
+#asplit
+#astats
+#astreamsync
+#atadenoise
+#atempo
+#atrim
+#avectorscope
+#bbox
+#blackdetect
+#blackframe
+#blend
+#buffer
+#buffersink
+#cellauto
+#channelmap
+#channelsplit
+chorus in_gain=0.400000:out_gain=0.400000:delays=1|1:decays=1|1:speeds=1|1:depths=1|1
+#codecview
+#color
+colormatrix src=bt601:dst=smpte240m
+#concat
+#copy
+#cover_rect
+#cropdetect
+#curves
+#dctdnoiz
+#decimate
+delogo x=1:y=1:w=1:h=1:band=1:show=0
+#detelecine
+#drawgraph
+#dynaudnorm
+#ebur128
+#elbg
+equalizer frequency=1000.000000:width_type=1:width=200.000000:gain=-10.000000
+#extractplanes
+#ffabuffersink
+#ffbuffersink
+#fftfilt
+#field
+#fieldmatch
+#fieldorder
+#fifo
+#find_rect
+#fliporder
+#format
+#fps
+#framepack
+#framerate
+#framestep
+#geq
+#haldclut
+#haldclutsrc
+hflip
+#hstack
+#hue
+#idet
+#interlace
+#interleave
+#isdesctest
+#join
+#life
+#lut
+#lut3d
+#lutrgb
+#lutyuv
+#mandelbrot
+#mergeplanes
+#movie
+#mpdecimate
+#mptestsrc
+#noformat
+#null
+#nullsink
+#nullsrc
+#overlay
+#pad
+#palettegen
+#paletteuse
+#pan
+#perms
+#pixdesctest
+#psnr
+#pullup
+#qp
+#random
+#removelogo
+#repeatfields
+#replaygain
+#reverse
+#rgbtestsrc
+#scale
+#scale2ref
+#select
+#sendcmd
+#separatefields
+#setdar
+#setfield
+#setpts
+#setsar
+#settb
+#showcqt
+#showfreqs
+#showinfo
+#showpalette
+#showspectrum
+#showvolume
+#showwaves
+#showwavespic
+#shuffleplanes
+#sidechaincompress
+#signalstats
+#silencedetect
+#silenceremove
+#sine
+#smptebars
+#smptehdbars
+#split
+#ssim
+swapuv
+#tblend
+#telecine
+#testsrc
+#thumbnail
+#tile
+#tinterlace
+#trim
+#vectorscope
+vflip
+#volume
+#volumedetect
+#vstack
+#w3fdif
+#waveform
+#zoompan
FileSystem directory;
directory.parse_tildas(this->filename);
- total = 0;
}
-BC_Hash::~BC_Hash()
+void BC_Hash::clear()
{
for(int i = 0; i < total; i++)
{
delete [] names[i];
delete [] values[i];
}
+ total = 0;
+}
+
+BC_Hash::~BC_Hash()
+{
+ clear();
delete [] names;
delete [] values;
}
void BC_Hash::copy_from(BC_Hash *src)
{
// Can't delete because this is used by file decoders after plugins
-// request data.
-// for(int i = 0; i < total; i++)
-// {
-// delete [] names[i];
-// delete [] values[i];
-// }
-// delete [] names;
-// delete [] values;
-//
-// allocated = 0;
-// names = 0;
-// values = 0;
-// total = 0;
+// request data. use explicit destructor to clear/clean
+// this->~BC_Hash();
SET_TRACE
reallocate_table(src->total);
int size();
char* get_key(int number);
char* get_value(int number);
+ void clear();
private:
// Reallocate table so at least total entries exist
{
next_effects.remove_all_objects();
prev_effects.remove_all_objects();
- delete params;
- params = new BC_Hash;
+ params->clear();
}
void VFrame::copy_params(VFrame *src)
strcpy(ptr, src->prev_effects.values[i]);
}
- params->copy_from(src->params);
+ copy_params(src);
}
int VFrame::equal_stacks(VFrame *src)
LIBS = \
../libzmpeg3/$(OBJDIR)/libzmpeg3.a \
- $(thirdparty_libraries) $(static_libraries) \
-lasound \
-lpthread \
-lpng \
-lbz2 \
-lm \
-ldl \
- $(EXTRA_LIBS)
+
+LIBS += -Wl,--start-group $(thirdparty_libraries) -Wl,--end-group
+LIBS += $(EXTRA_LIBS)
HVEG2LIB = $(OBJDIR)/hveg2enc.a
HVEG2ENC = $(OBJDIR)/hveg2enc
+add ffmpeg filters as plugins
+fix nvidia gl lock problem, update active vwindow tests
+fix segv in formattools for record format ffmpeg
+add ffmpeg indexing
+upgrade to ffmpeg-2.8
+move aspect ratio fixex, better get_info, fixes for ffmpeg asset detection
+aspect ratio fixes for dvd/bd create, TZ fix
+remove old quicktime, replaced with current ffmpeg
+bunch of small fixes, add msg.txt to about prefs
sync to last commit on google_code
fixups for plugins interpolate, c41
so long, Michael Niedermayer... and thanks for all the fish!!!