audio chan pos rework, batchrender deadlock, titler/crikey grab_event tweak, thread...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / fileffmpeg.C
index d4f89e6c47795c4fef2feab4f7b6efb46ae25d3d..cc8a5371b7c9749e2fb9d69be23ad05beab082f2 100644 (file)
@@ -87,6 +87,22 @@ FFMpegAudioNum::FFMpegAudioNum(BC_Window *window,
 int FFMpegAudioBitrate::handle_event()
 {
        int ret = FFMpegAudioNum::handle_event();
+       Asset *asset = window()->asset;
+       if( asset->ff_audio_bitrate > 0 )
+               window()->quality->disable();
+       else if( !window()->quality->get_textbox()->is_hidden() )
+               window()->quality->enable();
+       return ret;
+}
+
+int FFMpegAudioQuality::handle_event()
+{
+       int ret = FFMpegAudioNum::handle_event();
+       Asset *asset = window()->asset;
+       if( asset->ff_audio_quality >= 0 )
+               window()->bitrate->disable();
+       else if( !window()->bitrate->get_textbox()->is_hidden() )
+               window()->bitrate->enable();
        return ret;
 }
 
@@ -210,7 +226,6 @@ int FileFFMPEG::select_video_stream(Asset *asset, int vstream)
        if( !ff || !asset->video_data ) return 1;
        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);
@@ -241,6 +256,7 @@ int FileFFMPEG::open_file(int rd, int wr)
                                asset->channels = audio_channels;
                                asset->sample_rate = ff->ff_sample_rate(0);
                                asset->audio_length = ff->ff_audio_samples(0);
+                               strcpy(asset->acodec, ff->ff_audio_format(0));
                        }
                        int video_layers = ff->ff_total_video_layers();
                        if( video_layers > 0 ) {
@@ -254,6 +270,7 @@ int FileFFMPEG::open_file(int rd, int wr)
                                    (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);
+                               strcpy(asset->vcodec, ff->ff_video_format(0));
                        }
                        IndexState *index_state = asset->index_state;
                        index_state->read_markers(file->preferences->index_directory, asset->path);
@@ -334,38 +351,49 @@ int FileFFMPEG::colormodel_supported(int colormodel)
        return colormodel;
 }
 
-int FileFFMPEG::get_best_colormodel(Asset *asset, int driver)
+
+int FileFFMPEG::get_best_colormodel(int driver, int vstream)
 {
+       if( vstream < 0 ) vstream = 0;
+       int is_mpeg = !ff ? 0 : ff->ff_video_mpeg_color_range(vstream);
+
        switch(driver) {
        case PLAYBACK_X11:
-               return BC_RGB888;
-       case PLAYBACK_X11_XV:
-       case PLAYBACK_ASYNCHRONOUS:
-               return BC_YUV888;
-       case PLAYBACK_X11_GL:
-               return BC_YUV888;
-       case PLAYBACK_DV1394:
-       case PLAYBACK_FIREWIRE:
-               return BC_YUV422P;
-       case VIDEO4LINUX2:
-               return BC_RGB888;
-       case VIDEO4LINUX2JPEG:
-               return BC_COMPRESSED;
-       case CAPTURE_DVB:
-       case VIDEO4LINUX2MPEG:
-               return BC_YUV422P;
-       case CAPTURE_JPEG_WEBCAM:
-               return BC_COMPRESSED;
-       case CAPTURE_YUYV_WEBCAM:
-               return BC_YUV422;
-       case CAPTURE_FIREWIRE:
-       case CAPTURE_IEC61883:
-               return BC_YUV422P;
+       case PLAYBACK_X11_GL: return is_mpeg ? BC_YUV888 : BC_RGB888;
+       case PLAYBACK_X11_XV: return BC_YUV420P;
        }
 
        return BC_RGB888;
 }
 
+int FileFFMPEG::get_best_colormodel(Asset *asset, int driver)
+{
+       switch(driver) {
+// the direct X11 color model requires scaling in the codec
+       case SCREENCAPTURE:
+       case PLAYBACK_X11:
+       case PLAYBACK_X11_GL: return BC_RGB888;
+       case PLAYBACK_X11_XV: return BC_YUV420P;
+       }
+
+       return BC_YUV420P;
+}
+
+int FileFFMPEG::can_render(const char *fformat, const char *type)
+{
+       FileSystem fs;
+       char option_path[BCTEXTLEN];
+       FFMPEG::set_option_path(option_path, type);
+       fs.update(option_path);
+       int total_files = fs.total_files();
+       for( int i=0; i<total_files; ++i ) {
+               const char *name = fs.get_entry(i)->get_name();
+               const char *ext = strrchr(name,'.');
+               if( !ext ) continue;
+               if( !strcmp(fformat, ++ext) ) return 1;
+       }
+       return 0;
+}
 
 int FileFFMPEG::get_ff_option(const char *nm, const char *options, char *value)
 {
@@ -450,8 +478,13 @@ void FFMPEGConfigAudio::create_objects()
        bitrate->create_objects();
        bitrate->set_increment(1000);
        bitrate->set_boundaries((int64_t)0, (int64_t)INT_MAX);
+       y += bitrate->get_h() + 5;
+       quality = new FFMpegAudioQuality(this, x, y, _("Quality:"), &asset->ff_audio_quality);
+       quality->create_objects();
+       quality->set_increment(1);
+       quality->set_boundaries((int64_t)-1, (int64_t)51);
 
-       y += bitrate->get_h() + 10;
+       y += quality->get_h() + 10;
        BC_Title *title = new BC_Title(x, y, _("Audio Options:"));
        add_subwindow(title);
 
@@ -474,6 +507,10 @@ void FFMPEGConfigAudio::create_objects()
        show_window(1);
 
        bitrate->update_param("cin_bitrate", asset->ff_audio_options);
+       quality->update_param("cin_quality", asset->ff_audio_options);
+
+       if( asset->ff_audio_bitrate > 0 ) quality->disable();
+       else if( asset->ff_audio_quality >= 0 ) bitrate->disable();
 
        unlock_window();
 }
@@ -511,6 +548,7 @@ int FFMPEGConfigAudioPopup::handle_event()
        popup->audio_options->set_text_row(0);
 
        popup->bitrate->update_param("cin_bitrate", asset->ff_audio_options);
+       popup->quality->update_param("cin_quality", asset->ff_audio_options);
        return 1;
 }
 
@@ -1064,6 +1102,9 @@ void FFOptions::initialize(FFOptionsWindow *win, int kind)
                        if( dupl ) continue;
                        FFOptions_Opt *fopt = new FFOptions_Opt(this, opt, opt->name);
                        append(fopt);
+                       AVDictionaryEntry *elem = av_dict_get(win->dialog->ff_opts,
+                                       opt->name, 0, AV_DICT_IGNORE_SUFFIX);
+                       if( elem && elem->value ) fopt->set(elem->value);
                        char val[BCTEXTLEN], *vp = fopt->get(val, sizeof(val));
                        fopt->item_value->update(vp);
                }