rework keyframe hide popup, keyframe auto render, textbox set_selection wide text
[goodguy/history.git] / cinelerra-5.1 / cinelerra / fileffmpeg.C
index f2a0c43dc98426a0cb19231171e8dd5262afdaf2..660f750edd143038741c7dda5cfdd01678f1a79b 100644 (file)
@@ -9,7 +9,6 @@
 
 #include "asset.h"
 #include "bcwindowbase.h"
-#include "bcprogressbox.h"
 #include "bitspopup.h"
 #include "ffmpeg.h"
 #include "filebase.h"
@@ -17,6 +16,7 @@
 #include "fileffmpeg.h"
 #include "filesystem.h"
 #include "indexfile.h"
+#include "mainprogress.h"
 #include "mutex.h"
 #include "preferences.h"
 #include "videodevice.inc"
@@ -183,6 +183,8 @@ int FileFFMPEG::select_video_stream(Asset *asset, int vstream)
        asset->width = ff->ff_video_width(vstream);
        asset->height = ff->ff_video_height(vstream);
        asset->video_length = ff->ff_video_frames(vstream);
+       if( (asset->video_length = ff->ff_video_frames(vstream)) < 2 )
+               asset->video_length = asset->video_length < 0 ? 0 : -1;
        asset->frame_rate = ff->ff_frame_rate(vstream);
        return 0;
 }
@@ -220,7 +222,9 @@ int FileFFMPEG::open_file(int rd, int wr)
                                asset->actual_height = ff->ff_video_height(0);
                                if( !asset->width ) asset->width = asset->actual_width;
                                if( !asset->height ) asset->height = asset->actual_height;
-                               if( !asset->video_length ) asset->video_length = ff->ff_video_frames(0);
+                               if( !asset->video_length &&
+                                   (asset->video_length = ff->ff_video_frames(0)) < 2 )
+                                       asset->video_length = asset->video_length < 0 ? 0 : -1;
                                if( !asset->frame_rate ) asset->frame_rate = ff->ff_frame_rate(0);
                        }
                        IndexState *index_state = asset->index_state;
@@ -283,7 +287,7 @@ int FileFFMPEG::read_frame(VFrame *frame)
 {
         if( !ff ) return -1;
        int layer = file->current_layer;
-       int64_t pos = file->current_frame;
+       int64_t pos = asset->video_length >= 0 ? file->current_frame : 0;
        int ret = ff->decode(layer, pos, frame);
        frame->set_status(ret);
        if( ret >= 0 ) return 0;
@@ -592,15 +596,17 @@ int FFMPEGConfigVideoToggle::handle_event()
        return 1;
 }
 
-FFMPEGScanProgress::FFMPEGScanProgress(const char *title, int64_t length, int64_t *position, int *canceled)
+FFMPEGScanProgress::FFMPEGScanProgress(IndexFile *index_file, MainProgressBar *progress_bar,
+               const char *title, int64_t length, int64_t *position, int *canceled)
  : Thread(1, 0, 0)
 {
+       this->index_file = index_file;
+       this->progress_bar = progress_bar;
        strcpy(this->progress_title, title);
        this->length = length;
        this->position = position;
        this->canceled = canceled;
        done = 0;
-       progress = 0;
        start();
 }
 
@@ -613,42 +619,22 @@ FFMPEGScanProgress::~FFMPEGScanProgress()
 
 void FFMPEGScanProgress::run()
 {
-       BC_ProgressBox *progress = new BC_ProgressBox(-1, -1, progress_title, length);
-       progress->start();
-
-       struct timeval start_time, now, then;
-       gettimeofday(&start_time, 0);
-       then = start_time;
-
        while( !done ) {
-               if( progress->update(*position, 1) ) {
+               if( progress_bar->update(*position) ) {
                        *canceled = done = 1;
                        break;
                }
-               gettimeofday(&now, 0);
-               if(now.tv_sec - then.tv_sec >= 1) {
-                       int64_t elapsed = now.tv_sec - start_time.tv_sec;
-                       int64_t byte_rate = *position / elapsed;
-                       int64_t eta = !byte_rate ? 0 : (length - *position) / byte_rate;
-                       char string[BCTEXTLEN];
-                       sprintf(string, "%s\nETA: %jdm%jds",
-                               progress_title, eta / 60, eta % 60);
-                       progress->update_title(string, 1);
-                       then = now;
-               }
+               index_file->redraw_edits(0);
                usleep(500000);
        }
-
-       progress->stop_progress();
-       delete progress;
 }
 
-int FileFFMPEG::get_index(char *index_path)
+int FileFFMPEG::get_index(IndexFile *index_file, MainProgressBar *progress_bar)
 {
        if( !ff ) return -1;
        if( !file->preferences->ffmpeg_marker_indexes ) return 1;
 
-       IndexState *index_state = asset->index_state;
+       IndexState *index_state = index_file->get_state();
        if( index_state->index_status != INDEX_NOTTESTED ) return 0;
        index_state->reset_index();
        index_state->reset_markers();
@@ -659,21 +645,35 @@ int FileFFMPEG::get_index(char *index_path)
                index_state->add_audio_stream(aud->channels, aud->length);
        }
 
-       char progress_title[BCTEXTLEN];
-       sprintf(progress_title, _("Creating %s\n"), index_path);
         FileSystem fs;
        int64_t file_bytes = fs.get_size(ff->fmt_ctx->filename);
-       int64_t scan_position = 0;
+       char *index_path = index_file->index_filename;
+
        int canceled = 0;
-       FFMPEGScanProgress scan_progress(progress_title, file_bytes, &scan_position, &canceled);
+       int64_t scan_position = 0;
+       FFMPEGScanProgress *scan_progress = 0;
+       if( progress_bar ) {
+               char progress_title[BCTEXTLEN];
+               sprintf(progress_title, _("Creating %s\n"), index_path);
+               progress_bar->update_title(progress_title, 1);
+               progress_bar->update_length(file_bytes);
+               scan_progress = new FFMPEGScanProgress(index_file,
+                               progress_bar, progress_title, file_bytes,
+                               &scan_position, &canceled);
+       }
 
        index_state->index_bytes = file_bytes;
        index_state->init_scan(file->preferences->index_size);
+
        if( ff->scan(index_state, &scan_position, &canceled) || canceled ) {
                index_state->reset_index();
                index_state->reset_markers();
-               return 1;
+               canceled = 1;
        }
+
+       delete scan_progress;
+       if( canceled ) return 1;
+
        index_state->marker_status = MARKERS_READY;
        return index_state->create_index(index_path, asset);
 }