{
EDL *nested_edl = (EDL*)indexable;
- strcpy(changed_params->path, nested_edl->path);
+ strcpy(changed_params->path, nested_edl->path);
changed_params->sample_rate = nested_edl->session->sample_rate;
- changed_params->channels = nested_edl->session->audio_channels;
+ changed_params->channels = nested_edl->session->audio_channels;
//printf("AssetEdit::edit_asset %d %f\n", __LINE__, nested_edl->session->frame_rate);
changed_params->frame_rate = nested_edl->session->frame_rate;
- changed_params->width = nested_edl->session->output_w;
- changed_params->height = nested_edl->session->output_h;
+ changed_params->width = nested_edl->session->output_w;
+ changed_params->height = nested_edl->session->output_h;
}
BC_DialogThread::start();
ilacefixoption_chkboxw->ilacemode_textbox = textboxw;
add_subwindow(listboxw = new AssetEditInterlacemodePulldown(mwindow,
textboxw,
- &asset->interlace_mode,
+ &asset_edit->changed_params->interlace_mode,
(ArrayList<BC_ListBoxItem*>*)&mwindow->interlace_asset_modes,
ilacefixoption_chkboxw,
x2 + textboxw->get_w(),
ilacefixoption_chkboxw->ilacefixmethod_textbox = textboxw;
add_subwindow(listboxw = new InterlacefixmethodPulldown(mwindow,
textboxw,
- &asset->interlace_fixmethod,
+ &asset_edit->changed_params->interlace_fixmethod,
(ArrayList<BC_ListBoxItem*>*)&mwindow->interlace_asset_fixmethods,
x2 + textboxw->get_w(),
y));
// Calculate values to enter into textboxes
char text[32], *tc = text;
- Units::totext(tc, asset->tcstart / asset->frame_rate,
- TIME_HMSF, asset->sample_rate, asset->frame_rate);
+ if( asset )
+ Units::totext(tc, asset->tcstart / asset->frame_rate,
+ TIME_HMSF, asset->sample_rate, asset->frame_rate);
+ else
+ strcpy(tc, "0:00:00:00");
const char *tc_hours = tc, *tc_minutes, *tc_seconds, *tc_rest;
tc = strchr(tc, ':'); *tc++ = 0; tc_minutes = tc;
Interlaceautofix::Interlaceautofix(MWindow *mwindow,AssetEditWindow *fwindow, int x, int y)
: BC_CheckBox(x, y,
- ((Asset *)fwindow->asset_edit->indexable)->interlace_autofixoption,
+ fwindow->asset_edit->changed_params->interlace_autofixoption,
_("Automatically Fix Interlacing"))
{
this->fwindow = fwindow;
int Interlaceautofix::handle_event()
{
- Asset *asset = (Asset *)fwindow->asset_edit->indexable;
+ Asset *asset = fwindow->asset_edit->changed_params;
asset->interlace_autofixoption = get_value();
showhideotherwidgets();
return 1;
{
int thevalue = get_value();
- Asset *asset = (Asset *)fwindow->asset_edit->indexable;
+ Asset *asset = fwindow->asset_edit->changed_params;
if (thevalue == BC_ILACE_AUTOFIXOPTION_AUTO)
{
this->ilacemode_textbox->enable();
int AssetEditILaceautofixoption::handle_event()
{
- Asset *asset = (Asset *)fwindow->asset_edit->indexable;
+ Asset *asset = fwindow->asset_edit->changed_params;
asset->interlace_autofixoption = ilaceautofixoption_from_text(get_text(), this->thedefault);
return 1;
}
int AssetEditILacemode::handle_event()
{
- Asset *asset = (Asset *)fwindow->asset_edit->indexable;
+ Asset *asset = fwindow->asset_edit->changed_params;
asset->interlace_mode = ilacemode_from_text(get_text(),this->thedefault);
return 1;
}
AssetEditReelName::AssetEditReelName(AssetEditWindow *fwindow, int x, int y)
- : BC_TextBox(x, y, 220, 1,
- ((Asset *)fwindow->asset_edit->indexable)->reel_name,
+ : BC_TextBox(x, y, 220, 1, fwindow->asset_edit->changed_params->reel_name,
1, MEDIUMFONT, 1)
{
this->fwindow = fwindow;
AssetEditReelNumber::AssetEditReelNumber(AssetEditWindow *fwindow, int x, int y)
- : BC_TextBox(x, y, 200, 1, ((Asset *)fwindow->asset_edit->indexable)->reel_number)
+ : BC_TextBox(x, y, 200, 1, fwindow->asset_edit->changed_params->reel_number)
{
this->fwindow = fwindow;
}
#include "file.h"
#include "filedv.h"
#include "guicast.h"
+#include "interlacemodes.h"
#include "language.h"
#include "mutex.h"
#include "mwindow.inc"
asset->width = decoder->width;
asset->height = decoder->height;
+
+ if(dv_is_progressive(decoder) > 0)
+ asset->interlace_mode = BC_ILACE_MODE_NOTINTERLACED;
+ else
+ asset->interlace_mode = BC_ILACE_MODE_BOTTOM_FIRST;
+
isPAL = dv_is_PAL(decoder);
output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
video_position_lock->unlock();
-TRACE("FileDV::write_samples 210")
-
- int16_t **tmp_buf = new int16_t*[asset->channels];
- for(int a = 0; a < asset->channels; a++)
- tmp_buf[a] = new int16_t[asset->sample_rate];
-
TRACE("FileDV::write_samples 220")
for(int i = 0; i < nFrames; i++)
if(samples > audio_sample_buffer_maxsize - 1 - audio_sample_buffer_start)
{
+TRACE("FileDV::write_samples 210")
+ int16_t *tmp_buf[asset->channels];
+ for(int a = 0; a < asset->channels; a++)
+ tmp_buf[a] = new int16_t[asset->sample_rate];
+
TRACE("FileDV::write_samples 240")
int copy_size = audio_sample_buffer_maxsize - audio_sample_buffer_start - 1;
{
eprintf(_("ERROR: unable to encode audio frame %d\n"), audio_frames_written);
}
+TRACE("FileDV::write_samples 280")
+
+ for(int a = 0; a < asset->channels; a++)
+ delete[] tmp_buf[a];
}
else
{
if(audio_sample_buffer_start >= audio_sample_buffer_maxsize)
audio_sample_buffer_start -= audio_sample_buffer_maxsize;
}
-
-TRACE("FileDV::write_samples 280")
-
- for(int a = 0; a < asset->channels; a++)
- delete[] tmp_buf[a];
- delete[] tmp_buf;
-
TRACE("FileDV::write_samples 290")
-
UNTRACE
return 0;
native_cmodel = BC_RGBA_FLOAT;
else
native_cmodel = BC_RGB_FLOAT;
+ asset->exr_use_alpha = BC_CModels::has_alpha(native_cmodel) ? 1 : 0;
if(channels.findChannel("Y"))
is_yuv = 1;
asset->video_data = mpeg3_has_video(fd);
if( !result && asset->video_data ) {
- asset->interlace_mode = BC_ILACE_MODE_UNDETECTED;
+//TODO: this is not as easy as just looking at headers.
+//most interlaced media is rendered as FRM, not TOP/BOT in coding ext hdrs.
+//currently, just using the assetedit menu to set the required result as needed.
+// if( asset->interlace_mode == BC_ILACE_MODE_UNDETECTED )
+// asset->interlace_mode = mpeg3_detect_interlace(fd, 0);
if( !asset->layers ) {
asset->layers = mpeg3_total_vstreams(fd);
}
case 2: asset->vmpeg_progressive = 1; break;
}
-// Be quiet
- strcat(mjpeg_command, " -v0");
-
char string[BCTEXTLEN];
// The current usage of mpeg2enc requires bitrate of 0 when quantization is fixed and
// quantization of 1 when bitrate is fixed. Perfectly intuitive.
// verify colormodel supported in MPEG output
switch( output_cmodel ) {
case BC_YUV420P:
+ if( file->preferences->dvd_yuv420p_interlace &&
+ ( asset->interlace_mode == BC_ILACE_MODE_TOP_FIRST ||
+ asset->interlace_mode == BC_ILACE_MODE_BOTTOM_FIRST ) )
+ output_cmodel = BC_YUV420PI;
case BC_YUV422P:
break;
default:
// frame->get_h(),
// temp_frame->get_color_model(),
// frame->get_color_model()); sleep(1);
- BC_CModels::transfer(temp_frame->get_rows(),
- frame->get_rows(),
- temp_frame->get_y(),
- temp_frame->get_u(),
- temp_frame->get_v(),
- frame->get_y(),
- frame->get_u(),
- frame->get_v(),
- 0,
- 0,
- frame->get_w(),
- frame->get_h(),
- 0,
- 0,
- temp_frame->get_w(),
- temp_frame->get_h(),
- frame->get_color_model(),
- temp_frame->get_color_model(),
- 0,
- frame->get_w(),
- temp_frame->get_w());
+ temp_frame->transfer_from(frame);
//printf("FileMPEG::write_frames %d\n", __LINE__);sleep(1);
mjpeg_y = temp_frame->get_y();
int stream_cmdl = mpeg3_colormodel(fd,file->current_layer);
int stream_color_model = bc_colormodel(stream_cmdl);
int frame_color_model = frame->get_color_model();
- int frame_cmdl = zmpeg3_cmdl(frame_color_model);
+ int frame_cmdl = asset->interlace_mode == BC_ILACE_MODE_NOTINTERLACED ?
+ zmpeg3_cmdl(frame_color_model) : -1;
mpeg3_show_subtitle(fd, file->current_layer, file->playback_subtitle);
-
switch( frame_color_model ) { // check for direct copy
case BC_YUV420P:
+ if( frame_cmdl < 0 ) break;
case BC_YUV422P:
if( stream_color_model == frame_color_model &&
width == frame->get_w() && height == frame->get_h() ) {
char *y, *u, *v;
mpeg3_read_yuvframe_ptr(fd, &y, &u, &v, file->current_layer);
if( y && u && v ) {
+ if( stream_color_model == BC_YUV420P &&
+ file->preferences->dvd_yuv420p_interlace && (
+ asset->interlace_mode == BC_ILACE_MODE_TOP_FIRST ||
+ asset->interlace_mode == BC_ILACE_MODE_BOTTOM_FIRST ) )
+ stream_color_model = BC_YUV420PI;
BC_CModels::transfer(frame->get_rows(), 0,
- frame->get_y(),
- frame->get_u(),
- frame->get_v(),
- (unsigned char*)y,
- (unsigned char*)u,
- (unsigned char*)v,
- 0, 0, width, height,
- 0, 0, frame->get_w(), frame->get_h(),
- stream_color_model,
- frame_color_model,
- 0,
- width,
- frame->get_w());
+ frame->get_y(), frame->get_u(), frame->get_v(),
+ (unsigned char*)y, (unsigned char*)u, (unsigned char*)v,
+ 0,0, width,height, 0,0, frame->get_w(),frame->get_h(),
+ stream_color_model, frame_color_model, 0, width, frame->get_w());
}
return result;
native_cmodel = BC_RGB888;
}
+ asset->png_use_alpha = BC_CModels::has_alpha(native_cmodel) ? 1 : 0;
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
fclose(stream);
void Indexable::update_index(Indexable *src)
{
+ if( index_state == src->index_state ) return;
index_state->remove_user();
index_state = src->index_state;
index_state->add_user();
PrefsForceUniprocessor *force_1cpu = new PrefsForceUniprocessor(pwindow, x, y);
add_subwindow(force_1cpu);
- int x1 = force_1cpu->get_x() + force_1cpu->get_w() + 50;
+ int x1 = force_1cpu->get_x() + force_1cpu->get_w() + 100;
PrefsTrapSigSEGV *trap_segv = new PrefsTrapSigSEGV(this, x1, y);
add_subwindow(trap_segv);
ffmpeg_early_probe = new PrefsFFMPEGEarlyProbe(this, x, y);
add_subwindow(ffmpeg_early_probe);
- y += 30;
-
-
+ yuv420p_dvdlace = new PrefsYUV420P_DVDlace(pwindow, this, x1, y);
+ add_subwindow(yuv420p_dvdlace);
+ y += 30;
// Background rendering
add_subwindow(new BC_Bar(5, y, get_w() - 10));
PrefsRenderFarmVFS::PrefsRenderFarmVFS(PreferencesWindow *pwindow,
- PerformancePrefs *subwindow,
- int x,
- int y)
- : BC_CheckBox(x, y, pwindow->thread->preferences->renderfarm_vfs, _("Use virtual filesystem"))
+ PerformancePrefs *subwindow, int x, int y)
+ : BC_CheckBox(x, y, pwindow->thread->preferences->renderfarm_vfs,
+ _("Use virtual filesystem"))
{
this->pwindow = pwindow;
this->subwindow = subwindow;
return 1;
}
+
+PrefsYUV420P_DVDlace::PrefsYUV420P_DVDlace(PreferencesWindow *pwindow,
+ PerformancePrefs *subwindow, int x, int y)
+ : BC_CheckBox(x, y, pwindow->thread->preferences->dvd_yuv420p_interlace,
+ _("Use yuv420p dvd interlace format"))
+{
+ this->pwindow = pwindow;
+ this->subwindow = subwindow;
+}
+
+int PrefsYUV420P_DVDlace::handle_event()
+{
+ pwindow->thread->preferences->dvd_yuv420p_interlace = get_value();
+ return 1;
+}
+
FormatTools *brender_tools;
BC_Title *master_rate;
PrefsFFMPEGEarlyProbe *ffmpeg_early_probe;
+ PrefsYUV420P_DVDlace *yuv420p_dvdlace;
PrefsFFMPEGMarkerIndecies *ffmpeg_marker_indexes;
};
public:
PrefsRenderFarmReset(PreferencesWindow *pwindow,
PerformancePrefs *subwindow,
- int x,
- int y);
+ int x, int y);
int handle_event();
};
+class PrefsYUV420P_DVDlace : public BC_CheckBox
+{
+public:
+ PrefsYUV420P_DVDlace(PreferencesWindow *pwindow,
+ PerformancePrefs *subwindow,
+ int x, int y);
+
+ int handle_event();
+
+ PerformancePrefs *subwindow;
+ PreferencesWindow *pwindow;
+};
+
+
class CICacheSize : public BC_TumbleTextBox
{
PreferencesWindow *pwindow;
};
-
-
-
-
#endif
class PrefsRenderFarmDelNode;
class PrefsRenderFarmSortNodes;
class PrefsRenderFarmReset;
+class PrefsYUV420P_DVDlace;
class CICacheSize;
#endif
ffmpeg_early_probe = 0;
ffmpeg_marker_indexes = 1;
warn_indexes = 1;
+ dvd_yuv420p_interlace = 0;
// Default brender asset
brender_asset = new Asset;
ffmpeg_early_probe = that->ffmpeg_early_probe;
ffmpeg_marker_indexes = that->ffmpeg_marker_indexes;
warn_indexes = that->warn_indexes;
+ dvd_yuv420p_interlace = that->dvd_yuv420p_interlace;
renderfarm_nodes.remove_all_objects();
renderfarm_ports.remove_all();
renderfarm_enabled.remove_all();
ffmpeg_early_probe = defaults->get("FFMPEG_EARLY_PROBE", ffmpeg_early_probe);
ffmpeg_marker_indexes = defaults->get("FFMPEG_MARKER_INDEXES", ffmpeg_marker_indexes);
warn_indexes = defaults->get("WARN_INDEXES", warn_indexes);
+ dvd_yuv420p_interlace = defaults->get("DVD_YUV420P_INTERLACE", dvd_yuv420p_interlace);
use_brender = defaults->get("USE_BRENDER", use_brender);
brender_fragment = defaults->get("BRENDER_FRAGMENT", brender_fragment);
cache_size = defaults->get("CACHE_SIZE", cache_size);
defaults->update("FFMPEG_EARLY_PROBE", ffmpeg_early_probe);
defaults->update("FFMPEG_MARKER_INDEXES", ffmpeg_marker_indexes);
defaults->update("WARN_INDEXES", warn_indexes);
+ defaults->update("DVD_YUV420P_INTERLACE", dvd_yuv420p_interlace);
brender_asset->save_defaults(defaults,
"BRENDER_",
1,
int ffmpeg_marker_indexes;
// warning
int warn_indexes;
+// use dvd yuv420p interlace format
+ int dvd_yuv420p_interlace;
// Default positions for channels
int channel_positions[MAXCHANNELS * MAXCHANNELS];
for(Track *current = first; current; current = NEXT)
{
long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
- Auto *mute_keyframe = current->automation->autos[AUTOMATION_MUTE]->
+ Auto *mute_keyframe = 0;
+ current->automation->autos[AUTOMATION_MUTE]->
get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe);
IntAuto *mute_auto = (IntAuto *)mute_keyframe;
"w": " yop[j] = y>>8; uop[j/2] = u>>8; vop[j/2] = v>>8;",
},
},
+ "yuv420pi": {
+ "i8": {
+ "r": " int32_t y = *yip*0x010101u, u = *uip, v = *vip;",
+ "w": " yop[j] = y; uop[j/2] = u; vop[j/2] = v;",
+ },
+ "i16": {
+ "r": " int32_t y = *yip*0x010101u, u = *uip<<8, v = *vip<<8;",
+ "w": " yop[j] = y>>8; uop[j/2] = u>>8; vop[j/2] = v>>8;",
+ },
+ },
"yuv422p": {
"i8": {
add_cmodel(28, "bc_yuv410p", "i8", "yuv410p")
add_cmodel(32, "bc_rgb_floatp", "fp", "rgbfltp")
add_cmodel(33, "bc_rgba_floatp", "fp", "rgbfltp", "afpp")
+add_cmodel(34, "bc_yuv420pi", "i8", "yuv420pi")
specialize("bc_rgba8888", "bc_transparency", "XFER_rgba8888_to_transparency")
def is_yuv(nm):
return nm in [ "bc_yuv888", "bc_yuva8888", "bc_yuv161616", \
"bc_yuva16161616", "bc_yuv422", "bc_uvy422", "bc_yuv101010", \
- "bc_vyu888", "bc_uyva8888", "bc_yuv420p", "bc_yuv422p", \
+ "bc_vyu888", "bc_uyva8888", "bc_yuv420p", "bc_yuv420pi", "bc_yuv422p", \
"bc_yuv444p", "bc_yuv411p", "bc_yuv410p", ]
def is_planar(nm):
- return nm in [ "bc_yuv420p", "bc_yuv422p", "bc_yuv444p", \
+ return nm in [ "bc_yuv420p", "bc_yuv420pi", "bc_yuv422p", "bc_yuv444p", \
"bc_yuv411p", "bc_yuv410p", "bc_rgb_floatp", "bc_rgba_floatp", ]
def is_float(nm):
{
switch(colormodel) {
case BC_YUV420P:
+ case BC_YUV420PI:
case BC_YUV422P:
case BC_YUV444P:
case BC_YUV411P:
case BC_RGBA_FLOAT: return 16;
// Planar
case BC_YUV420P: return 1;
+ case BC_YUV420PI: return 1;
case BC_YUV422P: return 1;
case BC_YUV444P: return 1;
case BC_YUV422: return 2;
switch(color_model) {
case BC_YUV410P: return w * h + w * h / 8 + 4;
case BC_YUV420P:
+ case BC_YUV420PI:
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_VYU888:
case BC_UYVA8888:
case BC_YUV420P:
+ case BC_YUV420PI:
case BC_YUV422P:
case BC_YUV444P:
case BC_YUV411P:
#define BC_YUV410P 28
#define BC_RGB_FLOATP 32
#define BC_RGBA_FLOATP 33
+#define BC_YUV420PI 34
// Colormodels purely used by Quicktime are done in Quicktime.
"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",
+ "rgb_floatp", "rgba_floatp", "yuv420pi",
};
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<=32; ++fr_cmdl ) {
+ for( int fr_cmdl=1; fr_cmdl<=34; ++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;
case BC_YUV410P:
case BC_YUV411P:
case BC_YUV420P:
+ case BC_YUV420PI:
case BC_YUV422P:
case BC_YUV444P:
case BC_RGB_FLOATP:
break;
case BC_YUV420P:
+ case BC_YUV420PI:
case BC_YUV411P:
if( this->v_offset ) break;
this->y_offset = 0;
case BC_YUV411P:
case BC_YUV420P:
+ case BC_YUV420PI:
bzero(get_y(), sz);
bzero(get_u(), sz / 4);
bzero(get_v(), sz / 4);
break;
case BC_YUV420P:
+ case BC_YUV420PI:
case BC_YUV411P:
//printf("%d %d %p %p %p %p %p %p\n", w, h, get_y(), get_u(), get_v(), frame->get_y(), frame->get_u(), frame->get_v());
memcpy(get_y(), frame->get_y(), w * h);
switch( in_colormodel ) {
case BC_UVY422:
case BC_YUV422: in_w &= ~1; break; // 2x1
- case BC_YUV420P: in_w &= ~1; in_h &= ~1; break; // 2x2
+ case BC_YUV420P:
+ case BC_YUV420PI: in_w &= ~1; in_h &= ~1; break; // 2x2
case BC_YUV422P: in_w &= ~1; break; // 2x1
case BC_YUV410P: in_w &= ~3; in_h &= ~3; break; // 4x4
case BC_YUV411P: in_w &= ~3; break; // 4x1
switch( out_colormodel ) {
case BC_UVY422:
case BC_YUV422: out_w &= ~1; break;
- case BC_YUV420P: out_w &= ~1; out_h &= ~1; break;
+ case BC_YUV420P:
+ case BC_YUV420PI: out_w &= ~1; out_h &= ~1; break;
case BC_YUV422P: out_w &= ~1; break;
case BC_YUV410P: out_w &= ~3; out_h &= ~3; break;
case BC_YUV411P: out_w &= ~3; break;
oty_t *vop = (oty_t *)(out_vp + out_rofs); \
#define xfer_yuv420p_row_in(ity_t) \
- int in_rofs = row_table[i] * total_in_w; \
+ int in_r = row_table[i]; \
+ int in_rofs = in_r * total_in_w; \
+ uint8_t *yip_row = in_yp + in_rofs; \
+ in_rofs = in_r / 2 * total_in_w / 2; \
+ uint8_t *uip_row = in_up + in_rofs; \
+ uint8_t *vip_row = in_vp + in_rofs; \
+ for( unsigned j=0; j<out_w; ++j ) { \
+ int in_ofs = column_table[j]; \
+ ity_t *yip = (ity_t *)(yip_row + in_ofs); \
+ in_ofs /= 2; \
+ ity_t *uip = (ity_t *)(uip_row + in_ofs); \
+ ity_t *vip = (ity_t *)(vip_row + in_ofs); \
+
+// yuv420pi 2x2
+#define xfer_yuv420pi_row_out(oty_t) \
+ for( unsigned i=y0; i<y1; ++i ) { \
+ int out_rofs = i * total_out_w + out_x; \
+ oty_t *yop = (oty_t *)(out_yp + out_rofs); \
+ int ot_k = ((i/4)<<1) + (i&1); \
+ out_rofs = ot_k * total_out_w / 2 + out_x / 2; \
+ oty_t *uop = (oty_t *)(out_up + out_rofs); \
+ oty_t *vop = (oty_t *)(out_vp + out_rofs); \
+
+#define xfer_yuv420pi_row_in(ity_t) \
+ int in_r = row_table[i]; \
+ int in_rofs = in_r * total_in_w; \
uint8_t *yip_row = in_yp + in_rofs; \
- in_rofs = row_table[i] / 2 * total_in_w / 2; \
+ int in_k = ((in_r/4)<<1) + (in_r&1); \
+ in_rofs = in_k * total_in_w / 2; \
uint8_t *uip_row = in_up + in_rofs; \
uint8_t *vip_row = in_vp + in_rofs; \
for( unsigned j=0; j<out_w; ++j ) { \
config.size = 72;
if(config.stroke_width < 0 || config.stroke_width >= 512)
config.stroke_width = 0.0;
- if(!config.wlen)
+ if(!config.wlen && !config.timecode)
return 0;
if(!strlen(config.encoding))
strcpy(config.encoding, DEFAULT_ENCODING);
config.dropshadow = input.tag.get_property("DROPSHADOW", config.dropshadow);
config.outline_size = input.tag.get_property("OUTLINE_SIZE", config.outline_size);
config.timecode = input.tag.get_property("TIMECODE", config.timecode);
- input.tag.get_property("TIMECODEFORMAT", config.timecode_format);
+ config.timecode_format = input.tag.get_property("TIMECODEFORMAT", config.timecode_format);
config.window_w = input.tag.get_property("WINDOW_W", config.window_w);
config.window_h = input.tag.get_property("WINDOW_H", config.window_h);
const char *text = input.read_text();