new colorspace plugin
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / ffmpeg.C
index 261ef8693e651d82c09f1bf34759b69aec888198..26a8ddd54c38c729fbf5cadf0dee94a2bf5fce8d 100644 (file)
@@ -1033,7 +1033,8 @@ IndexMarks *FFAudioStream::get_markers()
 }
 
 FFVideoStream::FFVideoStream(FFMPEG *ffmpeg, AVStream *strm, int idx, int fidx)
- : FFStream(ffmpeg, strm, fidx)
+ : FFStream(ffmpeg, strm, fidx),
+   FFVideoConvert(ffmpeg->ff_prefs())
 {
        this->idx = idx;
        width = height = 0;
@@ -1367,7 +1368,7 @@ int FFVideoConvert::convert_picture_vframe(VFrame *frame, AVFrame *ip)
 }
 
 int FFVideoConvert::convert_picture_vframe(VFrame *frame, AVFrame *ip, AVFrame *ipic)
-{
+{ // picture = vframe
        int cmodel = frame->get_color_model();
        AVPixelFormat ofmt = color_model_to_pix_fmt(cmodel);
        if( ofmt == AV_PIX_FMT_NB ) return -1;
@@ -1421,6 +1422,32 @@ int FFVideoConvert::convert_picture_vframe(VFrame *frame, AVFrame *ip, AVFrame *
                                " sws_getCachedContext() failed\n");
                return -1;
        }
+
+       int color_range = 0;
+       switch( preferences->yuv_color_range ) {
+       case BC_COLORS_JPEG:  color_range = 1;  break;
+       case BC_COLORS_MPEG:  color_range = 0;  break;
+       }
+       int ff_color_space = SWS_CS_ITU601;
+       switch( preferences->yuv_color_space ) {
+       case BC_COLORS_BT601:  ff_color_space = SWS_CS_ITU601;  break;
+       case BC_COLORS_BT709:  ff_color_space = SWS_CS_ITU709;  break;
+       case BC_COLORS_BT2020: ff_color_space = SWS_CS_BT2020;  break;
+       }
+       const int *color_table = sws_getCoefficients(ff_color_space);
+
+       int *inv_table, *table, src_range, dst_range;
+       int brightness, contrast, saturation;
+       if( !sws_getColorspaceDetails(convert_ctx,
+                       &inv_table, &src_range, &table, &dst_range,
+                       &brightness, &contrast, &saturation) ) {
+               if( src_range != color_range || dst_range != color_range ||
+                   inv_table != color_table || table != color_table )
+                       sws_setColorspaceDetails(convert_ctx,
+                                       color_table, color_range, color_table, color_range,
+                                       brightness, contrast, saturation);
+       }
+
        int ret = sws_scale(convert_ctx, ip->data, ip->linesize, 0, ip->height,
            ipic->data, ipic->linesize);
        if( ret < 0 ) {
@@ -1485,7 +1512,7 @@ int FFVideoConvert::convert_vframe_picture(VFrame *frame, AVFrame *op)
 }
 
 int FFVideoConvert::convert_vframe_picture(VFrame *frame, AVFrame *op, AVFrame *opic)
-{
+{ // vframe = picture
        int cmodel = frame->get_color_model();
        AVPixelFormat ifmt = color_model_to_pix_fmt(cmodel);
        if( ifmt == AV_PIX_FMT_NB ) return -1;
@@ -1523,6 +1550,32 @@ int FFVideoConvert::convert_vframe_picture(VFrame *frame, AVFrame *op, AVFrame *
                                " sws_getCachedContext() failed\n");
                return -1;
        }
+
+
+       int color_range = 0;
+       switch( preferences->yuv_color_range ) {
+       case BC_COLORS_JPEG:  color_range = 1;  break;
+       case BC_COLORS_MPEG:  color_range = 0;  break;
+       }
+       int ff_color_space = SWS_CS_ITU601;
+       switch( preferences->yuv_color_space ) {
+       case BC_COLORS_BT601:  ff_color_space = SWS_CS_ITU601;  break;
+       case BC_COLORS_BT709:  ff_color_space = SWS_CS_ITU709;  break;
+       case BC_COLORS_BT2020: ff_color_space = SWS_CS_BT2020;  break;
+       }
+       const int *color_table = sws_getCoefficients(ff_color_space);
+
+       int *inv_table, *table, src_range, dst_range;
+       int brightness, contrast, saturation;
+       if( !sws_getColorspaceDetails(convert_ctx,
+                       &inv_table, &src_range, &table, &dst_range,
+                       &brightness, &contrast, &saturation) ) {
+               if( dst_range != color_range || table != color_table )
+                       sws_setColorspaceDetails(convert_ctx,
+                                       inv_table, src_range, color_table, color_range,
+                                       brightness, contrast, saturation);
+       }
+
        int ret = sws_scale(convert_ctx, opic->data, opic->linesize, 0, frame->get_h(),
                        op->data, op->linesize);
        if( ret < 0 ) {
@@ -3229,6 +3282,11 @@ const char *FFMPEG::ff_hw_dev()
        return &file_base->file->preferences->use_hw_dev[0];
 }
 
+Preferences *FFMPEG::ff_prefs()
+{
+       return !file_base ? 0 : file_base->file->preferences;
+}
+
 int FFVideoStream::create_filter(const char *filter_spec, AVCodecParameters *avpar)
 {
        avfilter_register_all();