$(OBJDIR)/file.o \
$(OBJDIR)/fileogg.o \
$(OBJDIR)/filepng.o \
+ $(OBJDIR)/fileppm.o \
$(OBJDIR)/filescene.o \
$(OBJDIR)/filesndfile.o \
$(OBJDIR)/filetga.o \
$(OBJDIR)/menueffects.o \
$(OBJDIR)/menutransitionlength.o \
$(OBJDIR)/menuveffects.o \
+ $(OBJDIR)/meterhistory.o \
$(OBJDIR)/meterpanel.o \
$(OBJDIR)/module.o \
$(OBJDIR)/mtimebar.o \
data_type = TRACK_AUDIO;
transition_temp = 0;
speed_temp = 0;
- level_history = 0;
- current_level = 0;
bzero(nested_output, sizeof(Samples*) * MAX_CHANNELS);
bzero(prev_head, SPEED_OVERLAP * sizeof(double));
bzero(prev_tail, SPEED_OVERLAP * sizeof(double));
+ meter_history = new MeterHistory();
nested_allocation = 0;
resample = 0;
asset = 0;
AModule::~AModule()
{
- if(transition_temp) delete transition_temp;
- if(speed_temp) delete speed_temp;
- if(level_history)
- {
- delete [] level_history;
- delete [] level_samples;
- }
-
+ delete transition_temp;
+ delete speed_temp;
+ delete meter_history;
for(int i = 0; i < MAX_CHANNELS; i++)
- {
- if(nested_output[i])
- {
- delete nested_output[i];
- }
- }
-
+ delete nested_output[i];
delete resample;
}
{
Module::create_objects();
// Not needed in pluginarray
- if(commonrender)
- {
- level_history = new double[((ARender*)commonrender)->total_peaks];
- level_samples = new int64_t[((ARender*)commonrender)->total_peaks];
- current_level = 0;
-
- for(int i = 0; i < ((ARender*)commonrender)->total_peaks; i++)
- {
- level_history[i] = 0;
- level_samples[i] = -1;
- }
+ if( commonrender ) {
+ meter_history->init(1, ((ARender*)commonrender)->total_peaks);
+ meter_history->reset_channel(0);
}
}
#include "filexml.inc"
#include "floatautos.inc"
#include "maxchannels.h"
+#include "meterhistory.h"
#include "module.h"
#include "resample.h"
#include "samples.inc"
FloatAutos* get_pan_automation(int channel); // get pan automation
FloatAutos* get_fade_automation(); // get the fade automation for this module
-
- double *level_history;
- int64_t *level_samples;
- int current_level;
+ MeterHistory *meter_history;
// Temporary buffer for rendering transitions
Samples *transition_temp;
: CommonRender(renderengine)
{
// Clear output buffers
- for(int i = 0; i < MAXCHANNELS; i++)
- {
+ for( int i=0; i<MAXCHANNELS; ++i ) {
buffer[i] = 0;
audio_out[i] = 0;
buffer_allocated[i] = 0;
- level_history[i] = 0;
}
- level_samples = 0;
total_peaks = 0;
-
+ meter_history = new MeterHistory();
data_type = TRACK_AUDIO;
}
ARender::~ARender()
{
- for(int i = 0; i < MAXCHANNELS; i++)
- {
- if(buffer[i]) delete buffer[i];
- if(level_history[i]) delete [] level_history[i];
- }
- if(level_samples) delete [] level_samples;
+ for( int i=0; i<MAXCHANNELS; ++i ) delete buffer[i];
+ delete meter_history;
}
void ARender::arm_command()
int ARender::calculate_history_size()
{
- if(total_peaks > 0)
- return total_peaks;
- else
- {
+ if( !total_peaks ) {
meter_render_fragment = renderengine->fragment_len;
+ int tracking_fragment = renderengine->get_edl()->session->sample_rate / TRACKING_RATE;
// This number and the timer in tracking.C determine the rate
- while(meter_render_fragment >
- renderengine->get_edl()->session->sample_rate / TRACKING_RATE)
- meter_render_fragment /= 2;
- total_peaks = 16 *
- renderengine->fragment_len /
- meter_render_fragment;
- return total_peaks;
+ while( meter_render_fragment > tracking_fragment ) meter_render_fragment /= 2;
+ total_peaks = 16 * renderengine->fragment_len / meter_render_fragment;
}
+ return total_peaks;
}
int ARender::init_meters()
{
// not providing enough peaks results in peaks that are ahead of the sound
- if(level_samples) delete [] level_samples;
- calculate_history_size();
- level_samples = new int64_t[total_peaks];
-
- for(int i = 0; i < MAXCHANNELS;i++)
- {
- current_level[i] = 0;
- if(buffer[i] && !level_history[i])
- level_history[i] = new double[total_peaks];
- }
-
- for(int i = 0; i < total_peaks; i++)
- {
- level_samples[i] = -1;
- }
-
- for(int j = 0; j < MAXCHANNELS; j++)
- {
- if(buffer[j])
- for(int i = 0; i < total_peaks; i++)
- level_history[j][i] = 0;
+ meter_history->init(MAXCHANNELS, calculate_history_size());
+ for( int i=0; i<MAXCHANNELS; ++i ) {
+ if( buffer[i] ) meter_history->reset_channel(i);
}
return 0;
}
void ARender::allocate_buffers(int samples)
{
- for(int i = 0; i < MAXCHANNELS; i++)
- {
+ for( int i=0; i<MAXCHANNELS; ++i ) {
// Reset the output buffers in case speed changed
- if(buffer_allocated[i] < samples)
- {
- delete buffer[i];
- buffer[i] = 0;
+ if( buffer_allocated[i] < samples ||
+ i >= renderengine->get_edl()->session->audio_channels ) {
+ delete buffer[i]; buffer[i] = 0;
}
- if(i < renderengine->get_edl()->session->audio_channels)
- {
+ if( !buffer[i] && i < renderengine->get_edl()->session->audio_channels ) {
buffer[i] = new Samples(samples);
buffer_allocated[i] = samples;
- audio_out[i] = buffer[i];
}
+ audio_out[i] = buffer[i];
}
}
return result;
}
-int ARender::get_history_number(int64_t *table, int64_t position)
-{
-// Get the entry closest to position
- int result = 0;
- int64_t min_difference = 0x7fffffff;
- for(int i = 0; i < total_peaks; i++)
- {
-
-//printf("%jd ", table[i]);
- if(labs(table[i] - position) < min_difference)
- {
- min_difference = labs(table[i] - position);
- result = i;
- }
- }
-//printf("\n");
-//printf("ARender::get_history_number %jd %d\n", position, result);
- return result;
-}
-
void ARender::send_last_buffer()
{
if( renderengine->audio )
stop_plugins();
}
-
-int ARender::get_next_peak(int current_peak)
-{
- current_peak++;
- if(current_peak >= total_peaks) current_peak = 0;
- return current_peak;
-}
-
-
#include "atrack.inc"
#include "commonrender.h"
#include "maxchannels.h"
+#include "meterhistory.h"
#include "samples.inc"
class ARender : public CommonRender
// Calculate number of samples in each meter fragment and how many
// meter fragments to buffer.
+ int init_meters();
int calculate_history_size();
-// Get subscript of history entry corresponding to sample
- int get_history_number(int64_t *table, int64_t position);
+ int total_peaks;
+ MeterHistory *meter_history;
+// samples to use for one meter update. Must be multiple of fragment_len
+ int64_t meter_render_fragment;
int64_t tounits(double position, int round);
double fromunits(int64_t position);
Samples *buffer[MAXCHANNELS];
// allocated buffer sizes for nested EDL rendering
int buffer_allocated[MAXCHANNELS];
-// information for meters
- int get_next_peak(int current_peak);
- int init_meters();
-// samples to use for one meter update. Must be multiple of fragment_len
- int64_t meter_render_fragment;
-// Level history of output buffers
- double *level_history[MAXCHANNELS];
-// sample position of each level
- int64_t *level_samples;
-// total entries in level_history
- int total_peaks;
-// Next level to store value in
- int current_level[MAXCHANNELS];
// Make VirtualAConsole block before the first buffer until video is ready
int first_buffer;
};
snapshot_submenu->add_submenuitem(new SnapshotMenuItem(snapshot_submenu, _("png"), SNAPSHOT_PNG));
snapshot_submenu->add_submenuitem(new SnapshotMenuItem(snapshot_submenu, _("jpeg"), SNAPSHOT_JPEG));
snapshot_submenu->add_submenuitem(new SnapshotMenuItem(snapshot_submenu, _("tiff"), SNAPSHOT_TIFF));
+ snapshot_submenu->add_submenuitem(new SnapshotMenuItem(snapshot_submenu, _("ppm"), SNAPSHOT_PPM));
GrabshotSubMenu *grabshot_submenu;
add_item(asset_grabshot = new AssetGrabshot(mwindow, this));
asset_grabshot->add_submenu(grabshot_submenu = new GrabshotSubMenu(asset_grabshot));
grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("png"), GRABSHOT_PNG));
grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("jpeg"), GRABSHOT_JPEG));
grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("tiff"), GRABSHOT_TIFF));
+ grabshot_submenu->add_submenuitem(new GrabshotMenuItem(grabshot_submenu, _("ppm"), GRABSHOT_PPM));
update_titles(shots_displayed = 1);
}
Preferences *preferences = mwindow->preferences;
char filename[BCTEXTLEN];
- static const char *exts[] = { "png", "jpg", "tif" };
+ static const char *exts[] = { "png", "jpg", "tif", "ppm" };
time_t tt; time(&tt);
struct tm tm; localtime_r(&tt,&tm);
snprintf(filename,sizeof(filename),"%s/%s_%04d%02d%02d-%02d%02d%02d.%s",
asset->tiff_cmodel = 0;
asset->tiff_compression = 0;
break;
+ case SNAPSHOT_PPM:
+ asset->format = FILE_PPM;
+ break;
}
asset->width = fw;
asset->height = fh;
MWindow *mwindow = grab_thread->mwindow;
Preferences *preferences = mwindow->preferences;
char filename[BCTEXTLEN];
- static const char *exts[] = { "png", "jpg", "tif" };
+ static const char *exts[] = { "png", "jpg", "tif", "ppm" };
time_t tt; time(&tt);
struct tm tm; localtime_r(&tt,&tm);
snprintf(filename,sizeof(filename),"%s/%s_%04d%02d%02d-%02d%02d%02d.%s",
Asset *asset = new Asset(filename);
switch( mode ) {
- case SNAPSHOT_PNG:
+ case GRABSHOT_PNG:
asset->format = FILE_PNG;
asset->png_use_alpha = 1;
break;
- case SNAPSHOT_JPEG:
+ case GRABSHOT_JPEG:
asset->format = FILE_JPEG;
asset->jpeg_quality = 90;
break;
- case SNAPSHOT_TIFF:
+ case GRABSHOT_TIFF:
asset->format = FILE_TIFF;
asset->tiff_cmodel = 0;
asset->tiff_compression = 0;
break;
+ case GRABSHOT_PPM:
+ asset->format = FILE_PPM;
+ break;
}
// no odd dimensions
int rw = get_root_w(0), rh = get_root_h(0);
#define SNAPSHOT_PNG 0
#define SNAPSHOT_JPEG 1
#define SNAPSHOT_TIFF 2
+#define SNAPSHOT_PPM 3
#define GRABSHOT_PNG 0
#define GRABSHOT_JPEG 1
#define GRABSHOT_TIFF 2
+#define GRABSHOT_PPM 3
class AssetPopup;
class AssetPopupInfo;
{
for(module = 0; module < total_modules; module++)
{
- modules[module]->create_objects();
+ modules[module]->Module::create_objects();
}
}
}
ret = write_packet(opkt);
if( ret < 0 ) break;
++pkts;
- if( stats_fp ) {
+ if( frame && stats_fp ) {
ret = write_stats_file();
if( ret < 0 ) break;
}
case BC_RGB161616: return AV_PIX_FMT_RGB48LE;
case BC_RGBA16161616: return AV_PIX_FMT_RGBA64LE;
case BC_AYUV16161616: return AV_PIX_FMT_AYUV64LE;
+ case BC_GBRP: return AV_PIX_FMT_GBRP;
default: break;
}
case AV_PIX_FMT_RGB48LE: return BC_RGB161616;
case AV_PIX_FMT_RGBA64LE: return BC_RGBA16161616;
case AV_PIX_FMT_AYUV64LE: return BC_AYUV16161616;
+ case AV_PIX_FMT_GBRP: return BC_GBRP;
default: break;
}
vstrm_index.append(ffidx(vidx, 0));
vid->avctx = ctx; ffvideo.append(vid); fst = vid;
vid->width = asset->width;
- ctx->width = (vid->width+3) & ~3;
vid->height = asset->height;
- ctx->height = (vid->height+3) & ~3;
vid->frame_rate = asset->frame_rate;
+ AVPixelFormat pix_fmt = codec->pix_fmts ?
+ codec->pix_fmts[0] : AV_PIX_FMT_YUV420P;
+ AVDictionaryEntry *tag = av_dict_get(sopts, "cin_pix_fmt", NULL, 0);
+ if( tag != 0 ) {
+ int avfmt = av_get_pix_fmt(tag->value);
+ if( avfmt < 0 ) {
+ eprintf(_("cin_pix_fmt unknown = %s\n"), tag->value);
+ ret = 1;
+ break;
+ }
+ pix_fmt = (AVPixelFormat)avfmt;
+ }
+ ctx->pix_fmt = pix_fmt;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+ int mask_w = (1<<desc->log2_chroma_w)-1;
+ if( mask_w > 0 ) ctx->width = (vid->width+mask_w) & ~mask_w;
+ int mask_h = (1<<desc->log2_chroma_h)-1;
+ if( mask_h > 0 ) ctx->height = (vid->height+mask_h) & ~mask_h;
ctx->sample_aspect_ratio = to_sample_aspect_ratio(asset);
- ctx->pix_fmt = codec->pix_fmts ? codec->pix_fmts[0] : AV_PIX_FMT_YUV420P;
AVRational frame_rate = check_frame_rate(codec, vid->frame_rate);
if( !frame_rate.num || !frame_rate.den ) {
eprintf(_("check_frame_rate failed %s\n"), filename);
#undef HAVE_STDLIB_H // automake conflict
#include "fileogg.h"
#include "filepng.h"
+#include "fileppm.h"
#include "filescene.h"
#include "filesndfile.h"
#include "filetga.h"
//ArrayList<PluginServer*> *plugindb = format->plugindb;
Asset *asset = format->asset;
+ format_window = 0;
getting_options = 1;
format_completion->lock("File::get_options");
switch( asset->format ) {
FilePNG::get_parameters(parent_window, asset, format_window,
audio_options, video_options);
break;
+ case FILE_PPM:
+ case FILE_PPM_LIST:
+ FilePPM::get_parameters(parent_window, asset, format_window,
+ audio_options, video_options);
+ break;
case FILE_TGA:
case FILE_TGA_LIST:
FileTGA::get_parameters(parent_window, asset, format_window,
#endif
"SndFile",
"PNG",
+ "PPM",
"JPEG",
"GIF",
#ifdef HAVE_OPENEXR
file = new FilePNG(this->asset, this);
return FILE_OK;
}
+ if( !strcmp(pref->name,"PPM") ) { // PPM file
+ if( !FilePPM::check_sig(this->asset) ) continue;
+ file = new FilePPM(this->asset, this);
+ return FILE_OK;
+ }
if( !strcmp(pref->name,"JPEG") ) { // JPEG file
if( !FileJPEG::check_sig(this->asset) ) continue;
file = new FileJPEG(this->asset, this);
file = new FilePNG(this->asset, this);
break;
+ case FILE_PPM:
+ case FILE_PPM_LIST:
+ file = new FilePPM(this->asset, this);
+ break;
+
case FILE_JPEG:
case FILE_JPEG_LIST:
file = new FileJPEG(this->asset, this);
if( !strcasecmp(format, _(SND_NAME)) ) return FILE_SND;
if( !strcasecmp(format, _(PNG_NAME)) ) return FILE_PNG;
if( !strcasecmp(format, _(PNG_LIST_NAME)) ) return FILE_PNG_LIST;
+ if( !strcasecmp(format, _(PPM_NAME)) ) return FILE_PPM;
+ if( !strcasecmp(format, _(PPM_LIST_NAME)) ) return FILE_PPM_LIST;
if( !strcasecmp(format, _(TIFF_NAME)) ) return FILE_TIFF;
if( !strcasecmp(format, _(TIFF_LIST_NAME)) ) return FILE_TIFF_LIST;
if( !strcasecmp(format, _(JPEG_NAME)) ) return FILE_JPEG;
case FILE_SND: return _(SND_NAME);
case FILE_PNG: return _(PNG_NAME);
case FILE_PNG_LIST: return _(PNG_LIST_NAME);
+ case FILE_PPM: return _(PPM_NAME);
+ case FILE_PPM_LIST: return _(PPM_LIST_NAME);
case FILE_JPEG: return _(JPEG_NAME);
case FILE_JPEG_LIST: return _(JPEG_LIST_NAME);
case FILE_CR2: return _(CR2_NAME);
#endif
case FILE_PNG:
case FILE_PNG_LIST: return FilePNG::get_best_colormodel(asset, driver);
+ case FILE_PPM:
+ case FILE_PPM_LIST: return FilePPM::get_best_colormodel(asset, driver);
case FILE_TGA:
case FILE_TGA_LIST: return FileTGA::get_best_colormodel(asset, driver);
case FILE_CR2:
case FILE_EXR_LIST:
case FILE_PNG:
case FILE_PNG_LIST:
+ case FILE_PPM:
+ case FILE_PPM_LIST:
case FILE_TGA:
case FILE_TGA_LIST:
case FILE_TIFF:
case FILE_EXR:
case FILE_JPEG:
case FILE_PNG:
+ case FILE_PPM:
case FILE_TGA:
case FILE_TIFF:
return 1;
case FILE_PCM: return "pcm";
case FILE_PNG: return "png";
case FILE_PNG_LIST: return "png";
+ case FILE_PPM: return "ppm";
+ case FILE_PPM_LIST: return "ppm";
case FILE_TGA: return "tga";
case FILE_TGA_LIST: return "tga";
case FILE_TIFF: return "tif";
case FILE_PCM: return "PCM";
case FILE_WAV: return "WAV";
case FILE_PNG: return "PNG";
+ case FILE_PPM: return "PPM";
case FILE_JPEG: return "JPEG";
case FILE_TIFF: return "TIFF";
case FILE_GIF: return "GIF";
case FILE_RAWDV: return "RAWDV";
case FILE_TIFF_LIST: return "TIFF_LIST";
case FILE_PNG_LIST: return "PNG_LIST";
+ case FILE_PPM_LIST: return "PPM_LIST";
case FILE_AC3: return "AC3";
case FILE_EXR: return "EXR";
case FILE_EXR_LIST: return "EXR_LIST";
#define FILE_CR2_LIST 35
#define FILE_GIF_LIST 36
#define FILE_DB 37
+#define FILE_PPM 38
+#define FILE_PPM_LIST 39
// For formats supported by plugins, the format number is the plugin number in the
// plugin list ORed with 0x8000.
N_("OGG Vorbis") // For decoding only
N_("PNG")
N_("PNG Sequence")
+N_("PPM")
+N_("PPM Sequence")
N_("Raw DV")
N_("Raw PCM")
N_("Sun/NeXT AU")
#define PCM_NAME "Raw PCM"
#define PNG_LIST_NAME "PNG Sequence"
#define PNG_NAME "PNG"
+#define PPM_LIST_NAME "PPM Sequence"
+#define PPM_NAME "PPM"
#define RAWDV_NAME "Raw DV"
#define SCENE_NAME "Text To Movie"
#define SND_NAME "Unknown sound"
--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "asset.h"
+#include "bccmodels.h"
+#include "file.h"
+#include "fileppm.h"
+#include "interlacemodes.h"
+#include "mainerror.h"
+
+#include <string.h>
+#include <unistd.h>
+
+
+FilePPM::FilePPM(Asset *asset, File *file)
+ : FileList(asset, file, "PPMLIST", ".ppm", FILE_PPM, FILE_PPM_LIST)
+{
+ reset();
+ if( asset->format == FILE_UNKNOWN )
+ asset->format = FILE_PPM;
+}
+
+FilePPM::~FilePPM()
+{
+ close_file();
+}
+
+void FilePPM::reset()
+{
+}
+
+int FilePPM::check_sig(Asset *asset)
+{
+ FILE *stream = fopen(asset->path, "r");
+ if( stream ) {
+ char test[10];
+ (void)fread(test, 10, 1, stream);
+ fclose(stream);
+ if( !strncmp("PPMLIST",test,6) ) return 1;
+ if( !strncmp("P6\n",test,3) ) return 1;
+ }
+ return 0;
+}
+
+int FilePPM::check_frame_header(FILE *fp)
+{
+ char text[BCSTRLEN];
+ if( !fgets(text, sizeof(text), fp) ) return 1;
+ if( strcmp("P6\n",text) ) return 1;
+ int ch = getc(fp);
+ while( ch == '#' ) { while( (ch=getc(fp))>=0 && ch!='\n' ); }
+ ungetc(ch,fp);
+ int w, h;
+ if( !fgets(text, sizeof(text), fp) ||
+ sscanf(text, "%d %d\n", &w, &h) != 2 ) return 1;
+ if( !fgets(text, sizeof(text), fp) ||
+ sscanf(text, "%d\n", &ch) != 1 || ch != 255 ) return 1;
+
+ asset->width = w; asset->height = h;
+ asset->interlace_mode = ILACE_MODE_NOTINTERLACED;
+ return 0;
+}
+
+int FilePPM::read_frame_header(char *path)
+{
+ int ret = 1;
+ FILE *fp = fopen(path, "r");
+ if( fp ) {
+ ret = check_frame_header(fp);
+ fclose(fp);
+ }
+ return ret;
+}
+
+int FilePPM::read_ppm(FILE *fp, VFrame *frame)
+{
+ int ch;
+ char text[BCSTRLEN];
+ if( !fgets(text, sizeof(text), fp) ) return 1;
+ if( strcmp("P6\n",text) ) {
+ printf("FilePPM::read_ppm: header err\n");
+ return 1;
+ }
+ while( (ch=getc(fp)) == '#' ) { while( (ch=getc(fp))>=0 && ch!='\n' ); }
+ ungetc(ch,fp);
+ int w, h;
+ if( !fgets(text, sizeof(text), fp) ||
+ sscanf(text, "%d %d\n", &w, &h) != 2 ) {
+ printf("FilePPM::read_ppm: geom err\n");
+ return 1;
+ }
+ if( w != frame->get_w() || h != frame->get_h() ) {
+ printf("FilePPM::read_ppm: geom mismatch\n");
+ return 1;
+ }
+ if( !fgets(text, sizeof(text), fp) ||
+ sscanf(text, "%d\n", &ch) != 1 || ch != 255 ) {
+ printf("FilePPM::read_ppm: mask err\n");
+ return 1;
+ }
+
+ unsigned char **rows = frame->get_rows();
+ int bpl = 3*w;
+ for( int y=0; y<h; ++y ) {
+ int ret = fread(rows[y],1,bpl,fp);
+ if( ret != bpl ) {
+ printf("FilePPM::read_ppm: read (%d,%d) err: %m\n", bpl, ret);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int FilePPM::read_frame(VFrame *frame, char *path)
+{
+ int result = 1;
+ FILE *fp = fopen(path,"r");
+ if( fp ) {
+ result = read_ppm(fp, frame);
+ fclose(fp);
+ }
+ if( result )
+ eprintf("FilePPM::read_frame: cant read file %s\n", path);
+ return result;
+}
+
+PPMUnit::PPMUnit(FilePPM *file, FrameWriter *writer)
+ : FrameWriterUnit(writer)
+{
+ this->file = file;
+ temp_frame = 0;
+}
+PPMUnit::~PPMUnit()
+{
+ delete temp_frame;
+}
+
+FrameWriterUnit* FilePPM::new_writer_unit(FrameWriter *writer)
+{
+ return new PPMUnit(this, writer);
+}
+
+int FilePPM::write_frame(VFrame *frame, VFrame *output,
+ FrameWriterUnit *frame_writer_unit)
+{
+ int w = asset->width, h = asset->height;
+ char prefix[BCTEXTLEN];
+ int pfx = sprintf(prefix, "P6\n%d %d\n%d\n", w, h, 255);
+ int bpl = 3*w, image_length = h*bpl, total_length = pfx + image_length;
+ if( output->get_compressed_allocated() < total_length ) {
+ int new_length = total_length + 255;
+ output->allocate_compressed_data(new_length);
+ }
+ unsigned char *dp = output->get_data(), *bp = dp;
+ memcpy(dp, prefix, pfx); dp += pfx;
+ unsigned char *rows[h+1], **rp = rows;
+ for( int y=h; --y>=0; dp+=bpl ) *rp++ = dp;
+ BC_CModels::transfer(rows, frame->get_rows(),
+ 0, 0, 0, frame->get_y(), frame->get_u(), frame->get_v(),
+ 0, 0, frame->get_w(), frame->get_h(), 0, 0, w, h,
+ frame->get_color_model(), BC_RGB888, 0,
+ frame->get_bytes_per_line(), bpl);
+
+ output->set_compressed_size(dp - bp);
+ return 0;
+}
+
+int FilePPM::colormodel_supported(int colormodel)
+{
+ return BC_RGB888;
+}
+
+int FilePPM::get_best_colormodel(Asset *asset, int driver)
+{
+ return BC_RGB888;
+}
+
+PPMConfigVideo::PPMConfigVideo(BC_WindowBase *gui, Asset *asset)
+ : BC_Window(_(PROGRAM_NAME ": Video Compression"),
+ gui->get_abs_cursor_x(1), gui->get_abs_cursor_y(1), 200, 100)
+{
+ this->gui = gui;
+ this->asset = asset;
+ lock_window("PPMConfigVideo::create_objects()");
+ int x = 10, y = 10;
+ add_subwindow(new BC_Title(x, y, _("PPM, RGB raw only")));
+ add_subwindow(new BC_OKButton(this));
+ show_window(1);
+ unlock_window();
+}
+
+void FilePPM::get_parameters(BC_WindowBase *parent_window, Asset *asset,
+ BC_WindowBase* &format_window, int audio_options, int video_options)
+{
+ if(video_options) {
+ PPMConfigVideo *window = new PPMConfigVideo(parent_window, asset);
+ format_window = window;
+ window->run_window();
+ delete window;
+ }
+}
+
+int FilePPM::use_path()
+{
+ return 1;
+}
--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef FILEPPM_H
+#define FILEPPM_H
+
+#include "filelist.h"
+#include "fileppm.inc"
+
+class FilePPM : public FileList
+{
+public:
+ FilePPM(Asset *asset, File *file);
+ ~FilePPM();
+
+ void reset();
+ static int check_sig(Asset *asset);
+ int read_ppm(FILE *fp, VFrame *frame);
+ int use_path();
+
+ int read_frame(VFrame *frame, char *path);
+ int colormodel_supported(int colormodel);
+ static int get_best_colormodel(Asset *asset, int driver);
+ int check_frame_header(FILE *fp);
+ int read_frame_header(char *path);
+ int write_frame(VFrame *frame, VFrame *output, FrameWriterUnit *unit);
+ FrameWriterUnit* new_writer_unit(FrameWriter *writer);
+ static void get_parameters(BC_WindowBase *parent_window, Asset *asset,
+ BC_WindowBase* &format_window, int audio_options, int video_options);
+};
+
+class PPMConfigVideo : public BC_Window
+{
+public:
+ PPMConfigVideo(BC_WindowBase *gui, Asset *asset);
+
+ BC_WindowBase *gui;
+ Asset *asset;
+};
+
+class PPMUnit : public FrameWriterUnit
+{
+public:
+ PPMUnit(FilePPM *file, FrameWriter *writer);
+ ~PPMUnit();
+
+ FilePPM *file;
+ VFrame *temp_frame;
+};
+
+#endif
--- /dev/null
+#ifndef __FILEPPM_INC__
+#define __FILEPPM_INC__
+
+class FilePPM;
+class PPMConfigVideo;
+class PPMUnit;
+
+#endif
post_item(FILE_AIFF);
post_item(FILE_AU);
post_item(FILE_FLAC);
- post_item(FILE_JPEG);
}
+ if(!use_brender)
+ post_item(FILE_JPEG);
post_item(FILE_JPEG_LIST);
if(!use_brender) {
post_item(FILE_VORBIS);
post_item(FILE_OGG);
post_item(FILE_PCM);
- post_item(FILE_PNG);
}
- format_items.append(new BC_ListBoxItem(_(PNG_LIST_NAME)));
-
if(!use_brender)
- {
- format_items.append(new BC_ListBoxItem(_(TGA_NAME)));
- }
-
- format_items.append(new BC_ListBoxItem(_(TGA_LIST_NAME)));
-
+ post_item(FILE_PNG);
+ post_item(FILE_PNG_LIST);
if(!use_brender)
- {
- format_items.append(new BC_ListBoxItem(_(TIFF_NAME)));
- }
+ post_item(FILE_PPM);
+ post_item(FILE_PPM_LIST);
+ if(!use_brender)
+ post_item(FILE_TGA);
+ post_item(FILE_TGA_LIST);
+ if(!use_brender)
+ post_item(FILE_TIFF);
+ post_item(FILE_TIFF_LIST);
- format_items.append(new BC_ListBoxItem(_(TIFF_LIST_NAME)));
update(&format_items, 0, 0, 1);
}
void MainError::show_error(const char *string)
{
- if( main_error )
- main_error->show_error_local(string);
- else {
- printf("%s", string);
- if( string[strlen(string) - 1] != '\n' )
- printf("\n");
- }
+ if( main_error ) main_error->show_error_local(string);
+ int len = strlen(string);
+ printf("%s%s", string, len>0 && string[len-1] == '\n' ? "" : "\n");
}
// Once created, it accumulates errors in a listbox until it's closed.
-// Macro to enable the simplest possible error output
-//#define eprintf(format, ...) {char error_string[1024]; sprintf(sprintf(error_string, "%s: " format, __PRETTY_FUNCTION__, ## __VA_ARGS__); MainError::show_error(error_string); }
-// We have to use longer version if we want to gettext error messages
-
-#define eprintf(...) do { \
- char err_msg[1024], *ep = err_msg; \
- ep += sprintf(ep, "%s:\n", __PRETTY_FUNCTION__); \
- sprintf(ep, __VA_ARGS__); (volatile void)MainError::show_error(err_msg); \
-} while(0)
-
-
class MainErrorGUI : public BC_Window
{
public:
};
+// format text to error dialog listbox
+static inline void eprint1(const char *func, const char *fmt, ...)
+{
+ char err_msg[1024], *cp = err_msg, *ep = cp + sizeof(err_msg)-1;
+ va_list va;
+ va_start(va, fmt);
+ cp += snprintf(cp, ep-cp, "%s:\n", func);
+ cp += vsnprintf(cp, ep-cp, fmt, va);
+ *cp = 0;
+ va_end(va);
+ MainError::show_error(err_msg); \
+}
+
+#define eprintf(s...) eprint1(__PRETTY_FUNCTION__, s)
#endif
--- /dev/null
+#include "meterhistory.h"
+
+#include <math.h>
+
+MeterHistory::MeterHistory()
+{
+ size = 0;
+ channels = 0;
+ current_peak = 0;
+ samples = 0;
+ values = 0;
+}
+MeterHistory::~MeterHistory()
+{
+ init(0, 0);
+}
+
+void MeterHistory::init(int chs, int sz)
+{
+ if( size != sz ) {
+ delete [] samples; samples = 0;
+ size = 0;
+ }
+ if( !samples && sz > 0 ) {
+ samples = new int64_t[size = sz];
+ for( int i=0; i<size; ++i ) samples[i] = -1;
+ }
+ if( channels != chs ) {
+ for( int i=0; i<channels; ++i ) delete [] values[i];
+ delete [] values; values = 0;
+ delete [] current_peak; current_peak = 0;
+ channels = 0;
+ }
+ if( !values && chs > 0 ) {
+ current_peak = new int[channels = chs];
+ for( int i=0; i<channels; ++i ) current_peak[i] = 0;
+ values = new double*[channels];
+ for( int i=0; i<channels; ++i ) values[i] = 0;
+ }
+}
+
+void MeterHistory::reset_channel(int ch)
+{
+ if( !ch ) for( int i=0; i<size; ++i ) samples[i] = -1;
+ current_peak[ch] = 0;
+ double *peaks = values[ch];
+ if( !peaks ) values[ch] = peaks = new double[size];
+ for( int i=0; i<size; ++i ) peaks[i] = 0;
+}
+
+void MeterHistory::set_peak(int ch, double peak, int64_t pos)
+{
+ int peak_idx = current_peak[ch];
+ samples[peak_idx] = pos;
+ values[ch][peak_idx++] = peak;
+ if( peak_idx >= size ) peak_idx = 0;
+ current_peak[ch] = peak_idx;
+}
+
+double MeterHistory::get_peak(int ch, int idx)
+{
+ return idx>=0 ? values[ch][idx] : 0;
+}
+
+int MeterHistory::get_nearest(int64_t pos, int64_t tolerance)
+{
+ int result = -1;
+ if( size > 0 ) {
+ int64_t best = tolerance;
+ for( int i=0; i<size; ++i ) {
+ int64_t diff = labs(samples[i] - pos);
+ if( diff >= tolerance || diff >= best ) continue;
+ best = diff; result = i;
+ }
+ }
+ return result;
+}
+
--- /dev/null
+#ifndef __METERHISTORY_H__
+#define __METERHISTORY_H__
+
+#include <stdint.h>
+
+class MeterHistory
+{
+public:
+ MeterHistory();
+ ~MeterHistory();
+
+ int size, channels;
+ int *current_peak;
+ int64_t *samples;
+ double **values;
+
+ void init(int chs, int sz);
+ void reset_channel(int ch);
+ void set_peak(int ch, double peak, int64_t pos);
+ double get_peak(int ch, int idx);
+ int get_nearest(int64_t pos, int64_t tolerance);
+};
+
+#endif
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());
+ read_frame(vframe, 0, filter_position++, frame_rate, 0);
frame->format = pix_fmt;
frame->width = width;
frame->height = height;
mwindow->gui->unlock_window();
redraw_overlays = 1;
}
+ PreferencesWindow *window = (PreferencesWindow*)get_gui();
+ if( window ) window->unlock_window();
+ mwindow->init_brender();
+ if( window ) window->lock_window("PreferencesThread::apply_settings 5");
if( strcmp(preferences->theme, mwindow->preferences->theme) != 0 )
mwindow->restart_status = -1; // reload, need new bcresources
mwindow->edl->copy_session(edl, 1);
mwindow->preferences->copy_from(preferences);
- mwindow->init_brender();
BC_Signals::set_catch_segv(mwindow->preferences->trap_sigsegv);
BC_Signals::set_catch_intr(mwindow->preferences->trap_sigintr);
#include "condition.h"
#include "edl.h"
#include "edlsession.h"
+#include "meterhistory.h"
#include "mutex.h"
#include "mwindow.h"
#include "playbackengine.h"
void RenderEngine::get_output_levels(double *levels, int64_t position)
{
- if(do_audio)
- {
- int history_entry = arender->get_history_number(arender->level_samples,
- position);
- for(int i = 0; i < MAXCHANNELS; i++)
- {
- if(arender->audio_out[i])
- levels[i] = arender->level_history[i][history_entry];
+ if( do_audio ) {
+ MeterHistory *meter_history = arender->meter_history;
+ int64_t tolerance = 4*arender->meter_render_fragment;
+ int pos = meter_history->get_nearest(position, tolerance);
+ for( int i=0; i<MAXCHANNELS; ++i ) {
+ if( !arender->audio_out[i] ) continue;
+ levels[i] = meter_history->get_peak(i, pos);
}
}
}
void RenderEngine::get_module_levels(ArrayList<double> *module_levels, int64_t position)
{
- if(do_audio)
- {
- for(int i = 0; i < arender->total_modules; i++)
- {
-//printf("RenderEngine::get_module_levels %p %p\n", ((AModule*)arender->modules[i]), ((AModule*)arender->modules[i])->level_samples);
- int history_entry = arender->get_history_number(((AModule*)arender->modules[i])->level_samples, position);
-
- module_levels->append(((AModule*)arender->modules[i])->level_history[history_entry]);
+ if( do_audio ) {
+ int64_t tolerance = 4*arender->meter_render_fragment;
+ for( int i=0; i<arender->total_modules; ++i ) {
+ AModule *amodule = (AModule *)arender->modules[i];
+ MeterHistory *meter_history = amodule->meter_history;
+ int pos = meter_history->get_nearest(position, tolerance);
+ module_levels->append(meter_history->get_peak(0, pos));
}
}
}
-
-
-
void RenderEngine::run()
{
render_active->lock("RenderEngine::run");
meter_render_end = len;
double peak = 0;
-
- for( ; j < meter_render_end; j++)
- {
+ while( j < meter_render_end ) {
// Level history comes before clipping to get over status
- double *sample = ¤t_buffer[j];
-
-
- if(fabs(*sample) > peak) peak = fabs(*sample);
+ double *sample = ¤t_buffer[j++];
+ if( fabs(*sample) > peak ) peak = fabs(*sample);
// Make the output device clip it
// if(*sample > 1) *sample = 1;
// else
// if(*sample < -1) *sample = -1;
}
-
- if(renderengine->command->realtime)
- {
- arender->level_history[i][arender->current_level[i]] = peak;
- arender->level_samples[arender->current_level[i]] =
- renderengine->command->get_direction() == PLAY_REVERSE ?
+ if( renderengine->command->realtime ) {
+ int direction = renderengine->command->get_direction();
+ int64_t pos = direction == PLAY_REVERSE ?
start_position - j :
- start_position + j;
- arender->current_level[i] = arender->get_next_peak(arender->current_level[i]);
- }
+ start_position + j ;
+ arender->meter_history->set_peak(i, peak, pos);
+ }
}
}
}
if(renderengine->command->get_speed() < 1)
{
// number of samples to skip
- int interpolate_len = (int)(1.0 / renderengine->command->get_speed());
+ int interpolate_len = (int)(1.0 / renderengine->command->get_speed());
real_output_len = len * interpolate_len;
for(in = len - 1, out = real_output_len - 1; in >= 0; )
// Scan fragment in meter sized fragments
for(int i = 0; i < len; )
{
- int current_level = ((AModule*)real_module)->current_level;
- double peak = 0;
meter_render_start = i;
meter_render_end = i + meter_render_fragment;
if(meter_render_end > len)
// Number of samples into the fragment this meter sized fragment is,
// normalized to project sample rate.
int64_t meter_render_start_project = meter_render_start *
- project_sample_rate /
- sample_rate;
+ project_sample_rate / sample_rate;
// Scan meter sized fragment
- double *output_samples = output_temp->get_data();
- for( ; i < meter_render_end; i++)
- {
- double sample = fabs(output_samples[i]);
- if(sample > peak) peak = sample;
+ double peak = 0, *output_samples = output_temp->get_data();
+ while( i < meter_render_end ) {
+ double sample = fabs(output_samples[i++]);
+ if( sample > peak ) peak = sample;
}
- ((AModule*)real_module)->level_history[current_level] =
- peak;
- ((AModule*)real_module)->level_samples[current_level] =
- (direction == PLAY_FORWARD) ?
+ MeterHistory *meter_history = ((AModule*)real_module)->meter_history;
+ int64_t pos = (direction == PLAY_FORWARD) ?
(start_position_project + meter_render_start_project) :
- (start_position_project - meter_render_start_project);
- ((AModule*)real_module)->current_level =
- arender->get_next_peak(current_level);
+ (start_position_project - meter_render_start_project) ;
+ meter_history->set_peak(0, peak, pos);
}
}
if(debug) printf("VirtualANode::render_as_module %d\n", __LINE__);
},
},
+ "gbrp": {
+ "i8": {
+ "r": " int g = *gip++, b = *bip++, r = *rip++;",
+ "w": " *gop++ = g; *bop++ = b; *rop++ = r;",
+ },
+ "i16": {
+ "r": " int ig = *gip++, g = (ig<<8) | ig, ib = *bip++, b = (ib<<8) | ib," +
+ " ir = *rip++, r = (ir<<8) | ir;",
+ "w": " *gop++ = g >> 8; *bop++ = b >> 8; *rop++ = r >> 8;",
+ },
+ "fp": {
+ "r": " float g = *gip++/255.f, b = *bip++/255.f, r = *rip++/255.f;",
+ "w": " *gop++ = clp(256,g); *bop++ = clp(256,b); *rop++ = clp(256,r);",
+ },
+ },
+
"grey8": {
"i8": {
"r": " int32_t y = *inp++, u = 0x80, v = 0x80;",
add_cmodel(36, "bc_grey8", "i8", "grey8")
add_cmodel(37, "bc_grey16", "i16", "grey16")
+add_cmodel(38, "bc_gbrp", "i8", "gbrp")
specialize("bc_rgba8888", "bc_transparency", "XFER_rgba8888_to_transparency")
"bc_bgr888", "bc_bgr8888", "bc_rgb888", "bc_rgba8888", \
"bc_argb8888", "bc_abgr8888", "bc_rgb", "bc_rgb161616", \
"bc_rgba16161616", "bc_rgb_float", "bc_rgba_float", \
- "bc_rgb_floatp", "bc_rgba_floatp", ]
+ "bc_rgb_floatp", "bc_rgba_floatp", "bc_gbrp", ]
def is_yuv(nm):
return nm in [ "bc_yuv888", "bc_yuva8888", "bc_yuv161616", \
"bc_yuva16161616", "bc_ayuv16161616", "bc_yuv422", "bc_uvy422", "bc_yuv101010", \
"bc_vyu888", "bc_uyva8888", "bc_yuv420p", "bc_yuv420pi", "bc_yuv422p", \
- "bc_yuv444p", "bc_yuv411p", "bc_yuv410p", "bc_grey8", "bc_grey16" ]
+ "bc_yuv444p", "bc_yuv411p", "bc_yuv410p", "bc_grey8", "bc_grey16", ]
def is_planar(nm):
return nm in [ "bc_yuv420p", "bc_yuv420pi", "bc_yuv422p", "bc_yuv444p", \
- "bc_yuv411p", "bc_yuv410p", "bc_rgb_floatp", "bc_rgba_floatp", ]
+ "bc_yuv411p", "bc_yuv410p", "bc_rgb_floatp", "bc_rgba_floatp", "bc_gbrp", ]
def is_float(nm):
return nm in ["bc_rgb_float", "bc_rgba_float", "bc_rgb_floatp", "bc_rgba_floatp", ]
# xfr fn body
print "{"
# loops / pointer preload
- in_cmdl = fr_cmdl[3:] if is_planar(fr_cmdl) else "flat";
- out_cmdl = to_cmdl[3:] if is_planar(to_cmdl) else "flat";
+ in_xfer = "flat" if not is_planar(fr_cmdl) else \
+ fr_cmdl[3:] if is_yuv(fr_cmdl) else \
+ "rgbp" if not has_alpha(fr_cmdl) else "rgbap"
+ out_xfer = "flat" if not is_planar(to_cmdl) else \
+ to_cmdl[3:] if is_yuv(to_cmdl) else \
+ "rgbp" if not has_alpha(to_cmdl) else "rgbap"
print " xfer_%s_row_out(%s) xfer_%s_row_in(%s)" % \
- (out_cmdl, ctype[otyp], in_cmdl, ctype[ityp],)
+ (out_xfer, ctype[otyp], in_xfer, ctype[ityp],)
# load inp
if( is_float(to_cmdl) and is_yuv(fr_cmdl) ):
for ic in layout[fr_cmdl]: print "%s" % (base[ic][ityp]['r']),
case BC_YUV420PI:
case BC_YUV422P:
case BC_YUV444P:
+ case BC_GBRP:
case BC_YUV411P:
case BC_YUV410P:
case BC_RGB_FLOATP:
- case BC_RGBA_FLOATP: return 1;
+ case BC_RGBA_FLOATP:
+ return 1;
}
return 0;
}
int BC_CModels::components(int colormodel)
{
switch(colormodel) {
- case BC_A8: return 1;
- case BC_A16: return 1;
- case BC_A_FLOAT: return 1;
- case BC_RGB888: return 3;
- case BC_RGBA8888: return 4;
- case BC_RGB161616: return 3;
- case BC_RGBA16161616: return 4;
- case BC_YUV888: return 3;
- case BC_YUVA8888: return 4;
- case BC_YUV161616: return 3;
- case BC_YUVA16161616: return 4;
- case BC_AYUV16161616: return 4;
- case BC_YUV101010: return 3;
- case BC_RGB_FLOAT: return 3;
- case BC_RGBA_FLOAT: return 4;
- case BC_RGB_FLOATP: return 3;
- case BC_RGBA_FLOATP: return 4;
- case BC_GREY8: return 1;
- case BC_GREY16: return 1;
+ case BC_RGB8:
+ case BC_RGB565:
+ case BC_BGR565:
+ case BC_BGR888:
+ case BC_RGB888:
+ case BC_RGB161616:
+ case BC_RGB_FLOAT:
+ case BC_BGR8888:
+ case BC_YUV888:
+ case BC_YUV161616:
+ case BC_UVY422:
+ case BC_YUV422:
+ case BC_YUV101010:
+ case BC_VYU888:
+ return 3;
+ case BC_RGBA8888:
+ case BC_ARGB8888:
+ case BC_ABGR8888:
+ case BC_RGBA16161616:
+ case BC_RGBA_FLOAT:
+ case BC_YUVA8888:
+ case BC_YUVA16161616:
+ case BC_UYVA8888:
+ case BC_AYUV16161616:
+ return 4;
+ case BC_A8:
+ case BC_A16:
+ case BC_A_FLOAT:
+ case BC_GREY8:
+ case BC_GREY16:
+ return 1;
}
+// planar, compressed, transparent
return 0;
}
case BC_YUV420PI: return 1;
case BC_YUV422P: return 1;
case BC_YUV444P: return 1;
+ case BC_GBRP: return 1;
case BC_YUV422: return 2;
case BC_UVY422: return 2;
case BC_YUV411P: return 1;
case BC_RGBA_FLOATP: return 1;
case BC_GREY8: return 0xff;
case BC_GREY16: return 0xffff;
+ case BC_GBRP: return 0xff;
}
return 0;
}
case BC_YUV411P: return w * h + w * h / 2 + 4;
case BC_YUV422P: return w * h * 2 + 4;
case BC_YUV444P: return w * h * 3 + 4;
+ case BC_GBRP: return w * h * 3 + 4;
case BC_RGB_FLOATP: return w * h * 3 * sizeof(float) + 4;
case BC_RGBA_FLOATP: return w * h * 4 * sizeof(float) + 4;
}
BC_RGB_FLOATP = 32,
BC_RGBA_FLOATP = 33,
BC_YUV420PI = 34,
+ BC_GBRP = 38,
// only used in intermediate ffmpeg xfers
BC_AYUV16161616 = 35,
BC_GREY8 = 36,
{
#ifdef HAVE_XFT
if( !get_resources()->use_xft ) return;
+// apparently, xft is not reentrant, more than this is needed
+static Mutex xft_init_lock("BC_WindowBase::xft_init_lock", 0);
+xft_init_lock.lock("BC_WindowBase::init_xft");
if(!(smallfont_xft =
(resources.small_font_xft[0] == '-' ?
XftFontOpenXlfd(display, screen, resources.small_font_xft) :
}
// _XftDisplayInfo needs a lock.
XftDefaultHasRender(display);
+xft_init_lock.unlock();
#endif // HAVE_XFT
}
"yuv422p", "rgb888", "rgba8888", "rgb161616", "rgba16161616", "yuv888", "yuva8888", "yuv161616",
"yuva16161616", "yuv411p", "uvy422", "yuv422", "argb8888", "abgr8888", "a8", "a16",
"yuv101010", "vyu888", "uyva8888", "yuv444p", "yuv410p", "rgb_float", "rgba_float", "a_float",
- "rgb_floatp", "rgba_floatp", "yuv420pi", "ayuv16161616", "grey8", "grey16",
+ "rgb_floatp", "rgba_floatp", "yuv420pi", "ayuv16161616", "grey8", "grey16", "gbrp",
};
void write_pgm(uint8_t *tp, int w, int h, const char *fmt, ...)
close(fd);
int w = ifrm.get_w(), h = ifrm.get_h();
TestWindow test_window(100, 100, w, h);
- for( int fr_cmdl=1; fr_cmdl<=37; ++fr_cmdl ) {
+ for( int fr_cmdl=1; fr_cmdl<=38; ++fr_cmdl ) {
if( fr_cmdl == BC_TRANSPARENCY || fr_cmdl == BC_COMPRESSED ) continue;
if( fr_cmdl == BC_A8 || fr_cmdl == BC_A16 ) continue;
if( fr_cmdl == BC_A_FLOAT || fr_cmdl == 8 ) continue;
VFrame afrm(w, h, fr_cmdl, -1);
afrm.transfer_from(&ifrm, 0);
- for( int to_cmdl=1; to_cmdl<=37; ++to_cmdl ) {
+ for( int to_cmdl=1; to_cmdl<=38; ++to_cmdl ) {
if( to_cmdl == BC_TRANSPARENCY || to_cmdl == BC_COMPRESSED ) continue;
if( to_cmdl == BC_A8 || to_cmdl == BC_A16 ) continue;
if( to_cmdl == BC_A_FLOAT || to_cmdl == 8 ) continue;
case BC_YUV444P:
case BC_RGB_FLOATP:
case BC_RGBA_FLOATP:
+ case BC_GBRP:
break;
default:
this->u_offset = sz;
this->v_offset = sz + sz;
break;
+ case BC_GBRP:
+ if( this->v_offset ) break;
+ this->y_offset = 0;
+ this->u_offset = sz * sizeof(uint8_t);
+ this->v_offset = 2 * sz * sizeof(uint8_t);
+ break;
case BC_RGBA_FLOATP:
if( this->v_offset || a ) break;
a = this->data + 3 * sz * sizeof(float);
bzero(get_v(), sz / 2);
break;
+ case BC_GBRP:
+ bzero(get_y(), sz);
+ bzero(get_u(), sz);
+ bzero(get_b(), sz);
+ break;
+
case BC_RGBA_FLOATP: if( a ) {
float *ap = (float *)a;
for( int i=sz; --i>=0; ++ap ) *ap = 1.f; }
this->out_h = out_h;
this->in_colormodel = in_colormodel;
switch( in_colormodel ) {
+ case BC_GBRP:
+ in_rowspan = in_w * sizeof(uint8_t);
+ break;
case BC_RGB_FLOATP:
case BC_RGBA_FLOATP:
if( !BC_CModels::has_alpha(out_colormodel) )
this->total_in_w = in_rowspan;
this->out_colormodel = out_colormodel;
switch( out_colormodel ) {
+ case BC_GBRP:
+ out_rowspan = out_w * sizeof(uint8_t);
+ break;
case BC_RGB_FLOATP:
case BC_RGBA_FLOATP:
out_rowspan = out_w * sizeof(float);
ity_t *uip = (ity_t *)(uip_row + in_ofs); \
ity_t *vip = (ity_t *)(vip_row + in_ofs); \
-// rgb_floatp
-#define xfer_rgb_fltp_row_out(oty_t) \
+// rgb planar
+#define xfer_rgbp_row_out(oty_t) \
for( unsigned i=y0; i<y1; ++i ) { \
int out_rofs = i * total_out_w + out_x; \
oty_t *rop = (oty_t *)(out_yp + out_rofs); \
oty_t *gop = (oty_t *)(out_up + out_rofs); \
oty_t *bop = (oty_t *)(out_vp + out_rofs); \
-#define xfer_rgb_fltp_row_in(ity_t) \
+#define xfer_rgbap_row_out(oty_t) \
+ xfer_rgbp_row_out(oty_t) \
+ oty_t *aop = (oty_t *)(out_ap + out_rofs); \
+
+
+#define xfer_row_in_rgbp(ity_t) \
int in_rofs = row_table[i] * total_in_w; \
uint8_t *rip_row = in_yp + in_rofs; \
uint8_t *gip_row = in_up + in_rofs; \
uint8_t *bip_row = in_vp + in_rofs; \
-#define xfer_rgb_fltp_col_in(ity_t) \
+#define xfer_row_in_rgbap(oty_t) \
+ xfer_row_in_rgbp(ity_t) \
+ uint8_t *aip_row = in_ap + in_rofs; \
+
+
+#define xfer_col_in_rgbp(ity_t) \
for( unsigned j=0; j<out_w; ++j ) { \
int in_ofs = column_table[j]; \
ity_t *rip = (ity_t *)(rip_row + in_ofs); \
ity_t *gip = (ity_t *)(gip_row + in_ofs); \
ity_t *bip = (ity_t *)(bip_row + in_ofs); \
-#define xfer_rgb_floatp_row_out(oty_t) \
- xfer_rgb_fltp_row_out(oty_t) \
+#define xfer_col_in_rgbap(ity_t) \
+ xfer_col_in_rgbp(ity_t) \
+ ity_t *aip = (ity_t *)(aip_row + in_ofs); \
-#define xfer_rgba_floatp_row_out(oty_t) \
- xfer_rgb_fltp_row_out(oty_t) \
- oty_t *aop = (oty_t *)(out_ap + out_rofs); \
-#define xfer_rgb_floatp_row_in(ity_t) \
- xfer_rgb_fltp_row_in(ity_t) \
- xfer_rgb_fltp_col_in(ity_t) \
+#define xfer_rgbp_row_in(ity_t) \
+ xfer_row_in_rgbp(ity_t) \
+ xfer_col_in_rgbp(ity_t) \
-#define xfer_rgba_floatp_row_in(ity_t) \
- xfer_rgb_fltp_row_in(ity_t) \
- uint8_t *aip_row = in_ap + in_rofs; \
- xfer_rgb_fltp_col_in(ity_t) \
- ity_t *aip = (ity_t *)(aip_row + in_ofs); \
+#define xfer_rgbap_row_in(ity_t) \
+ xfer_row_in_rgbap(ity_t) \
+ xfer_col_in_rgbap(ity_t) \
class BC_Xfer {
load_configuration();
+ if(get_use_opengl()) return run_opengl();
+
//printf("ScaleRatioMain::process_realtime 1 %p\n", input);
if( input->get_rows()[0] == output->get_rows()[0] ) {
if( temp_frame && (
}
+int ScaleRatioMain::handle_opengl()
+{
+#ifdef HAVE_GL
+ VFrame *input = get_input(), *output = get_output();
+ float ix1 = (input->get_w() - config.src_w)/2 + config.src_x;
+ float iy1 = (input->get_h() - config.src_h)/2 + config.src_y;
+ float ix2 = ix1 + config.src_w;
+ float iy2 = iy1 + config.src_h;
+ float ox1 = (output->get_w() - config.dst_w)/2 + config.dst_x;
+ float oy1 = (output->get_h() - config.dst_h)/2 + config.dst_y;
+ float ox2 = ox1 + config.dst_w;
+ float oy2 = oy1 + config.dst_h;
+
+ output->to_texture();
+ output->enable_opengl();
+ output->init_screen();
+ output->clear_pbuffer();
+ output->bind_texture(0);
+ output->draw_texture(ix1,iy1, ix2,iy2, ox1,oy1, ox2,oy2);
+ output->set_opengl_state(VFrame::SCREEN);
+#endif
+ return 0;
+}
+
+
void update_gui();
void save_data(KeyFrame *keyframe);
void read_data(KeyFrame *keyframe);
-
+ int handle_opengl();
OverlayFrame *overlayer;
VFrame *temp_frame;
ScaleRatioWin::ScaleRatioWin(ScaleRatioMain *client)
- : PluginClientWindow(client, 400, 300, 400, 300, 0)
+ : PluginClientWindow(client, 400, 320, 400, 320, 0)
{
this->client = client;
}