From d6c6d4a07f9ff4c6b8f5d034306df375815b060a Mon Sep 17 00:00:00 2001 From: Good Guy Date: Tue, 15 Sep 2020 20:40:29 -0600 Subject: [PATCH] fix undo segv with plugin guis open, add cache demand limits, exit when malloc fails, 12 ffmpeg format changes/additions --- cinelerra-5.1/cinelerra/ffmpeg.C | 9 +- cinelerra-5.1/cinelerra/framecache.C | 7 +- cinelerra-5.1/cinelerra/mainundo.C | 1 + cinelerra-5.1/cinelerra/vmodule.C | 2 +- cinelerra-5.1/ffmpeg/audio/mpeg1_mp2.mpeg | 1 + cinelerra-5.1/ffmpeg/video/AVC_Intra_100.mp4 | 8 + cinelerra-5.1/ffmpeg/video/div3.qt | 9 + cinelerra-5.1/ffmpeg/video/div3v2.qt | 9 + cinelerra-5.1/ffmpeg/video/div5.qt | 9 + cinelerra-5.1/ffmpeg/video/flv_h264.flv | 1 + .../ffmpeg/video/huffyuv_screencapture.mov | 1 + cinelerra-5.1/ffmpeg/video/mjpeg_444.qt | 4 +- cinelerra-5.1/ffmpeg/video/mpeg1.mpeg | 6 + cinelerra-5.1/ffmpeg/video/mpeg2.mpeg | 6 + cinelerra-5.1/ffmpeg/video/msmpeg4.avi | 10 + cinelerra-5.1/ffmpeg/video/xvid.avi | 7 + cinelerra-5.1/guicast/vframe.C | 183 ++++++++++-------- 17 files changed, 181 insertions(+), 92 deletions(-) create mode 100644 cinelerra-5.1/ffmpeg/audio/mpeg1_mp2.mpeg create mode 100644 cinelerra-5.1/ffmpeg/video/AVC_Intra_100.mp4 create mode 100644 cinelerra-5.1/ffmpeg/video/flv_h264.flv create mode 100644 cinelerra-5.1/ffmpeg/video/mpeg1.mpeg create mode 100644 cinelerra-5.1/ffmpeg/video/mpeg2.mpeg diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index 7dca62a6..97b6698a 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -1222,6 +1222,7 @@ int FFVideoStream::load(VFrame *vframe, int64_t pos) return -1; } int i = MAX_RETRY + pos - curr_pos; + int64_t cache_start = 0; while( ret>=0 && !flushed && curr_pos<=pos && --i>=0 ) { ret = read_frame(frame); if( ret > 0 ) { @@ -1230,15 +1231,19 @@ int FFVideoStream::load(VFrame *vframe, int64_t pos) if( use_cache < 0 ) { // for reverse read, reload file frame_cache from keyframe to pos ffmpeg->purge_cache(); + int count = preferences->cache_size / + vframe->get_data_size() / 2; // try to burn only 1/2 of cache + cache_start = pos - count + 1; seeking = 1; } else seeking = 0; } - if( seeking > 0 && curr_pos < pos ) { + if( seeking > 0 && curr_pos >= cache_start && curr_pos < pos ) { int vw =vframe->get_w(), vh = vframe->get_h(); int vcolor_model = vframe->get_color_model(); - VFrame *cache_frame = new VFrame(vw, vh, vcolor_model); +// do not use shm here, puts too much pressure on 32bit systems + VFrame *cache_frame = new VFrame(vw, vh, vcolor_model, 0); ret = convert_cmodel(cache_frame, frame); if( ret > 0 ) ffmpeg->put_cache_frame(cache_frame, curr_pos); diff --git a/cinelerra-5.1/cinelerra/framecache.C b/cinelerra-5.1/cinelerra/framecache.C index 4f1a8eb0..b8eed886 100644 --- a/cinelerra-5.1/cinelerra/framecache.C +++ b/cinelerra-5.1/cinelerra/framecache.C @@ -181,7 +181,12 @@ void FrameCache::put_cache_frame(VFrame *frame, int64_t position, int color_model = frame->get_color_model(); int ret = frame_exists(position, layer, frame_rate, w, h, color_model, &item, -1); - if( use_copy ) frame = new VFrame(*frame); + if( use_copy ) { +// do not use shm here, puts too much pressure on 32bit systems + VFrame *vframe = new VFrame(w, h, color_model, 0); + vframe->copy_from(frame); + frame = vframe; + } if( ret ) { delete item->data; item->data = frame; diff --git a/cinelerra-5.1/cinelerra/mainundo.C b/cinelerra-5.1/cinelerra/mainundo.C index 2e960b3b..c19a6ada 100644 --- a/cinelerra-5.1/cinelerra/mainundo.C +++ b/cinelerra-5.1/cinelerra/mainundo.C @@ -256,6 +256,7 @@ int MainUndo::redo() // Here the master EDL loads int MainUndo::load_from_undo(FileXML *file, uint32_t load_flags) { + mwindow->hide_plugins(); if( load_flags & LOAD_SESSION ) { mwindow->gui->unlock_window(); mwindow->close_mixers(); diff --git a/cinelerra-5.1/cinelerra/vmodule.C b/cinelerra-5.1/cinelerra/vmodule.C index a9bb93df..0829999f 100644 --- a/cinelerra-5.1/cinelerra/vmodule.C +++ b/cinelerra-5.1/cinelerra/vmodule.C @@ -279,7 +279,7 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit, VEdit *vnext = (VEdit *)current_edit->next; pos = Units::to_int64((double)input_position / frame_rate * edl_rate); if( renderengine->preferences->cache_transitions && !use_cache && -// cache transitions not using cache and inside transition +// cache transitions, not caching and inside transition vnext && vnext->transition && file->get_video_length() >= 0 && pos >= vnext->startproject && pos < vnext->startproject + vnext->transition->length ) { diff --git a/cinelerra-5.1/ffmpeg/audio/mpeg1_mp2.mpeg b/cinelerra-5.1/ffmpeg/audio/mpeg1_mp2.mpeg new file mode 100644 index 00000000..2297eb21 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/mpeg1_mp2.mpeg @@ -0,0 +1 @@ +mpeg libtwolame diff --git a/cinelerra-5.1/ffmpeg/video/AVC_Intra_100.mp4 b/cinelerra-5.1/ffmpeg/video/AVC_Intra_100.mp4 new file mode 100644 index 00000000..56f8bbef --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/AVC_Intra_100.mp4 @@ -0,0 +1,8 @@ +mp4 libx264 +cin_pix_fmt=yuv422p10le +flags -global_header +keyint_min=0 +x264-params=keyint=0:colorprim=bt709:transfer=bt709:colormatrix=bt709 +avcintra-class=100 +bufsize=100000000 +level=4.1 diff --git a/cinelerra-5.1/ffmpeg/video/div3.qt b/cinelerra-5.1/ffmpeg/video/div3.qt index 25a97fc4..0cd87f42 100644 --- a/cinelerra-5.1/ffmpeg/video/div3.qt +++ b/cinelerra-5.1/ffmpeg/video/div3.qt @@ -1 +1,10 @@ mov msmpeg4 +#trellis=1 +#mbd=bits +mbd=rd +flags=+aic +trellis=2 +cmp=2 +subcmp=2 +# bitrate in bits / second! +b=1000000 diff --git a/cinelerra-5.1/ffmpeg/video/div3v2.qt b/cinelerra-5.1/ffmpeg/video/div3v2.qt index 084aedfd..eda0e009 100644 --- a/cinelerra-5.1/ffmpeg/video/div3v2.qt +++ b/cinelerra-5.1/ffmpeg/video/div3v2.qt @@ -1 +1,10 @@ mov msmpeg4v2 +#trellis=1 +#mbd=bits +mbd=rd +flags=+aic +trellis=2 +cmp=2 +subcmp=2 +# bitrate in bits / second! +b=1000000 diff --git a/cinelerra-5.1/ffmpeg/video/div5.qt b/cinelerra-5.1/ffmpeg/video/div5.qt index c58795f7..2f1fe9f5 100644 --- a/cinelerra-5.1/ffmpeg/video/div5.qt +++ b/cinelerra-5.1/ffmpeg/video/div5.qt @@ -1 +1,10 @@ mov mpeg4 +#trellis=1 +#mbd=bits +mbd=rd +flags=+mv4+aic +trellis=2 +cmp=2 +subcmp=2 +# bitrate in bits / second! +b=1000000 diff --git a/cinelerra-5.1/ffmpeg/video/flv_h264.flv b/cinelerra-5.1/ffmpeg/video/flv_h264.flv new file mode 100644 index 00000000..4f185dd6 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/flv_h264.flv @@ -0,0 +1 @@ +flv libx264 diff --git a/cinelerra-5.1/ffmpeg/video/huffyuv_screencapture.mov b/cinelerra-5.1/ffmpeg/video/huffyuv_screencapture.mov index ec4951c7..4420bffc 100644 --- a/cinelerra-5.1/ffmpeg/video/huffyuv_screencapture.mov +++ b/cinelerra-5.1/ffmpeg/video/huffyuv_screencapture.mov @@ -2,3 +2,4 @@ mov huffyuv #probesize=100M #thread_queue_size=512 pixel_format=bgra +cin_pix_fmt bgra diff --git a/cinelerra-5.1/ffmpeg/video/mjpeg_444.qt b/cinelerra-5.1/ffmpeg/video/mjpeg_444.qt index 031ae314..d7e18863 100644 --- a/cinelerra-5.1/ffmpeg/video/mjpeg_444.qt +++ b/cinelerra-5.1/ffmpeg/video/mjpeg_444.qt @@ -1,4 +1,4 @@ mov mjpeg qmax=4 -pixel_format=yuvj444p -threads=3 \ No newline at end of file +cin_pix_fmt yuvj444p +threads=3 diff --git a/cinelerra-5.1/ffmpeg/video/mpeg1.mpeg b/cinelerra-5.1/ffmpeg/video/mpeg1.mpeg new file mode 100644 index 00000000..7ceaab39 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/mpeg1.mpeg @@ -0,0 +1,6 @@ +mpeg mpeg1video +trellis=2 +mbd=rd +cmp=2 +subcmp=2 +b=2000000 diff --git a/cinelerra-5.1/ffmpeg/video/mpeg2.mpeg b/cinelerra-5.1/ffmpeg/video/mpeg2.mpeg new file mode 100644 index 00000000..248cbf67 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/mpeg2.mpeg @@ -0,0 +1,6 @@ +mpeg mpeg2video +trellis=2 +mbd=rd +cmp=2 +subcmp=2 +b=4000000 diff --git a/cinelerra-5.1/ffmpeg/video/msmpeg4.avi b/cinelerra-5.1/ffmpeg/video/msmpeg4.avi index e58ac47d..ba033a65 100644 --- a/cinelerra-5.1/ffmpeg/video/msmpeg4.avi +++ b/cinelerra-5.1/ffmpeg/video/msmpeg4.avi @@ -1 +1,11 @@ avi msmpeg4 +#trellis=1 +#mbd=bits +mbd=rd +flags=+aic +trellis=2 +cmp=2 +subcmp=2 +# bitrate in bits / second! +b=1000000 + diff --git a/cinelerra-5.1/ffmpeg/video/xvid.avi b/cinelerra-5.1/ffmpeg/video/xvid.avi index be9e8e0f..53ff48fd 100644 --- a/cinelerra-5.1/ffmpeg/video/xvid.avi +++ b/cinelerra-5.1/ffmpeg/video/xvid.avi @@ -1,2 +1,9 @@ avi mpeg4 codec_tag 1145656920 +mbd=rd +flags=+mv4+aic +trellis=2 +cmp=2 +subcmp=2 +# bitrate in bits / second! +b=1000000 diff --git a/cinelerra-5.1/guicast/vframe.C b/cinelerra-5.1/guicast/vframe.C index d85245bd..af0e52a8 100644 --- a/cinelerra-5.1/guicast/vframe.C +++ b/cinelerra-5.1/guicast/vframe.C @@ -500,7 +500,7 @@ int VFrame::allocate_data(unsigned char *data, int shmid, bytes_per_line : this->bytes_per_pixel * w; // Allocate data + padding for MMX - if(data) { + if( data ) { //printf("VFrame::allocate_data %d %p\n", __LINE__, this->data); memory_type = VFrame::SHARED; this->data = data; @@ -509,9 +509,16 @@ int VFrame::allocate_data(unsigned char *data, int shmid, this->u_offset = u_offset; this->v_offset = v_offset; } - else if(shmid >= 0) { + else if( shmid >= 0 ) { memory_type = VFrame::SHMGET; this->data = (unsigned char*)shmat(shmid, NULL, 0); + if( this->data == (unsigned char*)-1 ) { + printf("VFrame::allocate_data %d could not attach" + " shared memory, %dx%d (model %d) shmid=0x%08x\n", + __LINE__, w, h, color_model, shmid); + BC_Trace::dump_shm_stats(stdout); + exit(1); + } //printf("VFrame::allocate_data %d shmid=%d data=%p\n", __LINE__, shmid, this->data); this->shmid = shmid; this->y_offset = y_offset; @@ -528,20 +535,24 @@ int VFrame::allocate_data(unsigned char *data, int shmid, this->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777); if( this->shmid >= 0 ) { this->data = (unsigned char*)shmat(this->shmid, NULL, 0); -//printf("VFrame::allocate_data %d %d %d %p\n", __LINE__, size, this->shmid, this->data); -// This causes it to automatically delete when the program exits. - shmctl(this->shmid, IPC_RMID, 0); + if( this->data == (unsigned char *)-1 ) this->data = 0; } - else { + if( !this->data ) { printf("VFrame::allocate_data %d could not allocate" " shared memory, %dx%d (model %d) size=0x%08x\n", __LINE__, w, h, color_model, size); BC_Trace::dump_shm_stats(stdout); + exit(1); } +// This causes it to automatically delete when the program exits. + shmctl(this->shmid, IPC_RMID, 0); } -// Have to use malloc for libpng - if( !this->data ) { + else { this->data = (unsigned char *)malloc(size); + if( !this->data ) { + printf("VFrame::allocate_data %dx%d: memory exhausted.\n", this->w, this->h); + exit(1); + } this->shmid = -1; } // Memory check @@ -549,8 +560,6 @@ int VFrame::allocate_data(unsigned char *data, int shmid, // printf("VFrame::allocate_data 2 this=%p w=%d h=%d this->data=%p\n", // this, this->w, this->h, this->data); - if(!this->data) - printf("VFrame::allocate_data %dx%d: memory exhausted.\n", this->w, this->h); #ifdef LEAKER printf("==new %p from %p sz %d\n", this->data, __builtin_return_address(0), size); #endif @@ -665,65 +674,76 @@ int VFrame::reallocate( int VFrame::allocate_compressed_data(long bytes) { - if(bytes < 1) return 1; + if( bytes < 1 ) return 1; // Want to preserve original contents - if(data && compressed_allocated < bytes) - { + if( data && compressed_allocated < bytes ) { int new_shmid = -1; unsigned char *new_data = 0; - if(BC_WindowBase::get_resources()->use_vframe_shm() && use_shm) - { - new_shmid = shmget(IPC_PRIVATE, - bytes, - IPC_CREAT | 0777); - new_data = (unsigned char*)shmat(new_shmid, NULL, 0); + if( BC_WindowBase::get_resources()->use_vframe_shm() && use_shm ) { + new_shmid = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0777); + if( new_shmid >= 0 ) { + new_data = (unsigned char *) shmat(new_shmid, NULL, 0); + if( new_data == (unsigned char *)-1 ) new_data = 0; + } + if( !new_data ) { + printf("VFrame::allocate_compressed_data %d could not allocate" + " shared memory, %ld\n", __LINE__, bytes); + BC_Trace::dump_shm_stats(stdout); + exit(1); + } shmctl(new_shmid, IPC_RMID, 0); } - else - { + else { // Have to use malloc for libpng new_data = (unsigned char *)malloc(bytes); + if( !new_data ) { + printf("VFrame::allocate_compressed_data %ld: memory exhausted.\n", bytes); + exit(1); + } } bcopy(data, new_data, compressed_allocated); UNBUFFER(data); - if(memory_type == VFrame::PRIVATE) - { - if(shmid > 0) { - if(data) - shmdt(data); + if( memory_type == VFrame::PRIVATE ) { + if( shmid > 0 ) { + if( data ) shmdt(data); } else free(data); } - else - if(memory_type == VFrame::SHMGET) - { - if(data) - shmdt(data); + else if( memory_type == VFrame::SHMGET ) { + if( data ) shmdt(data); } data = new_data; shmid = new_shmid; compressed_allocated = bytes; } - else - if(!data) - { - if(BC_WindowBase::get_resources()->use_vframe_shm() && use_shm) - { - shmid = shmget(IPC_PRIVATE, - bytes, - IPC_CREAT | 0777); - data = (unsigned char*)shmat(shmid, NULL, 0); + else if( !data ) { + if( BC_WindowBase::get_resources()->use_vframe_shm() && use_shm ) { + shmid = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0777); + if( shmid >= 0 ) { + data = (unsigned char *)shmat(shmid, NULL, 0); + if( data == (unsigned char *)-1 ) data = 0; + } + if( !data ) { + printf("VFrame::allocate_compressed_data %d: could not allocate" + " shared memory, %ld\n", __LINE__, bytes); + BC_Trace::dump_shm_stats(stdout); + exit(1); + } shmctl(shmid, IPC_RMID, 0); } - else - { + else { // Have to use malloc for libpng data = (unsigned char *)malloc(bytes); + if( !data ) { + printf("VFrame::allocate_compressed_data %d: memory exhausted, %ld\n", + __LINE__, bytes); + exit(1); + } } compressed_allocated = bytes; @@ -1114,15 +1134,10 @@ void VFrame::flip_horiz() int VFrame::copy_from(VFrame *frame) { - if(this->w != frame->get_w() || - this->h != frame->get_h()) - { + if( this->w != frame->get_w() || + this->h != frame->get_h() ) { printf("VFrame::copy_from %d sizes differ src %dx%d != dst %dx%d\n", - __LINE__, - frame->get_w(), - frame->get_h(), - get_w(), - get_h()); + __LINE__, frame->get_w(), frame->get_h(), get_w(), get_h()); return 1; } @@ -1130,50 +1145,46 @@ int VFrame::copy_from(VFrame *frame) int h = MIN(this->h, frame->get_h()); timestamp = frame->timestamp; - switch(frame->color_model) - { - case BC_COMPRESSED: - allocate_compressed_data(frame->compressed_size); - memcpy(data, frame->data, frame->compressed_size); - this->compressed_size = frame->compressed_size; - break; + switch( frame->color_model ) { + case BC_COMPRESSED: + allocate_compressed_data(frame->compressed_size); + memcpy(data, frame->data, frame->compressed_size); + this->compressed_size = frame->compressed_size; + break; - case BC_YUV410P: - memcpy(get_y(), frame->get_y(), w * h); - memcpy(get_u(), frame->get_u(), w / 4 * h / 4); - memcpy(get_v(), frame->get_v(), w / 4 * h / 4); - break; + case BC_YUV410P: + memcpy(get_y(), frame->get_y(), w * h); + memcpy(get_u(), frame->get_u(), w / 4 * h / 4); + memcpy(get_v(), frame->get_v(), w / 4 * h / 4); + break; - case BC_YUV420P: - case BC_YUV420PI: - case BC_YUV411P: + 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); - memcpy(get_u(), frame->get_u(), w * h / 4); - memcpy(get_v(), frame->get_v(), w * h / 4); - break; + memcpy(get_y(), frame->get_y(), w * h); + memcpy(get_u(), frame->get_u(), w * h / 4); + memcpy(get_v(), frame->get_v(), w * h / 4); + break; - case BC_YUV422P: + case BC_YUV422P: //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); - memcpy(get_u(), frame->get_u(), w * h / 2); - memcpy(get_v(), frame->get_v(), w * h / 2); - break; + memcpy(get_y(), frame->get_y(), w * h); + memcpy(get_u(), frame->get_u(), w * h / 2); + memcpy(get_v(), frame->get_v(), w * h / 2); + break; - case BC_YUV444P: + case BC_YUV444P: //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); - memcpy(get_u(), frame->get_u(), w * h); - memcpy(get_v(), frame->get_v(), w * h); - break; - default: -// printf("VFrame::copy_from %d\n", calculate_data_size(w, -// h, -// -1, -// frame->color_model)); + memcpy(get_y(), frame->get_y(), w * h); + memcpy(get_u(), frame->get_u(), w * h); + memcpy(get_v(), frame->get_v(), w * h); + break; + default: +// printf("VFrame::copy_from %d\n", calculate_data_size(w, h, -1, frame->color_model)); // Copy without extra 4 bytes in case the source is a hardware device - memmove(data, frame->data, get_data_size()); - break; + memmove(data, frame->data, get_data_size()); + break; } return 0; -- 2.26.2