[FFmpeg-devel,2/2] WIP: steps to ditch YUVJ formats

Submitted by Paul B Mahol on Dec. 6, 2017, 8:10 p.m.

Details

Message ID 20171206201022.11073-2-onemda@gmail.com
State New
Headers show

Commit Message

Paul B Mahol Dec. 6, 2017, 8:10 p.m.
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---

Does not work! Why?

---
 fftools/ffmpeg_filter.c  |  9 +++++++--
 libavfilter/avfilter.c   |  2 ++
 libavfilter/avfilter.h   |  2 ++
 libavfilter/buffersink.c |  1 +
 libavfilter/buffersink.h |  1 +
 libavfilter/buffersrc.c  | 13 +++++++++++++
 libavfilter/buffersrc.h  |  5 +++++
 libavfilter/vf_scale.c   |  1 +
 8 files changed, 32 insertions(+), 2 deletions(-)

Comments

Michael Niedermayer Dec. 7, 2017, 8:51 p.m.
On Wed, Dec 06, 2017 at 09:10:22PM +0100, Paul B Mahol wrote:
[...]
> diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
> index 2fd9c90d84..be6dcb9307 100644
> --- a/libavfilter/vf_scale.c
> +++ b/libavfilter/vf_scale.c
> @@ -578,6 +578,7 @@ static const AVOption scale_options[] = {
>      {  "in_range", "set input color range",  OFFSET( in_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range" },
>      { "out_range", "set output color range", OFFSET(out_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range" },
>      { "auto",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, "range" },
> +    { "unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, "range" },
>      { "full",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
>      { "jpeg",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
>      { "mpeg",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
> -- 

The change to libavfilter/vf_scale.c is ok

[...]
Paul B Mahol Dec. 7, 2017, 9:25 p.m.
On 12/7/17, Michael Niedermayer <michael@niedermayer.cc> wrote:
> On Wed, Dec 06, 2017 at 09:10:22PM +0100, Paul B Mahol wrote:
> [...]
>> diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
>> index 2fd9c90d84..be6dcb9307 100644
>> --- a/libavfilter/vf_scale.c
>> +++ b/libavfilter/vf_scale.c
>> @@ -578,6 +578,7 @@ static const AVOption scale_options[] = {
>>      {  "in_range", "set input color range",  OFFSET( in_range),
>> AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range"
>> },
>>      { "out_range", "set output color range", OFFSET(out_range),
>> AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range"
>> },
>>      { "auto",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 =
>> AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, "range" },
>> +    { "unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 =
>> AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, "range" },
>>      { "full",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0,
>> 0, FLAGS, "range" },
>>      { "jpeg",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0,
>> 0, FLAGS, "range" },
>>      { "mpeg",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0,
>> 0, FLAGS, "range" },
>> --
>
> The change to libavfilter/vf_scale.c is ok

I cannot grasp how to get color_range set by -color_range as encoder option
for mjpeg encoder to pick it up into scale filter insertion as last step
in filtergraph.

Idea is to have user set color_range as encoding option for jpeg
(could be auto added later) and then have scale filter auto inserted
at end of filtergraph and before buffersink so it converts from one
range to another if required.

Please help if you can!

Patch hide | download patch | download mbox

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 877fd670e6..7a7d79e334 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -474,6 +474,10 @@  static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
             av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
         }
 
+        av_strlcatf(args, sizeof(args), ":out_range=%s:in_range=%s",
+                    av_color_range_name(ost->enc_ctx->color_range),
+                    av_color_range_name(last_filter->inputs[pad_idx]->color_range));
+
         snprintf(name, sizeof(name), "scaler_out_%d_%d",
                  ost->file_index, ost->index);
         if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
@@ -777,10 +781,11 @@  static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
     av_bprint_init(&args, 0, 1);
     av_bprintf(&args,
              "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
-             "pixel_aspect=%d/%d:sws_param=flags=%d",
+             "pixel_aspect=%d/%d:sws_param=flags=%d:color_range=%s",
              ifilter->width, ifilter->height, ifilter->format,
              tb.num, tb.den, sar.num, sar.den,
-             SWS_BILINEAR + ((ist->dec_ctx->flags&AV_CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
+             SWS_BILINEAR + ((ist->dec_ctx->flags&AV_CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0),
+             av_color_range_name(ist->dec_ctx->color_range));
     if (fr.num && fr.den)
         av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);
     snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index b98b32bacb..4a579bb49d 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -336,6 +336,8 @@  int avfilter_config_links(AVFilterContext *filter)
                         link->w = inlink->w;
                     if (!link->h)
                         link->h = inlink->h;
+                    if (!link->color_range)
+                        link->color_range = inlink->color_range;
                 } else if (!link->w || !link->h) {
                     av_log(link->src, AV_LOG_ERROR,
                            "Video source filters must set their output link's "
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 47546c15e5..a5f4df74de 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -448,6 +448,8 @@  struct AVFilterLink {
      */
     AVRational time_base;
 
+    int color_range;
+
     /*****************************************************************
      * All fields below this line are not part of the public API. They
      * may not be used outside of libavfilter and can be changed and
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index 0f87b5439a..5f3c932d92 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -194,6 +194,7 @@  MAKE_AVFILTERLINK_ACCESSOR(AVRational       , frame_rate         )
 MAKE_AVFILTERLINK_ACCESSOR(int              , w                  )
 MAKE_AVFILTERLINK_ACCESSOR(int              , h                  )
 MAKE_AVFILTERLINK_ACCESSOR(AVRational       , sample_aspect_ratio)
+MAKE_AVFILTERLINK_ACCESSOR(int              , color_range        )
 
 MAKE_AVFILTERLINK_ACCESSOR(int              , channels           )
 MAKE_AVFILTERLINK_ACCESSOR(uint64_t         , channel_layout     )
diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h
index 21d6bb505b..c0acee48d6 100644
--- a/libavfilter/buffersink.h
+++ b/libavfilter/buffersink.h
@@ -114,6 +114,7 @@  AVRational       av_buffersink_get_frame_rate          (const AVFilterContext *c
 int              av_buffersink_get_w                   (const AVFilterContext *ctx);
 int              av_buffersink_get_h                   (const AVFilterContext *ctx);
 AVRational       av_buffersink_get_sample_aspect_ratio (const AVFilterContext *ctx);
+int              av_buffersink_get_color_range         (const AVFilterContext *ctx);
 
 int              av_buffersink_get_channels            (const AVFilterContext *ctx);
 uint64_t         av_buffersink_get_channel_layout      (const AVFilterContext *ctx);
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index cd56f8ca45..67f8bdf158 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -52,6 +52,7 @@  typedef struct BufferSourceContext {
     int               w, h;
     enum AVPixelFormat  pix_fmt;
     AVRational        pixel_aspect;
+    int               color_range;
     char              *sws_param;
 
     AVBufferRef *hw_frames_ctx;
@@ -109,6 +110,8 @@  int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *par
             s->h = param->height;
         if (param->sample_aspect_ratio.num > 0 && param->sample_aspect_ratio.den > 0)
             s->pixel_aspect = param->sample_aspect_ratio;
+        if (param->color_range > 0)
+            s->color_range = param->color_range;
         if (param->frame_rate.num > 0 && param->frame_rate.den > 0)
             s->frame_rate = param->frame_rate;
         if (param->hw_frames_ctx) {
@@ -309,6 +312,15 @@  static const AVOption buffer_options[] = {
     { "time_base",     NULL,                     OFFSET(time_base),        AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
     { "frame_rate",    NULL,                     OFFSET(frame_rate),       AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
     { "sws_param",     NULL,                     OFFSET(sws_param),        AV_OPT_TYPE_STRING,                    .flags = V },
+    { "color_range",   NULL,                     OFFSET(color_range),      AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V, "range" },
+    { "unspecified",   NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED},  0, 0, V, "range"},
+    { "unknown",       NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED},  0, 0, V, "range"},
+    { "limited",       NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG},         0, 0, V, "range"},
+    { "tv",            NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG},         0, 0, V, "range"},
+    { "mpeg",          NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG},         0, 0, V, "range"},
+    { "full",          NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG},         0, 0, V, "range"},
+    { "pc",            NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG},         0, 0, V, "range"},
+    { "jpeg",          NULL,   0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG},         0, 0, V, "range"},
     { NULL },
 };
 
@@ -434,6 +446,7 @@  static int config_props(AVFilterLink *link)
         link->w = c->w;
         link->h = c->h;
         link->sample_aspect_ratio = c->pixel_aspect;
+        link->color_range = c->color_range;
 
         if (c->hw_frames_ctx) {
             link->hw_frames_ctx = av_buffer_ref(c->hw_frames_ctx);
diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h
index 0652113f2b..1004121c4e 100644
--- a/libavfilter/buffersrc.h
+++ b/libavfilter/buffersrc.h
@@ -114,6 +114,11 @@  typedef struct AVBufferSrcParameters {
      * Audio only, the audio channel layout
      */
     uint64_t channel_layout;
+
+   /**
+     * Video only,
+     */
+    int color_range;
 } AVBufferSrcParameters;
 
 /**
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 2fd9c90d84..be6dcb9307 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -578,6 +578,7 @@  static const AVOption scale_options[] = {
     {  "in_range", "set input color range",  OFFSET( in_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range" },
     { "out_range", "set output color range", OFFSET(out_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range" },
     { "auto",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, "range" },
+    { "unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, "range" },
     { "full",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
     { "jpeg",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
     { "mpeg",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },