arch=('x86_64')
url="http://www.cinelerra-cv.org"
license=('GPL')
-depends=('xorg-server' 'xorg-server-utils' 'libpng' 'libxv' 'libva'
+depends=('xorg-server' 'libpng' 'libxv' 'libva'
'libxft' 'freetype2' 'alsa-lib' 'inkscape' 'dvdauthor')
makedepends=('yasm' 'nasm' 'cmake'
'libxml2' 'perl-xml-libxml' 'perl-xml-parser')
#include "mwindowgui.h"
#include "mutex.h"
#include "mwindow.h"
+#include "playback3d.h"
+#include "videodevice.h"
#include "vframe.h"
return 1;
}
+void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame)
+{
+ int best_color_model = output_frame->get_color_model();
+ int use_opengl =
+ device->out_config->driver == PLAYBACK_X11_GL &&
+ output_frame->get_opengl_state() == VFrame::SCREEN;
+// OpenGL does YUV->RGB in the compositing step
+ if( use_opengl )
+ best_color_model = BC_RGB888;
+ if( refresh_frame &&
+ (refresh_frame->get_w() != device->out_w ||
+ refresh_frame->get_h() != device->out_h ||
+ refresh_frame->get_color_model() != best_color_model) ) {
+ delete refresh_frame; refresh_frame = 0;
+ }
+ if( !refresh_frame ) {
+ refresh_frame =
+ new VFrame(device->out_w, device->out_h, best_color_model);
+ }
+ if( use_opengl ) {
+ get_canvas()->unlock_window();
+ unlock_canvas();
-
-
-
-
-
-
+ mwindow->playback_3d->copy_from(this, refresh_frame, output_frame, 0);
+ lock_canvas(" Canvas::output_refresh");
+ get_canvas()->lock_window(" Canvas::output_refresh");
+ }
+ else
+ refresh_frame->copy_from(output_frame);
+}
#include "edl.inc"
#include "guicast.h"
#include "mwindow.inc"
+#include "videodevice.inc"
// Output for all X11 video
virtual int get_xscroll() { return 0; };
virtual int get_yscroll() { return 0; };
virtual float get_zoom() { return 0; };
-// Redraws the image
+// Updates the refresh_frame
+ void update_refresh(VideoDevice *device, VFrame *output_frame);
+// Redraws the refresh_frame
virtual void draw_refresh(int flush = 1) {};
// Get top left offset of canvas relative to output.
x = output_x - cx / zoom;
y = output_y - cy / zoom;
}
- canvas->update_zoom((int)x, (int)y, zoom);
+ canvas->update_zoom((int)(x+0.5), (int)(y+0.5), zoom);
if( update_menu )
zoom_panel->update(value);
int FFStream::load_filter(AVFrame *frame)
{
+ av_frame_unref(frame);
int ret = av_buffersrc_add_frame_flags(buffersrc_ctx,
frame, AV_BUFFERSRC_FLAG_KEEP_REF);
- if( ret < 0 ) {
- av_frame_unref(frame);
+ if( ret < 0 )
eprintf(_("av_buffersrc_add_frame_flags failed\n"));
- }
return ret;
}
int FFStream::read_frame(AVFrame *frame)
{
+ av_frame_unref(frame);
if( !filter_graph || !buffersrc_ctx || !buffersink_ctx )
return decode(frame);
if( !fframe && !(fframe=av_frame_alloc()) ) {
void FormatPopup::create_objects()
{
- format_items.append(new BC_ListBoxItem(_(FFMPEG_NAME)));
-
if(!use_brender)
{
+ format_items.append(new BC_ListBoxItem(_(FFMPEG_NAME)));
format_items.append(new BC_ListBoxItem(_(AC3_NAME)));
format_items.append(new BC_ListBoxItem(_(AIFF_NAME)));
format_items.append(new BC_ListBoxItem(_(AU_NAME)));
#include <string.h>
#if 0
-#define STRC printf("==new %jd from %p\n", n, __builtin_return_address(0));
-void *operator new(size_t n) { STRC void *vp = malloc(n); bzero(vp,n); return vp; }
-void operator delete(void *t) { free(t); }
-void operator delete(void *t,size_t n) { free(t); }
-void *operator new[](size_t n) { STRC void *vp = malloc(n); bzero(vp,n); return vp; }
-void operator delete[](void *t) { free(t); }
-void operator delete[](void *t,size_t n) { free(t); }
+#define STRC(v) printf("==new %p from %p sz %jd\n", v, __builtin_return_address(0), n)
+#define STRD(v) printf("==del %p from %p\n", v, __builtin_return_address(0))
+void *operator new(size_t n) { void *vp = malloc(n); STRC(vp); bzero(vp,n); return vp; }
+void operator delete(void *t) { STRD(t); free(t); }
+void operator delete(void *t,size_t n) { STRD(t); free(t); }
+void *operator new[](size_t n) { void *vp = malloc(n); STRC(vp); bzero(vp,n); return vp; }
+void operator delete[](void *t) { STRD(t); free(t); }
+void operator delete[](void *t,size_t n) { STRD(t); free(t); }
#endif
enum
show_plugin(plugin);
}
}
- else
- {
- plugin->show = 0;
- }
plugin = (Plugin*)plugin->next;
}
const int debug = 0;
if(debug) PRINT_TRACE
- restart_brender();
+ init_brender();
edl->tracks->update_y_pixels(theme);
if(debug) PRINT_TRACE
mwindow->gui->unlock_window();
mwindow->edl->save_defaults(mwindow->defaults);
create_new_edl();
- create_new_project();
thread->start();
mwindow->gui->lock_window("New::handle_event");
{
start_lock->unlock();
- do
- {
+ while( !done ) {
// Wait for current command to finish
que->output_lock->lock("PlaybackEngine::run");
-
wait_render_engine();
// Read the new command
command->copy_from(&que->command);
que->command.reset();
que->input_lock->unlock();
-
//printf("PlaybackEngine::run 1 %d\n", command->command);
- switch(command->command)
- {
+ switch( command->command ) {
// Parameter change only
- case COMMAND_NONE:
-// command->command = last_command;
- perform_change();
- break;
-
- case PAUSE:
- init_cursor(0);
- pause_lock->lock("PlaybackEngine::run");
- stop_cursor();
- break;
-
- case STOP:
+ case COMMAND_NONE:
+// command->command = last_command;
+ perform_change();
+ break;
+
+ case PAUSE:
+ init_cursor(0);
+ pause_lock->lock("PlaybackEngine::run");
+ stop_cursor();
+ break;
+
+ case STOP:
// No changing
- break;
+ break;
- case CURRENT_FRAME:
- last_command = command->command;
- perform_change();
- arm_render_engine();
+ case CURRENT_FRAME:
+ last_command = command->command;
+ perform_change();
+ arm_render_engine();
// Dispatch the command
- start_render_engine();
- break;
-
- default:
- last_command = command->command;
- is_playing_back = 1;
- if(command->command == SINGLE_FRAME_FWD ||
- command->command == SINGLE_FRAME_REWIND)
- {
- command->playbackstart = get_tracking_position();
- }
+ start_render_engine();
+ break;
- perform_change();
- arm_render_engine();
+ case SINGLE_FRAME_FWD:
+ case SINGLE_FRAME_REWIND:
+ command->playbackstart = get_tracking_position();
+// fall through
+ default:
+ last_command = command->command;
+ is_playing_back = 1;
+
+ perform_change();
+ arm_render_engine();
// Start tracking after arming so the tracking position doesn't change.
// The tracking for a single frame command occurs during PAUSE
- init_tracking();
+ init_tracking();
// Dispatch the command
- start_render_engine();
- break;
+ start_render_engine();
+ break;
}
//printf("PlaybackEngine::run 100\n");
- }while(!done);
+ }
}
if( do_stop ) {
engine->que->send_command(STOP, CHANGE_NONE, 0, 0, 0, 0);
engine->interrupt_playback(wait_tracking);
-// This is necessary to get an OpenGL output buffer
-// printf("PlayTransport::handle_transport 2 update_refresh=%d prev_command=%d prev_direction=%d\n",
-// update_refresh, prev_command, prev_direction);
- if( !prev_single_frame && update_refresh &&
- prev_command != STOP && prev_command != COMMAND_NONE ) {
- int command = (prev_direction == PLAY_FORWARD) ?
- SINGLE_FRAME_REWIND : SINGLE_FRAME_FWD;
- engine->que->send_command(command,
- CHANGE_NONE, get_edl(), 1, 0, 0);
- }
}
}
if(output && output_frame)
{
-// Copy our output frame buffer to the canvas's permanent frame buffer.
-// They must be different buffers because the output frame is being written
-// while the user is redrawing the canvas frame buffer over and over.
-
- int use_opengl = device->out_config->driver == PLAYBACK_X11_GL &&
- output_frame->get_opengl_state() == VFrame::SCREEN;
- int best_color_model = output_frame->get_color_model();
-
-// OpenGL does YUV->RGB in the compositing step
- if(use_opengl)
- best_color_model = BC_RGB888;
-
- if(output->refresh_frame &&
- (output->refresh_frame->get_w() != device->out_w ||
- output->refresh_frame->get_h() != device->out_h ||
- output->refresh_frame->get_color_model() != best_color_model))
- {
- delete output->refresh_frame;
- output->refresh_frame = 0;
- }
-
- if(!output->refresh_frame)
- {
- output->refresh_frame = new VFrame(0, -1,
- device->out_w, device->out_h,
- best_color_model, -1);
- }
-
- if(use_opengl)
- {
- output->get_canvas()->unlock_window();
- output->unlock_canvas();
-
- output->mwindow->playback_3d->copy_from(output,
- output->refresh_frame, output_frame, 0);
- output->lock_canvas("VDeviceX11::close_all 2");
- output->get_canvas()->lock_window("VDeviceX11::close_all 2");
- }
- else
- output->refresh_frame->copy_from(output_frame);
-
-// // Update the status bug
-// if(!device->single_frame)
-// {
-// output->stop_video();
-// }
-// else
-// {
-// output->stop_single();
-// }
-
-// Draw the first refresh with new frame.
-// Doesn't work if video and openGL because OpenGL doesn't have
-// the output buffer for video.
-// Not necessary for any case if we mandate a frame advance after
-// every stop.
- if(/* device->out_config->driver != PLAYBACK_X11_GL ||
- */ device->single_frame)
+ output->update_refresh(device, output_frame);
+ if( device->single_frame )
output->draw_refresh();
}
}
Asset* VEdit::get_nested_asset(int64_t *source_position,
- int64_t position,
- int direction)
+ int64_t position, int direction)
{
- const int debug = 0;
- Asset *result = 0;
+ double edit_frame_rate = nested_edl ?
+ nested_edl->session->frame_rate : asset->frame_rate;
// Make position relative to edit
- *source_position = position - startproject + startsource;
-
-if(debug) printf("VEdit::get_nested_asset %d %jd %jd %jd %jd\n",
-__LINE__, *source_position, position, startproject, startsource);
+ double edit_position = (position - startproject + startsource) *
+ edit_frame_rate / edl->session->frame_rate;
+ *source_position = Units::to_int64(edit_position);
+ if( !nested_edl ) return asset;
// Descend into nested EDLs
- if(nested_edl)
- {
-// Convert position to nested EDL rate
-if(debug) printf("VEdit::get_nested_asset %d\n",
-__LINE__);
- int64_t pos = *source_position;
- if(direction == PLAY_REVERSE && pos > 0) --pos;
- *source_position = Units::to_int64((double)pos *
- nested_edl->session->frame_rate /
- edl->session->frame_rate);
- PlayableTracks *playable_tracks = new PlayableTracks(
- nested_edl,
- *source_position,
- direction,
- TRACK_VIDEO,
- 1);
- if(playable_tracks->size())
- {
- VTrack *nested_track = (VTrack*)playable_tracks->get(0);
- VEdit* nested_edit = (VEdit*)nested_track->edits->editof(
- *source_position,
- direction,
- 1);
- if(nested_edit)
- {
- result = nested_edit->get_nested_asset(
- source_position,
- *source_position,
- direction);
- }
- }
-
- delete playable_tracks;
-if(debug) printf("VEdit::get_nested_asset %d\n",
-__LINE__);
- return result;
- }
- else
- {
-// Convert position to asset rate
-if(debug) printf("VEdit::get_nested_asset %d %jd %f %f\n",
-__LINE__,
-*source_position,
-asset->frame_rate,
-edl->session->frame_rate);
- int64_t pos = *source_position;
- if(direction == PLAY_REVERSE && pos > 0) --pos;
- *source_position = Units::to_int64((double)pos *
- asset->frame_rate /
- edl->session->frame_rate);
-
- return asset;
- }
+ PlayableTracks playable_tracks(nested_edl,
+ *source_position, direction, TRACK_VIDEO, 1);
+ if( !playable_tracks.size() ) return 0;
+ VTrack *nested_track = (VTrack*)playable_tracks[0];
+ VEdit* nested_edit = (VEdit*)nested_track->edits->
+ editof(*source_position, direction, 1);
+ if( !nested_edit ) return 0;
+ return nested_edit->get_nested_asset(source_position,
+ *source_position, direction);
}
-int VEdit::read_frame(VFrame *video_out,
- int64_t input_position,
- int direction,
- CICache *cache,
- int use_nudge,
- int use_cache,
- int use_asynchronous)
+int VEdit::read_frame(VFrame *video_out, int64_t input_position, int direction,
+ CICache *cache, int use_nudge, int use_cache, int use_asynchronous)
{
File *file = 0;
int result = 0;
if(debug) printf("VEdit::read_frame %d source_position=%jd input_position=%jd\n",
__LINE__, source_position, input_position);
- Asset *asset = get_nested_asset(&source_position,
- input_position,
- direction);
+ Asset *asset = get_nested_asset(&source_position, input_position, direction);
if( !asset ) result = 1;
if(debug) printf("VEdit::read_frame %d source_position=%jd input_position=%jd\n",
__LINE__, asset->path, source_position);
if( !result ) {
-if(debug) printf("VEdit::read_frame %d\n", __LINE__);
- source_position = (direction == PLAY_FORWARD) ?
- source_position :
- (source_position - 1);
-if(debug) printf("VEdit::read_frame %d %jd %jd\n",
- __LINE__, input_position, source_position);
-
+ if(direction == PLAY_REVERSE && source_position > 0)
+ --source_position;
if(use_asynchronous)
file->start_video_decode_thread();
else
int64_t start_position_project = (int64_t)(start_position *
edl_rate /
frame_rate);
- if(direction == PLAY_REVERSE) start_position_project--;
+ if(direction == PLAY_REVERSE && start_position_project > 0 )
+ start_position_project--;
// speed curve
-int VModule::import_frame(VFrame *output,
- VEdit *current_edit,
- int64_t input_position,
- double frame_rate,
- int direction,
- int use_opengl)
+int VModule::import_frame(VFrame *output, VEdit *current_edit,
+ int64_t input_position, double frame_rate, int direction, int use_opengl)
{
int64_t direction_position;
// Translation of edit
- float in_x;
- float in_y;
- float in_w;
- float in_h;
- float out_x;
- float out_y;
- float out_w;
- float out_h;
+ float in_x, in_y, in_w, in_h;
+ float out_x, out_y, out_w, out_h;
int result = 0;
const int debug = 0;
double edl_rate = get_edl()->session->frame_rate;
int64_t input_position_project = Units::to_int64(input_position *
- edl_rate /
- frame_rate +
- 0.001);
-
-
-
-
-
-
+ edl_rate / frame_rate + 0.001);
if(!output) printf("VModule::import_frame %d output=%p\n", __LINE__, output);
//output->dump_params();
-
if(debug) printf("VModule::import_frame %d this=%p input_position=%lld direction=%d\n",
- __LINE__,
- this,
- (long long)input_position,
- direction);
+ __LINE__, this, (long long)input_position, direction);
// Convert to position corrected for direction
direction_position = input_position;
- if(direction == PLAY_REVERSE)
- {
- direction_position--;
- input_position_project--;
+ if(direction == PLAY_REVERSE) {
+ if( direction_position > 0 ) direction_position--;
+ if( input_position_project > 0 ) input_position_project--;
}
if(!output) printf("VModule::import_frame %d output=%p\n", __LINE__, output);
}
if(!output) printf("VModule::import_frame %d output=%p x11_device=%p nested_edl=%p\n",
- __LINE__,
- output,
- x11_device,
- nested_edl);
-
+ __LINE__, output, x11_device, nested_edl);
if(debug) printf("VModule::import_frame %d current_edit=%p\n",
- __LINE__,
- current_edit);
-
+ __LINE__, current_edit);
// Load frame into output
// Create objects for nested EDL
- if(current_edit &&
- current_edit->nested_edl)
- {
+ if(current_edit && current_edit->nested_edl) {
int command;
if(debug) printf("VModule::import_frame %d nested_edl=%p current_edit->nested_edl=%p\n",
- __LINE__,
- nested_edl,
- current_edit->nested_edl);
+ __LINE__, nested_edl, current_edit->nested_edl);
// Convert requested direction to command
if(renderengine->command->command == CURRENT_FRAME)
--- /dev/null
+#include <stdio.h>
+#include <strings.h>
+
+#include <map>
+using namespace std;
+
+#if 0
+#define STRC(v) printf("==new %p from %p sz %jd\n", v, __builtin_return_address(0), n)
+#define STRD(v) printf("==del %p from %p\n", v, __builtin_return_address(0))
+void *operator new(size_t n) { void *vp = malloc(n); STRC(vp); bzero(vp,n); return vp; }
+void operator delete(void *t) { STRD(t); free(t); }
+void operator delete(void *t,size_t n) { STRD(t); free(t); }
+void *operator new[](size_t n) { void *vp = malloc(n); STRC(vp); bzero(vp,n); return vp; }
+void operator delete[](void *t) { STRD(t); free(t); }
+void operator delete[](void *t,size_t n) { STRD(t); free(t); }
+#endif
+
+
+class blob
+{
+public:
+ int64_t adr, from, sz;
+ blob(int64_t adr, int64_t from, int64_t sz) {
+ this->adr = adr; this->from = from; this->sz = sz;
+ }
+};
+typedef map<int64_t, blob*> recd_map;
+typedef recd_map::value_type recd_val;
+typedef recd_map::iterator recd_it;
+
+int main(int ac, char **av)
+{
+ int64_t adr, from, sz;
+ recd_map recds;
+ char line[256];
+ FILE *fp = stdin;
+
+ while( fgets(line,sizeof(line),fp) ) {
+ if( line[0] != '=' ) continue;
+ if( line[1] != '=' ) continue;
+ if( sscanf(line, "==new %jx from %jx sz %jd\n", &adr, &from, &sz) == 3 ) {
+ recds.insert(recd_val(adr, new blob(adr,from,sz)));
+ continue;
+ }
+ if( sscanf(line, "==del %jx from %jx\n", &adr, &from) == 2 ) {
+ recd_it ri = recds.lower_bound(adr);
+ if( ri == recds.end() || ri->first != adr ) {
+ printf("del miss adr %jx\n", adr);
+ continue;
+ }
+ recds.erase(ri);
+ }
+ }
+
+ int64_t n = recds.size(); sz = 0;
+ for( recd_it ri = recds.begin(); ri != recds.end(); ++ri ) sz += ri->second->sz;
+ printf("in use: %jd sz %jd\n", n, sz);
+
+ recd_map leaks;
+ for( recd_it ri = recds.begin(); ri != recds.end(); ++ri ) {
+ adr = ri->second->adr; from = ri->second->from; sz = ri->second->sz;
+ recd_it li = leaks.lower_bound(from);
+ if( li == leaks.end() || li->first != from ) {
+ leaks.insert(recd_val(from, new blob(adr,from,sz)));
+ }
+ else {
+ li->second->sz += sz;
+ }
+ }
+ sz = 0; n = 0;
+ for( recd_it li = leaks.begin(); li != leaks.end(); ++li,++n ) {
+ printf("==leak at %jx sz %jd\n", li->second->from, li->second->sz);
+ sz += li->second->sz;
+ }
+ printf("leakers: %jd/%jd sz %jd\n", leaks.size(), n, sz);
+ return 0;
+}
+
if( row[2] > maxima_b ) maxima_b = row[2];
}
}
- if( minima_r < 1e-6 ) minima_r = 1e-6;
- if( minima_g < 1e-6 ) minima_g = 1e-6;
- if( minima_b < 1e-6 ) minima_b = 1e-6;
values.min_r = minima_r; values.max_r = maxima_r;
values.min_g = minima_g; values.max_g = maxima_g;
values.min_b = minima_b; values.max_b = maxima_b;
values.light = maxima_r < 1e-6 ? 1.0 : minima_r / maxima_r;
- values.gamma_g = logf(maxima_r / minima_r) / logf(maxima_g / minima_g);
- values.gamma_b = logf(maxima_r / minima_r) / logf(maxima_b / minima_b);
+ bclamp(minima_r, 1e-6, 1-1e-6); bclamp(maxima_r, 1e-6, 1-1e-6);
+ bclamp(minima_g, 1e-6, 1-1e-6); bclamp(maxima_g, 1e-6, 1-1e-6);
+ bclamp(minima_b, 1e-6, 1-1e-6); bclamp(maxima_b, 1e-6, 1-1e-6);
+ float log_r = logf(maxima_r / minima_r);
+ float log_g = logf(maxima_g / minima_g);
+ float log_b = logf(maxima_b / minima_b);
+ if( log_g < 1e-6 ) log_g = 1e-6;
+ if( log_b < 1e-6 ) log_b = 1e-6;
+ values.gamma_g = log_r / log_g;
+ values.gamma_b = log_r / log_b;
values.shave_min_col = shave_min_col;
values.shave_max_col = shave_max_col;
values.shave_min_row = shave_min_row;
values.shave_max_row = shave_max_row;
- values.coef1 = -1;
- values.coef2 = -1;
+ values.coef1 = values.coef2 = -1;
// Update GUI
send_render_gui(&values);
// Calculate postprocessing coeficents
values.coef2 = minima_r;
- if( minima_g < values.coef2 )
- values.coef2 = minima_g;
- if( minima_b < values.coef2 )
- values.coef2 = minima_b;
+ if( minima_g < values.coef2 ) values.coef2 = minima_g;
+ if( minima_b < values.coef2 ) values.coef2 = minima_b;
values.coef1 = maxima_r;
- if( maxima_g > values.coef1 )
- values.coef1 = maxima_g;
- if( maxima_b > values.coef1 )
- values.coef1 = maxima_b;
- // Try not to overflow RGB601
- // (235 - 16) / 256 * 0.9
+ if( maxima_g > values.coef1 ) values.coef1 = maxima_g;
+ if( maxima_b > values.coef1 ) values.coef1 = maxima_b;
+ // Try not to overflow RGB601 (235 - 16) / 256 * 0.9
float den = values.coef1 - values.coef2;
- if( fabs(den) < 1e-6 )
- den = den < 0 ? -1e-6 : 1e-6;
+ if( fabs(den) < 1e-6 ) den = 1e-6;
values.coef1 = 0.770 / den;
values.coef2 = 0.065 - values.coef2 * values.coef1;
send_render_gui(&values);