From: Good Guy Date: Sat, 28 Jan 2017 22:11:13 +0000 (-0700) Subject: textbox cursor fix, h265 param files, bluray updates, new-proj theme fixes X-Git-Url: https://cinelerra-gg.org/git/?a=commitdiff_plain;h=27d1d08d9125dc46f252073aaf1fead7518ee4c8;p=goodguy%2Fhistory.git textbox cursor fix, h265 param files, bluray updates, new-proj theme fixes --- diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C index 57c207ba..b784d0ed 100644 --- a/cinelerra-5.1/cinelerra/bdcreate.C +++ b/cinelerra-5.1/cinelerra/bdcreate.C @@ -46,10 +46,10 @@ static struct bd_format { { "1920x1080 24p", 1920,1080, 24., 1, ILACE_MODE_NOTINTERLACED }, { "1920x1080 25i", 1920,1080, 25., 1, ILACE_MODE_TOP_FIRST }, { "1920x1080 23.976p", 1920,1080, 23.976, 1, ILACE_MODE_NOTINTERLACED }, - { "1440x1080 29.97i", 1440,1080, 29.97, 1, ILACE_MODE_TOP_FIRST }, - { "1440x1080 25i", 1440,1080, 25., 1, ILACE_MODE_TOP_FIRST }, - { "1440x1080 24p", 1440,1080, 24., 1, ILACE_MODE_NOTINTERLACED }, - { "1440x1080 23.976p", 1440,1080, 23.976, 1, ILACE_MODE_NOTINTERLACED }, + { "1440x1080 29.97i", 1440,1080, 29.97, -1, ILACE_MODE_TOP_FIRST }, + { "1440x1080 25i", 1440,1080, 25., -1, ILACE_MODE_TOP_FIRST }, + { "1440x1080 24p", 1440,1080, 24., -1, ILACE_MODE_NOTINTERLACED }, + { "1440x1080 23.976p", 1440,1080, 23.976,-1, ILACE_MODE_NOTINTERLACED }, { "1280x720 59.94p", 1280,720, 59.94, 1, ILACE_MODE_NOTINTERLACED }, { "1280x720 50p", 1280,720, 50., 1, ILACE_MODE_NOTINTERLACED }, { "1280x720 24p", 1280,720, 24., 1, ILACE_MODE_NOTINTERLACED }, @@ -69,8 +69,8 @@ const double CreateBD_Thread::BD_WIDE_ASPECT_HEIGHT = 9.; const double CreateBD_Thread::BD_ASPECT_WIDTH = 4.; const double CreateBD_Thread::BD_ASPECT_HEIGHT = 3.; const double CreateBD_Thread::BD_FRAMERATE = 24000. / 1001.; -const int CreateBD_Thread::BD_MAX_BITRATE = 40000000; -//const int CreateBD_Thread::BD_MAX_BITRATE = 8000000; +//const int CreateBD_Thread::BD_MAX_BITRATE = 40000000; +const int CreateBD_Thread::BD_MAX_BITRATE = 10000000; const int CreateBD_Thread::BD_CHANNELS = 2; const int CreateBD_Thread::BD_WIDE_CHANNELS = 6; const double CreateBD_Thread::BD_SAMPLERATE = 48000; @@ -334,6 +334,7 @@ void CreateBD_Thread::handle_close_event(int result) edit->startproject, edit->length, PLUGIN_STANDALONE, 0, &keyframe, 0); } + vtrk->optimize(); } } if( use_resize_tracks ) @@ -803,6 +804,7 @@ insert_video_plugin(const char *title, KeyFrame *default_keyframe) edit->startproject, edit->length, PLUGIN_STANDALONE, 0, default_keyframe, 0); } + vtrk->optimize(); } return 0; } @@ -838,10 +840,11 @@ option_presets() bd_width = bd_formats[use_standard].w; bd_height = bd_formats[use_standard].h; bd_framerate = bd_formats[use_standard].framerate; - bd_aspect_width = bd_formats[use_standard].wide ? - BD_WIDE_ASPECT_WIDTH : BD_ASPECT_WIDTH; - bd_aspect_height = bd_formats[use_standard].wide ? - BD_WIDE_ASPECT_HEIGHT : BD_ASPECT_HEIGHT; + int wide = bd_formats[use_standard].wide; + bd_aspect_width = wide < 0 ? 1. : + wide > 0 ? BD_WIDE_ASPECT_WIDTH : BD_ASPECT_WIDTH; + bd_aspect_height = wide < 0 ? 1. : + wide > 0 ? BD_WIDE_ASPECT_HEIGHT : BD_ASPECT_HEIGHT; bd_interlace_mode = bd_formats[use_standard].interlaced; double bd_aspect = bd_aspect_width / bd_aspect_height; @@ -865,7 +868,8 @@ option_presets() float aw, ah; MWindow::create_aspect_ratio(aw, ah, w, h); double aspect = ah > 0 ? aw / ah : 1; - if( !EQUIV(aspect, bd_aspect) ) use_scale = Rescale::scaled; + if( wide >= 0 && !EQUIV(aspect, bd_aspect) ) + use_scale = Rescale::scaled; } for( int i=0; iplugin_set.size(); ++i ) { for(Plugin *plugin = (Plugin*)trk->plugin_set[i]->first; diff --git a/cinelerra-5.1/cinelerra/bdwrite.C b/cinelerra-5.1/cinelerra/bdwrite.C index e70aa69a..a8596706 100644 --- a/cinelerra-5.1/cinelerra/bdwrite.C +++ b/cinelerra-5.1/cinelerra/bdwrite.C @@ -54,6 +54,7 @@ #define BCTEXTLEN 1024 #define BLURAY_TS_PKTSZ 192L +static const int bd_sig = 2; extern "C" { #include "libavfilter/buffersrc.h" @@ -186,15 +187,19 @@ class bs_length { int64_t fpos, len; public: bs_length() { fpos = len = 0; } + int64_t bs_posb(bs_file &bs) { return bs.posb() - fpos; } void bs_len(bs_file &bs, int n) { bs.write(len, n); fpos = bs.posb(); } void bs_end(bs_file &bs) { - len = bs.posb() - fpos; + len = bs_posb(bs); } void bs_ofs(bs_file &bs, int n) { bs.write(fpos-n/8, n); } + void bs_zofs(bs_file &bs, int n) { + bs.write(!len ? 0 : fpos-n/8, n); + } }; class _bd_stream_info { @@ -580,6 +585,15 @@ public: ~clpi_cpi() { remove_all_objects(); } }; +class clpi_cmrk : public bs_length { +public: + int write(); + + clpi_cmrk() {} + ~clpi_cmrk() {} +}; + + class bd_uo_mask { public: unsigned int menu_call : 1; @@ -890,7 +904,7 @@ public: int write_pip_metadata_extension(); int write(); - mpls_pl() { sig = 1; } + mpls_pl() { sig = bd_sig; } ~mpls_pl() { play_item.remove_all_objects(); sub_path.remove_all_objects(); @@ -922,6 +936,7 @@ public: clpi_extents extents; clpi_programs programs_ss; clpi_cpi cpi_ss; + clpi_cmrk cmrk; int write_header(); int write(); @@ -929,7 +944,7 @@ public: int write_clpi_extension(int id1, int id2, void *handle); int write_mpls_extension(int id1, int id2, void *handle); - clpi_cl() { sig = 1; } + clpi_cl() { sig = bd_sig; } ~clpi_cl() {} }; @@ -983,7 +998,7 @@ public: int sig; ArrayList movies; - movie_file() { sig = 1; } + movie_file() { sig = bd_sig; } ~movie_file() { movies.remove_all_objects(); } @@ -1062,7 +1077,7 @@ public: int write(); index_file() { - sig = 1; + sig = bd_sig; memset(user_data, 0, sizeof(user_data)); } ~index_file() { @@ -1086,7 +1101,7 @@ public: int sig; int write(); - bdid() { sig = 1; } + bdid() { sig = bd_sig; } ~bdid() {} }; @@ -1200,6 +1215,7 @@ public: ArrayList cl; ArrayList pl; + void add_movie(uint32_t *ops, int n); int compose(); int write(char *fn); @@ -1402,7 +1418,7 @@ index_file::write() bs.writeb("INDX", 4); bs.writeb(sig == 1 ? "0100" : "0200", 4); bs_ofs(bs, 32); - exten.bs_ofs(bs, 32); + exten.bs_zofs(bs, 32); int appinfo_start = 0x28; bs.posb(appinfo_start); appinf.bs_len(bs, 32); @@ -1530,6 +1546,7 @@ clpi_prog_stream::write() return 1; }; + bs.padb(0x15 - bs_posb(bs)); bs_end(bs); return 0; } @@ -1734,6 +1751,14 @@ clpi_cpi::write() return 0; } +int +clpi_cmrk::write() +{ + bs_len(bs, 32); + bs_end(bs); + return 0; +} + int clpi_extents::write() { @@ -1787,6 +1812,8 @@ clpi_cl::write() if( programs.write() ) return 1; cpi_start_addr = bs.posb(); if( cpi.write() ) return 1; + clip_mark_start_addr = bs.posb(); + if( cmrk.write() ) return 1; //if( has_ext_data ) { // ext_data_start_addr = bs.pos(); // bdmv_write_extension_data(write_clpi_extension, this); @@ -1897,6 +1924,7 @@ write() fprintf(stderr, "unrecognized stream type %02x\n", stream_type); break; }; + bs.padb(9 - strm.bs_posb(bs)); strm.bs_end(bs); code.bs_len(bs, 8); @@ -1940,6 +1968,7 @@ write() fprintf(stderr, "mpls_stream: unrecognized coding type %02x\n", coding_type); break; }; + bs.padb(5 - code.bs_posb(bs)); code.bs_end(bs); return 0; } @@ -2303,14 +2332,20 @@ mkbdmv(char *path) char bdmv_path[BCTEXTLEN]; sprintf(bdmv_path, "%s/BDMV", path); if( mk_bdmv_dir(bdmv_path) ) return 1; + char cert_path[BCTEXTLEN]; + sprintf(cert_path, "%s/CERTIFICATE", path); + if( mk_bdmv_dir(cert_path) ) return 1; + char cert_backup[BCTEXTLEN]; + sprintf(cert_backup, "%s/BACKUP", cert_path); + if( mk_bdmv_dir(cert_backup) ) return 1; char stream_path[BCTEXTLEN]; - sprintf(stream_path, "%s/BDMV/STREAM", path); + sprintf(stream_path, "%s/STREAM", bdmv_path); if( mk_dir(stream_path) ) return 1; char auxdata_path[BCTEXTLEN]; - sprintf(auxdata_path, "%s/BDMV/AUXDATA", path); + sprintf(auxdata_path, "%s/AUXDATA", bdmv_path); if( mk_dir(auxdata_path) ) return 1; char meta_path[BCTEXTLEN]; - sprintf(meta_path, "%s/BDMV/META", path); + sprintf(meta_path, "%s/META", bdmv_path); if( mk_dir(meta_path) ) return 1; char backup_path[BCTEXTLEN]; sprintf(backup_path, "%s/BACKUP", bdmv_path); @@ -2334,15 +2369,15 @@ build_toc(clpi_ep_map_entry *map) uint32_t pkt = mp->pos / BLURAY_TS_PKTSZ; if( last_pkt >= pkt ) continue; last_pkt = pkt; - int64_t coarse_pts = (pts >> 18) & ~0x01; + int64_t coarse_pts = (pts >> 18); // & ~0x01; int64_t fine_pts = (pts & 0x7ffff) >> 8; uint32_t mpkt = pkt & ~0x1ffff; - if( !cp || cp->pts_ep != coarse_pts || cp->spn_ep != mpkt ) { + if( !cp || cp->pts_ep != coarse_pts || mpkt > cp->spn_ep ) { cp = new clpi_ep_coarse(); map->coarse.append(cp); cp->ref_ep_fine_id = map->fine.size(); cp->pts_ep = coarse_pts; - cp->spn_ep = mpkt; + cp->spn_ep = pkt; } clpi_ep_fine *fp = new clpi_ep_fine(); map->fine.append(fp); @@ -2362,6 +2397,8 @@ static int bd_stream_type(AVCodecID codec_id) int stream_type = 0; switch (codec_id) { case AV_CODEC_ID_MPEG1VIDEO: + stream_type = BLURAY_STREAM_TYPE_VIDEO_MPEG1; + break; case AV_CODEC_ID_MPEG2VIDEO: stream_type = BLURAY_STREAM_TYPE_VIDEO_MPEG2; break; @@ -2369,18 +2406,26 @@ static int bd_stream_type(AVCodecID codec_id) stream_type = BLURAY_STREAM_TYPE_VIDEO_H264; break; case AV_CODEC_ID_MP2: - case AV_CODEC_ID_MP3: stream_type = BLURAY_STREAM_TYPE_AUDIO_MPEG1; break; + case AV_CODEC_ID_MP3: + stream_type = BLURAY_STREAM_TYPE_AUDIO_MPEG2; + break; case AV_CODEC_ID_AC3: stream_type = BLURAY_STREAM_TYPE_AUDIO_AC3; break; + case AV_CODEC_ID_EAC3: + stream_type = BLURAY_STREAM_TYPE_AUDIO_AC3PLUS; + break; case AV_CODEC_ID_DTS: stream_type = BLURAY_STREAM_TYPE_AUDIO_DTS; break; case AV_CODEC_ID_TRUEHD: stream_type = BLURAY_STREAM_TYPE_AUDIO_TRUHD; break; + case AV_CODEC_ID_HDMV_PGS_SUBTITLE: + stream_type = BLURAY_STREAM_TYPE_SUB_PG; + break; default: fprintf(stderr, "unknown bluray stream type %s\n", avcodec_get_name(codec_id)); exit(1); @@ -2524,6 +2569,7 @@ int media_info::scan() switch( type ) { case AVMEDIA_TYPE_VIDEO: break; case AVMEDIA_TYPE_AUDIO: break; + case AVMEDIA_TYPE_SUBTITLE: break; default: continue; } stream *s = new stream(type, i); @@ -2549,7 +2595,12 @@ int media_info::scan() s->coding_type = bd_stream_type(codec_id); s->format = bd_audio_format(st->codec->channels); s->rate = bd_audio_rate(st->codec->sample_rate); - strcpy((char*)s->lang, "und"); + strcpy((char*)s->lang, "eng"); + break; } + case AVMEDIA_TYPE_SUBTITLE: { + s->coding_type = bd_stream_type(codec_id); + AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", 0, 0); + strncpy((char*)s->lang, lang ? lang->value : "und", sizeof(s->lang)); break; } default: break; @@ -2574,7 +2625,7 @@ int media_info::scan() program *pgm = new program(-1, 1); pgm->ep_pid = ep_pid; pgm->pmt_pid = 0x1000; - pgm->pcr_pid = 0x100; + pgm->pcr_pid = 0x1001; pgm->duration = 0; for( int jj=0; jjstreams[jj]; @@ -2609,6 +2660,7 @@ int media_info::scan() if( ep_pid < 0 ) ep_pid = st->id; break; case AVMEDIA_TYPE_AUDIO: + case AVMEDIA_TYPE_SUBTITLE: break; default: continue; @@ -2647,7 +2699,7 @@ int media_info::scan(AVFormatContext *fmt_ctx) int ret = 0; AVPacket ipkt; av_init_packet(&ipkt); -#if 0 +#if 1 // zero pts at pos zero for( int i=0; iresume_intention_flag = 1; + uint32_t *eop = ops + n/sizeof(*ops); + while( ops < eop ) { + command_obj *cmd = new command_obj(); + cmd->cmd = htobe32(*ops++); + cmd->dst = *ops++; + cmd->src = *ops++; + mp->cmds.append(cmd); + } + mov.movies.append(mp); +} + int Media::compose() { -// index - bs.init(); - idx.sig = 1; - idx.first_play.set_hdmv(0, pb_typ_movie); - idx.top_menu.set_hdmv(0xffff, pb_typ_iactv); - // movie bs.init(); - mov.sig = 1; + +// top menu + int top_menu_obj = mov.movies.size(); movie_obj *mp = new movie_obj(); mp->resume_intention_flag = 1; command_obj *cmd = new command_obj(); cmd->cmd = htobe32(0x21810000); cmd->dst = 1; cmd->src = 0; mp->cmds.append(cmd); // JUMP_TITLE 1 - cmd = new command_obj(); - cmd->cmd = htobe32(0x00020000); cmd->dst = 0; cmd->src = 0; - mp->cmds.append(cmd); - mov.movies.append(mp); // BREAK - + mov.movies.append(mp); +// titles for( int ii=0; iiresume_intention_flag = 1; @@ -2745,15 +2806,19 @@ Media::compose() mov.movies.append(mp); // BREAK } +// first play + int first_play_obj = mov.movies.size(); mp = new movie_obj(); mp->resume_intention_flag = 1; cmd = new command_obj(); - cmd->cmd = htobe32(0x21810000); cmd->dst = 1; cmd->src = 0; - mp->cmds.append(cmd); // JUMP_TITLE 1 - cmd = new command_obj(); - cmd->cmd = htobe32(0x00020000); cmd->dst = 0; cmd->src = 0; - mp->cmds.append(cmd); - mov.movies.append(mp); // BREAK + cmd->cmd = htobe32(0x21810000); cmd->dst = 0; cmd->src = 0; + mp->cmds.append(cmd); // JUMP_TITLE 0 ; top menu + mov.movies.append(mp); + +// index + bs.init(); + idx.first_play.set_hdmv(first_play_obj, pb_typ_iactv); + idx.top_menu.set_hdmv(top_menu_obj, pb_typ_iactv); title_obj *tp = 0; // clips @@ -2776,7 +2841,7 @@ Media::compose() cp->clip.clip_stream_type = 1; cp->clip.application_type = BLURAY_APP_TYPE_MAIN_MOVIE; cp->clip.ts_recording_rate = ip->bit_rate; - uint32_t ts_pkt_count = ip->file_size / BLURAY_TS_PKTSZ + 1; + uint32_t ts_pkt_count = ip->file_size / BLURAY_TS_PKTSZ; cp->clip.num_source_packets = ts_pkt_count; cp->clip.ts_type_info.validity = 0x80; strcpy(cp->clip.ts_type_info.format_id, "HDMV"); @@ -2801,6 +2866,7 @@ Media::compose() s->aspect = sp->aspect; break; case AVMEDIA_TYPE_AUDIO: + case AVMEDIA_TYPE_SUBTITLE: memcpy(s->lang,sp->lang,sizeof(s->lang)); break; default: @@ -2809,6 +2875,7 @@ Media::compose() p->streams.append(s); } clpi_ep_map_entry *map = new clpi_ep_map_entry(pgm->ep_pid); + map->ep_stream_type = 1; pgm->build_toc(map); cp->cpi.append(map); cp->programs.append(p); @@ -2843,6 +2910,7 @@ Media::compose() pgm = ip->prog(); mpls_pi *pi = new mpls_pi(); pi->connection_condition = 1; // seamless +// pi->uo_mask.xxx = 1; pi->in_time = pgm->start_time; pi->out_time = pgm->end_time; if( ip->still ) @@ -2857,6 +2925,7 @@ Media::compose() switch( sp->type ) { case AVMEDIA_TYPE_VIDEO: break; case AVMEDIA_TYPE_AUDIO: break; + case AVMEDIA_TYPE_SUBTITLE: break; default: continue; } mpls_stream *ps = new mpls_stream(); @@ -2873,6 +2942,10 @@ Media::compose() memcpy(ps->lang, sp->lang, sizeof(ps->lang)); pi->stn.audio.append(ps); break; + case AVMEDIA_TYPE_SUBTITLE: + memcpy(ps->lang, sp->lang, sizeof(ps->lang)); + pi->stn.pg.append(ps); + break; default: break; } @@ -2880,7 +2953,7 @@ Media::compose() pp->play_item.append(pi); } // chapter marks every ch_duration ticks - int64_t ch_duration = 45000 * 60*10; + int64_t ch_duration = 45000 * 60*5; int64_t mrktm = ch_duration; int64_t plytm = 0; int pmark = 0, pitem = 0; diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index 3ba22244..60a17ed4 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -21,6 +21,7 @@ #include "file.h" #include "ffmpeg.h" #include "indexfile.h" +#include "interlacemodes.h" #include "libdv.h" #include "libmjpeg.h" #include "mainerror.h" @@ -725,6 +726,8 @@ FFVideoStream::FFVideoStream(FFMPEG *ffmpeg, AVStream *strm, int idx, int fidx) frame_rate = 0; aspect_ratio = 0; length = 0; + interlaced = 0; + top_field_first = 0; } FFVideoStream::~FFVideoStream() @@ -822,6 +825,10 @@ int FFVideoStream::encode(VFrame *vframe) int FFVideoStream::encode_frame(AVPacket *pkt, AVFrame *frame, int &got_packet) { + if( frame ) { + frame->interlaced_frame = interlaced; + frame->top_field_first = top_field_first; + } int ret = avcodec_encode_video2(st->codec, pkt, frame, &got_packet); if( ret < 0 ) { ff_err(ret, "FFVideoStream::encode_frame: encode video failed\n"); @@ -1172,7 +1179,7 @@ AVRational FFMPEG::to_sample_aspect_ratio(Asset *asset) int width = 1000000, height = width * sample_aspect + 0.5; float w, h; MWindow::create_aspect_ratio(w, h, width, height); - return (AVRational){(int)h, (int)w}; + return (AVRational){(int)w, (int)h}; #else // square pixels return (AVRational){1, 1}; @@ -1245,20 +1252,38 @@ int FFMPEG::get_codec(char *codec, const char *path, const char *spec) int FFMPEG::get_file_format() { - int ret = 0; + char audio_muxer[BCSTRLEN], video_muxer[BCSTRLEN]; char audio_format[BCSTRLEN], video_format[BCSTRLEN]; - file_format[0] = audio_format[0] = video_format[0] = 0; + audio_muxer[0] = audio_format[0] = 0; + video_muxer[0] = video_format[0] = 0; Asset *asset = file_base->asset; - if( !ret && asset->audio_data ) - ret = get_format(audio_format, "audio", asset->acodec); - if( !ret && asset->video_data ) - ret = get_format(video_format, "video", asset->vcodec); - if( !ret && !audio_format[0] && !video_format[0] ) + int ret = asset ? 0 : 1; + if( !ret && asset->audio_data ) { + if( !(ret=get_format(audio_format, "audio", asset->acodec)) ) { + if( get_format(audio_muxer, "format", audio_format) ) { + strcpy(audio_muxer, audio_format); + audio_format[0] = 0; + } + } + } + if( !ret && asset->video_data ) { + if( !(ret=get_format(video_format, "video", asset->vcodec)) ) { + if( get_format(video_muxer, "format", video_format) ) { + strcpy(video_muxer, video_format); + video_format[0] = 0; + } + } + } + if( !ret && !audio_muxer[0] && !video_muxer[0] ) ret = 1; + if( !ret && audio_muxer[0] && video_muxer[0] && + strcmp(audio_muxer, video_muxer) ) ret = -1; if( !ret && audio_format[0] && video_format[0] && strcmp(audio_format, video_format) ) ret = -1; if( !ret ) - strcpy(file_format, audio_format[0] ? audio_format : video_format); + strcpy(file_format, !audio_format[0] && !video_format[0] ? + (audio_muxer[0] ? audio_muxer : video_muxer) : + (audio_format[0] ? audio_format : video_format)); return ret; } @@ -1266,7 +1291,7 @@ int FFMPEG::scan_option_line(char *cp, char *tag, char *val) { while( *cp == ' ' || *cp == '\t' ) ++cp; char *bp = cp; - while( *cp && *cp != ' ' && *cp != '\t' && *cp != '=' ) ++cp; + while( *cp && *cp != ' ' && *cp != '\t' && *cp != '=' && *cp != '\n' ) ++cp; int len = cp - bp; if( !len || len > BCSTRLEN-1 ) return 1; while( bp < cp ) *tag++ = *bp++; @@ -1287,7 +1312,7 @@ int FFMPEG::load_defaults(const char *path, const char *type, char *codec, char *codec_options, int len) { char default_file[BCTEXTLEN]; - FFMPEG::set_option_path(default_file, "%s/%s.dfl", path, type); + set_option_path(default_file, "%s/%s.dfl", path, type); FILE *fp = fopen(default_file,"r"); if( !fp ) return 1; fgets(codec, BCSTRLEN, fp); @@ -1299,14 +1324,15 @@ int FFMPEG::load_defaults(const char *path, const char *type, codec_options += n; len -= n; } fclose(fp); - FFMPEG::set_option_path(default_file, "%s/%s", path, codec); - return FFMPEG::load_options(default_file, codec_options, len); + set_option_path(default_file, "%s/%s", path, codec); + return load_options(default_file, codec_options, len); } void FFMPEG::set_asset_format(Asset *asset, const char *text) { if( asset->format != FILE_FFMPEG ) return; - strcpy(asset->fformat, text); + if( text != asset->fformat ) + strcpy(asset->fformat, text); if( !asset->ff_audio_options[0] ) { asset->audio_data = !load_defaults("audio", text, asset->acodec, asset->ff_audio_options, sizeof(asset->ff_audio_options)); @@ -1347,11 +1373,18 @@ int FFMPEG::get_encoder(FILE *fp, return 0; } -int FFMPEG::read_options(const char *options, AVDictionary *&opts) +int FFMPEG::read_options(const char *options, AVDictionary *&opts, int skip) { FILE *fp = fopen(options,"r"); if( !fp ) return 1; - int ret = read_options(fp, options, opts); + int ret = 0; + while( !ret && --skip >= 0 ) { + int ch = getc(fp); + while( ch >= 0 && ch != '\n' ) ch = getc(fp); + if( ch < 0 ) ret = 1; + } + if( !ret ) + ret = read_options(fp, options, opts); fclose(fp); return ret; } @@ -1373,7 +1406,6 @@ int FFMPEG::read_options(FILE *fp, const char *options, AVDictionary *&opts) char line[BCTEXTLEN]; while( !ret && fgets(line, sizeof(line), fp) ) { line[sizeof(line)-1] = 0; - ++no; if( line[0] == '#' ) continue; if( line[0] == '\n' ) continue; char key[BCSTRLEN], val[BCTEXTLEN]; @@ -1678,7 +1710,10 @@ int FFMPEG::init_encoder(const char *filename) } ff_lock("FFMPEG::init_encoder"); av_register_all(); - avformat_alloc_output_context2(&fmt_ctx, 0, file_format, filename); + char format[BCSTRLEN]; + if( get_format(format, "format", file_format) ) + strcpy(format, file_format); + avformat_alloc_output_context2(&fmt_ctx, 0, format, filename); if( !fmt_ctx ) { eprintf(_("failed: %s\n"), filename); ret = 1; @@ -1836,6 +1871,9 @@ int FFMPEG::open_encoder(const char *type, const char *spec) ctx->time_base = (AVRational) { frame_rate.den, frame_rate.num }; st->time_base = ctx->time_base; vid->writing = -1; + vid->interlaced = asset->interlace_mode == ILACE_MODE_TOP_FIRST || + asset->interlace_mode == ILACE_MODE_BOTTOM_FIRST ? 1 : 0; + vid->top_field_first = asset->interlace_mode == ILACE_MODE_TOP_FIRST ? 1 : 0; break; } default: eprintf(_("not audio/video, %s:%s\n"), codec_name, filename); @@ -1985,17 +2023,51 @@ int FFMPEG::encode_activate() return -1; } + int prog_id = 1; + AVProgram *prog = av_new_program(fmt_ctx, prog_id); + for( int i=0; i< ffvideo.size(); ++i ) + av_program_add_stream_index(fmt_ctx, prog_id, ffvideo[i]->fidx); + for( int i=0; i< ffaudio.size(); ++i ) + av_program_add_stream_index(fmt_ctx, prog_id, ffaudio[i]->fidx); + int pi = fmt_ctx->nb_programs; + while( --pi >= 0 && fmt_ctx->programs[pi]->id != prog_id ); + AVDictionary **meta = &prog->metadata; + av_dict_set(meta, "service_provider", "cin5", 0); + const char *path = fmt_ctx->filename, *bp = strrchr(path,'/'); + if( bp ) path = bp + 1; + av_dict_set(meta, "title", path, 0); + + if( ffaudio.size() ) { + const char *ep = getenv("CIN_AUDIO_LANG"), *lp = 0; + if( !ep && (lp=getenv("LANG")) ) { // some are guesses + static struct { const char lc[3], lng[4]; } lcode[] = { + { "en", "eng" }, { "de", "ger" }, { "es", "spa" }, + { "eu", "bas" }, { "fr", "fre" }, { "el", "gre" }, + { "hi", "hin" }, { "it", "ita" }, { "ja", "jap" }, + { "ko", "kor" }, { "du", "dut" }, { "pl", "pol" }, + { "pt", "por" }, { "ru", "rus" }, { "sl", "slv" }, + { "uk", "ukr" }, { "vi", "vie" }, { "zh", "chi" }, + }; + for( int i=sizeof(lcode)/sizeof(lcode[0]); --i>=0 && !ep; ) + if( !strncmp(lcode[i].lc,lp,2) ) ep = lcode[i].lng; + } + char lang[4]; + strncpy(lang,ep,3); lang[3] = 0; + AVStream *st = ffaudio[0]->st; + av_dict_set(&st->metadata,"language",lang,0); + } + AVDictionary *fopts = 0; char option_path[BCTEXTLEN]; set_option_path(option_path, "format/%s", file_format); - read_options(option_path, fopts); + read_options(option_path, fopts, 1); ret = avformat_write_header(fmt_ctx, &fopts); - av_dict_free(&fopts); if( ret < 0 ) { ff_err(ret, "FFMPEG::encode_activate: write header failed %s\n", fmt_ctx->filename); return -1; } + av_dict_free(&fopts); encoding = 1; } return encoding; diff --git a/cinelerra-5.1/cinelerra/ffmpeg.h b/cinelerra-5.1/cinelerra/ffmpeg.h index 91ad65a6..f665fa92 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.h +++ b/cinelerra-5.1/cinelerra/ffmpeg.h @@ -243,9 +243,8 @@ public: int64_t length; float aspect_ratio; - uint8_t *pkt_bfr; - int pkt_bfr_sz; - int64_t start_pts; + int interlaced; + int top_field_first; }; class FFMPEG : public Thread { @@ -272,7 +271,7 @@ public: char *format, char *codec, char *bsfilter, char *bsargs); int get_encoder(FILE *fp, char *format, char *codec, char *bsfilter, char *bsargs); - int read_options(const char *options, AVDictionary *&opts); + int read_options(const char *options, AVDictionary *&opts, int skip=0); int scan_options(const char *options, AVDictionary *&opts, AVStream *st); int read_options(FILE *fp, const char *options, AVDictionary *&opts); int load_options(const char *options, AVDictionary *&opts); diff --git a/cinelerra-5.1/cinelerra/fileffmpeg.C b/cinelerra-5.1/cinelerra/fileffmpeg.C index 4d7c713b..e99732b3 100644 --- a/cinelerra-5.1/cinelerra/fileffmpeg.C +++ b/cinelerra-5.1/cinelerra/fileffmpeg.C @@ -502,6 +502,7 @@ int FFMPEGConfigAudioPopup::handle_event() FFMPEG::load_options(option_path, asset->ff_audio_options, sizeof(asset->ff_audio_options)); popup->audio_options->update(asset->ff_audio_options); + popup->audio_options->set_text_row(0); char value[BCTEXTLEN]; if( !FileFFMPEG::get_ff_option("cin_bitrate", asset->ff_audio_options, value) ) @@ -663,6 +664,7 @@ int FFMPEGConfigVideoPopup::handle_event() FFMPEG::load_options(option_path, asset->ff_video_options, sizeof(asset->ff_video_options)); popup->video_options->update(asset->ff_video_options); + popup->video_options->set_text_row(0); char value[BCTEXTLEN]; if( !FileFFMPEG::get_ff_option("cin_quality", asset->ff_video_options, value) ) { diff --git a/cinelerra-5.1/cinelerra/new.C b/cinelerra-5.1/cinelerra/new.C index fce4c09f..949de932 100644 --- a/cinelerra-5.1/cinelerra/new.C +++ b/cinelerra-5.1/cinelerra/new.C @@ -49,9 +49,8 @@ #include -#define WIDTH 600 -#define HEIGHT 400 - +#define WIDTH 640 +#define HEIGHT 425 New::New(MWindow *mwindow) : BC_MenuItem(_("New Project..."), "n", 'n') @@ -163,8 +162,8 @@ BC_Window* NewThread::new_gui() load_defaults(); mwindow->gui->lock_window("NewThread::new_gui"); - int x = mwindow->gui->get_abs_cursor_x(0) - WIDTH / 2; - int y = mwindow->gui->get_abs_cursor_y(0) - HEIGHT / 2; + int x = mwindow->gui->get_pop_cursor_x(0); + int y = mwindow->gui->get_pop_cursor_y(0); nwindow = new NewWindow(mwindow, this, x, y); nwindow->create_objects(); @@ -177,6 +176,7 @@ BC_Window* NewThread::new_gui() void NewThread::handle_close_event(int result) { + if( !new_project->new_edl ) return; new_project->new_edl->save_defaults(mwindow->defaults); mwindow->defaults->save(); @@ -227,16 +227,8 @@ int NewThread::update_aspect() NewWindow::NewWindow(MWindow *mwindow, NewThread *new_thread, int x, int y) - : BC_Window(_(_(PROGRAM_NAME ": New Project")), - x, - y, - WIDTH, - HEIGHT, - -1, - -1, - 0, - 0, - 1) + : BC_Window(_(PROGRAM_NAME ": New Project"), x, y, WIDTH, HEIGHT, + -1, -1, 0, 0, 1) { this->mwindow = mwindow; this->new_thread = new_thread; @@ -306,7 +298,7 @@ void NewWindow::create_objects() y += 30; x1 = x; add_subwindow(new BC_Title(x1, y, _("Tracks:"))); - x1 += 100; + x1 += 115; add_subwindow(vtracks = new NewVTracks(this, "", x1, y)); x1 += vtracks->get_w(); add_subwindow(new NewVTracksTumbler(this, x1, y)); @@ -321,7 +313,7 @@ void NewWindow::create_objects() // y += vchannels->get_h() + 5; x1 = x; add_subwindow(new BC_Title(x1, y, _("Framerate:"))); - x1 += 100; + x1 += 115; add_subwindow(frame_rate = new NewFrameRate(this, "", x1, y)); x1 += frame_rate->get_w(); add_subwindow(new FrameRatePulldown(mwindow, frame_rate, x1, y)); @@ -347,7 +339,7 @@ void NewWindow::create_objects() x1 = x; add_subwindow(new BC_Title(x1, y, _("Canvas size:"))); - x1 += 100; + x1 += 115; add_subwindow(output_w_text = new NewOutputW(this, x1, y)); x1 += output_w_text->get_w() + 2; add_subwindow(new BC_Title(x1, y, "x")); @@ -360,13 +352,13 @@ void NewWindow::create_objects() output_h_text, x1, y)); - x1 += pulldown->get_w() + 5; + x1 += pulldown->get_w() + 10; add_subwindow(new NewSwapExtents(mwindow, this, x1, y)); y += output_h_text->get_h() + 5; x1 = x; add_subwindow(new BC_Title(x1, y, _("Aspect ratio:"))); - x1 += 100; + x1 += 115; add_subwindow(aspect_w_text = new NewAspectW(this, "", x1, y)); x1 += aspect_w_text->get_w() + 2; add_subwindow(new BC_Title(x1, y, ":")); @@ -383,25 +375,23 @@ void NewWindow::create_objects() y += aspect_w_text->get_h() + 5; add_subwindow(new NewAspectAuto(this, x1, y)); y += 40; - add_subwindow(new BC_Title(x, y, _("Color model:"))); - add_subwindow(textbox = new BC_TextBox(x + 100, y, 200, 1, "")); + BC_Title *title; + add_subwindow(title = new BC_Title(x, y, _("Color model:"))); + x1 = x + title->get_w(); + y1 = y; y += title->get_h() + 10; + add_subwindow(title = new BC_Title(x, y, _("Interlace mode:"))); + int x2 = x + title->get_w(); + int y2 = y; y += title->get_h() + 10; + if( x1 < x2 ) x1 = x2; + x1 += 20; + add_subwindow(textbox = new BC_TextBox(x1, y1, 150, 1, "")); add_subwindow(color_model = new ColormodelPulldown(mwindow, - textbox, - &new_edl->session->color_model, - x + 100 + textbox->get_w(), - y)); - y += textbox->get_h() + 5; - - // -------------------- - add_subwindow(new BC_Title(x, y, _("Interlace mode:"))); - add_subwindow(textbox = new BC_TextBox(x + 100, y, 140, 1, "")); + textbox, &new_edl->session->color_model, x1+textbox->get_w(), y1)); + add_subwindow(textbox = new BC_TextBox(x1, y2, 150, 1, "")); add_subwindow(interlace_pulldown = new InterlacemodePulldown(mwindow, - textbox, - &new_edl->session->interlace_mode, + textbox, &new_edl->session->interlace_mode, (ArrayList*)&mwindow->interlace_project_modes, - x + 100 + textbox->get_w(), - y)); - y += textbox->get_h() + 5; + x1+textbox->get_w(), y2)); add_subwindow(new BC_OKButton(this, mwindow->theme->get_image_set("new_ok_images"))); diff --git a/cinelerra-5.1/cinelerra/render.C b/cinelerra-5.1/cinelerra/render.C index 1f76a92a..d6db3811 100644 --- a/cinelerra-5.1/cinelerra/render.C +++ b/cinelerra-5.1/cinelerra/render.C @@ -336,13 +336,10 @@ BC_Window* Render::new_gui() if(!asset) asset = new Asset; load_defaults(asset); check_asset(mwindow->edl, *asset); - + int px = mwindow->gui->get_pop_cursor_x(1); + int py = mwindow->gui->get_pop_cursor_y(1); // Get format from user - render_window = new RenderWindow(mwindow, - this, - asset, - mwindow->gui->get_abs_cursor_x(1), - mwindow->gui->get_abs_cursor_y(1)); + render_window = new RenderWindow(mwindow, this, asset, px, py); render_window->create_objects(); } @@ -1108,10 +1105,8 @@ RenderWindow::RenderWindow(MWindow *mwindow, Asset *asset, int x, int y) - : BC_Window(_(PROGRAM_NAME ": Render"), - x - WIDTH / 2, y - HEIGHT / 2, - WIDTH, HEIGHT, WIDTH, HEIGHT, - 0, 0, 1) + : BC_Window(_(PROGRAM_NAME ": Render"), x, y, + WIDTH, HEIGHT, WIDTH, HEIGHT, 0, 0, 1) { this->mwindow = mwindow; this->render = render; diff --git a/cinelerra-5.1/configure.ac b/cinelerra-5.1/configure.ac index 40ac01b3..8f8b3c68 100644 --- a/cinelerra-5.1/configure.ac +++ b/cinelerra-5.1/configure.ac @@ -764,7 +764,7 @@ if test $WANT_X264_HIDEPTH = "yes" ; then echo "x264.cfg_params := --enable-static --bit-depth=10" fi if test $WANT_X265_HIDEPTH = "yes" ; then - echo "x265.cfg_params := -DENABLE_SHARED=no -DHIGH_BIT_DEPTH:BOOL=ON" + echo "x265.cfg_params := -DENABLE_SHARED=no -DHIGH_BIT_DEPTH:BOOL=ON -DMAIN12:BOOL=ON" fi for pkg in $STATIC_PKGS; do echo "static_pkgs += $pkg"; done diff --git a/cinelerra-5.1/ffmpeg/audio/bluray.m2ts b/cinelerra-5.1/ffmpeg/audio/bluray.m2ts index 45fd78be..6408df92 100644 --- a/cinelerra-5.1/ffmpeg/audio/bluray.m2ts +++ b/cinelerra-5.1/ffmpeg/audio/bluray.m2ts @@ -1,4 +1,4 @@ -mpegts ac3 +bluray ac3 id 0x1100 maxrate 9000000 minrate 0 diff --git a/cinelerra-5.1/ffmpeg/format/bluray b/cinelerra-5.1/ffmpeg/format/bluray new file mode 100644 index 00000000..292b00cf --- /dev/null +++ b/cinelerra-5.1/ffmpeg/format/bluray @@ -0,0 +1,7 @@ +mpegts +mpegts_m2ts_mode=2 +mpegts_pmt_start_pid=256 +sdt_period=-1 +packetsize 2048 +muxrate 10080000 +preload 500000 diff --git a/cinelerra-5.1/ffmpeg/plugin.opts b/cinelerra-5.1/ffmpeg/plugin.opts index 8e3012b9..f24dccd8 100644 --- a/cinelerra-5.1/ffmpeg/plugin.opts +++ b/cinelerra-5.1/ffmpeg/plugin.opts @@ -156,6 +156,7 @@ swapuv #tblend #telecine #testsrc +#testsrc2 #thumbnail #tile #tinterlace diff --git a/cinelerra-5.1/ffmpeg/video/avc422.m2ts b/cinelerra-5.1/ffmpeg/video/avc422.m2ts index a388e6f3..4271cd62 100644 --- a/cinelerra-5.1/ffmpeg/video/avc422.m2ts +++ b/cinelerra-5.1/ffmpeg/video/avc422.m2ts @@ -1,8 +1,15 @@ -mpegts libx264 +bluray libx264 +bluray-compat=1 id=0x1011 +level=41 +bf=2 +refs=3 +color_range=mpeg +colorspace=bt709 +color_trc=bt709 +color_primaries=bt709 profile=high422 -pixel_format=yuv422p -level=3.0 preset=medium -bluray-compat=1 +pixel_format=yuv422p +flags=+cgop x264opts keyint=25:min-keyint=4:qpmin=3:qpmax=33:qp_step=4:merange=8 diff --git a/cinelerra-5.1/ffmpeg/video/bluray.m2ts b/cinelerra-5.1/ffmpeg/video/bluray.m2ts index d484e8ec..51112c9c 100644 --- a/cinelerra-5.1/ffmpeg/video/bluray.m2ts +++ b/cinelerra-5.1/ffmpeg/video/bluray.m2ts @@ -1,8 +1,15 @@ -mpegts libx264 +bluray libx264 +bluray-compat=1 id=0x1011 +level=41 +bf=2 +refs=3 +color_range=mpeg +colorspace=bt709 +color_trc=bt709 +color_primaries=bt709 profile=high -level=3.0 preset=medium -bluray-compat=1 +flags=+cgop # must be last for bdcreate.C x264opts keyint=25:min-keyint=4:qpmin=3:qpmax=33:qp_step=4:merange=8 diff --git a/cinelerra-5.1/ffmpeg/video/bluray_lo.m2ts b/cinelerra-5.1/ffmpeg/video/bluray_lo.m2ts index 90de1b93..68c42545 100644 --- a/cinelerra-5.1/ffmpeg/video/bluray_lo.m2ts +++ b/cinelerra-5.1/ffmpeg/video/bluray_lo.m2ts @@ -1,7 +1,14 @@ -mpegts libx264 +bluray libx264 +bluray-compat=1 id=0x1011 +level=41 +bf=2 +refs=3 +color_range=mpeg +colorspace=bt709 +color_trc=bt709 +color_primaries=bt709 profile=baseline -level=3.0 preset=medium -bluray-compat=1 +flags=+cgop x264opts keyint=25:min-keyint=4:qpmin=3:qpmax=33:qp_step=4:merange=8 diff --git a/cinelerra-5.1/ffmpeg/video/h265-12bit.mp4 b/cinelerra-5.1/ffmpeg/video/h265-12bit.mp4 new file mode 100644 index 00000000..3d42dbb8 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/h265-12bit.mp4 @@ -0,0 +1,9 @@ +mp4 libx265 +# only works in build cinx hi-depth build +strict=-2 +colorspace=bt2020_cl +color_primaries=bt2020 +color_trc=bt2020_12bit +pixel_format=yuv422p12 +x265-params=output-depth=12 + diff --git a/cinelerra-5.1/ffmpeg/video/h265.mp4 b/cinelerra-5.1/ffmpeg/video/h265-hi.mp4 similarity index 66% rename from cinelerra-5.1/ffmpeg/video/h265.mp4 rename to cinelerra-5.1/ffmpeg/video/h265-hi.mp4 index d045e233..8e2a09d6 100644 --- a/cinelerra-5.1/ffmpeg/video/h265.mp4 +++ b/cinelerra-5.1/ffmpeg/video/h265-hi.mp4 @@ -1 +1,2 @@ mp4 libx265 +crf=5 diff --git a/cinelerra-5.1/ffmpeg/video/h265-lo.mp4 b/cinelerra-5.1/ffmpeg/video/h265-lo.mp4 new file mode 100644 index 00000000..1bbf933d --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/h265-lo.mp4 @@ -0,0 +1,3 @@ +mp4 libx265 +# lossy but faster +crf=25 diff --git a/cinelerra-5.1/ffmpeg/video/h265-med.mp4 b/cinelerra-5.1/ffmpeg/video/h265-med.mp4 new file mode 100644 index 00000000..b8b93753 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/h265-med.mp4 @@ -0,0 +1,3 @@ +mp4 libx265 +# visually lossless +crf=18 diff --git a/cinelerra-5.1/ffmpeg/video/hevc422p10.m2ts b/cinelerra-5.1/ffmpeg/video/hevc422p10.m2ts index effb81a5..f15e594a 100644 --- a/cinelerra-5.1/ffmpeg/video/hevc422p10.m2ts +++ b/cinelerra-5.1/ffmpeg/video/hevc422p10.m2ts @@ -1,9 +1,8 @@ -mpegts libx265 -loglevel=debug +bluray libx265 id=0x1011 #preset=ultrafast,superfast,veryfast,faster,fast, #preset=medium,slow,slower,veryslow,placebo preset=medium #tune=psnr,ssim,grain,zerolatency,fastdecode pixel_format=yuv422p10 -x265_opts=output-depth=10 +x265_opts=profile=main10:output-depth=10 diff --git a/cinelerra-5.1/ffmpeg/video/hevc422p8.m2ts b/cinelerra-5.1/ffmpeg/video/hevc422p8.m2ts index 0496a829..90f7c11b 100644 --- a/cinelerra-5.1/ffmpeg/video/hevc422p8.m2ts +++ b/cinelerra-5.1/ffmpeg/video/hevc422p8.m2ts @@ -1,9 +1,8 @@ mpegts libx265 -loglevel=debug id=0x1011 #preset=ultrafast,superfast,veryfast,faster,fast, #preset=medium,slow,slower,veryslow,placebo preset=medium #tune=psnr,ssim,grain,zerolatency,fastdecode pixel_format=yuv422p -x265_opts=output-depth=8 +x265_opts=profile=main:output-depth=8 diff --git a/cinelerra-5.1/ffmpeg/video/lossless.m2ts b/cinelerra-5.1/ffmpeg/video/lossless.m2ts index 8ba87569..316ad72b 100644 --- a/cinelerra-5.1/ffmpeg/video/lossless.m2ts +++ b/cinelerra-5.1/ffmpeg/video/lossless.m2ts @@ -1,2 +1,4 @@ mpegts libx264 +cin_bitrate=0 +cin_quality=0 qp=0 diff --git a/cinelerra-5.1/ffmpeg/video/visually_lossless.m2ts b/cinelerra-5.1/ffmpeg/video/visually_lossless.m2ts new file mode 100644 index 00000000..db41439c --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/visually_lossless.m2ts @@ -0,0 +1,19 @@ +bluray libx264 +bluray-compat=1 +id=0x1011 +crf=18 +maxrate=20000000 +bufsize=20000000 +cin_bitrate=20000000 +cin_quality=0 +preset=medium +level=41 +bf=2 +refs=3 +color_range=mpeg +colorspace=bt709 +color_trc=bt709 +color_primaries=bt709 +flags=+cgop +# must be last for bdcreate.C +x264opts keyint=25:min-keyint=4:qpmin=3:qpmax=33:qp_step=4:merange=8 diff --git a/cinelerra-5.1/guicast/bcfilebox.C b/cinelerra-5.1/guicast/bcfilebox.C index 7baaedb3..7d52d98c 100644 --- a/cinelerra-5.1/guicast/bcfilebox.C +++ b/cinelerra-5.1/guicast/bcfilebox.C @@ -215,7 +215,7 @@ int BC_FileBoxDirectoryText::handle_event() while( *cp ) ++cp; if( cp > path && *--cp != '/' ) return 0; char *file_path = FileSystem::basepath(path); - char *dir_path = FileSystem::basepath(filebox->fs->get_current_dir()); + char *dir_path = FileSystem::basepath(filebox->directory); int ret = !strcmp(file_path, dir_path) ? 0 : 1; if( ret ) { strcpy(filebox->directory, file_path); @@ -497,7 +497,7 @@ BC_FileBox::BC_FileBox(int x, int y, const char *init_path, this->want_directory = want_directory; if(show_all_files) fs->set_show_all(); fs->complete_path(this->current_path); - fs->complete_path(this->submitted_path); + strcpy(this->submitted_path, this->current_path); fs->extract_dir(directory, this->current_path); fs->extract_name(filename, this->current_path); @@ -535,16 +535,12 @@ BC_FileBox::BC_FileBox(int x, int y, const char *init_path, // Test if current directory exists if(!fs->is_dir(directory)) { - sprintf(this->current_path, "~"); - fs->complete_path(this->current_path); - fs->set_current_dir(this->current_path); -// fs->update(this->current_path); - strcpy(directory, fs->get_current_dir()); + sprintf(directory, "~"); + fs->complete_path(directory); + strcpy(current_path,directory); filename[0] = 0; } - else - fs->set_current_dir(this->directory); - + fs->set_current_dir(directory); if(h_padding == -1) { @@ -592,10 +588,6 @@ void BC_FileBox::create_objects() fs->set_filter(get_resources()->filebox_filter); } - fs->set_sort_order(sort_order); - fs->set_sort_field(column_type[sort_column]); - fs->update(directory); - create_icons(); create_tables(); @@ -653,8 +645,12 @@ void BC_FileBox::create_objects() if( newest >= 0 ) { strcpy(directory, resources->filebox_history[newest].path); fs->change_dir(directory, 0); + strcpy(directory, fs->get_current_dir()); directory_title->update(fs->get_current_dir()); } + fs->set_sort_order(sort_order); + fs->set_sort_field(column_type[sort_column]); + fs->update(directory); // Create recent dir list create_history(); @@ -678,7 +674,7 @@ void BC_FileBox::create_objects() rename_thread = new BC_RenameThread(this); - + refresh(); show_window(); } diff --git a/cinelerra-5.1/guicast/bctextbox.C b/cinelerra-5.1/guicast/bctextbox.C index c76f67ef..5a9cac03 100644 --- a/cinelerra-5.1/guicast/bctextbox.C +++ b/cinelerra-5.1/guicast/bctextbox.C @@ -766,6 +766,8 @@ void BC_TextBox::draw(int flush) draw_wtext(text_x, k + text_ascent, wtext_row, len, 0, &positions[wtext_row - wtext]); } + else + positions[wtext_row - wtext] = 0; // Get ibeam location if(ibeam_letter >= row_begin && ibeam_letter <= row_end) { @@ -778,14 +780,8 @@ void BC_TextBox::draw(int flush) //printf("BC_TextBox::draw 3 %d\n", ibeam_y); if(need_ibeam) { - if( wtext_len == 0 ) { - ibeam_x = 0; - ibeam_y = 0; - } - else { - ibeam_x = -1; - ibeam_y = -1; - } +// ibeam_x = ibeam_y = !wtext_len ? 0 : -1; + ibeam_x = 0; ibeam_y = k - text_y; } //printf("BC_TextBox::draw 4 %d\n", ibeam_y); @@ -1853,9 +1849,8 @@ void BC_TextBox::get_ibeam_position(int &x, int &y) { int i, row_begin, row_end; int wtext_len = wtext_update(); + x = y = 0; - y = 0; - x = 0; for( i=0; iadd_subwindow(yscroll = new BC_ScrollTextBoxYScroll(this)); text->yscroll = yscroll; yscroll->bound_to = text; - + set_text_row(0); } int BC_ScrollTextBox::handle_event() diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index 75e37fb4..7d4fa2b5 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -2886,27 +2886,21 @@ int BC_WindowBase::get_text_width(int font, const char *text, int length) int BC_WindowBase::get_text_width(int font, const wchar_t *text, int length) { - int i, j, w = 0, line_w = 0; - - if(length < 0) length = wcslen(text); - - for(i = 0, j = 0; i <= length; i++) - { - line_w = 0; - if(text[i] == '\n') - { - line_w = get_single_text_width(font, &text[j], i - j); - j = i + 1; + int i, j, w = 0; + if( length < 0 ) length = wcslen(text); + + for( i=j=0; i j ) { + int lw = get_single_text_width(font, &text[j], i-j); + if( w < lw ) w = lw; } - else - if(text[i] == 0) - line_w = get_single_text_width(font, &text[j], length - j); - - if(line_w > w) w = line_w; + j = i + 1; + } + if( j < length ) { + int lw = get_single_text_width(font, &text[j], length-j); + if( w < lw ) w = lw; } - - if(i > length && w == 0) - w = get_single_text_width(font, text, length); return w; } @@ -3696,6 +3690,26 @@ int BC_WindowBase::get_abs_cursor_y(int lock_window) return abs_y; } +int BC_WindowBase::get_pop_cursor_x(int lock_window) +{ + int margin = 100; + int px = get_abs_cursor_x(lock_window); + if( px < margin ) px = margin; + int wd = get_screen_w(lock_window,-1) - margin; + if( px > wd ) px = wd; + return px; +} + +int BC_WindowBase::get_pop_cursor_y(int lock_window) +{ + int margin = 100; + int py = get_abs_cursor_y(lock_window); + if( py < margin ) py = margin; + int ht = get_screen_h(lock_window,-1) - margin; + if( py > ht ) py = ht; + return py; +} + int BC_WindowBase::match_window(Window win) { if (this->win == win) return 1; diff --git a/cinelerra-5.1/guicast/bcwindowbase.h b/cinelerra-5.1/guicast/bcwindowbase.h index 2acfe5c3..4136b110 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.h +++ b/cinelerra-5.1/guicast/bcwindowbase.h @@ -281,6 +281,8 @@ public: // Get current position int get_abs_cursor_x(int lock_window); int get_abs_cursor_y(int lock_window); + int get_pop_cursor_x(int lock_window); + int get_pop_cursor_y(int lock_window); int get_relative_cursor_x(); int get_relative_cursor_y(); void get_root_coordinates(int x, int y, int *abs_x, int *abs_y); diff --git a/cinelerra-5.1/plugins/theme_blond/data/new_bg.png b/cinelerra-5.1/plugins/theme_blond/data/new_bg.png index 43b75778..7a47887e 100644 Binary files a/cinelerra-5.1/plugins/theme_blond/data/new_bg.png and b/cinelerra-5.1/plugins/theme_blond/data/new_bg.png differ diff --git a/cinelerra-5.1/plugins/theme_blond_cv/data/new_bg.png b/cinelerra-5.1/plugins/theme_blond_cv/data/new_bg.png index 33d12ecc..b3bbd1e1 100644 Binary files a/cinelerra-5.1/plugins/theme_blond_cv/data/new_bg.png and b/cinelerra-5.1/plugins/theme_blond_cv/data/new_bg.png differ diff --git a/cinelerra-5.1/plugins/theme_blue/data/new_bg.png b/cinelerra-5.1/plugins/theme_blue/data/new_bg.png index a5269f57..0d24e024 100644 Binary files a/cinelerra-5.1/plugins/theme_blue/data/new_bg.png and b/cinelerra-5.1/plugins/theme_blue/data/new_bg.png differ diff --git a/cinelerra-5.1/plugins/theme_blue_dot/data/new_bg.png b/cinelerra-5.1/plugins/theme_blue_dot/data/new_bg.png index f3668648..aac3a476 100644 Binary files a/cinelerra-5.1/plugins/theme_blue_dot/data/new_bg.png and b/cinelerra-5.1/plugins/theme_blue_dot/data/new_bg.png differ diff --git a/cinelerra-5.1/plugins/theme_bright/data/new_bg.png b/cinelerra-5.1/plugins/theme_bright/data/new_bg.png index d678a701..a4b9cb70 100644 Binary files a/cinelerra-5.1/plugins/theme_bright/data/new_bg.png and b/cinelerra-5.1/plugins/theme_bright/data/new_bg.png differ diff --git a/cinelerra-5.1/plugins/theme_hulk/data/new_bg.png b/cinelerra-5.1/plugins/theme_hulk/data/new_bg.png index 10d1dad1..d5485436 100644 Binary files a/cinelerra-5.1/plugins/theme_hulk/data/new_bg.png and b/cinelerra-5.1/plugins/theme_hulk/data/new_bg.png differ diff --git a/cinelerra-5.1/plugins/theme_pinklady/data/new_bg.png b/cinelerra-5.1/plugins/theme_pinklady/data/new_bg.png index cb78e378..74291ebe 100644 Binary files a/cinelerra-5.1/plugins/theme_pinklady/data/new_bg.png and b/cinelerra-5.1/plugins/theme_pinklady/data/new_bg.png differ diff --git a/cinelerra-5.1/plugins/theme_suv/data/new_bg.png b/cinelerra-5.1/plugins/theme_suv/data/new_bg.png index f9f6730c..07a59148 100644 Binary files a/cinelerra-5.1/plugins/theme_suv/data/new_bg.png and b/cinelerra-5.1/plugins/theme_suv/data/new_bg.png differ diff --git a/cinelerra-5.1/plugins/theme_unflat/data/new_bg.png b/cinelerra-5.1/plugins/theme_unflat/data/new_bg.png index c1482cb4..e27a20f4 100644 Binary files a/cinelerra-5.1/plugins/theme_unflat/data/new_bg.png and b/cinelerra-5.1/plugins/theme_unflat/data/new_bg.png differ diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.patch4 b/cinelerra-5.1/thirdparty/src/ffmpeg.patch4 new file mode 100644 index 00000000..cd7c4252 --- /dev/null +++ b/cinelerra-5.1/thirdparty/src/ffmpeg.patch4 @@ -0,0 +1,261 @@ +--- a/libavformat/mpegtsenc.c 2016-09-30 19:12:42.000000000 -0600 ++++ b/libavformat/mpegtsenc.c 2017-01-25 17:25:58.720017593 -0700 +@@ -55,7 +55,7 @@ + int sid; /* service ID */ + char *name; + char *provider_name; +- int pcr_pid; ++ int pcr_sid, pcr_pid; + int pcr_packet_count; + int pcr_packet_period; + AVProgram *program; +@@ -94,8 +94,10 @@ + int service_type; + + int pmt_start_pid; ++ int pcr_start_pid; + int start_pid; + int m2ts_mode; ++ int64_t pcr_offset; + + int reemit_pat_pmt; // backward compatibility + +@@ -704,6 +706,7 @@ + service->pmt.pid = ts->pmt_start_pid + ts->nb_services; + service->sid = sid; + service->pcr_pid = 0x1fff; ++ service->pcr_sid = 0x1fff; + service->provider_name = av_strdup(provider_name); + service->name = av_strdup(name); + if (!service->provider_name || !service->name) +@@ -722,7 +725,7 @@ + static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb) + { + return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + +- ts->first_pcr; ++ ts->first_pcr + ts->pcr_offset; + } + + static void mpegts_prefix_m2ts_header(AVFormatContext *s) +@@ -760,6 +763,14 @@ + if (s->max_delay < 0) /* Not set by the caller */ + s->max_delay = 0; + ++ if (ts->m2ts_mode == -1) { ++ if (av_match_ext(s->filename, "m2ts")) { ++ ts->m2ts_mode = 1; ++ } else { ++ ts->m2ts_mode = 0; ++ } ++ } ++ + // round up to a whole number of TS packets + ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14; + +@@ -803,6 +814,8 @@ + service->program = program; + } + } ++ if (ts->m2ts_mode > 1) ++ service->pmt.pid = 0x00ff + ts->service_id; + + ts->pat.pid = PAT_PID; + /* Initialize at 15 so that it wraps and is equal to 0 for the +@@ -885,10 +898,9 @@ + ts_st->cc = 15; + /* update PCR pid by using the first video stream */ + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && +- service->pcr_pid == 0x1fff) { +- service->pcr_pid = ts_st->pid; ++ service->pcr_sid == 0x1fff) + pcr_st = st; +- } ++ + if (st->codecpar->codec_id == AV_CODEC_ID_AAC && + st->codecpar->extradata_size > 0) { + AVStream *ast; +@@ -924,12 +936,24 @@ + av_freep(&pids); + + /* if no video stream, use the first stream as PCR */ +- if (service->pcr_pid == 0x1fff && s->nb_streams > 0) { +- pcr_st = s->streams[0]; +- ts_st = pcr_st->priv_data; +- service->pcr_pid = ts_st->pid; +- } else +- ts_st = pcr_st->priv_data; ++ if (!pcr_st && s->nb_streams > 0) ++ pcr_st = s->streams[0]; ++ if (!pcr_st) { ++ av_log(s, AV_LOG_ERROR, "no streams\n"); ++ ret = AVERROR(EINVAL); ++ goto fail; ++ } ++ ts_st = pcr_st->priv_data; ++ if (service->pcr_sid == 0x1fff) ++ service->pcr_sid = ts_st->pid; ++ if (service->pcr_pid == 0x1fff) ++ service->pcr_pid = ts->m2ts_mode > 1 ? ++ 0x1000 + ts->service_id : service->pcr_sid ; ++ if (service->pmt.pid == service->pcr_pid) { ++ av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", service->pcr_pid); ++ ret = AVERROR(EINVAL); ++ goto fail; ++ } + + if (ts->mux_rate > 1) { + service->pcr_packet_period = (int64_t)ts->mux_rate * ts->pcr_period / +@@ -989,14 +1013,6 @@ + service->pcr_packet_period, + ts->sdt_packet_period, ts->pat_packet_period); + +- if (ts->m2ts_mode == -1) { +- if (av_match_ext(s->filename, "m2ts")) { +- ts->m2ts_mode = 1; +- } else { +- ts->m2ts_mode = 0; +- } +- } +- + return 0; + + fail: +@@ -1010,9 +1026,9 @@ + MpegTSWrite *ts = s->priv_data; + int i; + +- if (++ts->sdt_packet_count == ts->sdt_packet_period || ++ if ( ts->sdt_period >= 0 && (++ts->sdt_packet_count == ts->sdt_packet_period || + (dts != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) || +- (dts != AV_NOPTS_VALUE && dts - ts->last_sdt_ts >= ts->sdt_period*90000.0) ++ (dts != AV_NOPTS_VALUE && dts - ts->last_sdt_ts >= ts->sdt_period*90000.0)) + ) { + ts->sdt_packet_count = 0; + if (dts != AV_NOPTS_VALUE) +@@ -1067,13 +1083,14 @@ + { + MpegTSWrite *ts = s->priv_data; + MpegTSWriteStream *ts_st = st->priv_data; ++ uint32_t pcr_pid = ts_st->service->pcr_pid; + uint8_t *q; + uint8_t buf[TS_PACKET_SIZE]; + + q = buf; + *q++ = 0x47; +- *q++ = ts_st->pid >> 8; +- *q++ = ts_st->pid; ++ *q++ = pcr_pid >> 8; ++ *q++ = pcr_pid; + *q++ = 0x20 | ts_st->cc; /* Adaptation only */ + /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */ + *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */ +@@ -1148,7 +1165,7 @@ + uint8_t buf[TS_PACKET_SIZE]; + uint8_t *q; + int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags; +- int afc_len, stuffing_len; ++ int afc_len, stuffing_len, write_null; + int64_t pcr = -1; /* avoid warning */ + int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); + int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key; +@@ -1163,8 +1180,8 @@ + retransmit_si_info(s, force_pat, dts); + force_pat = 0; + +- write_pcr = 0; +- if (ts_st->pid == ts_st->service->pcr_pid) { ++ write_pcr = write_null = 0; ++ if (ts_st->pid == ts_st->service->pcr_sid) { + if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames + ts_st->service->pcr_packet_count++; + if (ts_st->service->pcr_packet_count >= +@@ -1173,15 +1190,17 @@ + write_pcr = 1; + } + } +- + if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE && +- (dts - get_pcr(ts, s->pb) / 300) > delay) { +- /* pcr insert gets priority over null packet insert */ +- if (write_pcr) +- mpegts_insert_pcr_only(s, st); +- else +- mpegts_insert_null_packet(s); +- /* recalculate write_pcr and possibly retransmit si_info */ ++ (dts - get_pcr(ts, s->pb) / 300) > delay) { ++ write_null = 1; ++ } ++ /* pcr insert gets priority over null packet insert */ ++ if (write_pcr && ts_st->service->pcr_sid != ts_st->service->pcr_pid) { ++ mpegts_insert_pcr_only(s, st); ++ continue; ++ } ++ if (write_null) { ++ mpegts_insert_null_packet(s); + continue; + } + +@@ -1191,13 +1210,17 @@ + val = ts_st->pid >> 8; + if (is_start) + val |= 0x40; ++ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && ++ st->codecpar->codec_id == AV_CODEC_ID_AC3 && ++ ts->m2ts_mode > 1) ++ val |= 0x20; + *q++ = val; + *q++ = ts_st->pid; + ts_st->cc = ts_st->cc + 1 & 0xf; + *q++ = 0x10 | ts_st->cc; // payload indicator + CC + if (key && is_start && pts != AV_NOPTS_VALUE) { + // set Random Access for key frames +- if (ts_st->pid == ts_st->service->pcr_pid) ++ if (ts_st->pid == ts_st->service->pcr_sid) + write_pcr = 1; + set_af_flag(buf, 0x40); + q = get_ts_payload_start(buf); +@@ -1310,11 +1333,13 @@ + *q++ = flags; + *q++ = header_len; + if (pts != AV_NOPTS_VALUE) { +- write_pts(q, flags >> 6, pts); ++ int64_t ts_pts = pts + ts->pcr_offset; ++ write_pts(q, flags >> 6, ts_pts); + q += 5; + } + if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) { +- write_pts(q, 1, dts); ++ int64_t ts_dts = dts + ts->pcr_offset; ++ write_pts(q, 1, ts_dts); + q += 5; + } + if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) { +@@ -1838,12 +1863,18 @@ + { "mpegts_pmt_start_pid", "Set the first pid of the PMT.", + offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT, + { .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM }, ++ { "mpegts_pcr_start_pid", "Set the first pid of the PCR.", ++ offsetof(MpegTSWrite, pcr_start_pid), AV_OPT_TYPE_INT, ++ { .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM }, + { "mpegts_start_pid", "Set the first pid.", + offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT, + { .i64 = 0x0100 }, 0x0020, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM }, + { "mpegts_m2ts_mode", "Enable m2ts mode.", + offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL, +- { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM }, ++ { .i64 = -1 }, -1, 2, AV_OPT_FLAG_ENCODING_PARAM }, ++ { "mpegts_pcr_offset", "clock offset.", ++ offsetof(MpegTSWrite, pcr_offset), AV_OPT_TYPE_BOOL, ++ { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, + { "muxrate", NULL, + offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, + { .i64 = 1 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, +@@ -1886,7 +1917,7 @@ + { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, + { "sdt_period", "SDT retransmission time limit in seconds", + offsetof(MpegTSWrite, sdt_period), AV_OPT_TYPE_DOUBLE, +- { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, ++ { .dbl = INT_MAX }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, + { NULL }, + }; +