[FFmpeg-devel] [PATCH] avutil/display: fix inverted doc

2021-12-12 Thread Zhao Zhili
---
 libavutil/display.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavutil/display.h b/libavutil/display.h
index 515adad795..d87bf68425 100644
--- a/libavutil/display.h
+++ b/libavutil/display.h
@@ -88,7 +88,7 @@
 double av_display_rotation_get(const int32_t matrix[9]);
 
 /**
- * Initialize a transformation matrix describing a pure counterclockwise
+ * Initialize a transformation matrix describing a pure clockwise
  * rotation by the specified angle (in degrees).
  *
  * @param matrix an allocated transformation matrix (will be fully overwritten
-- 
2.31.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avutil/display: fix inverted doc

2021-12-12 Thread Andreas Rheinhardt
Zhao Zhili:
> ---
>  libavutil/display.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/libavutil/display.h b/libavutil/display.h
> index 515adad795..d87bf68425 100644
> --- a/libavutil/display.h
> +++ b/libavutil/display.h
> @@ -88,7 +88,7 @@
>  double av_display_rotation_get(const int32_t matrix[9]);
>  
>  /**
> - * Initialize a transformation matrix describing a pure counterclockwise
> + * Initialize a transformation matrix describing a pure clockwise
>   * rotation by the specified angle (in degrees).
>   *
>   * @param matrix an allocated transformation matrix (will be fully 
> overwritten
> 

If you look at the documentation, you will notice that the matrix
returned from the function is supposed to be multiplied from the right
to the coordinate (row) vector, not from the left to the coordinate
(column) vector as is standard in linear algebra. This is tantamount to
transposing the matrix which for rotation matrices means negating the
degree. So this doxy is correct.
Notice that last time I looked at this, I came to the conclusion that
the whole H.2645 SEI parsing code uses it wrongly.

- Andreas
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avutil/display: fix inverted doc

2021-12-12 Thread Andreas Rheinhardt
Andreas Rheinhardt:
> Zhao Zhili:
>> ---
>>  libavutil/display.h | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/libavutil/display.h b/libavutil/display.h
>> index 515adad795..d87bf68425 100644
>> --- a/libavutil/display.h
>> +++ b/libavutil/display.h
>> @@ -88,7 +88,7 @@
>>  double av_display_rotation_get(const int32_t matrix[9]);
>>  
>>  /**
>> - * Initialize a transformation matrix describing a pure counterclockwise
>> + * Initialize a transformation matrix describing a pure clockwise
>>   * rotation by the specified angle (in degrees).
>>   *
>>   * @param matrix an allocated transformation matrix (will be fully 
>> overwritten
>>
> 
> If you look at the documentation, you will notice that the matrix
> returned from the function is supposed to be multiplied from the right
> to the coordinate (row) vector, not from the left to the coordinate
> (column) vector as is standard in linear algebra. This is tantamount to
> transposing the matrix which for rotation matrices means negating the
> degree. So this doxy is correct.
> Notice that last time I looked at this, I came to the conclusion that
> the whole H.2645 SEI parsing code uses it wrongly.
> 

Wait, there is another difference to ordinary linear algebra: The y axis
is directed downwards. Maybe you are right. Let me think this through...

- Andreas
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v5 4/6] lavc: Implement Dolby Vision RPU parsing

2021-12-12 Thread Niklas Haas
From: Niklas Haas 

Based on a mixture of guesswork, partial documentation in patents, and
reverse engineering of real-world samples. Confirmed working for all the
samples I've thrown at it.

Contains some annoying machinery to persist these values in between
frames, which is needed in theory even though I've never actually seen a
sample that relies on it in practice. May or may not work.

Since the distinction matters greatly for parsing the color matrix
values, this includes a small helper function to guess the right profile
from the RPU itself in case the user has forgotten to forward the dovi
configuration record to the decoder. (Which in practice, only ffmpeg.c
and ffplay do..)

Notable omissions / deviations:
- CRC32 verification. This is based on the MPEG2 CRC32 type, which does
  not seem to be implemented in lavu. (And I don't care enough to do so)
- Linear interpolation support. Nothing documents this (beyond its
  existence) and no samples use it, so impossible to implement.
- All of the extension metadata blocks, but these contain values that
  seem largely congruent with ST2094, HDR10, or other existing forms of
  side data, so I will defer parsing/attaching them to a future commit.
- The patent describes a mechanism for predicting coefficients from
  previous RPUs, but the bit for the flag whether to use the
  prediction deltas or signal entirely new coefficients does not seem to
  be present in actual RPUs, so we ignore this subsystem entirely.
- In the patent's spec, the NLQ subsystem also loops over
  num_nlq_pivots, but even in the patent the number is hard-coded to one
  iteration rather than signalled. So we only store one set of coefs.

Heavily influenced by https://github.com/quietvoid/dovi_tool
Documentation drawn from US Patent 10,701,399 B2 and ETSI GS CCM 001

Signed-off-by: Niklas Haas 
---
 configure |   2 +
 libavcodec/Makefile   |   1 +
 libavcodec/dovi_rpu.c | 432 ++
 libavcodec/dovi_rpu.h |  71 +++
 4 files changed, 506 insertions(+)
 create mode 100644 libavcodec/dovi_rpu.c
 create mode 100644 libavcodec/dovi_rpu.h

diff --git a/configure b/configure
index a7593ec2db..b8c9c5d2ae 100755
--- a/configure
+++ b/configure
@@ -2426,6 +2426,7 @@ CONFIG_EXTRA="
 cbs_vp9
 dirac_parse
 dnn
+dovi_rpu
 dvprofile
 exif
 faandct
@@ -2693,6 +2694,7 @@ cbs_mpeg2_select="cbs"
 cbs_vp9_select="cbs"
 dct_select="rdft"
 dirac_parse_select="golomb"
+dovi_rpu_select="golomb"
 dnn_suggest="libtensorflow libopenvino"
 dnn_deps="avformat swscale"
 error_resilience_select="me_cmp"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 4122a9b144..127e5db7df 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -77,6 +77,7 @@ OBJS-$(CONFIG_CBS_MPEG2)   += cbs_mpeg2.o
 OBJS-$(CONFIG_CBS_VP9) += cbs_vp9.o
 OBJS-$(CONFIG_CRYSTALHD)   += crystalhd.o
 OBJS-$(CONFIG_DCT) += dct.o dct32_fixed.o dct32_float.o
+OBJS-$(CONFIG_DOVI_RPU)+= dovi_rpu.o
 OBJS-$(CONFIG_ERROR_RESILIENCE)+= error_resilience.o
 OBJS-$(CONFIG_EXIF)+= exif.o tiff_common.o
 OBJS-$(CONFIG_FAANDCT) += faandct.o
diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
new file mode 100644
index 00..e3c860464e
--- /dev/null
+++ b/libavcodec/dovi_rpu.c
@@ -0,0 +1,432 @@
+/*
+ * Dolby Vision RPU decoder
+ *
+ * Copyright (C) 2021 Jan Ekström
+ * Copyright (C) 2021 Niklas Haas
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/buffer.h"
+
+#include "dovi_rpu.h"
+#include "golomb.h"
+#include "get_bits.h"
+
+enum {
+RPU_COEFF_FIXED = 0,
+RPU_COEFF_FLOAT = 1,
+};
+
+/**
+ * Private contents of vdr_ref.
+ */
+typedef struct DOVIVdrRef {
+AVDOVIDataMapping mapping;
+AVDOVIColorMetadata color;
+} DOVIVdrRef;
+
+void ff_dovi_ctx_unref(DOVIContext *s)
+{
+for (int i = 0; i < DOVI_MAX_DM_ID; i++)
+av_buffer_unref(&s->vdr_ref[i]);
+
+/* Preserve the user-provided fields explicitly, reset everything else */
+*s = (DOVIContext) {
+.avctx = s->avctx,
+.config = s->config,
+};
+}
+
+int ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext *s

[FFmpeg-devel] [PATCH v5 3/6] ffprobe: Support AV_FRAME_DATA_DOVI_METADATA

2021-12-12 Thread Niklas Haas
From: Jan Ekström 

Co-authored-by: Niklas Haas 
---
 fftools/ffprobe.c | 173 +-
 1 file changed, 170 insertions(+), 3 deletions(-)

diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
index 0711e02922..75263cd3a9 100644
--- a/fftools/ffprobe.c
+++ b/fftools/ffprobe.c
@@ -175,6 +175,10 @@ typedef enum {
 SECTION_ID_FRAME_SIDE_DATA,
 SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST,
 SECTION_ID_FRAME_SIDE_DATA_TIMECODE,
+SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST,
+SECTION_ID_FRAME_SIDE_DATA_COMPONENT,
+SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST,
+SECTION_ID_FRAME_SIDE_DATA_PIECE,
 SECTION_ID_FRAME_LOG,
 SECTION_ID_FRAME_LOGS,
 SECTION_ID_LIBRARY_VERSION,
@@ -219,9 +223,13 @@ static struct section sections[] = {
 [SECTION_ID_FRAME] =  { SECTION_ID_FRAME, "frame", 0, { 
SECTION_ID_FRAME_TAGS, SECTION_ID_FRAME_SIDE_DATA_LIST, SECTION_ID_FRAME_LOGS, 
-1 } },
 [SECTION_ID_FRAME_TAGS] = { SECTION_ID_FRAME_TAGS, "tags", 
SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = 
"frame_tags" },
 [SECTION_ID_FRAME_SIDE_DATA_LIST] ={ SECTION_ID_FRAME_SIDE_DATA_LIST, 
"side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA, -1 }, 
.element_name = "side_data", .unique_name = "frame_side_data_list" },
-[SECTION_ID_FRAME_SIDE_DATA] = { SECTION_ID_FRAME_SIDE_DATA, 
"side_data", 0, { SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST, -1 } },
-[SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST] = { 
SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST, "timecodes", SECTION_FLAG_IS_ARRAY, { 
SECTION_ID_FRAME_SIDE_DATA_TIMECODE, -1 } },
-[SECTION_ID_FRAME_SIDE_DATA_TIMECODE] = { 
SECTION_ID_FRAME_SIDE_DATA_TIMECODE, "timecode", 0, { -1 } },
+[SECTION_ID_FRAME_SIDE_DATA] = { SECTION_ID_FRAME_SIDE_DATA, 
"side_data", 0, { SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST, 
SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST, -1 } },
+[SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST] =  { 
SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST, "timecodes", SECTION_FLAG_IS_ARRAY, { 
SECTION_ID_FRAME_SIDE_DATA_TIMECODE, -1 } },
+[SECTION_ID_FRAME_SIDE_DATA_TIMECODE] =   { 
SECTION_ID_FRAME_SIDE_DATA_TIMECODE, "timecode", 0, { -1 } },
+[SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST] = { 
SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST, "components", SECTION_FLAG_IS_ARRAY, 
{ SECTION_ID_FRAME_SIDE_DATA_COMPONENT, -1 } },
+[SECTION_ID_FRAME_SIDE_DATA_COMPONENT] =  { 
SECTION_ID_FRAME_SIDE_DATA_COMPONENT, "component", 0, { 
SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, -1 } },
+[SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST] =   { 
SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST, "pieces", SECTION_FLAG_IS_ARRAY, { 
SECTION_ID_FRAME_SIDE_DATA_PIECE, -1 } },
+[SECTION_ID_FRAME_SIDE_DATA_PIECE] ={ 
SECTION_ID_FRAME_SIDE_DATA_PIECE, "section", 0, { -1 } },
 [SECTION_ID_FRAME_LOGS] = { SECTION_ID_FRAME_LOGS, "logs", 
SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_LOG, -1 } },
 [SECTION_ID_FRAME_LOG] =  { SECTION_ID_FRAME_LOG, "log", 0, { -1 
},  },
 [SECTION_ID_LIBRARY_VERSIONS] =   { SECTION_ID_LIBRARY_VERSIONS, 
"library_versions", SECTION_FLAG_IS_ARRAY, { SECTION_ID_LIBRARY_VERSION, -1 } },
@@ -1807,6 +1815,16 @@ static void writer_register_all(void)
 writer_print_string(w, k, pbuf.str, 0);\
 } while (0)
 
+#define print_list_fmt(k, f, n, ...) do {   \
+av_bprint_clear(&pbuf); \
+for (int idx = 0; idx < n; idx++) { \
+if (idx > 0)\
+av_bprint_chars(&pbuf, ' ', 1); \
+av_bprintf(&pbuf, f, __VA_ARGS__);  \
+}   \
+writer_print_string(w, k, pbuf.str, 0); \
+} while (0)
+
 #define print_int(k, v) writer_print_integer(w, k, v)
 #define print_q(k, v, s)writer_print_rational(w, k, v, s)
 #define print_str(k, v) writer_print_string(w, k, v, 0)
@@ -1852,6 +1870,153 @@ static inline int show_tags(WriterContext *w, 
AVDictionary *tags, int section_id
 return ret;
 }
 
+static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi)
+{
+if (!dovi)
+return;
+
+{
+const AVDOVIRpuDataHeader *hdr = &dovi->header;
+const AVDOVIDataMapping   *mapping = &dovi->mapping;
+const AVDOVIColorMetadata *color   = &dovi->color;
+AVBPrint pbuf;
+
+av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
+
+// header
+print_int("rpu_type",hdr->rpu_type);
+print_int("rpu_format",  hdr->rpu_format);
+print_int("vdr_rpu_profile", hdr->vdr_rpu_profile);
+print_int("vdr_rpu_level",   hdr->vdr_rpu_level);
+print_int("chroma_resampling_explicit_filter_flag",
+  hdr->chroma_resampling_explicit_filter_flag);
+print_int("coef_data_type",   hdr->coef_data_type);
+print_int("coef_log2_denom",   

[FFmpeg-devel] [PATCH v5 2/6] lavfi/showinfo: Support AV_FRAME_DATA_DOVI_METADATA

2021-12-12 Thread Niklas Haas
From: Niklas Haas 

Signed-off-by: Niklas Haas 
---
 libavfilter/vf_showinfo.c | 108 ++
 1 file changed, 108 insertions(+)

diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
index 62c7833247..8a7efc15b7 100644
--- a/libavfilter/vf_showinfo.c
+++ b/libavfilter/vf_showinfo.c
@@ -27,6 +27,7 @@
 #include "libavutil/bswap.h"
 #include "libavutil/adler32.h"
 #include "libavutil/display.h"
+#include "libavutil/dovi_meta.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
 #include "libavutil/film_grain_params.h"
@@ -429,6 +430,110 @@ static void 
dump_sei_film_grain_params_metadata(AVFilterContext *ctx, const AVFr
 }
 }
 
+static void dump_dovi_metadata(AVFilterContext *ctx, const AVFrameSideData *sd)
+{
+const AVDOVIMetadata *dovi = (const AVDOVIMetadata *) sd->data;
+const AVDOVIRpuDataHeader *hdr = &dovi->header;
+const AVDOVIDataMapping *mapping = &dovi->mapping;
+const AVDOVIColorMetadata *color = &dovi->color;
+
+av_log(ctx, AV_LOG_INFO, "Dolby Vision Metadata:\n");
+av_log(ctx, AV_LOG_INFO, "rpu_type=%"PRIu8"; ", hdr->rpu_type);
+av_log(ctx, AV_LOG_INFO, "rpu_format=%"PRIu16"; ", hdr->rpu_format);
+av_log(ctx, AV_LOG_INFO, "vdr_rpu_profile=%"PRIu8"; ", 
hdr->vdr_rpu_profile);
+av_log(ctx, AV_LOG_INFO, "vdr_rpu_level=%"PRIu8"; ", hdr->vdr_rpu_level);
+av_log(ctx, AV_LOG_INFO, "chroma_resampling_explicit_filter_flag=%d; ", 
hdr->chroma_resampling_explicit_filter_flag);
+av_log(ctx, AV_LOG_INFO, "coef_data_type=%"PRIu8"; ", hdr->coef_data_type);
+av_log(ctx, AV_LOG_INFO, "coef_log2_denom=%"PRIu8"; ", 
hdr->coef_log2_denom);
+av_log(ctx, AV_LOG_INFO, "vdr_rpu_normalized_idc=%"PRIu8"; ", 
hdr->vdr_rpu_normalized_idc);
+av_log(ctx, AV_LOG_INFO, "bl_video_full_range_flag=%d; ", 
hdr->bl_video_full_range_flag);
+av_log(ctx, AV_LOG_INFO, "bl_bit_depth=%"PRIu8"; ", hdr->bl_bit_depth);
+av_log(ctx, AV_LOG_INFO, "el_bit_depth=%"PRIu8"; ", hdr->el_bit_depth);
+av_log(ctx, AV_LOG_INFO, "vdr_bit_depth=%"PRIu8"; ", hdr->vdr_bit_depth);
+av_log(ctx, AV_LOG_INFO, "spatial_resampling_filter_flag=%d; ", 
hdr->spatial_resampling_filter_flag);
+av_log(ctx, AV_LOG_INFO, "el_spatial_resampling_filter_flag=%d; ", 
hdr->el_spatial_resampling_filter_flag);
+av_log(ctx, AV_LOG_INFO, "disable_residual_flag=%d\n", 
hdr->disable_residual_flag);
+
+av_log(ctx, AV_LOG_INFO, "data mapping: ");
+av_log(ctx, AV_LOG_INFO, "vdr_rpu_id=%"PRIu8"; ", mapping->vdr_rpu_id);
+av_log(ctx, AV_LOG_INFO, "mapping_color_space=%"PRIu8"; ", 
mapping->mapping_color_space);
+av_log(ctx, AV_LOG_INFO, "mapping_chroma_format_idc=%"PRIu8"; ", 
mapping->mapping_chroma_format_idc);
+av_log(ctx, AV_LOG_INFO, "nlq_method_idc=%d; ", (int) 
mapping->nlq_method_idc);
+av_log(ctx, AV_LOG_INFO, "num_x_partitions=%"PRIu32"; ", 
mapping->num_x_partitions);
+av_log(ctx, AV_LOG_INFO, "num_y_partitions=%"PRIu32"\n", 
mapping->num_y_partitions);
+
+for (int c = 0; c < 3; c++) {
+const AVDOVIReshapingCurve *curve = &mapping->curves[c];
+const AVDOVINLQParams *nlq = &mapping->nlq[c];
+av_log(ctx, AV_LOG_INFO, "  channel %d: ", c);
+av_log(ctx, AV_LOG_INFO, "pivots={ ");
+for (int i = 0; i < curve->num_pivots; i++)
+av_log(ctx, AV_LOG_INFO, "%"PRIu16" ", curve->pivots[i]);
+av_log(ctx, AV_LOG_INFO, "}; mapping_idc={ ");
+for (int i = 0; i < curve->num_pivots - 1; i++)
+av_log(ctx, AV_LOG_INFO, "%d ", (int) curve->mapping_idc[i]);
+av_log(ctx, AV_LOG_INFO, "}; poly_order={ ");
+for (int i = 0; i < curve->num_pivots - 1; i++)
+av_log(ctx, AV_LOG_INFO, "%"PRIu8" ", curve->poly_order[i]);
+av_log(ctx, AV_LOG_INFO, "}; poly_coef={ ");
+for (int i = 0; i < curve->num_pivots - 1; i++) {
+av_log(ctx, AV_LOG_INFO, "{%"PRIi64", %"PRIi64", %"PRIi64"} ",
+   curve->poly_coef[i][0],
+   curve->poly_coef[i][1],
+   curve->poly_coef[i][2]);
+}
+
+av_log(ctx, AV_LOG_INFO, "}; mmr_order={ ");
+for (int i = 0; i < curve->num_pivots - 1; i++)
+av_log(ctx, AV_LOG_INFO, "%"PRIu8" ", curve->mmr_order[i]);
+av_log(ctx, AV_LOG_INFO, "}; mmr_constant={ ");
+for (int i = 0; i < curve->num_pivots - 1; i++)
+av_log(ctx, AV_LOG_INFO, "%"PRIi64" ", curve->mmr_constant[i]);
+av_log(ctx, AV_LOG_INFO, "}; mmr_coef={ ");
+for (int i = 0; i < curve->num_pivots - 1; i++) {
+av_log(ctx, AV_LOG_INFO, "{");
+for (int j = 0; j < curve->mmr_order[i]; j++) {
+for (int k = 0; k < 7; k++)
+av_log(ctx, AV_LOG_INFO, "%"PRIi64" ", 
curve->mmr_coef[i][j][k]);
+}
+av_log(ctx, AV_LOG_INFO, "} ");
+}
+
+av_log(ctx, AV_LOG_INFO, "}; nlq_offset=%"PRIu64"; ", nlq->nlq_offset);
+   

[FFmpeg-devel] [PATCH v5 1/6] lavu/frame: Add Dolby Vision metadata side data type

2021-12-12 Thread Niklas Haas
From: Niklas Haas 

Signed-off-by: Niklas Haas 
---
 doc/APIchanges|   3 +
 libavutil/dovi_meta.c |  12 
 libavutil/dovi_meta.h | 132 ++
 libavutil/frame.c |   1 +
 libavutil/frame.h |   9 ++-
 libavutil/version.h   |   2 +-
 6 files changed, 157 insertions(+), 2 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 17aa664ca3..0ddde40bdf 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,9 @@ libavutil: 2021-04-27
 
 API changes, most recent first:
 
+2021-12-xx - xx - lavu 57.12.100 - frame.h
+  Add AV_FRAME_DATA_DOVI_RESHAPING.
+
 2021-12-xx - xx - lavf 59.10.100 - avformat.h
   Add AVFormatContext io_close2 which returns an int
 
diff --git a/libavutil/dovi_meta.c b/libavutil/dovi_meta.c
index 7bd08f6c54..60b4cb2376 100644
--- a/libavutil/dovi_meta.c
+++ b/libavutil/dovi_meta.c
@@ -33,3 +33,15 @@ AVDOVIDecoderConfigurationRecord *av_dovi_alloc(size_t *size)
 
 return dovi;
 }
+
+AVDOVIMetadata *av_dovi_metadata_alloc(size_t *size)
+{
+AVDOVIMetadata *dovi = av_mallocz(sizeof(AVDOVIMetadata));
+if (!dovi)
+return NULL;
+
+if (size)
+*size = sizeof(*dovi);
+
+return dovi;
+}
diff --git a/libavutil/dovi_meta.h b/libavutil/dovi_meta.h
index 299911d434..20efd41676 100644
--- a/libavutil/dovi_meta.h
+++ b/libavutil/dovi_meta.h
@@ -29,6 +29,7 @@
 
 #include 
 #include 
+#include "rational.h"
 
 /*
  * DOVI configuration
@@ -67,4 +68,135 @@ typedef struct AVDOVIDecoderConfigurationRecord {
  */
 AVDOVIDecoderConfigurationRecord *av_dovi_alloc(size_t *size);
 
+/**
+ * Dolby Vision RPU data header.
+ */
+typedef struct AVDOVIRpuDataHeader {
+uint8_t rpu_type;
+uint16_t rpu_format;
+uint8_t vdr_rpu_profile;
+uint8_t vdr_rpu_level;
+int chroma_resampling_explicit_filter_flag;
+uint8_t coef_data_type; /* informative, lavc always converts to fixed */
+uint8_t coef_log2_denom;
+uint8_t vdr_rpu_normalized_idc;
+int bl_video_full_range_flag;
+uint8_t bl_bit_depth; /* [8, 16] */
+uint8_t el_bit_depth; /* [8, 16] */
+uint8_t vdr_bit_depth; /* [8, 16] */
+int spatial_resampling_filter_flag;
+int el_spatial_resampling_filter_flag;
+int disable_residual_flag;
+} AVDOVIRpuDataHeader;
+
+enum AVDOVIMappingMethod {
+AV_DOVI_MAPPING_POLYNOMIAL = 0,
+AV_DOVI_MAPPING_MMR = 1,
+};
+
+/**
+ * Coefficients of a piece-wise function. The pieces of the function span the
+ * value ranges between two adjacent pivot values.
+ */
+#define FF_DOVI_MAX_PIECES 8
+typedef struct AVDOVIReshapingCurve {
+uint8_t num_pivots; /* [2, 9] */
+uint16_t pivots[FF_DOVI_MAX_PIECES + 1];/* sorted ascending */
+enum AVDOVIMappingMethod mapping_idc[FF_DOVI_MAX_PIECES];
+/* AV_DOVI_MAPPING_POLYNOMIAL */
+uint8_t poly_order[FF_DOVI_MAX_PIECES]; /* [1, 2] */
+int64_t poly_coef[FF_DOVI_MAX_PIECES][3];   /* x^0, x^1, x^2 */
+/* AV_DOVI_MAPPING_MMR */
+uint8_t mmr_order[FF_DOVI_MAX_PIECES];  /* [1, 3] */
+int64_t mmr_constant[FF_DOVI_MAX_PIECES];
+int64_t mmr_coef[FF_DOVI_MAX_PIECES][3/* order - 1 */][7];
+} AVDOVIReshapingCurve;
+
+enum AVDOVINLQMethod {
+AV_DOVI_NLQ_NONE = -1,
+AV_DOVI_NLQ_LINEAR_DZ = 0,
+};
+
+/**
+ * Coefficients of the non-linear inverse quantization. For the interpretation
+ * of these, see ETSI GS CCM 001.
+ */
+typedef struct AVDOVINLQParams {
+uint64_t nlq_offset;
+uint64_t vdr_in_max;
+/* AV_DOVI_NLQ_LINEAR_DZ */
+uint64_t linear_deadzone_slope;
+uint64_t linear_deadzone_threshold;
+} AVDOVINLQParams;
+
+/**
+ * Dolby Vision RPU data mapping parameters.
+ */
+typedef struct AVDOVIDataMapping {
+uint8_t vdr_rpu_id;
+uint8_t mapping_color_space;
+uint8_t mapping_chroma_format_idc;
+AVDOVIReshapingCurve curves[3]; /* per component */
+
+/* Non-linear inverse quantization */
+enum AVDOVINLQMethod nlq_method_idc;
+uint32_t num_x_partitions;
+uint32_t num_y_partitions;
+AVDOVINLQParams nlq[3]; /* per component */
+} AVDOVIDataMapping;
+
+typedef struct AVDOVIColorMetadata {
+uint8_t dm_metadata_id;
+int scene_refresh_flag;
+
+/**
+ * Coefficients of the custom Dolby Vision IPT-PQ matrices. These are to be
+ * used instead of the matrices indicated by the frame's colorspace tags.
+ * The output of rgb_to_lms_matrix is to be fed into a BT.2020 LMS->RGB
+ * matrix based on a Hunt-Pointer-Estevez transform, but without any
+ * crosstalk. (See the definition of the ICtCp colorspace for more
+ * information.)
+ */
+AVRational ycc_to_rgb_matrix[9]; /* before PQ linearization */
+AVRational ycc_to_rgb_offset[3]; /* input offset of neutral value */
+AVRational rgb_to_lms_matrix[9]; /* after PQ linearization */
+
+/**
+ * Extra signal metadata (see Dolby patents for more info).
+ */
+uint16_t signal_eotf;
+uint16_t signal_eotf_param0;
+u

[FFmpeg-devel] [PATCH v5 5/6] fate: Limit Dolby Vision RPU test frame count

2021-12-12 Thread Niklas Haas
From: Niklas Haas 

To avoid the ref for this growing to a very large size when attaching
the parsed RPU side data. Since this sample does not have any dynamic
metadata, two frames will serve just as well as 100.

Signed-off-by: Niklas Haas 
---
 tests/fate/hevc.mak|   2 +-
 tests/ref/fate/hevc-dv-rpu | 499 -
 2 files changed, 1 insertion(+), 500 deletions(-)

diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak
index abe4264662..95dcf5bfc5 100644
--- a/tests/fate/hevc.mak
+++ b/tests/fate/hevc.mak
@@ -273,7 +273,7 @@ FATE_HEVC_FFPROBE-$(call DEMDEC, HEVC, HEVC) += 
fate-hevc-monochrome-crop
 fate-hevc-hdr10-plus-metadata: CMD = probeframes -show_entries 
frame=side_data_list $(TARGET_SAMPLES)/hevc/hdr10_plus_h265_sample.hevc
 FATE_HEVC_FFPROBE-$(call DEMDEC, HEVC, HEVC) += fate-hevc-hdr10-plus-metadata
 
-fate-hevc-dv-rpu: CMD = probeframes -show_entries frame=side_data_list 
-select_streams 0 $(TARGET_SAMPLES)/hevc/dv84.mov
+fate-hevc-dv-rpu: CMD = probeframes -show_entries frame=side_data_list 
-select_streams 0 -read_intervals "%+\#2" $(TARGET_SAMPLES)/hevc/dv84.mov
 FATE_HEVC_FFPROBE-$(call DEMDEC, HEVC, HEVC) += fate-hevc-dv-rpu
 
 fate-hevc-two-first-slice: CMD = threads=2 framemd5 -i 
$(TARGET_SAMPLES)/hevc/two_first_slice.mp4 -sws_flags bitexact -t 00:02.00 -an
diff --git a/tests/ref/fate/hevc-dv-rpu b/tests/ref/fate/hevc-dv-rpu
index 37ad9ffec2..416d9c51a6 100644
--- a/tests/ref/fate/hevc-dv-rpu
+++ b/tests/ref/fate/hevc-dv-rpu
@@ -11,502 +11,3 @@ side_data_type=Dolby Vision RPU Data
 side_data_type=Dolby Vision RPU Data
 [/SIDE_DATA]
 [/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=H.26[45] User Data Unregistered SEI message
-[/SIDE_DATA]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]
-[SIDE_DATA]
-side_data_type=Dolby Vision RPU Data
-[/SIDE_DATA]
-[/FRAME]
-[FRAME]

[FFmpeg-devel] [PATCH v5 6/6] lavc/hevcdec: Parse DOVI RPU NALs

2021-12-12 Thread Niklas Haas
From: Niklas Haas 

And expose the parsed values as frame side data. Update FATE results to
match.

It's worth documenting that this relies on the dovi configuration record
being present on the first AVPacket fed to the decoder, which in
practice is the case if if the API user has called something like
av_format_inject_global_side_data, which is unfortunately not the
default.

This commit is not the time and place to change that behavior, though.

Signed-off-by: Niklas Haas 
---
 configure  |   2 +-
 libavcodec/hevcdec.c   |  62 --
 libavcodec/hevcdec.h   |   3 +
 tests/ref/fate/hevc-dv-rpu | 224 +
 4 files changed, 282 insertions(+), 9 deletions(-)

diff --git a/configure b/configure
index b8c9c5d2ae..d4336d20f5 100755
--- a/configure
+++ b/configure
@@ -2813,7 +2813,7 @@ h264_decoder_suggest="error_resilience"
 hap_decoder_select="snappy texturedsp"
 hap_encoder_deps="libsnappy"
 hap_encoder_select="texturedspenc"
-hevc_decoder_select="atsc_a53 bswapdsp cabac golomb hevcparse videodsp"
+hevc_decoder_select="atsc_a53 bswapdsp cabac dovi_rpu golomb hevcparse 
videodsp"
 huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
 huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp"
 hymt_decoder_select="huffyuv_decoder"
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 46d9edf8eb..82410ae5cc 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -2723,6 +2723,7 @@ error:
 static int set_side_data(HEVCContext *s)
 {
 AVFrame *out = s->ref->frame;
+int ret;
 
 if (s->sei.frame_packing.present &&
 s->sei.frame_packing.arrangement_type >= 3 &&
@@ -2967,6 +2968,9 @@ static int set_side_data(HEVCContext *s)
 s->rpu_buf = NULL;
 }
 
+if ((ret = ff_dovi_attach_side_data(&s->dovi_ctx, out)) < 0)
+return ret;
+
 return 0;
 }
 
@@ -3298,16 +3302,23 @@ static int decode_nal_units(HEVCContext *s, const 
uint8_t *buf, int length)
 if (s->pkt.nb_nals > 1 && s->pkt.nals[s->pkt.nb_nals - 1].type == 
HEVC_NAL_UNSPEC62 &&
 s->pkt.nals[s->pkt.nb_nals - 1].size > 2 && 
!s->pkt.nals[s->pkt.nb_nals - 1].nuh_layer_id
 && !s->pkt.nals[s->pkt.nb_nals - 1].temporal_id) {
+H2645NAL *nal = &s->pkt.nals[s->pkt.nb_nals - 1];
 if (s->rpu_buf) {
 av_buffer_unref(&s->rpu_buf);
 av_log(s->avctx, AV_LOG_WARNING, "Multiple Dolby Vision RPUs found 
in one AU. Skipping previous.\n");
 }
 
-s->rpu_buf = av_buffer_alloc(s->pkt.nals[s->pkt.nb_nals - 1].raw_size 
- 2);
+s->rpu_buf = av_buffer_alloc(nal->raw_size - 2);
 if (!s->rpu_buf)
 return AVERROR(ENOMEM);
+memcpy(s->rpu_buf->data, nal->raw_data + 2, nal->raw_size - 2);
 
-memcpy(s->rpu_buf->data, s->pkt.nals[s->pkt.nb_nals - 1].raw_data + 2, 
s->pkt.nals[s->pkt.nb_nals - 1].raw_size - 2);
+ret = ff_dovi_rpu_parse(&s->dovi_ctx, nal->data + 2, nal->size - 2);
+if (ret < 0) {
+av_buffer_unref(&s->rpu_buf);
+av_log(s->avctx, AV_LOG_WARNING, "Error parsing DOVI NAL unit.\n");
+/* ignore */
+}
 }
 
 /* decode the NAL units */
@@ -3440,8 +3451,8 @@ static int hevc_decode_frame(AVCodecContext *avctx, void 
*data, int *got_output,
  AVPacket *avpkt)
 {
 int ret;
-size_t new_extradata_size;
-uint8_t *new_extradata;
+uint8_t *sd;
+size_t sd_size;
 HEVCContext *s = avctx->priv_data;
 
 if (!avpkt->size) {
@@ -3453,14 +3464,37 @@ static int hevc_decode_frame(AVCodecContext *avctx, 
void *data, int *got_output,
 return 0;
 }
 
-new_extradata = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA,
-&new_extradata_size);
-if (new_extradata && new_extradata_size > 0) {
-ret = hevc_decode_extradata(s, new_extradata, new_extradata_size, 0);
+sd = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &sd_size);
+if (sd && sd_size > 0) {
+ret = hevc_decode_extradata(s, sd, sd_size, 0);
 if (ret < 0)
 return ret;
 }
 
+sd = av_packet_get_side_data(avpkt, AV_PKT_DATA_DOVI_CONF, &sd_size);
+if (sd && sd_size > 0) {
+if (s->dovi_cfg) {
+/* Reuse existing buffer */
+if ((ret = av_buffer_make_writable(&s->dovi_cfg)) < 0)
+return ret;
+} else {
+/* Allocate new buffer */
+AVDOVIDecoderConfigurationRecord *cfg;
+size_t cfg_size;
+cfg = av_dovi_alloc(&cfg_size);
+if (!cfg)
+return AVERROR(ENOMEM);
+s->dovi_cfg = av_buffer_create((uint8_t *) cfg, cfg_size, NULL, 
NULL, 0);
+if (!s->dovi_cfg) {
+av_free(cfg);
+return AVERROR(ENOMEM);
+}
+}
+
+av_assert0(sd_size >= s->dovi_cfg->size);
+memcpy(s->d

Re: [FFmpeg-devel] [PATCH v2] lavfi/drawtext: Add localtime_ms for millisecond precision

2021-12-12 Thread Thilo Borgmann



On 11 Dec 2021, at 23:17, Andreas Rheinhardt wrote:


Thilo Borgmann:



On 10 Dec 2021, at 17:46, Michael Niedermayer wrote:


On Fri, Dec 10, 2021 at 12:36:21PM +0100, Thilo Borgmann wrote:



On 10 Dec 2021, at 3:47, zhilizhao(赵志立) wrote:

On Dec 10, 2021, at 3:11 AM, Thilo Borgmann 


wrote:

Hi,

add %{localtime_ms}, %{gmtime_ms} functions to the drawtext 
filter.
Same as %{localtime}/%{gmtime} but with additional millisecond 
part.


sorry for delay, second version including review remarks:

-get timing once
-also add gmtime_ms instead of just localtime_ms




+    if (tag == 'M' || tag == 'm') {
+    char ms[5] = {0};
+    int64_t dnow = (unow - ((int64_t)now) * 100) 
/ 1000;

+    snprintf(ms, 5, ".%03d", (int)dnow);
+    av_bprint_append_data(bp, ms, 4);
+    }




How about

    av_bprintf(&bp, ".%03d", (int)(unow % 100) / 1000);


Makes way too much sense. I need holidays…

Attached v3.

Thanks!
-Thilo



 doc/filters.texi  |    8 
 libavfilter/vf_drawtext.c |   12 ++--
 2 files changed, 18 insertions(+), 2 deletions(-)
87d34e4106b829d42c5e57c847c28bed08bf3a81 
v3-0001-lavfi-drawtext-Add-localtime_ms-for-millisecond-p.patch
From fd34d1434e2243a881c24f6db4cc0db92289f4bb Mon Sep 17 00:00:00 
2001

From: Thilo Borgmann 
Date: Fri, 10 Dec 2021 12:34:23 +0100
Subject: [PATCH v3] lavfi/drawtext: Add localtime_ms for 
millisecond

precision


Iam missining something here as it doesnt build

AR    libavdevice/libavdevice.a
CC    libavfilter/vf_drawtext.o
libavfilter/vf_drawtext.c: In function ‘func_strftime’:
libavfilter/vf_drawtext.c:1052:12: error: implicit declaration of
function ‘av_gettime’; did you mean ‘av_get_token’?
[-Werror=implicit-function-declaration]
 unow = av_gettime();
    ^~
    av_get_token
libavfilter/vf_drawtext.c:1061:20: warning: passing argument 1 of
‘av_bprintf’ from incompatible pointer type
[-Wincompatible-pointer-types]
 av_bprintf(&bp, ".%03d", (int)(unow % 100) / 
1000);

    ^
In file included from libavfilter/vf_drawtext.c:47:0:
./libavutil/bprint.h:127:6: note: expected ‘AVBPrint * {aka struct
AVBPrint *}’ but argument is of type ‘AVBPrint ** {aka struct 
AVBPrint

**}’
 void av_bprintf(AVBPrint *buf, const char *fmt, ...)
av_printf_format(2, 3);
  ^~
cc1: some warnings being treated as errors
ffbuild/common.mak:70: recipe for target 'libavfilter/vf_drawtext.o'
failed
make: *** [libavfilter/vf_drawtext.o] Error 1


Works for me on OSX.

av_gettime() is in lavu/time.c which gets included via
lavu/time_internal.h….



av_gettime() is public and resides in lavu/time.h, not
lavu/time_internal.h; the latter does not include the former in any 
way.


Ups,  was it…



But compat/os2threads.h and compat/w32pthreads.h include lavu/time.h.
Maybe you have it from the former? It doesn't work here (Ubuntu 21.10)
either.


Retested and I got no clue how this appeared to be working for me 
yesterday - sorry.


v4 attached, including lavu/time.h and fixed pointer type warning.

Thanks!
-ThiloFrom 9b70c93c754fa4cd1b55fd3967910727f685a6b6 Mon Sep 17 00:00:00 2001
From: Thilo Borgmann 
Date: Sun, 12 Dec 2021 16:17:03 +0100
Subject: [PATCH v4] lavfi/drawtext: Add localtime_ms for millisecond precision

Suggested-By: ffm...@fb.com
---
 doc/filters.texi  |  8 
 libavfilter/vf_drawtext.c | 13 +++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 78faf76..db75632 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -10949,10 +10949,18 @@ It can be used to add padding with zeros from the 
left.
 The time at which the filter is running, expressed in UTC.
 It can accept an argument: a strftime() format string.
 
+@item gmtime_ms
+Same as @code{gmtime} but with millisecond precision.
+It can accept an argument: a strftime() format string.
+
 @item localtime
 The time at which the filter is running, expressed in the local time zone.
 It can accept an argument: a strftime() format string.
 
+@item localtime_ms
+Same as @code{localtime} but with millisecond precision.
+It can accept an argument: a strftime() format string.
+
 @item metadata
 Frame metadata. Takes one or two arguments.
 
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index 382d589..d047a8c 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -51,6 +51,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/random_seed.h"
 #include "libavutil/parseutils.h"
+#include "libavutil/time.h"
 #include "libavutil/timecode.h"
 #include "libavutil/time_internal.h"
 #include "libavutil/tree.h"
@@ -1045,15 +1046,21 @@ static int func_strftime(AVFilterContext *ctx, AVBPrint 
*bp,
  char *fct, unsigned argc, char **argv, int tag)
 {
 const char *fmt = argc ? argv[0] : "%Y-%m-%d %H:%M:%S";
+int64_t unow;
 time_t now;
 struct tm tm;
 
-time(&now);
-if (tag == 'L')
+

Re: [FFmpeg-devel] Politics

2021-12-12 Thread Daniel Cantarín

> yesterday, it happened for the 4th and 5th times that another developer
> called my patchset a “hack”.

Hope it wasn't me. If I did, I'm sorry, didn't wanted to imply bad code
or lack of skills, or anything: I was trying to understand if there's some
way to actually unblock your patchset. And the quicker the way, the
better.


> subtitle_pts

LOL... that's some elegant answer.

I have my own doubts about subtitle_pts, but that's exactly why I
wouldn't call it "hack": because I don't fully grasp it yet.
I've read some devs arguments (not all) against it, but it also
wasn't clear for me back then why the strong backlash. Some
seemed just conservative and/or idealists, others didn't seem to
value live-streaming as a first class citizen between use cases.
Can't tell if they were right or wrong, or myself at reading them.
But mixed feelings for sure.

Howerver, *if* subtitle_pts is truly the last point against softworkz
patchset, then it's very close to see the light, and that's exciting.

I have a strong bias towards softworkz code, because I value
non-breaking newer use cases over quality of design. This is what
I see:
  - The problems softworkz mentions with live subtitles are VERY real.
  - I can't defend subtitle_pts, at least yet, because I don't get it.
  - If it solves live-streaming subtitles problems, and doesn't break
    anything else, it's fine by me.

But if there's some consensus between established community
figures against that property and that blocks the release, well...
removing the property sounds like the quickest path. Will test it
during week.


Now, the question remains: are we sure subtitle_pts is the last
barrier here?


___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] Politics

2021-12-12 Thread Nicolas George
Daniel Cantarín (12021-12-12):
> Howerver, *if* subtitle_pts is truly the last point against softworkz
> patchset, then it's very close to see the light, and that's exciting.

Far from it. I have pointed the core flaws with the design a few times,
but having been received with rudeness, I did not bother insisting. This
patch series is nowhere near anything that can be accepted.

Regards,

-- 
  Nicolas George


signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/3] avcodec/speedhq: Replace always-true check by assert

2021-12-12 Thread Andreas Rheinhardt
Should fix Coverity tickets #1473572 and #1473504.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/speedhq.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavcodec/speedhq.c b/libavcodec/speedhq.c
index 91ba80ebd3..743dacc6ce 100644
--- a/libavcodec/speedhq.c
+++ b/libavcodec/speedhq.c
@@ -295,7 +295,8 @@ static int decode_speedhq_border(const SHQContext *s, 
GetBitContext *gb, AVFrame
 if (s->subsampling == SHQ_SUBSAMPLING_420) {
 dest_cb = frame->data[1] + frame->linesize[1] * (y/2 + 
field_number) + x / 2;
 dest_cr = frame->data[2] + frame->linesize[2] * (y/2 + 
field_number) + x / 2;
-} else if (s->subsampling == SHQ_SUBSAMPLING_422) {
+} else {
+av_assert2(s->subsampling == SHQ_SUBSAMPLING_422);
 dest_cb = frame->data[1] + frame->linesize[1] * (y + field_number) 
+ x / 2;
 dest_cr = frame->data[2] + frame->linesize[2] * (y + field_number) 
+ x / 2;
 }
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/3] avformat/moflex: Free AVPackets via av_packet_free() on error

2021-12-12 Thread Andreas Rheinhardt
(This is not a leak as long as av_free() completely frees blank
packets.)

Signed-off-by: Andreas Rheinhardt 
---
 libavformat/moflex.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavformat/moflex.c b/libavformat/moflex.c
index 234b0fb06e..67adebe5e0 100644
--- a/libavformat/moflex.c
+++ b/libavformat/moflex.c
@@ -383,4 +383,5 @@ const AVInputFormat ff_moflex_demuxer = {
 .read_close = moflex_read_close,
 .extensions = "moflex",
 .flags  = AVFMT_GENERIC_INDEX,
+.flags_internal = FF_FMT_INIT_CLEANUP,
 };
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/3] avformat/moflex: Don't use uninitialized timebase for data stream

2021-12-12 Thread Andreas Rheinhardt
Signed-off-by: Andreas Rheinhardt 
---
 libavformat/moflex.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/libavformat/moflex.c b/libavformat/moflex.c
index 67adebe5e0..1d342417f7 100644
--- a/libavformat/moflex.c
+++ b/libavformat/moflex.c
@@ -172,7 +172,7 @@ static int moflex_read_sync(AVFormatContext *s)
 unsigned type, ssize, codec_id = 0;
 unsigned codec_type, width = 0, height = 0, sample_rate = 0, channels 
= 0;
 int stream_index = -1;
-AVRational fps;
+AVRational tb = av_make_q(0, 1);
 
 read_var_byte(s, &type);
 read_var_byte(s, &ssize);
@@ -195,6 +195,7 @@ static int moflex_read_sync(AVFormatContext *s)
 return AVERROR_PATCHWELCOME;
 }
 sample_rate = avio_rb24(pb) + 1;
+tb = av_make_q(1, sample_rate);
 channels = avio_r8(pb) + 1;
 break;
 case 1:
@@ -208,8 +209,8 @@ static int moflex_read_sync(AVFormatContext *s)
 av_log(s, AV_LOG_ERROR, "Unsupported video codec: %d\n", 
codec_id);
 return AVERROR_PATCHWELCOME;
 }
-fps.num = avio_rb16(pb);
-fps.den = avio_rb16(pb);
+tb.den = avio_rb16(pb);
+tb.num = avio_rb16(pb);
 width = avio_rb16(pb);
 height = avio_rb16(pb);
 avio_skip(pb, type == 3 ? 3 : 2);
@@ -237,10 +238,8 @@ static int moflex_read_sync(AVFormatContext *s)
 if (!st->priv_data)
 return AVERROR(ENOMEM);
 
-if (sample_rate)
-avpriv_set_pts_info(st, 63, 1, sample_rate);
-else
-avpriv_set_pts_info(st, 63, fps.den, fps.num);
+if (tb.num)
+avpriv_set_pts_info(st, 63, tb.num, tb.den);
 }
 }
 
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v6] lavc/hevcdec: Parse DOVI RPU NALs

2021-12-12 Thread Niklas Haas
From: Niklas Haas 

Oops. The previous version of this patch forgot to actually forward the
dovi configuration record to the DOVIContext.

---
And expose the parsed values as frame side data. Update FATE results to
match.

It's worth documenting that this relies on the dovi configuration record
being present on the first AVPacket fed to the decoder, which in
practice is the case if if the API user has called something like
av_format_inject_global_side_data, which is unfortunately not the
default.

This commit is not the time and place to change that behavior, though.

Signed-off-by: Niklas Haas 
---
 configure  |   2 +-
 libavcodec/hevcdec.c   |  63 +--
 libavcodec/hevcdec.h   |   3 +
 tests/ref/fate/hevc-dv-rpu | 224 +
 4 files changed, 283 insertions(+), 9 deletions(-)

diff --git a/configure b/configure
index b8c9c5d2ae..d4336d20f5 100755
--- a/configure
+++ b/configure
@@ -2813,7 +2813,7 @@ h264_decoder_suggest="error_resilience"
 hap_decoder_select="snappy texturedsp"
 hap_encoder_deps="libsnappy"
 hap_encoder_select="texturedspenc"
-hevc_decoder_select="atsc_a53 bswapdsp cabac golomb hevcparse videodsp"
+hevc_decoder_select="atsc_a53 bswapdsp cabac dovi_rpu golomb hevcparse 
videodsp"
 huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
 huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp"
 hymt_decoder_select="huffyuv_decoder"
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 46d9edf8eb..9ca2fa224d 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -2723,6 +2723,7 @@ error:
 static int set_side_data(HEVCContext *s)
 {
 AVFrame *out = s->ref->frame;
+int ret;
 
 if (s->sei.frame_packing.present &&
 s->sei.frame_packing.arrangement_type >= 3 &&
@@ -2967,6 +2968,9 @@ static int set_side_data(HEVCContext *s)
 s->rpu_buf = NULL;
 }
 
+if ((ret = ff_dovi_attach_side_data(&s->dovi_ctx, out)) < 0)
+return ret;
+
 return 0;
 }
 
@@ -3298,16 +3302,24 @@ static int decode_nal_units(HEVCContext *s, const 
uint8_t *buf, int length)
 if (s->pkt.nb_nals > 1 && s->pkt.nals[s->pkt.nb_nals - 1].type == 
HEVC_NAL_UNSPEC62 &&
 s->pkt.nals[s->pkt.nb_nals - 1].size > 2 && 
!s->pkt.nals[s->pkt.nb_nals - 1].nuh_layer_id
 && !s->pkt.nals[s->pkt.nb_nals - 1].temporal_id) {
+H2645NAL *nal = &s->pkt.nals[s->pkt.nb_nals - 1];
 if (s->rpu_buf) {
 av_buffer_unref(&s->rpu_buf);
 av_log(s->avctx, AV_LOG_WARNING, "Multiple Dolby Vision RPUs found 
in one AU. Skipping previous.\n");
 }
 
-s->rpu_buf = av_buffer_alloc(s->pkt.nals[s->pkt.nb_nals - 1].raw_size 
- 2);
+s->rpu_buf = av_buffer_alloc(nal->raw_size - 2);
 if (!s->rpu_buf)
 return AVERROR(ENOMEM);
+memcpy(s->rpu_buf->data, nal->raw_data + 2, nal->raw_size - 2);
 
-memcpy(s->rpu_buf->data, s->pkt.nals[s->pkt.nb_nals - 1].raw_data + 2, 
s->pkt.nals[s->pkt.nb_nals - 1].raw_size - 2);
+s->dovi_ctx.config = s->dovi_cfg ? (void *) s->dovi_cfg->data : NULL;
+ret = ff_dovi_rpu_parse(&s->dovi_ctx, nal->data + 2, nal->size - 2);
+if (ret < 0) {
+av_buffer_unref(&s->rpu_buf);
+av_log(s->avctx, AV_LOG_WARNING, "Error parsing DOVI NAL unit.\n");
+/* ignore */
+}
 }
 
 /* decode the NAL units */
@@ -3440,8 +3452,8 @@ static int hevc_decode_frame(AVCodecContext *avctx, void 
*data, int *got_output,
  AVPacket *avpkt)
 {
 int ret;
-size_t new_extradata_size;
-uint8_t *new_extradata;
+uint8_t *sd;
+size_t sd_size;
 HEVCContext *s = avctx->priv_data;
 
 if (!avpkt->size) {
@@ -3453,14 +3465,37 @@ static int hevc_decode_frame(AVCodecContext *avctx, 
void *data, int *got_output,
 return 0;
 }
 
-new_extradata = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA,
-&new_extradata_size);
-if (new_extradata && new_extradata_size > 0) {
-ret = hevc_decode_extradata(s, new_extradata, new_extradata_size, 0);
+sd = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &sd_size);
+if (sd && sd_size > 0) {
+ret = hevc_decode_extradata(s, sd, sd_size, 0);
 if (ret < 0)
 return ret;
 }
 
+sd = av_packet_get_side_data(avpkt, AV_PKT_DATA_DOVI_CONF, &sd_size);
+if (sd && sd_size > 0) {
+if (s->dovi_cfg) {
+/* Reuse existing buffer */
+if ((ret = av_buffer_make_writable(&s->dovi_cfg)) < 0)
+return ret;
+} else {
+/* Allocate new buffer */
+AVDOVIDecoderConfigurationRecord *cfg;
+size_t cfg_size;
+cfg = av_dovi_alloc(&cfg_size);
+if (!cfg)
+return AVERROR(ENOMEM);
+s->dovi_cfg = av_buffer_create((uint8_t *) cfg, cfg_size, NULL, 
NULL, 0);
+

Re: [FFmpeg-devel] Politics

2021-12-12 Thread Daniel Cantarín

> Far from it. I have pointed the core flaws with the design a few times,
> but having been received with rudeness, I did not bother insisting. This
> patch series is nowhere near anything that can be accepted.
>

This quickly went from exciting to depressing. :(

I guess some recent-times archeology will also be needed in order to
discuss this, as the patchset is 23 versions now and has 21 parts. I'll 
give

it some time starting from tomorrow. If you Mr. George happen to
remember where to look at, please kindly point me in the right direction,
in order to avoid reading the full patchset history of messages. Of
course, I'll read the whole thing otherwise, no problem.

Also, from your last comment, I feel you're kinda pissed off with this
patchset (or with softworkz, obviously). Yet, I've seen several answers
from you years ago (like, about a decade now) where you were actually
involved in the whole "subtitles in lavfi" thing. I mean: I've searched for
this several times from years by now, and most of the time you were
involved in the debates. I would say then this is something you care
and have some knowledge about.

If I were doing all the work softworkz is doing, I'll be pissed off with 
the

backslash, no doubt about it. And if I were dealing with this use case for
the last 10 years and people keep not doing what I'm convinced should
be done, I'll be very pissed off too. So, this is kinda understandable.
But I find it to be a pity that this use cases get blocked by people just
not getting along. There has to be some way around it.

Isn't there anything that can be done to combine both your knowledge
and softworkz's will to tackle the issue? Perhaps laying down some base
design that should be honored, while other people like softworkz or I
could just progressively implement it?

I bet that if softworkz code actually do the job, then it can't be THAT far
away from an acceptable design, and thus that distance should be
workable.


___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] Politics

2021-12-12 Thread Nicolas George
Daniel Cantarín (12021-12-12):
> This quickly went from exciting to depressing. :(

I find this whole situation depressing too.

> I guess some recent-times archeology will also be needed in order to
> discuss this, as the patchset is 23 versions now and has 21 parts. I'll give
> it some time starting from tomorrow. If you Mr. George happen to
> remember where to look at, please kindly point me in the right direction,
> in order to avoid reading the full patchset history of messages. Of
> course, I'll read the whole thing otherwise, no problem.
> 
> Also, from your last comment, I feel you're kinda pissed off with this
> patchset (or with softworkz, obviously). Yet, I've seen several answers
> from you years ago (like, about a decade now) where you were actually
> involved in the whole "subtitles in lavfi" thing. I mean: I've searched for
> this several times from years by now, and most of the time you were
> involved in the debates. I would say then this is something you care
> and have some knowledge about.
> 
> If I were doing all the work softworkz is doing, I'll be pissed off with the
> backslash, no doubt about it. And if I were dealing with this use case for
> the last 10 years and people keep not doing what I'm convinced should
> be done, I'll be very pissed off too. So, this is kinda understandable.
> But I find it to be a pity that this use cases get blocked by people just
> not getting along. There has to be some way around it.
> 
> Isn't there anything that can be done to combine both your knowledge
> and softworkz's will to tackle the issue? Perhaps laying down some base
> design that should be honored, while other people like softworkz or I
> could just progressively implement it?

I have told Soft Works they were going at it the wrong way when they
posted the very first patch. At the time, I was working on refactoring
that needs to happen before libavfilter can be extended with a third
media type. I gave Soft Works advice on how to help for tasks that are
necessary to implement subtitles the right way. Instead of listening to
my expertise, they persisted. If they wasted six months of effort and
counting, they can blame only themselves.

I still intend to work on this, I have clear plans on how to go forward,
but right now I find the whole mess too depressing to even consider
investing time in it.

> I bet that if softworkz code actually do the job, then it can't be THAT far
> away from an acceptable design, and thus that distance should be
> workable.

Unfortunately, it is that far. They designed and tested their patches
with file inputs and simple grpahs. We need libavfilter to work with
complex graphs where timestamps are changed, frames arrive in the wrong
order on filters, etc. More importantly, they completely bypassed the
format negotiation system, letting the responsibility fall onto users
and making it impossible to have the many necessary utility filters
without unacceptable code duplication.

Regards,

-- 
  Nicolas George


signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] Politics

2021-12-12 Thread Ronald S. Bultje
Hi,

On Sun, Dec 12, 2021 at 1:21 PM Nicolas George  wrote:

> I have told Soft Works they were going at it the wrong way when they
> posted the very first patch
>

There is no one magic correct way to do it. People work on things
differently, and that's OK.

Now, if there's issues with his approach, that's fine. But your argument
here that you would've done it differently is not fair as a reason to
reject the patch set.

(No opinion on the patch set itself.)

Ronald
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 000/279] New channel layout API

2021-12-12 Thread Anton Khirnov
Quoting Marton Balint (2021-12-10 01:04:57)
> 
> 
> On Thu, 9 Dec 2021, Anton Khirnov wrote:
> 
> > Quoting Nicolas George (2021-12-09 11:31:54)
> >> Anton Khirnov (12021-12-09):
> >>> I disagree. Technical limitations that were overcome 10 years ago should
> >>> not guide new API design.
> >>
> >> In the case of amerge, it was not a technical limitation, merging
> >> several streams into one so that they can be handled by single-stream
> >> filters is 100% part of the design.
> >
> > I fail to see how that is an advantage. You can just as well create
> > multiple instances of those single-stream filters instead of adding
> > hacks into core APIs.
> >
> >> I suspect devices that capture several independent channels are
> >> designed that way intentionally too, possibly to reduce the risk of
> >> desynchronization.
> >
> > "possibly" is not a strong enough argument. I'd like to hear at least
> > one clearly-defined use case that cannot just as well be handled by
> > using multiple streams.
> 
> I recently worked on the MXF demuxer to recognize channel designations in 
> MXF files, and in MXF the designation and grouping of the channels is 
> completely separate from the track those channels are muxed in.
> 
> So if you have e.g. english stereo sound, and german stereo sound you 
> can mux it
> - as a single 4 channel track
> - as two 2 channel tracks
> - as four 1 channel tracks.
> Some MXF flavors use the multichannel single track approach, others the 
> mono-track-only approach. So the user may not be able to choose the 
> optimal muxed track assignment...
> 
> So ultimately, if you demux and decode a packet from a track, you will 
> have an AVFrame, which might contain a single sound group on its own 
> (optimal case), part of a sound group, or multiple sound groups.
> 
> To summerize, muxed tracks are not necessarily 1:1 mapping between sound 
> groups. And when processing/filtering audio, you typically want sound 
> groups, not tracks. And yes, it is very rare to have a soundgroup which 
> has channels with the same designation, but for a muxed track, it depends 
> on the format.
> 
> The goal of the end user is probably to be able to specify sound groups, 
> not select muxed tracks. Preferably a demuxer should provide which channel 
> is part of which sound group, and you should be able to use a filter or a 
> combination of filters select a specific sound group. E.g. amerge all 
> tracks, then keep only the channels from all the merged channels which are 
> part of a specific sound group.

So what are you proposing? In my view, such higher level information
should live at a higher level - e.g. in the side data. You can then
have a filter that reads this side data and gets you the group you want.

-- 
Anton Khirnov
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] Politics

2021-12-12 Thread Nicolas George
Ronald S. Bultje (12021-12-12):
> There is no one magic correct way to do it. People work on things
> differently, and that's OK.

There are wrong ways to do it.

> Now, if there's issues with his approach, that's fine.

There are many issues, I pointed them at the time and was rudely
ignored.

-- 
  Nicolas George


signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 000/279] New channel layout API

2021-12-12 Thread Nicolas George
Anton Khirnov (12021-12-12):
> So what are you proposing? In my view, such higher level information
> should live at a higher level - e.g. in the side data. You can then
> have a filter that reads this side data and gets you the group you want.

So, what is the point of this new API if anything of value needs to be
done with side data and yet another API?

It seems to me you are indulging in a sunken-costs fallacy: you wrote
this API and all the code but you neglected to poll your fellow
developers for needs that it should cover, and as a result got something
much too limited. But now, you are trying to force it anyway.

What I propose is:

(1) define the needs properly;

(2) redesign the API;

(3) see how much code can still be used.

The needs as far as I can see, please add to the list:

A. Allow the same channel to appear several time in the layout. Hendrik
agreed that it was useful for some kind of USER_SPECIFIED or UNKNOWN
channel specification, but allowing for any channel specification is
actually simpler.

It is not limited to just having the same channel in the list, it
requires API and user interface support: the API must be able to tell
the user "this USER_SPECIFIED channel is the oboe, this USER_SPECIFIED
is the piano", and the user must be able to tell the API "the second
USER_SPECIFIED channel" or "the USER_SPECIFIED channel relating to the
piano".

B. Possibly, I do not personally insist on it like A: groups of
channels.

-- 
  Nicolas George


signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] Politics

2021-12-12 Thread Soft Works



> -Original Message-
> From: ffmpeg-devel  On Behalf Of Soft Works
> Sent: Sunday, December 12, 2021 7:16 AM
> To: FFmpeg development discussions and patches 
> Subject: [FFmpeg-devel] Politics

Hi,

let me clarify a bit on the status and the motivation.

I have started this development, because I needed the functionality.
The decision - which retrospectively turned out to be stupid
and non-rewarding - to do it in a way that it could also be
merged into official ffmpeg has always been secondary.

Nonetheless I have followed all suggestions (which were specific 
and constructive) to match everybody's expectation.

At this point the development cycle for thy has come to an 
end. I have achieved all the goals I had and all things 
are working as expected without regressions in existing 
functionality.

I find it offending when some developers which have followed my
patchset over time and have even given earlier advice are
approaching me now at the end and at the 23rd versions 
with ideas that would require going back and starting over
to a large part or changing things that would endanger 
stability and require an enormous amount of work to get
to the same degree of stability again.
My response to that is: Sorry - you could have come earlier,
but the window for such changes has closed long ago.

(Nicolas, no need to respond, it's not about you)


So what's the status?

My patchset is an offering to ffmpeg - nothing more, nothing
less. At this point, I am ready to do:

- Small corrections or adjustments to satisfy requirements
  to get merged
- Fixing all bugs and issues that get reported
- Future updates, improvements and adding additional features
  and filter after merge

As a benefit, this brings features and functionality to ffmpeg 
that have been lacking and highly requested for almost a decade.

It's rather unlikely that a comparable submission will be made
by anybody else in the next few years, even less likely from 
those who haven't managed to get going in that area for a long
time.

I understand that some developers are dissatisfied with the
existence of the subtitle_pts field in the AVFrame struct.
But it is a requirement for my patchset to work and I will
not change it. Not because I don't want, but because it doesn't 
work without it. 
Not that I hadn't tried, but it remains the grain of salt 
that can't be avoided.


So I think it burns down to the following:

Everybody will need build his own opinion and decision 
about which of these things will outweigh the other:
An undesired field in the AVFrame struct vs. a whole range of
new functionality added to ffmpeg.

(of course in addition to all other decision criteria every
body will find important to consider).


Maybe it's possible to put this up for a vote?

If there's a majority against it, then it will be fine for
me. It would just be great to find out better sooner than 
later, because then I could stop wasting my time on this.

Kind regards,
softworkz




___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] Politics

2021-12-12 Thread Paul B Mahol
On Sun, Dec 12, 2021 at 8:42 PM Nicolas George  wrote:

> Ronald S. Bultje (12021-12-12):
> > There is no one magic correct way to do it. People work on things
> > differently, and that's OK.
>
> There are wrong ways to do it.


And there is only one path dictated by you.


>
> > Now, if there's issues with his approach, that's fine.
>
> There are many issues, I pointed them at the time and was rudely
> ignored.
>

Lie.


>
> --
>   Nicolas George
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2] lavfi/drawtext: Add localtime_ms for millisecond precision

2021-12-12 Thread Nicolas George
Thilo Borgman (12021-12-12):
> +@item localtime_ms
> +Same as @code{localtime} but with millisecond precision.
> +It can accept an argument: a strftime() format string.

What happens if the format string is something like '%H:%M:%S%z'? My
guess it it prints 21:12:42+0100.1234 instead of 21:12:42.1234+0100.

Regards,

-- 
  Nicolas George


signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] Politics

2021-12-12 Thread Soft Works



> -Original Message-
> From: ffmpeg-devel  On Behalf Of Paul B
> Mahol
> Sent: Sunday, December 12, 2021 9:09 PM
> To: FFmpeg development discussions and patches 
> Subject: Re: [FFmpeg-devel] Politics
> 
> On Sun, Dec 12, 2021 at 8:42 PM Nicolas George  wrote:
> 
> > Ronald S. Bultje (12021-12-12):
> > > There is no one magic correct way to do it. People work on things
> > > differently, and that's OK.
> >
> > There are wrong ways to do it.
> 
> 
> And there is only one path dictated by you.
> 
> 
> >
> > > Now, if there's issues with his approach, that's fine.
> >
> > There are many issues, I pointed them at the time and was rudely
> > ignored.
> >
> 
> Lie.

It's in fact a plain lie because he never mentioned any technical 
and specific reason for objection.

softworkz



___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v20 02/20] avutil/frame: Prepare AVFrame\n for subtitle handling

2021-12-12 Thread Michael Niedermayer
On Sun, Dec 12, 2021 at 02:21:42AM +, Soft Works wrote:
> 
> 
> > -Original Message-
> > From: ffmpeg-devel  On Behalf Of Daniel
> > Cantarín
> > Sent: Sunday, December 12, 2021 12:39 AM
> > To: ffmpeg-devel@ffmpeg.org
> > Subject: Re: [FFmpeg-devel] [PATCH v20 02/20] avutil/frame: Prepare 
> > AVFrame\n
> > for subtitle handling
> > 
> >  > One of the important points to understand is that - in case of subtitles,
> >  > the AVFrame IS NOT the subtitle event. The subtitle event is actually
> >  > a different and separate entity. (...)
> > 
> > 
> > Wouldn't it qualify then as a different abstraction?
> > 
> > I mean: instead of avframe.subtitle_property, perhaps something in the
> > lines of avframe.some_property_used_for_linked_abstractions, which in
> > turn lets you access some proper Subtitle abstraction instance.
> > 
> > That way, devs would not need to defend AVFrame, and Subtitle could
> > have whatever properties needed.
> > 
> > I see there's AVSubtitle, as you mention:
> > https://ffmpeg.org/doxygen/trunk/structAVSubtitle.html
> > 
> > Isn't it less socially problematic to just link an instance of AVSubtitle,
> > instead of adding a subtitle timing property to AVFrame?
> > IIUC, that AVSubtitle instance could live in filter context, and be linked
> > by the filter doing the heartbeat frames.
> > 
> > Please note I'm not saying the property is wrong, or even that I understand
> > the best way to deal with it, but that I recognize some social problem here.
> > Devs don't like that property, that's a fact. And technical or not, seems to
> > be a problem.
> > 
> >  > (...)
> >  > The chairs are obviously AVFrames. They need to be numbered monotonically
> >  > increasing - that's the frame.pts. without increasing numbering the
> >  > transport would get stuck. We are filling the chairs with copies
> >  > of the most recent subtitle event, so an AVSubtitle could be repeated
> >  > like for example 5 times. It's always the exact same AVSubtitle event
> >  > sitting in those 5 chairs. The subtitle event has always the same
> > start time
> >  > (subtitle_pts) but each frame has a different pts.
> > 
> > I can see AVSubtitle has a "start_display_time" property, as well as a
> > "pts" property "in AV_TIME_BASE":
> > 
> > https://ffmpeg.org/doxygen/trunk/structAVSubtitle.html#af7cc390bba4f9d6c32e39
> > 1ca59d117a2
> > 
> > Is it too much trouble to reuse that while persisting an AVSubtitle instance
> > in filter context? I guess it could even be used in decoder context.
> > 
> > I also see a quirky property in AVFrame: "best_effort_timestamp"
> > https://ffmpeg.org/doxygen/trunk/structAVFrame.html#a0943e85eb624c2191490862e
> > cecd319d
> > Perhaps adding there some added "various heuristics" that it claims to
> > have,
> > this time related to a linked AVSubtitle, so an extra property is not
> > needed?
> > 
> > 
> >  > (...)
> >  > Considering the relation between AVFrame and subtitle event as laid out
> >  > above, it should be apparent that there's no guarantee for a certain
> >  > kind of relation between the subtitle_pts and the frame's pts who
> >  > is carrying it. Such relation _can_ exist, but doesn't necessarily.
> >  > It can easily be possible that the frame pts is just increased by 1
> >  > on subsequent frames. The time_base may change from filter to filter
> >  > and can be oriented on the transport of the subtitle events which
> >  > might have nothing to do with the subtitle display time at all.
> > 
> > This confuses me.
> > I understand the difference between filler frame pts and subtitle pts.
> > That's ok.
> > But if transport timebase changes, I understand subtitle pts also changes.
> > 
> > I mean: "transport timebase" means "video timebase", and if subs are synced
> > to video, then that sync needs to be mantained. If subs are synced, then
> > their timing is never independant. And if they're not synced, then its
> > AVFrame
> > is independant from video frames, and thus does not need any extra prop.
> > 
> > Here's what I do right now with the filler frames. I'm talking about current
> > ffmpeg with no subs frames in lavfi, and real-time conversion from dvbsub
> > to WEBVTT using OCR. Quite dirty stuff what I do:
> >    - Change FPS to a low value, let's say 1.
> >    - Apply OCR to dvb sub, using vf_ocr.
> >    - Read the metadata downstream, and writting vtt to file or pipe output.
> > 
> > As there's no sub frame capability in lavfi, I can't use vtt encoder
> > downstream.
> > Therefore, the output is raw C string and file manipulation. And given
> > that I
> > set first the FPS to 1, I have 1 line per second, no matter the
> > timestamp of
> > either subs or video or filler frame. The point then is to check for
> > text diffs
> > instead of pts for detecting the frame nature. And I can even naively
> > just put
> > the frame's pts once per sec with the same text, and with empty lines when
> > there's no text, without caring about the frame nature (filler or not).
> 

Re: [FFmpeg-devel] [PATCH v20 02/20] avutil/frame: Prepare AVFrame\n for subtitle handling

2021-12-12 Thread Michael Niedermayer
On Sat, Dec 11, 2021 at 06:03:39PM +, Soft Works wrote:
> 
> 
> > -Original Message-
> > From: ffmpeg-devel  On Behalf Of Michael
> > Niedermayer
> > Sent: Saturday, December 11, 2021 6:21 PM
> > To: FFmpeg development discussions and patches 
> > Subject: Re: [FFmpeg-devel] [PATCH v20 02/20] avutil/frame: Prepare 
> > AVFrame\n
> > for subtitle handling
> > 
> > On Fri, Dec 10, 2021 at 03:02:32PM +, Soft Works wrote:
> > >
> > >
> > > > -Original Message-
> > > > From: ffmpeg-devel  On Behalf Of Daniel
> > > > Cantarín
> > > > Sent: Thursday, December 9, 2021 10:33 PM
> > > > To: ffmpeg-devel@ffmpeg.org
> > > > Subject: Re: [FFmpeg-devel] [PATCH v20 02/20] avutil/frame: Prepare
> > AVFrame\n
> > > > for subtitle handling
> > > >
> > > > Hi there.
> > > > This is my first message to this list, so please excuse me if I
> > > > unintendedly break some rule.
> > > >
> > > > I've read the debate between Soft Works and others, and would like to
> > > > add something to it.
> > > > I don't have a deep knowledge of the libs as other people here show. My
> > > > knowledge comes from working with live streams for some years now. And I
> > > > do understand the issue about modifying a public API for some use case
> > > > under debate: I believe it's a legit line of questioning to Soft Works
> > > > patches. However, I also feel we live streaming people are often let
> > > > aside as "border case" when it comes to ffmpeg/libav usage, and this
> > > > bias is present in many subtitles/captions debates.
> > > >
> > > > I work with Digital TV signals as input, and several different target
> > > > outputs more related to live streaming (mobiles, PCs, and so on). The
> > > > target location is Latin America, and thus I need subtitles/captions for
> > > > when we use english spoken audio (we speak mostly Spanish in LATAM). TV
> > > > people send you TV subtitle formats: scte-27, dvb subs, and so on. And
> > > > live streaming people uses other subtitles formats, mostly vtt and ttml.
> > > > I've found that CEA-608 captions are the most compatible caption format,
> > > > as it's understood natively by smart tvs and other devices, as well as
> > > > non-natively by any other device using popular player-side libraries.
> > > > So, I've made my own filter for generating CEA-608 captions for live
> > > > streams, using ffmpeg with the previously available OCR filter. Tried
> > > > VTT first, but it was problematic for live-streaming packaging, and with
> > > > CEA-608 I could just ignore that part of the process.
> > > >
> > > > While doing those filters, besides the whole deal of implementing the
> > > > conversion from text to CEA-608, I struggled with stuff like this:
> > > > - the sparseness of input subtitles, leading to OOM in servers and
> > > > stalled players.
> > > > - the "libavfilter doesn't take subtitle frames" and "it's all ASS
> > > > internally" issues.
> > > > - the "captions timings vs video frame timings vs audio timings"
> > > > problems (people talk a lot about syncing subs with video frames, but
> > > > rarely against actual dialogue audio).
> > > > - other (meta)data problems, like screen positioning or text encoding.
> > > >
> > > > This are all problems Soft Works seems to have faced as well.
> > > >
> > > > But of all the problems regarding live streaming subtitles with ffmpeg
> > > > (and there are LOTS of it), the most annoying problem is always this:
> > > > almost every time someone talked about implementing subtitles in filters
> > > > (in mail lists, in tickets, in other places like stack overflow,
> > > > etcetera), they always asumed input files. When the people specifically
> > > > talked about live streams, their peers always reasoned with files
> > > > mindset, and stated live streaming subtitles/captions as "border case".
> > > >
> > > > Let me be clear: this are not "border case" issues, but actually appear
> > > > in the most common use cases of live streaming transcoding. They all
> > > > appear *inmediatelly* when you try to use subtitles/captions in live
> > > > streams.
> > > >
> > > > I got here (I mean this thread) while looking for ways to fixing some
> > > > issues in my setup. I was reconsidering VTT/TTML generation instead of
> > > > CEA-608 (as rendering behave significantly different from device to
> > > > device), and thus I was about to generate subtitle type output from some
> > > > filter, was about to create my own standalone "heartbeat" filter to
> > > > normalize the sparseness, and so on and so on: again, all stuff Soft
> > > > Works seems to be handling as well. So I was quite happy to find someone
> > > > working on this again; last time I've seen it in ffmpeg's
> > > > mailing/patchwork
> > > > (https://patchwork.ffmpeg.org/project/ffmpeg/patch/20161102220934.26010-
> > 1-
> > > > u...@pkh.me)
> > > > the code there seemed to die, and I was already late to say anything
> > > > about it. However, reading the other devs reaction to Soft Works 

Re: [FFmpeg-devel] [PATCH v3 1/2] swscale/x86/output.asm: add x86-optimized planer gbr yuv2anyX functions

2021-12-12 Thread Mark Reid
On Wed, Nov 24, 2021 at 1:15 PM  wrote:

> From: Mark Reid 
>
> changes since v2:
>  * fixed label
> changes since v1:
>  * remove vex intruction on sse4 path
>  * some load/pack marcos use less intructions
>  * fixed some typos
>
> yuv2gbrp_full_X_4_512_c: 12757.6
> yuv2gbrp_full_X_4_512_sse2: 8946.6
> yuv2gbrp_full_X_4_512_sse4: 5138.6
> yuv2gbrp_full_X_4_512_avx2: 3889.6
> yuv2gbrap_full_X_4_512_c: 15368.6
> yuv2gbrap_full_X_4_512_sse2: 11916.1
> yuv2gbrap_full_X_4_512_sse4: 6294.6
> yuv2gbrap_full_X_4_512_avx2: 3477.1
> yuv2gbrp9be_full_X_4_512_c: 14381.6
> yuv2gbrp9be_full_X_4_512_sse2: 9139.1
> yuv2gbrp9be_full_X_4_512_sse4: 5150.1
> yuv2gbrp9be_full_X_4_512_avx2: 2834.6
> yuv2gbrp9le_full_X_4_512_c: 12990.1
> yuv2gbrp9le_full_X_4_512_sse2: 9118.1
> yuv2gbrp9le_full_X_4_512_sse4: 5132.1
> yuv2gbrp9le_full_X_4_512_avx2: 2833.1
> yuv2gbrp10be_full_X_4_512_c: 14401.6
> yuv2gbrp10be_full_X_4_512_sse2: 9133.1
> yuv2gbrp10be_full_X_4_512_sse4: 5126.1
> yuv2gbrp10be_full_X_4_512_avx2: 2837.6
> yuv2gbrp10le_full_X_4_512_c: 12718.1
> yuv2gbrp10le_full_X_4_512_sse2: 9106.1
> yuv2gbrp10le_full_X_4_512_sse4: 5120.1
> yuv2gbrp10le_full_X_4_512_avx2: 2826.1
> yuv2gbrap10be_full_X_4_512_c: 18535.6
> yuv2gbrap10be_full_X_4_512_sse2: 33617.6
> yuv2gbrap10be_full_X_4_512_sse4: 6264.1
> yuv2gbrap10be_full_X_4_512_avx2: 3422.1
> yuv2gbrap10le_full_X_4_512_c: 16724.1
> yuv2gbrap10le_full_X_4_512_sse2: 11787.1
> yuv2gbrap10le_full_X_4_512_sse4: 6282.1
> yuv2gbrap10le_full_X_4_512_avx2: 3441.6
> yuv2gbrp12be_full_X_4_512_c: 13723.6
> yuv2gbrp12be_full_X_4_512_sse2: 9128.1
> yuv2gbrp12be_full_X_4_512_sse4: 7997.6
> yuv2gbrp12be_full_X_4_512_avx2: 2844.1
> yuv2gbrp12le_full_X_4_512_c: 12257.1
> yuv2gbrp12le_full_X_4_512_sse2: 9107.6
> yuv2gbrp12le_full_X_4_512_sse4: 5142.6
> yuv2gbrp12le_full_X_4_512_avx2: 2837.6
> yuv2gbrap12be_full_X_4_512_c: 18511.1
> yuv2gbrap12be_full_X_4_512_sse2: 12156.6
> yuv2gbrap12be_full_X_4_512_sse4: 6251.1
> yuv2gbrap12be_full_X_4_512_avx2: 3444.6
> yuv2gbrap12le_full_X_4_512_c: 16687.1
> yuv2gbrap12le_full_X_4_512_sse2: 11785.1
> yuv2gbrap12le_full_X_4_512_sse4: 6243.6
> yuv2gbrap12le_full_X_4_512_avx2: 3446.1
> yuv2gbrp14be_full_X_4_512_c: 13690.6
> yuv2gbrp14be_full_X_4_512_sse2: 9120.6
> yuv2gbrp14be_full_X_4_512_sse4: 5138.1
> yuv2gbrp14be_full_X_4_512_avx2: 2843.1
> yuv2gbrp14le_full_X_4_512_c: 14995.6
> yuv2gbrp14le_full_X_4_512_sse2: 9119.1
> yuv2gbrp14le_full_X_4_512_sse4: 5126.1
> yuv2gbrp14le_full_X_4_512_avx2: 2843.1
> yuv2gbrp16be_full_X_4_512_c: 12367.1
> yuv2gbrp16be_full_X_4_512_sse2: 8233.6
> yuv2gbrp16be_full_X_4_512_sse4: 4820.1
> yuv2gbrp16be_full_X_4_512_avx2: 2666.6
> yuv2gbrp16le_full_X_4_512_c: 10904.1
> yuv2gbrp16le_full_X_4_512_sse2: 8214.1
> yuv2gbrp16le_full_X_4_512_sse4: 4824.1
> yuv2gbrp16le_full_X_4_512_avx2: 2629.1
> yuv2gbrap16be_full_X_4_512_c: 26569.6
> yuv2gbrap16be_full_X_4_512_sse2: 10884.1
> yuv2gbrap16be_full_X_4_512_sse4: 5488.1
> yuv2gbrap16be_full_X_4_512_avx2: 3272.1
> yuv2gbrap16le_full_X_4_512_c: 14010.1
> yuv2gbrap16le_full_X_4_512_sse2: 10562.1
> yuv2gbrap16le_full_X_4_512_sse4: 5463.6
> yuv2gbrap16le_full_X_4_512_avx2: 3255.1
> yuv2gbrpf32be_full_X_4_512_c: 14524.1
> yuv2gbrpf32be_full_X_4_512_sse2: 8552.6
> yuv2gbrpf32be_full_X_4_512_sse4: 4636.1
> yuv2gbrpf32be_full_X_4_512_avx2: 2474.6
> yuv2gbrpf32le_full_X_4_512_c: 13060.6
> yuv2gbrpf32le_full_X_4_512_sse2: 9682.6
> yuv2gbrpf32le_full_X_4_512_sse4: 4298.1
> yuv2gbrpf32le_full_X_4_512_avx2: 2453.1
> yuv2gbrapf32be_full_X_4_512_c: 18629.6
> yuv2gbrapf32be_full_X_4_512_sse2: 11363.1
> yuv2gbrapf32be_full_X_4_512_sse4: 15201.6
> yuv2gbrapf32be_full_X_4_512_avx2: 3727.1
> yuv2gbrapf32le_full_X_4_512_c: 16677.6
> yuv2gbrapf32le_full_X_4_512_sse2: 10221.6
> yuv2gbrapf32le_full_X_4_512_sse4: 5693.6
> yuv2gbrapf32le_full_X_4_512_avx2: 3656.6
> ---
>  libswscale/x86/output.asm | 434 +-
>  libswscale/x86/swscale.c  |  98 +
>  tests/checkasm/Makefile   |   2 +-
>  tests/checkasm/checkasm.c |   1 +
>  tests/checkasm/checkasm.h |   1 +
>  tests/checkasm/sw_gbrp.c  | 198 +
>  tests/fate/checkasm.mak   |   1 +
>  7 files changed, 733 insertions(+), 2 deletions(-)
>  create mode 100644 tests/checkasm/sw_gbrp.c
>
> diff --git a/libswscale/x86/output.asm b/libswscale/x86/output.asm
> index 52cf9f2c2e..e277a61449 100644
> --- a/libswscale/x86/output.asm
> +++ b/libswscale/x86/output.asm
> @@ -38,7 +38,49 @@ pw_32: times 8 dw 32
>  pd_255:times 8 dd 255
>  pw_512:times 8 dw 512
>  pw_1024:   times 8 dw 1024
> -
> +pd_65535_invf: times 8 dd 0x37800080 ;1.0/65535.0
> +pd_yuv2gbrp16_start:   times 8 dd -0x4000
> +pd_yuv2gbrp_y_start:   times 8 dd  (1 << 9)
> +pd_yuv2gbrp_uv_start:  times 8 dd  ((1 << 9) - (128 << 19))
> +pd_yuv2gbrp_a_start:   times 8 dd  (1 << 18)
> +pd_yuv2gbrp16_offset:  times 8 dd  0x1  ;(1 << 16)
> +pd_yuv2gbrp16_round13: times 8 dd  0x02000  ;(1 << 13)
> +pd_yuv2g

Re: [FFmpeg-devel] [PATCH v3 0/5] Switch mmaldec to receive_frame API

2021-12-12 Thread Ming Shun Ho
It would definitely have to be an option.

I tried lowering MAX_DELAYED_FRAMES myself. While it might work for live
video
streams, games streaming in your case, RTSP from CCTV cameras in mine, lower
MAX_DELAYED_FRAMES seems to cause a decoding stall in any video with
re-ordered
frames.

Thanks for testing this patchset!


On Sun, Dec 12, 2021 at 9:09 AM Cameron Gutman 
wrote:

> On 12/9/2021 7:01 AM, Andreas Rheinhardt wrote:
> > This is an updated and extended version of [1] by Ho Ming Shun
> > together with some additions by me. Notice that I am unable
> > to test these patches (not even compilation), so I hope that
> > others (Ho Ming Shun) do so.
> >
> > [1]:
> https://ffmpeg.org/pipermail/ffmpeg-devel/2021-September/285992.html
> >
> > Andreas Rheinhardt (2):
> >avcodec/mmaldec: Avoid creating unnecessary reference, simplify code
> >avcodec/mmaldec: Deduplicate AVClasses
> >
> > Ho Ming Shun (3):
> >avcodec/mmaldec: use decoupled dataflow
> >avcodec/mmaldec: re-use AVPacket for extra_data
> >avcodec/mmaldec: fix pointer type warning
> >
> >   libavcodec/mmaldec.c | 81 +++-
> >   1 file changed, 42 insertions(+), 39 deletions(-)
> >
>
> This is fantastic work! I'm seeing significantly improved decode latency
> here. I've been carrying an out-of-tree hack[0] for years to address the
> extremely poor performance of mmaldec due to this async decoding behavior.
>
> The refactoring in this patch set _almost_ matches my dirty hack.
>
> With a realtime 60 FPS stream (so 1 packet per 16 ms) via Moonlight-Qt[1]:
> - Current master: ~250 ms
> - This patch set: ~18 ms
> - My hack: ~14 ms
>
> With this patchset, I usually end up receiving frame N-1 when submitting
> frame N. My hack manages to avoid asynchronous decoding altogether, so
> I'm always receiving frame N after sending frame N for decoding.
>
> The absolute latency numbers are very close, but going over a frame of
> latency is significant. The effective latency difference when it comes to
> drawing the resulting image is 16 ms on a 60 Hz monitor due to V-sync.
>
> I assume my hack is unsuitable for inclusion in FFmpeg, but perhaps we
> can figure out a way to avoid having to patch FFmpeg to get that behavior.
> Maybe an AVOption to set MAX_DELAYED_FRAMES rather than hardcoding it?
>
> In any case, this is a _major_ improvement for my use so feel free to add
> my Tested-by to this patch series:
>
> Tested-by: Cameron Gutman 
>
>
>
> Regards,
> Cam
>
>
> [0]:
> https://github.com/cgutman/FFmpeg/commit/193a0320afd5f316da407208eb2fdceea888ff64
> [1]: https://github.com/moonlight-stream/moonlight-qt
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/7] avcodec/mpegvideo: Move closed_gop to Mpeg1Context

2021-12-12 Thread Andreas Rheinhardt
Only used there and only by the main thread.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/mpeg12dec.c | 8 +---
 libavcodec/mpegvideo.c | 1 -
 libavcodec/mpegvideo.h | 1 -
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 09b2902bca..672031b6db 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -69,6 +69,7 @@ typedef struct Mpeg1Context {
 int rc_buffer_size;
 AVRational frame_rate_ext;  /* MPEG-2 specific framerate modificator */
 int sync;   /* Did we reach a sync point like a 
GOP/SEQ/KEYFrame? */
+int closed_gop;
 int tmpgexs;
 int first_slice;
 int extradata_decoded;
@@ -2449,7 +2450,7 @@ static void mpeg_decode_gop(AVCodecContext *avctx,
 
 tc = s-> timecode_frame_start = get_bits(&s->gb, 25);
 
-s->closed_gop = get_bits1(&s->gb);
+s1->closed_gop = get_bits1(&s->gb);
 /* broken_link indicates that after editing the
  * reference frames of the first B-Frames after GOP I-Frame
  * are missing (open gop) */
@@ -2460,7 +2461,7 @@ static void mpeg_decode_gop(AVCodecContext *avctx,
 av_timecode_make_mpeg_tc_string(tcbuf, tc);
 av_log(s->avctx, AV_LOG_DEBUG,
"GOP (%s) closed_gop=%d broken_link=%d\n",
-   tcbuf, s->closed_gop, broken_link);
+   tcbuf, s1->closed_gop, broken_link);
 }
 }
 
@@ -2694,7 +2695,7 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame 
*picture,
 /* Skip B-frames if we do not have reference frames and
  * GOP is not closed. */
 if (s2->pict_type == AV_PICTURE_TYPE_B) {
-if (!s2->closed_gop) {
+if (!s->closed_gop) {
 skip_frame = 1;
 av_log(s2->avctx, AV_LOG_DEBUG,
"Skipping B slice due to open GOP\n");
@@ -2882,6 +2883,7 @@ static void flush(AVCodecContext *avctx)
 Mpeg1Context *s = avctx->priv_data;
 
 s->sync   = 0;
+s->closed_gop = 0;
 
 ff_mpeg_flush(avctx);
 }
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index ba5b51955e..55399a7478 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -2317,7 +2317,6 @@ void ff_mpeg_flush(AVCodecContext *avctx){
 ff_mpeg_unref_picture(s->avctx, &s->next_picture);
 
 s->mb_x= s->mb_y= 0;
-s->closed_gop= 0;
 
 #if FF_API_FLAG_TRUNCATED
 s->parse_context.state= -1;
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index e90669b776..85f02b1355 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -198,7 +198,6 @@ typedef struct MpegEncContext {
 int *lambda_table;
 int adaptive_quant; ///< use adaptive quantization
 int dquant; ///< qscale difference to prev qscale
-int closed_gop; ///< MPEG1/2 GOP is closed
 int pict_type;  ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, 
AV_PICTURE_TYPE_B, ...
 int vbv_delay;
 int last_pict_type; //FIXME removes
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/7] avcodec/mpegvideo: Don't update encoder-only fields for decoders

2021-12-12 Thread Andreas Rheinhardt
ff_mpeg_update_thread_context() is only used by decoders.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/mpegvideo.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 55399a7478..b5ff4cec69 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -658,12 +658,6 @@ do {\
 memcpy(&s->progressive_sequence, &s1->progressive_sequence,
(char *) &s1->rtp_mode - (char *) &s1->progressive_sequence);
 
-if (!s1->first_field) {
-s->last_pict_type = s1->pict_type;
-if (s1->current_picture_ptr)
-s->last_lambda_for[s1->pict_type] = 
s1->current_picture_ptr->f->quality;
-}
-
 return 0;
 }
 
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/7] avcodec/mpegvideo_end, vc1dec: Remove always-false check

2021-12-12 Thread Andreas Rheinhardt
Mpeg1EncContext.droppable is only nonzero for the FLV decoder.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/mpegvideo_enc.c | 3 +--
 libavcodec/vc1dec.c| 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index f804b8215d..d33cf9477d 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1658,8 +1658,7 @@ static int frame_start(MpegEncContext *s)
 
 if (s->pict_type != AV_PICTURE_TYPE_B) {
 s->last_picture_ptr = s->next_picture_ptr;
-if (!s->droppable)
-s->next_picture_ptr = s->current_picture_ptr;
+s->next_picture_ptr = s->current_picture_ptr;
 }
 
 if (s->last_picture_ptr) {
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index e636fa6160..267d72d15b 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -862,7 +862,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
 s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
 
 /* skip B-frames if we don't have reference frames */
-if (!s->last_picture_ptr && (s->pict_type == AV_PICTURE_TYPE_B || 
s->droppable)) {
+if (!s->last_picture_ptr && s->pict_type == AV_PICTURE_TYPE_B) {
 av_log(v->s.avctx, AV_LOG_DEBUG, "Skipping B frame without reference 
frames\n");
 goto end;
 }
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/7] avcodec/mpegvideo: Don't allocate encoder-only buffers when decoding

2021-12-12 Thread Andreas Rheinhardt
Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/mpegvideo.c | 20 +++-
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index b5ff4cec69..e2cdba8bb1 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -768,11 +768,9 @@ static int init_context_frame(MpegEncContext *s)
 !FF_ALLOC_TYPED_ARRAY (s->cplx_tab, mb_array_size) ||
 !FF_ALLOC_TYPED_ARRAY (s->bits_tab, mb_array_size))
 return AVERROR(ENOMEM);
-}
 
 if (s->codec_id == AV_CODEC_ID_MPEG4 ||
 (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
-/* interlaced direct mode decoding tables */
 for (i = 0; i < 2; i++) {
 int j, k;
 for (j = 0; j < 2; j++) {
@@ -782,15 +780,27 @@ static int init_context_frame(MpegEncContext *s)
 s->b_field_mv_table[i][j][k] = 
s->b_field_mv_table_base[i][j][k] +
s->mb_stride + 1;
 }
-if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_select_table [i][j], 
mv_table_size * 2) ||
-!FF_ALLOCZ_TYPED_ARRAY(s->p_field_mv_table_base[i][j], 
mv_table_size))
+if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_select_table [i][j], 
mv_table_size * 2))
 return AVERROR(ENOMEM);
-s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + 
s->mb_stride + 1;
 }
 if (!FF_ALLOCZ_TYPED_ARRAY(s->p_field_select_table[i], 
mv_table_size * 2))
 return AVERROR(ENOMEM);
 }
 }
+}
+
+if (s->codec_id == AV_CODEC_ID_MPEG4 ||
+(s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
+/* interlaced direct mode decoding tables */
+for (int i = 0; i < 2; i++) {
+for (int j = 0; j < 2; j++) {
+if (!FF_ALLOCZ_TYPED_ARRAY(s->p_field_mv_table_base[i][j], 
mv_table_size))
+return AVERROR(ENOMEM);
+s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + 
s->mb_stride + 1;
+}
+}
+}
+
 if (s->out_format == FMT_H263) {
 /* cbp values, cbp, ac_pred, pred_dir */
 if (!FF_ALLOCZ_TYPED_ARRAY(s->coded_block_base, y_size + 
(s->mb_height&1)*2*s->b8_stride) ||
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 7/7] avcodec/mpegvideo: Reindentation

2021-12-12 Thread Andreas Rheinhardt
Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/mpegvideo.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index be47ccb8ed..46e56ca08e 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -770,8 +770,8 @@ static int init_context_frame(MpegEncContext *s)
 return AVERROR(ENOMEM);
 
 #define ALLOCZ_ARRAYS(p, mult, numb) ((p) = av_calloc(numb, mult * 
sizeof(*(p
-if (s->codec_id == AV_CODEC_ID_MPEG4 ||
-(s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
+if (s->codec_id == AV_CODEC_ID_MPEG4 ||
+(s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
 int16_t (*tmp1)[2];
 uint8_t *tmp2;
 if (!(tmp1 = ALLOCZ_ARRAYS(s->b_field_mv_table_base, 8, 
mv_table_size)) ||
@@ -782,19 +782,18 @@ static int init_context_frame(MpegEncContext *s)
 s->p_field_select_table[1] = s->p_field_select_table[0] + 2 * 
mv_table_size;
 tmp1 += s->mb_stride + 1;
 
-for (i = 0; i < 2; i++) {
-int j, k;
-for (j = 0; j < 2; j++) {
-for (k = 0; k < 2; k++) {
+for (int i = 0; i < 2; i++) {
+for (int j = 0; j < 2; j++) {
+for (int k = 0; k < 2; k++) {
 s->b_field_mv_table[i][j][k] = tmp1;
 tmp1 += mv_table_size;
-}
+}
 s->b_field_select_table[i][j] = tmp2;
 tmp2 += 2 * mv_table_size;
+}
 }
 }
 }
-}
 
 if (s->codec_id == AV_CODEC_ID_MPEG4 ||
 (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 6/7] avcodec/h263: Remove declaration of inexistent function

2021-12-12 Thread Andreas Rheinhardt
Forgotten in c46eeae2a80dfe0046c15b542e8b9a2c78f19bf7.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/h263.h | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/libavcodec/h263.h b/libavcodec/h263.h
index d6bef8318d..84a3a19517 100644
--- a/libavcodec/h263.h
+++ b/libavcodec/h263.h
@@ -87,13 +87,6 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s);
 int ff_h263_decode_mb(MpegEncContext *s,
   int16_t block[6][64]);
 
-/**
- * Return the value of the 3-bit "source format" syntax element.
- * This represents some standard picture dimensions or indicates that
- * width&height are explicitly stored later.
- */
-int av_const h263_get_picture_format(int width, int height);
-
 void ff_clean_h263_qscales(MpegEncContext *s);
 int ff_h263_resync(MpegEncContext *s);
 void ff_h263_encode_motion(PutBitContext *pb, int val, int f_code);
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 5/7] avcodec/mpegvideo: Allocate several buffers jointly

2021-12-12 Thread Andreas Rheinhardt
Reduces the amount of allocations and frees.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/mpegvideo.c | 46 ++
 libavcodec/mpegvideo.h |  8 
 2 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index e2cdba8bb1..be47ccb8ed 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -769,34 +769,44 @@ static int init_context_frame(MpegEncContext *s)
 !FF_ALLOC_TYPED_ARRAY (s->bits_tab, mb_array_size))
 return AVERROR(ENOMEM);
 
+#define ALLOCZ_ARRAYS(p, mult, numb) ((p) = av_calloc(numb, mult * 
sizeof(*(p
 if (s->codec_id == AV_CODEC_ID_MPEG4 ||
 (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
+int16_t (*tmp1)[2];
+uint8_t *tmp2;
+if (!(tmp1 = ALLOCZ_ARRAYS(s->b_field_mv_table_base, 8, 
mv_table_size)) ||
+!(tmp2 = ALLOCZ_ARRAYS(s->b_field_select_table[0][0], 2 * 4, 
mv_table_size)) ||
+!ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * 2, 
mv_table_size))
+return AVERROR(ENOMEM);
+
+s->p_field_select_table[1] = s->p_field_select_table[0] + 2 * 
mv_table_size;
+tmp1 += s->mb_stride + 1;
+
 for (i = 0; i < 2; i++) {
 int j, k;
 for (j = 0; j < 2; j++) {
 for (k = 0; k < 2; k++) {
-if 
(!FF_ALLOCZ_TYPED_ARRAY(s->b_field_mv_table_base[i][j][k], mv_table_size))
-return AVERROR(ENOMEM);
-s->b_field_mv_table[i][j][k] = 
s->b_field_mv_table_base[i][j][k] +
-   s->mb_stride + 1;
+s->b_field_mv_table[i][j][k] = tmp1;
+tmp1 += mv_table_size;
 }
-if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_select_table [i][j], 
mv_table_size * 2))
-return AVERROR(ENOMEM);
+s->b_field_select_table[i][j] = tmp2;
+tmp2 += 2 * mv_table_size;
 }
-if (!FF_ALLOCZ_TYPED_ARRAY(s->p_field_select_table[i], 
mv_table_size * 2))
-return AVERROR(ENOMEM);
 }
 }
 }
 
 if (s->codec_id == AV_CODEC_ID_MPEG4 ||
 (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
+int16_t (*tmp)[2];
 /* interlaced direct mode decoding tables */
+if (!(tmp = ALLOCZ_ARRAYS(s->p_field_mv_table_base, 4, mv_table_size)))
+return AVERROR(ENOMEM);
+tmp += s->mb_stride + 1;
 for (int i = 0; i < 2; i++) {
 for (int j = 0; j < 2; j++) {
-if (!FF_ALLOCZ_TYPED_ARRAY(s->p_field_mv_table_base[i][j], 
mv_table_size))
-return AVERROR(ENOMEM);
-s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + 
s->mb_stride + 1;
+s->p_field_mv_table[i][j] = tmp;
+tmp += mv_table_size;
 }
 }
 }
@@ -880,14 +890,14 @@ static void clear_context(MpegEncContext *s)
 s->b_bidir_forw_mv_table = NULL;
 s->b_bidir_back_mv_table = NULL;
 s->b_direct_mv_table = NULL;
+s->b_field_mv_table_base = NULL;
+s->p_field_mv_table_base = NULL;
 for (i = 0; i < 2; i++) {
 for (j = 0; j < 2; j++) {
 for (k = 0; k < 2; k++) {
-s->b_field_mv_table_base[i][j][k] = NULL;
 s->b_field_mv_table[i][j][k] = NULL;
 }
 s->b_field_select_table[i][j] = NULL;
-s->p_field_mv_table_base[i][j] = NULL;
 s->p_field_mv_table[i][j] = NULL;
 }
 s->p_field_select_table[i] = NULL;
@@ -1026,17 +1036,19 @@ static void free_context_frame(MpegEncContext *s)
 s->b_bidir_forw_mv_table = NULL;
 s->b_bidir_back_mv_table = NULL;
 s->b_direct_mv_table = NULL;
+av_freep(&s->b_field_mv_table_base);
+av_freep(&s->b_field_select_table[0][0]);
+av_freep(&s->p_field_mv_table_base);
+av_freep(&s->p_field_select_table[0]);
 for (i = 0; i < 2; i++) {
 for (j = 0; j < 2; j++) {
 for (k = 0; k < 2; k++) {
-av_freep(&s->b_field_mv_table_base[i][j][k]);
 s->b_field_mv_table[i][j][k] = NULL;
 }
-av_freep(&s->b_field_select_table[i][j]);
-av_freep(&s->p_field_mv_table_base[i][j]);
+s->b_field_select_table[i][j] = NULL;
 s->p_field_mv_table[i][j] = NULL;
 }
-av_freep(&s->p_field_select_table[i]);
+s->p_field_select_table[i] = NULL;
 }
 
 av_freep(&s->dc_val_base);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 85f02b1355..879b019ffc 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -232,8 +232,8 @@ typedef struct MpegEncContext {
 int16_t (*b_bidir_forw_mv_table_base)[2];
 int16_t (*b_bidir_back_mv_table_base)[

Re: [FFmpeg-devel] [PATCH 1/5] avformat/movenc: remove unused argument from get_sample_flags()

2021-12-12 Thread zhilizhao(赵志立)
Ping for patch 1-3.

> On Dec 3, 2021, at 1:06 PM, Zhao Zhili  wrote:
> 
> ---
> libavformat/movenc.c | 12 ++--
> 1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> index 38ff90833a..634a829f28 100644
> --- a/libavformat/movenc.c
> +++ b/libavformat/movenc.c
> @@ -4427,7 +4427,7 @@ static int mov_write_mfhd_tag(AVIOContext *pb, 
> MOVMuxContext *mov)
> return 0;
> }
> 
> -static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
> +static uint32_t get_sample_flags(MOVIentry *entry)
> {
> return entry->flags & MOV_SYNC_SAMPLE ? MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO :
>(MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | 
> MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC);
> @@ -4487,7 +4487,7 @@ static int mov_write_tfhd_tag(AVIOContext *pb, 
> MOVMuxContext *mov,
> /* Set the default flags based on the second sample, if available.
>  * If the first sample is different, that can be signaled via a 
> separate field. */
> if (track->entry > 1)
> -track->default_sample_flags = get_sample_flags(track, 
> &track->cluster[1]);
> +track->default_sample_flags = 
> get_sample_flags(&track->cluster[1]);
> else
> track->default_sample_flags =
> track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
> @@ -4512,11 +4512,11 @@ static int mov_write_trun_tag(AVIOContext *pb, 
> MOVMuxContext *mov,
> flags |= MOV_TRUN_SAMPLE_DURATION;
> if (track->cluster[i].size != track->default_size)
> flags |= MOV_TRUN_SAMPLE_SIZE;
> -if (i > first && get_sample_flags(track, &track->cluster[i]) != 
> track->default_sample_flags)
> +if (i > first && get_sample_flags(&track->cluster[i]) != 
> track->default_sample_flags)
> flags |= MOV_TRUN_SAMPLE_FLAGS;
> }
> if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > 0 &&
> - get_sample_flags(track, &track->cluster[0]) != 
> track->default_sample_flags)
> + get_sample_flags(&track->cluster[0]) != track->default_sample_flags)
> flags |= MOV_TRUN_FIRST_SAMPLE_FLAGS;
> if (track->flags & MOV_TRACK_CTTS)
> flags |= MOV_TRUN_SAMPLE_CTS;
> @@ -4538,7 +4538,7 @@ static int mov_write_trun_tag(AVIOContext *pb, 
> MOVMuxContext *mov,
> avio_wb32(pb, moof_size + 8 + track->data_offset +
>   track->cluster[first].pos); /* data offset */
> if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
> -avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
> +avio_wb32(pb, get_sample_flags(&track->cluster[first]));
> 
> for (i = first; i < end; i++) {
> if (flags & MOV_TRUN_SAMPLE_DURATION)
> @@ -4546,7 +4546,7 @@ static int mov_write_trun_tag(AVIOContext *pb, 
> MOVMuxContext *mov,
> if (flags & MOV_TRUN_SAMPLE_SIZE)
> avio_wb32(pb, track->cluster[i].size);
> if (flags & MOV_TRUN_SAMPLE_FLAGS)
> -avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
> +avio_wb32(pb, get_sample_flags(&track->cluster[i]));
> if (flags & MOV_TRUN_SAMPLE_CTS)
> avio_wb32(pb, track->cluster[i].cts);
> }
> -- 
> 2.31.1
> 

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v9 1/2] avformat/imf: Demuxer

2021-12-12 Thread Zane van Iperen



On 9/12/21 13:55, p...@sandflow.com wrote:


+
+#define FF_UUID_FORMAT\
+"urn:uuid:%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-" \
+"%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
+
+/**
+ * UUID as defined in IETF RFC 422
+ */
+typedef uint8_t FFUUID[16];
+


Perhaps change to FF_IMF_UUID_FORMAT and FFIMFUUID, unless you intend these
to be used for all of FFmpeg?

I also agree with Lynne that we shouldn't ad-hoc UUIDs. libuuid is nice
and wouldn't be too bad to add as a dependency. It'll also be handy if
some other part needs to handle UUIDs in the future.

Even though it might not support "urn:uuid:", you can just offset the pointer
before giving it to uuid_parse (or uuid_parse_range).

Alternatively, if all you need to do is compare them, could you not
just compare the raw strings, skipping the parsing entirely?


+/**
+ * Parse an IMF CompositionPlaylist element into the FFIMFCPL data structure.
+ * @param[in] doc An XML document from which the CPL is read.
+ * @param[out] cpl Pointer to a memory area (allocated by the client), where 
the
+ *  function writes a pointer to the newly constructed FFIMFCPL structure (or
+ *  NULL if the CPL could not be parsed). The client is responsible for freeing
+ *  the FFIMFCPL structure using ff_imf_cpl_free().
+ * @return A non-zero value in case of an error.
+ */
+int ff_parse_imf_cpl_from_xml_dom(xmlDocPtr doc, FFIMFCPL **cpl);
+


ff_imf_parse_cpl_from_xml_dom(), ff_parse_* is taken.
Also for consistency with everything else.


+/**
+ * Parse an IMF Composition Playlist document into the FFIMFCPL data structure.
+ * @param[in] in The context from which the CPL is read.
+ * @param[out] cpl Pointer to a memory area (allocated by the client), where 
the
+ * function writes a pointer to the newly constructed FFIMFCPL structure (or
+ * NULL if the CPL could not be parsed). The client is responsible for freeing
+ * the FFIMFCPL structure using ff_imf_cpl_free().
+ * @return A non-zero value in case of an error.
+ */
+int ff_parse_imf_cpl(AVIOContext *in, FFIMFCPL **cpl);
+


Ditto.


+/**
+ * Reads an unsigned 32-bit integer from an XML element
+ * @return 0 on success, < 0 AVERROR code on error.
+ */
+int ff_xml_read_uint32(xmlNodePtr element, uint32_t *number);
+
+/**
+ * Reads an AVRational from an XML element
+ * @return 0 on success, < 0 AVERROR code on error.
+ */
+int ff_xml_read_rational(xmlNodePtr element, AVRational *rational);
+
+/**
+ * Reads a UUID from an XML element
+ * @return 0 on success, < 0 AVERROR code on error.
+ */
+int ff_xml_read_uuid(xmlNodePtr element, uint8_t uuid[16]);
+
+/**
+ * Returns the first child element with the specified local name
+ * @return A pointer to the child element, or NULL if no such child element 
exists.
+ */
+xmlNodePtr ff_xml_get_child_element_by_name(xmlNodePtr parent, const char 
*name_utf8);
+


If these are only used for IMF, then ff_imf_xml_*().
Afaik FFmpeg doesn't have any centralised XML helpers (and perhaps it should, 
there's a few
things that use libxml from a quick grep).


+
+const AVInputFormat ff_imf_demuxer = {
+.name   = "imf",
+.long_name  = NULL_IF_CONFIG_SMALL("IMF (Interoperable Master 
Format)"),
+.flags_internal = FF_FMT_INIT_CLEANUP,
+.priv_class = &imf_class,
+.priv_data_size = sizeof(IMFContext),
+.read_header= imf_read_header,
+.read_packet= imf_read_packet,
+.read_close = imf_close,
+.extensions = "xml",


I'm a bit apprehensive about this. This will unconditionally set all XML files 
as imf.
How difficult would it be to add a probe function?


+.mime_type  = "application/xml,text/xml",
+};


___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v10 1/2] avformat/imf: Demuxer

2021-12-12 Thread pal
From: Pierre-Anthony Lemieux 

Signed-off-by: Pierre-Anthony Lemieux 
---

Notes:
The IMF demuxer accepts as input an IMF CPL. The assets referenced by the 
CPL can be
contained in multiple deliveries, each defined by an ASSETMAP file:

ffmpeg -assetmaps ,,... -i 

If -assetmaps is not specified, FFMPEG looks for a file called ASSETMAP.xml 
in the same directory as the CPL.

EXAMPLE:
ffmpeg -i 
http://ffmpeg-imf-samples-public.s3-website-us-west-1.amazonaws.com/countdown/CPL_f5095caa-f204-4e1c-8a84-7af48c7ae16b.xml
 out.mp4

The Interoperable Master Format (IMF) is a file-based media format for the
delivery and storage of professional audio-visual masters.
An IMF Composition consists of an XML playlist (the Composition Playlist)
and a collection of MXF files (the Track Files). The Composition Playlist 
(CPL)
assembles the Track Files onto a timeline, which consists of multiple 
tracks.
The location of the Track Files referenced by the Composition Playlist is 
stored
in one or more XML documents called Asset Maps. More details at 
https://www.imfug.com/explainer.
The IMF standard was first introduced in 2013 and is managed by the SMPTE.

CHANGE NOTES:

- add imf_probe
- improve imf-specific function names

 MAINTAINERS  |   1 +
 configure|   3 +-
 doc/demuxers.texi|   6 +
 libavformat/Makefile |   1 +
 libavformat/allformats.c |   1 +
 libavformat/imf.h| 207 +
 libavformat/imf_cpl.c| 782 +
 libavformat/imfdec.c | 905 +++
 8 files changed, 1905 insertions(+), 1 deletion(-)
 create mode 100644 libavformat/imf.h
 create mode 100644 libavformat/imf_cpl.c
 create mode 100644 libavformat/imfdec.c

diff --git a/MAINTAINERS b/MAINTAINERS
index dcac46003e..7a6972fe1a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -433,6 +433,7 @@ Muxers/Demuxers:
   idroqdec.cMike Melanson
   iff.c Jaikrishnan Menon
   img2*.c   Michael Niedermayer
+  imf*.cMarc-Antoine Arnaud, Pierre-Anthony 
Lemieux, Valentin Noël
   ipmovie.c Mike Melanson
   ircam*Paul B Mahol
   iss.c Stefan Gehrer
diff --git a/configure b/configure
index a7593ec2db..aa8bae4d62 100755
--- a/configure
+++ b/configure
@@ -298,7 +298,7 @@ External library support:
   --enable-libxvid enable Xvid encoding via xvidcore,
native MPEG-4/Xvid encoder exists [no]
   --enable-libxml2 enable XML parsing using the C library libxml2, 
needed
-   for dash demuxing support [no]
+   for dash and imf demuxing support [no]
   --enable-libzimg enable z.lib, needed for zscale filter [no]
   --enable-libzmq  enable message passing via libzmq [no]
   --enable-libzvbi enable teletext support via libzvbi [no]
@@ -3400,6 +3400,7 @@ hls_muxer_select="mpegts_muxer"
 hls_muxer_suggest="gcrypt openssl"
 image2_alias_pix_demuxer_select="image2_demuxer"
 image2_brender_pix_demuxer_select="image2_demuxer"
+imf_demuxer_deps="libxml2"
 ipod_muxer_select="mov_muxer"
 ismv_muxer_select="mov_muxer"
 ivf_muxer_select="av1_metadata_bsf vp9_superframe_bsf"
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index cab8a7072c..655704d2c4 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -267,6 +267,12 @@ which streams to actually receive.
 Each stream mirrors the @code{id} and @code{bandwidth} properties from the
 @code{} as metadata keys named "id" and "variant_bitrate" 
respectively.
 
+@section imf
+
+Interoperable Master Format demuxer.
+
+This demuxer presents audio and video streams found in an IMF Composition.
+
 @section flv, live_flv, kux
 
 Adobe Flash Video Format demuxer.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 2b5caf9d33..7f058f3ea0 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -285,6 +285,7 @@ OBJS-$(CONFIG_IMAGE_WEBP_PIPE_DEMUXER)+= img2dec.o 
img2.o
 OBJS-$(CONFIG_IMAGE_XBM_PIPE_DEMUXER) += img2dec.o img2.o
 OBJS-$(CONFIG_IMAGE_XPM_PIPE_DEMUXER) += img2dec.o img2.o
 OBJS-$(CONFIG_IMAGE_XWD_PIPE_DEMUXER) += img2dec.o img2.o
+OBJS-$(CONFIG_IMF_DEMUXER)   += imfdec.o imf_cpl.o
 OBJS-$(CONFIG_INGENIENT_DEMUXER) += ingenientdec.o rawdec.o
 OBJS-$(CONFIG_IPMOVIE_DEMUXER)   += ipmovie.o
 OBJS-$(CONFIG_IPU_DEMUXER)   += ipudec.o rawdec.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 1054ac9667..f680616cdd 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -212,6 +212,7 @@ extern const AVInputFormat  ff_image2pipe_demuxer;
 extern const AVOutputFormat ff_image2pipe_muxer;
 extern const AVInputFormat  ff_i

[FFmpeg-devel] [PATCH v10 2/2] avformat/imf: Tests

2021-12-12 Thread pal
From: Pierre-Anthony Lemieux 

Signed-off-by: Pierre-Anthony Lemieux 
---

Notes:
Tests for the IMF demuxer.

 libavformat/Makefile|   1 +
 libavformat/tests/imf.c | 525 
 2 files changed, 526 insertions(+)
 create mode 100644 libavformat/tests/imf.c

diff --git a/libavformat/Makefile b/libavformat/Makefile
index 7f058f3ea0..533bb67f31 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -697,6 +697,7 @@ TESTPROGS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh
 TESTPROGS-$(CONFIG_MOV_MUXER)+= movenc
 TESTPROGS-$(CONFIG_NETWORK)  += noproxy
 TESTPROGS-$(CONFIG_SRTP) += srtp
+TESTPROGS-$(CONFIG_IMF_DEMUXER)  += imf
 
 TOOLS = aviocat \
 ismindex\
diff --git a/libavformat/tests/imf.c b/libavformat/tests/imf.c
new file mode 100644
index 00..f163886ba8
--- /dev/null
+++ b/libavformat/tests/imf.c
@@ -0,0 +1,525 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ *
+ * Copyright (c) Sandflow Consulting LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, 
this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Tests for IMF CPL and ASSETMAP processing
+ * 
+ * @author Valentin Noel
+ * @author Pierre-Anthony Lemieux
+ * @file
+ * @ingroup lavu_imf
+ */
+
+#include "libavformat/imf_cpl.c"
+#include "libavformat/imfdec.c"
+#include "libavformat/mxf.h"
+
+#include 
+
+const char *cpl_doc =
+"http://www.smpte-ra.org/schemas/2067-3/2016\"";
+" xmlns:cc=\"http://www.smpte-ra.org/schemas/2067-2/2016\"";
+" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\";>"
+"urn:uuid:8713c020-2489-45f5-a9f7-87be539e20b5"
+"2021-07-13T17:06:22Z"
+"FFMPEG"
+"FFMPEG sample content"
+""
+"  "
+"urn:uuid:8e097bb0-cff7-4969-a692-bad47bfb528f"
+"  "
+""
+"24000 1001"
+""
+""
+"urn:uuid:81fed4e5-9722-400a-b9d1-7f2bd21df4b6"
+""
+""
+"urn:uuid:16327185-9205-47ef-a17b-ee28df251db7"
+"urn:uuid:461f5424-8f6e-48a9-a385-5eda46fda381"
+""
+""
+"urn:uuid:ea3d0f23-55d6-4e03-86ec-cfe0666f0e6a"
+"24"
+""
+"LFOA"
+"5"
+""
+""
+""
+""
+""
+"urn:uuid:6ae100b0-92d1-41be-9321-85e0933dfc42"
+"urn:uuid:e8ef9653-565c-479c-8039-82d4547973c5"
+""
+""
+"urn:uuid:7d418acb-07a3-4e57-984c-b8ea2f7de4ec"
+"24"
+
"urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751"
+"urn:uuid:6f768ca4-c89e-4dac-9056-a29425d40ba1"
+""
+""
+""
+""
+"urn:uuid:754dae53-c25f-4f3c-97e4-2bfe5463f83b"
+"urn:uuid:68e3fae5-d94b-44d2-92a6-b94877fbcdb5"
+""
+""
+"urn:uuid:61ce2a70-10a2-4521-850b-4218755ff3c9"
+"24"
+
"urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751"
+"urn:uuid:381dadd2-061e-46cc-a63a-e3d58ce7f488"
+""
+""
+""
+""
+"urn:uuid:d29b3884-6633-4dad-9c67-7154af342bc6"
+"urn:uuid:6978c106-95bc-424b-a17

Re: [FFmpeg-devel] [PATCH v3 2/2] avcodec/vpp_qsv: Copy side data from input to output frame

2021-12-12 Thread Xiang, Haihao


> > -Original Message-
> > From: ffmpeg-devel  On Behalf Of Xiang,
> > Haihao
> > Sent: Thursday, December 9, 2021 9:35 AM
> > To: ffmpeg-devel@ffmpeg.org
> > Subject: Re: [FFmpeg-devel] [PATCH v3 2/2] avcodec/vpp_qsv: Copy side data
> > from input to output frame
> > 
> > On Tue, 2021-12-07 at 12:39 +, Soft Works wrote:
> > > > -Original Message-
> > > > From: ffmpeg-devel  On Behalf Of Anton
> > > > Khirnov
> > > > Sent: Tuesday, December 7, 2021 12:51 PM
> > > > To: FFmpeg development discussions and patches 
> > > > Subject: Re: [FFmpeg-devel] [PATCH v3 2/2] avcodec/vpp_qsv: Copy side
> > 
> > data
> > > > from input to output frame
> > > > 
> > > > Quoting Soft Works (2021-12-07 09:55:37)
> > > > > 
> > > > > 
> > > > > > -Original Message-
> > > > > > From: ffmpeg-devel  On Behalf Of
> > 
> > Anton
> > > > > > Khirnov
> > > > > > Sent: Tuesday, December 7, 2021 9:04 AM
> > > > > > To: ffmpeg-devel@ffmpeg.org
> > > > > > Subject: Re: [FFmpeg-devel] [PATCH v3 2/2] avcodec/vpp_qsv: Copy
> > > > > > side
> > > > 
> > > > data
> > > > > > from input to output frame
> > > > > > 
> > > > > > Quoting Soft Works (2021-12-03 08:58:31)
> > > > > > > Signed-off-by: softworkz 
> > > > > > > ---
> > > > > > >  libavfilter/qsvvpp.c |  5 +
> > > > > > >  libavfilter/vf_overlay_qsv.c | 19 +++
> > > > > > >  2 files changed, 20 insertions(+), 4 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
> > > > > > > index d1218355c7..b291216292 100644
> > > > > > > --- a/libavfilter/qsvvpp.c
> > > > > > > +++ b/libavfilter/qsvvpp.c
> > > > > > > @@ -849,6 +849,11 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s,
> > > > > > 
> > > > > > AVFilterLink *inlink, AVFrame *picr
> > > > > > >  return AVERROR(EAGAIN);
> > > > > > >  break;
> > > > > > >  }
> > > > > > > +
> > > > > > > +ret = av_frame_copy_side_data(out_frame->frame, in_frame-
> > > > > 
> > > > > frame,
> > > > > > 0);
> > > > > > > +if (ret < 0)
> > > > > > > +return ret;
> > > > > > > +
> > > > > > >  out_frame->frame->pts = av_rescale_q(out_frame-
> > > > > > > surface.Data.TimeStamp,
> > > > > > >   default_tb, outlink-
> > > > > > > time_base);
> > > > > > > 
> > > > > > > diff --git a/libavfilter/vf_overlay_qsv.c
> > > > 
> > > > b/libavfilter/vf_overlay_qsv.c
> > > > > > > index 7e76b39aa9..02518e020c 100644
> > > > > > > --- a/libavfilter/vf_overlay_qsv.c
> > > > > > > +++ b/libavfilter/vf_overlay_qsv.c
> > > > > > > @@ -231,13 +231,24 @@ static int process_frame(FFFrameSync *fs)
> > > > > > >  {
> > > > > > >  AVFilterContext  *ctx = fs->parent;
> > > > > > >  QSVOverlayContext  *s = fs->opaque;
> > > > > > > +AVFrame   *frame0 = NULL;
> > > > > > >  AVFrame*frame = NULL;
> > > > > > > -int   ret = 0, i;
> > > > > > > +int   ret = 0;
> > > > > > > 
> > > > > > > -for (i = 0; i < ctx->nb_inputs; i++) {
> > > > > > > +for (unsigned i = 0; i < ctx->nb_inputs; i++) {
> > > > > > >  ret = ff_framesync_get_frame(fs, i, &frame, 0);
> > > > > > > -if (ret == 0)
> > > > > > > -ret = ff_qsvvpp_filter_frame(s->qsv, ctx->inputs[i],
> > > > 
> > > > frame);
> > > > > > > +
> > > > > > > +if (ret == 0) {
> > > > > > > +AVFrame *temp;
> > > > > > > +
> > > > > > > +if (i == 0)
> > > > > > > +frame0 = frame;
> > > > > > > +else
> > > > > > > +ret = av_frame_copy_side_data(frame, frame0, 0);
> > > > > > > +
> > > > > > > +ret = ret < 0 ? ret : ff_qsvvpp_filter_frame(s->qsv,
> > 
> > ctx-
> > > > > > > inputs[i], frame);
> > > > > > 
> > > > > > I don't quite understand the ownership semantics here. This function
> > > > > > does not free frame, so I assume ff_qsvvpp_filter_frame() takes
> > > > > > ownership of it. That would mean you're not allowed to keep a
> > > > > > pointer
> > 
> > to
> > > > > > it and access it later, because it might have already been freed.
> > > > > 
> > > > > The filter is using framesync, which is taking care of the ownership.
> > > > > ff_qsvvpp_filter_frame() clones or copies the frame, depending on
> > > > > case.
> > > > > Other than with the normal overlay filter, the frame from input0 is
> > > > > not used for output. But the regular overlay filter has established
> > > > > the
> > > > > convention that side data from input0 is being kept at the output.
> > > > 
> > > > Okay, if you're sure that framesync guarantees the frame remaining valid
> > > > then I have no objections.
> > > > 
> > > > But note that temp is unused and should be removed.
> > > 
> > > OK, thanks. Let's see what Haihao says, he's closest to the subject at the
> > > moment.
> > 
> > Is it possible that the frame from input1 and the frame from input0 have the
> > same type 

Re: [FFmpeg-devel] [PATCH v9 1/2] avformat/imf: Demuxer

2021-12-12 Thread Pierre-Anthony Lemieux
On Sun, Dec 12, 2021 at 7:58 PM Zane van Iperen  wrote:
>
>
> On 9/12/21 13:55, p...@sandflow.com wrote:
>
> > +
> > +#define FF_UUID_FORMAT\
> > +"urn:uuid:%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-" \
> > +"%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
> > +
> > +/**
> > + * UUID as defined in IETF RFC 422
> > + */
> > +typedef uint8_t FFUUID[16];
> > +
>
> Perhaps change to FF_IMF_UUID_FORMAT and FFIMFUUID, unless you intend these
> to be used for all of FFmpeg?

Addressed by patchset v10.

>
> I also agree with Lynne that we shouldn't ad-hoc UUIDs. libuuid is nice
> and wouldn't be too bad to add as a dependency. It'll also be handy if
> some other part needs to handle UUIDs in the future.
>
> Even though it might not support "urn:uuid:", you can just offset the pointer
> before giving it to uuid_parse (or uuid_parse_range).

We would first need to make sure that the string is exactly 45 chars.

On the output side, it looks like uuid_unparse() requires the caller
to allocate a 36-char buffer. Wouldn't that complicate calls like the
following:

av_log(s, AV_LOG_DEBUG, "Found asset id: " FF_IMF_UUID_FORMAT
"\n", UID_ARG(asset->uuid));

In fact, I wonder why libuuid [1] doesn't offer a simple printf format
string, like FF_IMF_UUID_FORMAT? Maybe I missed it?

[1] https://github.com/util-linux/util-linux/blob/master/libuuid/src/uuid.h

>
> Alternatively, if all you need to do is compare them, could you not
> just compare the raw strings, skipping the parsing entirely?

The sscanf() in ff_imf_xml_read_uuid() would be replaced by a strlen()
followed by a memcpy(), and FFIMFUUID would be char[46] instead of
uint8_t[16]. I am not convinced the code would be more
maintainable/simpler.

I am wondering if FFMPEG shouldn't ultimately define a thin wrapper
over libuuid, like it does for memory and string functions?

>
> > +/**
> > + * Parse an IMF CompositionPlaylist element into the FFIMFCPL data 
> > structure.
> > + * @param[in] doc An XML document from which the CPL is read.
> > + * @param[out] cpl Pointer to a memory area (allocated by the client), 
> > where the
> > + *  function writes a pointer to the newly constructed FFIMFCPL structure 
> > (or
> > + *  NULL if the CPL could not be parsed). The client is responsible for 
> > freeing
> > + *  the FFIMFCPL structure using ff_imf_cpl_free().
> > + * @return A non-zero value in case of an error.
> > + */
> > +int ff_parse_imf_cpl_from_xml_dom(xmlDocPtr doc, FFIMFCPL **cpl);
> > +
>
> ff_imf_parse_cpl_from_xml_dom(), ff_parse_* is taken.
> Also for consistency with everything else.

Addressed by patchset v10.

>
> > +/**
> > + * Parse an IMF Composition Playlist document into the FFIMFCPL data 
> > structure.
> > + * @param[in] in The context from which the CPL is read.
> > + * @param[out] cpl Pointer to a memory area (allocated by the client), 
> > where the
> > + * function writes a pointer to the newly constructed FFIMFCPL structure 
> > (or
> > + * NULL if the CPL could not be parsed). The client is responsible for 
> > freeing
> > + * the FFIMFCPL structure using ff_imf_cpl_free().
> > + * @return A non-zero value in case of an error.
> > + */
> > +int ff_parse_imf_cpl(AVIOContext *in, FFIMFCPL **cpl);
> > +
>
> Ditto.

Addressed by patchset v10.

>
> > +/**
> > + * Reads an unsigned 32-bit integer from an XML element
> > + * @return 0 on success, < 0 AVERROR code on error.
> > + */
> > +int ff_xml_read_uint32(xmlNodePtr element, uint32_t *number);
> > +
> > +/**
> > + * Reads an AVRational from an XML element
> > + * @return 0 on success, < 0 AVERROR code on error.
> > + */
> > +int ff_xml_read_rational(xmlNodePtr element, AVRational *rational);
> > +
> > +/**
> > + * Reads a UUID from an XML element
> > + * @return 0 on success, < 0 AVERROR code on error.
> > + */
> > +int ff_xml_read_uuid(xmlNodePtr element, uint8_t uuid[16]);
> > +
> > +/**
> > + * Returns the first child element with the specified local name
> > + * @return A pointer to the child element, or NULL if no such child 
> > element exists.
> > + */
> > +xmlNodePtr ff_xml_get_child_element_by_name(xmlNodePtr parent, const char 
> > *name_utf8);
> > +
>
> If these are only used for IMF, then ff_imf_xml_*().

Addressed by patchset v10.

> Afaik FFmpeg doesn't have any centralised XML helpers (and perhaps it should, 
> there's a few
> things that use libxml from a quick grep).

Happy to look at refactoring the use of libxml after the IMF demuxer
is merged -- just trying to keep the patch surface small.

>
> > +
> > +const AVInputFormat ff_imf_demuxer = {
> > +.name   = "imf",
> > +.long_name  = NULL_IF_CONFIG_SMALL("IMF (Interoperable Master 
> > Format)"),
> > +.flags_internal = FF_FMT_INIT_CLEANUP,
> > +.priv_class = &imf_class,
> > +.priv_data_size = sizeof(IMFContext),
> > +.read_header= imf_read_header,
> > +.read_packet= imf_read_packet,
> > +.read_close = imf_close,
>

[FFmpeg-devel] [PATCH] lavc/qsvenc: set base address for V plane

2021-12-12 Thread Haihao Xiang
The SDK checks Data.V when using system memory for VP9 encoding. This
fixed the error below:

$ ffmpeg -qsv_device /dev/dri/renderD129 -f lavfi -i yuvtestsrc -c:v
vp9_qsv -f null -

[vp9_qsv @ 0x55b8387cbe90] Error during encoding: NULL pointer (-2)
Video encoding failed
---
 libavcodec/qsvenc.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 26a94cd419..7431ccfca5 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1389,8 +1389,23 @@ static int submit_frame(QSVEncContext *q, const AVFrame 
*frame,
 qf->surface.Data.PitchLow  = qf->frame->linesize[0];
 qf->surface.Data.Y = qf->frame->data[0];
 qf->surface.Data.UV= qf->frame->data[1];
-}
 
+/* The SDK checks Data.V when using system memory for VP9 encoding */
+switch (frame->format) {
+case AV_PIX_FMT_NV12:
+qf->surface.Data.V = qf->surface.Data.UV + 1;
+break;
+
+case AV_PIX_FMT_P010:
+qf->surface.Data.V = qf->surface.Data.UV + 2;
+break;
+
+default:
+/* should not reach here */
+av_assert0(0);
+break;
+}
+}
 qf->surface.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, 
(AVRational){1, 9});
 
 *new_frame = qf;
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/5] lavc/qsvenc: remove VC1 profiles

2021-12-12 Thread Haihao Xiang
The SDK doesn't support VC1 encoding. In addition, both
MFX_PROFILE_VC1_SIMPLE and MFX_PROFILE_HEVC_MAIN are 1 in the SDK, HEVC
main profile is recognized as simple profile in the verbose output if
don't remove VC1 profiles.

$ ffmpeg -v verbose -qsv_device /dev/dri/renderD129 -f lavfi -i
yuvtestsrc -c:v hevc_qsv -f null -

[hevc_qsv @ 0x55bdf7eb4eb0] profile: simple; level: 21
---
 libavcodec/qsvenc.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 26a94cd419..dc0c45dc45 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -60,9 +60,6 @@ static const struct {
 { MFX_PROFILE_MPEG2_SIMPLE, "simple"},
 { MFX_PROFILE_MPEG2_MAIN,   "main"  },
 { MFX_PROFILE_MPEG2_HIGH,   "high"  },
-{ MFX_PROFILE_VC1_SIMPLE,   "simple"},
-{ MFX_PROFILE_VC1_MAIN, "main"  },
-{ MFX_PROFILE_VC1_ADVANCED, "advanced"  },
 #if QSV_VERSION_ATLEAST(1, 8)
 { MFX_PROFILE_HEVC_MAIN,"main"  },
 { MFX_PROFILE_HEVC_MAIN10,  "main10"},
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/5] lavc/qsvenc: define profile array per codec

2021-12-12 Thread Haihao Xiang
The SDK defines HEVC, VP9 and AV1 profiles in the same values
e.g.
MFX_PROFILE_HEVC_MAIN =1,
MFX_PROFILE_VP9_0 =1,
MFX_PROFILE_AV1_MAIN  =1,

To avoid potential errors when adding VP9, AV1 profiles later,
this patch defines profile array per codec.
---
 libavcodec/qsvenc.c | 47 +
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index dc0c45dc45..7dab8bab0f 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -41,10 +41,12 @@
 #include "qsv_internal.h"
 #include "qsvenc.h"
 
-static const struct {
+struct profile_names {
 mfxU16 profile;
 const char *name;
-} profile_names[] = {
+};
+
+static const struct profile_names avc_profiles[] = {
 { MFX_PROFILE_AVC_BASELINE, "baseline"  },
 { MFX_PROFILE_AVC_MAIN, "main"  },
 { MFX_PROFILE_AVC_EXTENDED, "extended"  },
@@ -57,9 +59,15 @@ static const struct {
 { MFX_PROFILE_AVC_CONSTRAINED_HIGH, "constrained high"  },
 { MFX_PROFILE_AVC_PROGRESSIVE_HIGH, "progressive high"  },
 #endif
+};
+
+static const struct profile_names mpeg2_profiles[] = {
 { MFX_PROFILE_MPEG2_SIMPLE, "simple"},
 { MFX_PROFILE_MPEG2_MAIN,   "main"  },
 { MFX_PROFILE_MPEG2_HIGH,   "high"  },
+};
+
+static const struct profile_names hevc_profiles[] = {
 #if QSV_VERSION_ATLEAST(1, 8)
 { MFX_PROFILE_HEVC_MAIN,"main"  },
 { MFX_PROFILE_HEVC_MAIN10,  "main10"},
@@ -68,12 +76,35 @@ static const struct {
 #endif
 };
 
-static const char *print_profile(mfxU16 profile)
+static const char *print_profile(enum AVCodecID codec_id, mfxU16 profile)
 {
-int i;
-for (i = 0; i < FF_ARRAY_ELEMS(profile_names); i++)
-if (profile == profile_names[i].profile)
-return profile_names[i].name;
+const struct profile_names *profiles;
+int i, num_profiles;
+
+switch (codec_id) {
+case AV_CODEC_ID_H264:
+profiles = avc_profiles;
+num_profiles = FF_ARRAY_ELEMS(avc_profiles);
+break;
+
+case AV_CODEC_ID_MPEG2VIDEO:
+profiles = mpeg2_profiles;
+num_profiles = FF_ARRAY_ELEMS(mpeg2_profiles);
+break;
+
+case AV_CODEC_ID_HEVC:
+profiles = hevc_profiles;
+num_profiles = FF_ARRAY_ELEMS(hevc_profiles);
+break;
+
+default:
+return "unknown";
+}
+
+for (i = 0; i < num_profiles; i++)
+if (profile == profiles[i].profile)
+return profiles[i].name;
+
 return "unknown";
 }
 
@@ -143,7 +174,7 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 #endif
 
 av_log(avctx, AV_LOG_VERBOSE, "profile: %s; level: %"PRIu16"\n",
-   print_profile(info->CodecProfile), info->CodecLevel);
+   print_profile(avctx->codec_id, info->CodecProfile), 
info->CodecLevel);
 
 av_log(avctx, AV_LOG_VERBOSE, "GopPicSize: %"PRIu16"; GopRefDist: 
%"PRIu16"; GopOptFlag: ",
info->GopPicSize, info->GopRefDist);
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/5] lavc/qsvenc: add VP9 profiles

2021-12-12 Thread Haihao Xiang
---
 libavcodec/qsvenc.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 7dab8bab0f..a2a8a79189 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -76,6 +76,15 @@ static const struct profile_names hevc_profiles[] = {
 #endif
 };
 
+static const struct profile_names vp9_profiles[] = {
+#if QSV_VERSION_ATLEAST(1, 19)
+{ MFX_PROFILE_VP9_0,"0" },
+{ MFX_PROFILE_VP9_1,"1" },
+{ MFX_PROFILE_VP9_2,"2" },
+{ MFX_PROFILE_VP9_3,"3" },
+#endif
+};
+
 static const char *print_profile(enum AVCodecID codec_id, mfxU16 profile)
 {
 const struct profile_names *profiles;
@@ -97,6 +106,11 @@ static const char *print_profile(enum AVCodecID codec_id, 
mfxU16 profile)
 num_profiles = FF_ARRAY_ELEMS(hevc_profiles);
 break;
 
+case AV_CODEC_ID_VP9:
+profiles = vp9_profiles;
+num_profiles = FF_ARRAY_ELEMS(vp9_profiles);
+break;
+
 default:
 return "unknown";
 }
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/5] lavc/qsvenc: dump parameters for VP9 encoding in verbose mode

2021-12-12 Thread Haihao Xiang
---
 libavcodec/qsvenc.c | 80 +
 1 file changed, 80 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index a2a8a79189..106438f227 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -343,6 +343,84 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 
 }
 
+static void dump_video_vp9_param(AVCodecContext *avctx, QSVEncContext *q,
+ mfxExtBuffer **coding_opts)
+{
+mfxInfoMFX *info = &q->param.mfx;
+#if QSV_HAVE_EXT_VP9_PARAM
+mfxExtVP9Param *vp9_param = (mfxExtVP9Param *)coding_opts[0];
+#endif
+#if QSV_HAVE_CO2
+mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];
+#endif
+
+av_log(avctx, AV_LOG_VERBOSE, "profile: %s \n",
+   print_profile(avctx->codec_id, info->CodecProfile));
+
+av_log(avctx, AV_LOG_VERBOSE, "GopPicSize: %"PRIu16"; GopRefDist: 
%"PRIu16"; GopOptFlag: ",
+   info->GopPicSize, info->GopRefDist);
+if (info->GopOptFlag & MFX_GOP_CLOSED)
+av_log(avctx, AV_LOG_VERBOSE, "closed ");
+if (info->GopOptFlag & MFX_GOP_STRICT)
+av_log(avctx, AV_LOG_VERBOSE, "strict ");
+av_log(avctx, AV_LOG_VERBOSE, "; IdrInterval: %"PRIu16"\n", 
info->IdrInterval);
+
+av_log(avctx, AV_LOG_VERBOSE, "TargetUsage: %"PRIu16"; RateControlMethod: 
%s\n",
+   info->TargetUsage, print_ratecontrol(info->RateControlMethod));
+
+if (info->RateControlMethod == MFX_RATECONTROL_CBR ||
+info->RateControlMethod == MFX_RATECONTROL_VBR) {
+av_log(avctx, AV_LOG_VERBOSE,
+   "BufferSizeInKB: %"PRIu16"; InitialDelayInKB: %"PRIu16"; 
TargetKbps: %"PRIu16"; MaxKbps: %"PRIu16"; BRCParamMultiplier: %"PRIu16"\n",
+   info->BufferSizeInKB, info->InitialDelayInKB, info->TargetKbps, 
info->MaxKbps, info->BRCParamMultiplier);
+} else if (info->RateControlMethod == MFX_RATECONTROL_CQP) {
+av_log(avctx, AV_LOG_VERBOSE, "QPI: %"PRIu16"; QPP: %"PRIu16"; QPB: 
%"PRIu16"\n",
+   info->QPI, info->QPP, info->QPB);
+}
+#if QSV_HAVE_ICQ
+else if (info->RateControlMethod == MFX_RATECONTROL_ICQ) {
+av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", 
info->ICQQuality);
+}
+#endif
+else {
+av_log(avctx, AV_LOG_VERBOSE, "Unsupported ratecontrol method: %d \n", 
info->RateControlMethod);
+}
+
+av_log(avctx, AV_LOG_VERBOSE, "NumRefFrame: %"PRIu16"\n", 
info->NumRefFrame);
+
+#if QSV_HAVE_CO2
+av_log(avctx, AV_LOG_VERBOSE,
+   "IntRefType: %"PRIu16"; IntRefCycleSize: %"PRIu16"; IntRefQPDelta: 
%"PRId16"\n",
+   co2->IntRefType, co2->IntRefCycleSize, co2->IntRefQPDelta);
+
+av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d; ", co2->MaxFrameSize);
+av_log(avctx, AV_LOG_VERBOSE, "\n");
+
+av_log(avctx, AV_LOG_VERBOSE,
+   "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
+   print_threestate(co2->BitrateLimit), print_threestate(co2->MBBRC),
+   print_threestate(co2->ExtBRC));
+
+#if QSV_HAVE_VDENC
+av_log(avctx, AV_LOG_VERBOSE, "VDENC: %s\n", 
print_threestate(info->LowPower));
+#endif
+
+#if QSV_VERSION_ATLEAST(1, 9)
+av_log(avctx, AV_LOG_VERBOSE,
+   "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP: 
%"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
+   co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2->MinQPB, 
co2->MaxQPB);
+#endif
+#endif
+
+av_log(avctx, AV_LOG_VERBOSE, "FrameRateExtD: %"PRIu32"; FrameRateExtN: 
%"PRIu32" \n",
+   info->FrameInfo.FrameRateExtD, info->FrameInfo.FrameRateExtN);
+
+#if QSV_HAVE_EXT_VP9_PARAM
+av_log(avctx, AV_LOG_VERBOSE, "WriteIVFHeaders: %s \n",
+   print_threestate(vp9_param->WriteIVFHeaders));
+#endif
+}
+
 static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
 {
 const char *rc_desc;
@@ -941,6 +1019,8 @@ static int qsv_retrieve_enc_vp9_params(AVCodecContext 
*avctx, QSVEncContext *q)
 
 q->packet_size = q->param.mfx.BufferSizeInKB * 
q->param.mfx.BRCParamMultiplier * 1000;
 
+dump_video_vp9_param(avctx, q, ext_buffers);
+
 return 0;
 }
 
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 5/5] lavc/qsvenc: dump parameters for mjpeg encoding in verbose mode

2021-12-12 Thread Haihao Xiang
---
 libavcodec/qsvenc.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 106438f227..92a8b49fe3 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -421,6 +421,18 @@ static void dump_video_vp9_param(AVCodecContext *avctx, 
QSVEncContext *q,
 #endif
 }
 
+static void dump_video_mjpeg_param(AVCodecContext *avctx, QSVEncContext *q)
+{
+mfxInfoMFX *info = &q->param.mfx;
+
+av_log(avctx, AV_LOG_VERBOSE, "Interleaved: %"PRIu16" \n", 
info->Interleaved);
+av_log(avctx, AV_LOG_VERBOSE, "Quality: %"PRIu16" \n", info->Quality);
+av_log(avctx, AV_LOG_VERBOSE, "RestartInterval: %"PRIu16" \n", 
info->RestartInterval);
+
+av_log(avctx, AV_LOG_VERBOSE, "FrameRateExtD: %"PRIu32"; FrameRateExtN: 
%"PRIu32" \n",
+   info->FrameInfo.FrameRateExtD, info->FrameInfo.FrameRateExtN);
+}
+
 static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
 {
 const char *rc_desc;
@@ -970,6 +982,8 @@ static int qsv_retrieve_enc_jpeg_params(AVCodecContext 
*avctx, QSVEncContext *q)
 if (q->packet_size == 0)
 q->packet_size = q->param.mfx.FrameInfo.Height * 
q->param.mfx.FrameInfo.Width * 4;
 
+dump_video_mjpeg_param(avctx, q);
+
 return 0;
 }
 
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3 2/2] avcodec/vpp_qsv: Copy side data from input to output frame

2021-12-12 Thread Soft Works



> -Original Message-
> From: ffmpeg-devel  On Behalf Of Xiang,
> Haihao
> Sent: Monday, December 13, 2021 6:55 AM
> To: ffmpeg-devel@ffmpeg.org
> Subject: Re: [FFmpeg-devel] [PATCH v3 2/2] avcodec/vpp_qsv: Copy side data
> from input to output frame
> 
> 
> > > -Original Message-
> > > From: ffmpeg-devel  On Behalf Of Xiang,
> > > Haihao
> > > Sent: Thursday, December 9, 2021 9:35 AM
> > > To: ffmpeg-devel@ffmpeg.org
> > > Subject: Re: [FFmpeg-devel] [PATCH v3 2/2] avcodec/vpp_qsv: Copy side
> data
> > > from input to output frame
> > >
> > > On Tue, 2021-12-07 at 12:39 +, Soft Works wrote:
> > > > > -Original Message-
> > > > > From: ffmpeg-devel  On Behalf Of
> Anton
> > > > > Khirnov
> > > > > Sent: Tuesday, December 7, 2021 12:51 PM
> > > > > To: FFmpeg development discussions and patches  de...@ffmpeg.org>
> > > > > Subject: Re: [FFmpeg-devel] [PATCH v3 2/2] avcodec/vpp_qsv: Copy side
> > >
> > > data
> > > > > from input to output frame
> > > > >
> > > > > Quoting Soft Works (2021-12-07 09:55:37)
> > > > > >
> > > > > >
> > > > > > > -Original Message-
> > > > > > > From: ffmpeg-devel  On Behalf Of
> > >
> > > Anton
> > > > > > > Khirnov
> > > > > > > Sent: Tuesday, December 7, 2021 9:04 AM
> > > > > > > To: ffmpeg-devel@ffmpeg.org
> > > > > > > Subject: Re: [FFmpeg-devel] [PATCH v3 2/2] avcodec/vpp_qsv: Copy
> > > > > > > side
> > > > >
> > > > > data
> > > > > > > from input to output frame
> > > > > > >
> > > > > > > Quoting Soft Works (2021-12-03 08:58:31)
> > > > > > > > Signed-off-by: softworkz 
> > > > > > > > ---
> > > > > > > >  libavfilter/qsvvpp.c |  5 +
> > > > > > > >  libavfilter/vf_overlay_qsv.c | 19 +++
> > > > > > > >  2 files changed, 20 insertions(+), 4 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
> > > > > > > > index d1218355c7..b291216292 100644
> > > > > > > > --- a/libavfilter/qsvvpp.c
> > > > > > > > +++ b/libavfilter/qsvvpp.c
> > > > > > > > @@ -849,6 +849,11 @@ int ff_qsvvpp_filter_frame(QSVVPPContext
> *s,
> > > > > > >
> > > > > > > AVFilterLink *inlink, AVFrame *picr
> > > > > > > >  return AVERROR(EAGAIN);
> > > > > > > >  break;
> > > > > > > >  }
> > > > > > > > +
> > > > > > > > +ret = av_frame_copy_side_data(out_frame->frame,
> in_frame-
> > > > > >
> > > > > > frame,
> > > > > > > 0);
> > > > > > > > +if (ret < 0)
> > > > > > > > +return ret;
> > > > > > > > +
> > > > > > > >  out_frame->frame->pts = av_rescale_q(out_frame-
> > > > > > > > surface.Data.TimeStamp,
> > > > > > > >   default_tb,
> outlink-
> > > > > > > > time_base);
> > > > > > > >
> > > > > > > > diff --git a/libavfilter/vf_overlay_qsv.c
> > > > >
> > > > > b/libavfilter/vf_overlay_qsv.c
> > > > > > > > index 7e76b39aa9..02518e020c 100644
> > > > > > > > --- a/libavfilter/vf_overlay_qsv.c
> > > > > > > > +++ b/libavfilter/vf_overlay_qsv.c
> > > > > > > > @@ -231,13 +231,24 @@ static int process_frame(FFFrameSync *fs)
> > > > > > > >  {
> > > > > > > >  AVFilterContext  *ctx = fs->parent;
> > > > > > > >  QSVOverlayContext  *s = fs->opaque;
> > > > > > > > +AVFrame   *frame0 = NULL;
> > > > > > > >  AVFrame*frame = NULL;
> > > > > > > > -int   ret = 0, i;
> > > > > > > > +int   ret = 0;
> > > > > > > >
> > > > > > > > -for (i = 0; i < ctx->nb_inputs; i++) {
> > > > > > > > +for (unsigned i = 0; i < ctx->nb_inputs; i++) {
> > > > > > > >  ret = ff_framesync_get_frame(fs, i, &frame, 0);
> > > > > > > > -if (ret == 0)
> > > > > > > > -ret = ff_qsvvpp_filter_frame(s->qsv, ctx-
> >inputs[i],
> > > > >
> > > > > frame);
> > > > > > > > +
> > > > > > > > +if (ret == 0) {
> > > > > > > > +AVFrame *temp;
> > > > > > > > +
> > > > > > > > +if (i == 0)
> > > > > > > > +frame0 = frame;
> > > > > > > > +else
> > > > > > > > +ret = av_frame_copy_side_data(frame, frame0,
> 0);
> > > > > > > > +
> > > > > > > > +ret = ret < 0 ? ret : ff_qsvvpp_filter_frame(s-
> >qsv,
> > >
> > > ctx-
> > > > > > > > inputs[i], frame);
> > > > > > >
> > > > > > > I don't quite understand the ownership semantics here. This
> function
> > > > > > > does not free frame, so I assume ff_qsvvpp_filter_frame() takes
> > > > > > > ownership of it. That would mean you're not allowed to keep a
> > > > > > > pointer
> > >
> > > to
> > > > > > > it and access it later, because it might have already been freed.
> > > > > >
> > > > > > The filter is using framesync, which is taking care of the
> ownership.
> > > > > > ff_qsvvpp_filter_frame() clones or copies the frame, depending on
> > > > > > case.
> > > > > > Other than with the normal overlay filter, the frame from input0 is
> > > > > > not used for output. But the regular over

[FFmpeg-devel] [PATCH v4 00/13] dshow enhancements

2021-12-12 Thread Diederick Niehorster
This series solves some outstanding bugs in the dshow device, implements
get_device_list so that `ffmpeg -sources dshow` works and adds logic to
select a video format with extended color information (color range,
space, etc) if exposed by the device.

This is a new version of part of the patch series in
https://ffmpeg.org/pipermail/ffmpeg-devel/2021-July/282073.html,
addressing review comments i got there. They have been previously OK'ed
offlist by the dshow maintainer Roger Pack. Specifically, these patches
are the enhancements that should be uncontroversial as they do not touch
the avformat API. I hope they can be swiftly pushed by someone, then
i'll re-send the other more controversial patches on top of these.

Diederick Niehorster (13):
  avdevice/dshow: prevent NULL access
  avdevice/dshow: implement option to use device video timestamps
  avdevice/dshow: add use_video_device_timestamps to docs
  avdevice/dshow: query graph and sample time only once
  avdevice/dshow: handle unknown sample time
  avdevice/dshow: set no-seek flags
  avdevice/dshow: implement get_device_list
  avdevice/dshow: list_devices: show media type(s) per device
  avdevice: add info about media types(s) to AVDeviceInfo
  avdevice/dshow: add media type info to get_device_list
  fftools: provide media type info for devices
  avdevice/dshow: discover source color range/space/etc
  avdevice/dshow: select format with extended color info

 doc/indevs.texi |   6 +
 fftools/cmdutils.c  |  34 +-
 libavdevice/avdevice.c  |   2 +
 libavdevice/avdevice.h  |   2 +
 libavdevice/dshow.c | 838 +++-
 libavdevice/dshow_capture.h |   1 +
 libavdevice/dshow_pin.c |  46 +-
 libavdevice/version.h   |   2 +-
 8 files changed, 797 insertions(+), 134 deletions(-)

-- 
2.28.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 01/13] avdevice/dshow: prevent NULL access

2021-12-12 Thread Diederick Niehorster
list_options true would crash when both a video and an audio device were
specified as input. Crash would occur on line 784 because
ctx->device_unique_name[otherDevType] would be NULL

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index ef78781865..cc0bef0474 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -708,9 +708,9 @@ dshow_list_device_options(AVFormatContext *avctx, 
ICreateDevEnum *devenum,
 if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, 
&device_filter, &device_unique_name)) < 0)
 return r;
 ctx->device_filter[devtype] = device_filter;
+ctx->device_unique_name[devtype] = device_unique_name;
 if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, 
NULL)) < 0)
 return r;
-av_freep(&device_unique_name);
 return 0;
 }
 
@@ -1143,6 +1143,7 @@ static int dshow_read_header(AVFormatContext *avctx)
 }
 }
 }
+// don't exit yet, allow it to list crossbar options in 
dshow_open_device
 }
 if (ctx->device_name[VideoDevice]) {
 if ((r = dshow_open_device(avctx, devenum, VideoDevice, 
VideoSourceDevice)) < 0 ||
-- 
2.28.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 02/13] avdevice/dshow: implement option to use device video timestamps

2021-12-12 Thread Diederick Niehorster
The dshow avdevice ignores timestamps for video frames provided by the
DirectShow device, instead using wallclock time, apparently because the
implementer of this code had a device that provided unreliable
timestamps. Me (and others) would like to use the device's timestamps.
The new use_video_device_timestamps option for dshow device enables them
to do so. Since the majority of video devices out there probably provide
fine timestamps, this patch sets the default to using the device
timestamps, which means best fidelity timestamps are used by default.
Using the new option, the user can switch this off and revert to the old
behavior, so a fall back remains available in case the device provides
broken timestamps.

Closes: #8620

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c |  1 +
 libavdevice/dshow_capture.h |  1 +
 libavdevice/dshow_pin.c | 11 ++-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index cc0bef0474..5e6eb9c85d 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -1310,6 +1310,7 @@ static const AVOption options[] = {
 { "audio_device_save", "save audio capture filter device (and properties) 
to file", OFFSET(audio_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 
0, DEC },
 { "video_device_load", "load video capture filter device (and properties) 
from file", OFFSET(video_filter_load_file), AV_OPT_TYPE_STRING, {.str = NULL}, 
0, 0, DEC },
 { "video_device_save", "save video capture filter device (and properties) 
to file", OFFSET(video_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 
0, DEC },
+{ "use_video_device_timestamps", "use device instead of wallclock 
timestamps for video frames", OFFSET(use_video_device_timestamps), 
AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
 { NULL },
 };
 
diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h
index 06ded2ba96..5a2691518c 100644
--- a/libavdevice/dshow_capture.h
+++ b/libavdevice/dshow_capture.h
@@ -312,6 +312,7 @@ struct dshow_ctx {
 char *audio_filter_save_file;
 char *video_filter_load_file;
 char *video_filter_save_file;
+int   use_video_device_timestamps;
 
 IBaseFilter *device_filter[2];
 IPin*device_pin[2];
diff --git a/libavdevice/dshow_pin.c b/libavdevice/dshow_pin.c
index 3dae405e65..8e56dccbfe 100644
--- a/libavdevice/dshow_pin.c
+++ b/libavdevice/dshow_pin.c
@@ -309,10 +309,14 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 if (!sample)
 return E_POINTER;
 
+priv_data = pin->filter->priv_data;
+s = priv_data;
+ctx = s->priv_data;
+
 IMediaSample_GetTime(sample, &orig_curtime, &dummy);
 orig_curtime += pin->filter->start_time;
 IReferenceClock_GetTime(clock, &graphtime);
-if (devtype == VideoDevice) {
+if (devtype == VideoDevice && !ctx->use_video_device_timestamps) {
 /* PTS from video devices is unreliable. */
 IReferenceClock_GetTime(clock, &curtime);
 } else {
@@ -322,7 +326,7 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
like 437650244077016960 which FFmpeg doesn't like.
TODO figure out math. For now just drop them. */
 av_log(NULL, AV_LOG_DEBUG,
-"dshow dropping initial (or ending) audio frame with odd PTS 
too high %"PRId64"\n", curtime);
+"dshow dropping initial (or ending) frame with odd PTS too 
high %"PRId64"\n", curtime);
 return S_OK;
 }
 curtime += pin->filter->start_time;
@@ -330,9 +334,6 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 
 buf_size = IMediaSample_GetActualDataLength(sample);
 IMediaSample_GetPointer(sample, &buf);
-priv_data = pin->filter->priv_data;
-s = priv_data;
-ctx = s->priv_data;
 index = pin->filter->stream_index;
 
 av_log(NULL, AV_LOG_VERBOSE, "dshow passing through packet of type %s size 
%8d "
-- 
2.28.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 03/13] avdevice/dshow: add use_video_device_timestamps to docs

2021-12-12 Thread Diederick Niehorster
Signed-off-by: Diederick Niehorster 
---
 doc/indevs.texi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index 5be647f70a..9d8020311a 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -625,6 +625,12 @@ Save the currently used video capture filter device and its
 parameters (if the filter supports it) to a file.
 If a file with the same name exists it will be overwritten.
 
+@item use_video_device_timestamps
+If set to @option{false}, the timestamp for video frames will be
+derived from the wallclock instead of the timestamp provided by
+the capture device. This allows working around devices that
+provide unreliable timestamps.
+
 @end table
 
 @subsection Examples
-- 
2.28.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 04/13] avdevice/dshow: query graph and sample time only once

2021-12-12 Thread Diederick Niehorster
No need to query twice, use value we've already unconditionally got.
Improve variable names

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow_pin.c | 28 
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/libavdevice/dshow_pin.c b/libavdevice/dshow_pin.c
index 8e56dccbfe..1d0e880480 100644
--- a/libavdevice/dshow_pin.c
+++ b/libavdevice/dshow_pin.c
@@ -295,9 +295,10 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 uint8_t *buf;
 int buf_size; /* todo should be a long? */
 int index;
-int64_t curtime;
-int64_t orig_curtime;
+int64_t chosentime;
+int64_t sampletime;
 int64_t graphtime;
+int use_sample_time = 1;
 const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
 IReferenceClock *clock = pin->filter->clock;
 int64_t dummy;
@@ -313,24 +314,27 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 s = priv_data;
 ctx = s->priv_data;
 
-IMediaSample_GetTime(sample, &orig_curtime, &dummy);
-orig_curtime += pin->filter->start_time;
+IMediaSample_GetTime(sample, &sampletime, &dummy);
 IReferenceClock_GetTime(clock, &graphtime);
 if (devtype == VideoDevice && !ctx->use_video_device_timestamps) {
 /* PTS from video devices is unreliable. */
-IReferenceClock_GetTime(clock, &curtime);
+chosentime = graphtime;
+use_sample_time = 0;
 } else {
-IMediaSample_GetTime(sample, &curtime, &dummy);
-if(curtime > 40LL) {
+if (sampletime > 40LL) {
 /* initial frames sometimes start < 0 (shown as a very large 
number here,
-   like 437650244077016960 which FFmpeg doesn't like.
+   like 437650244077016960 which FFmpeg doesn't like).
TODO figure out math. For now just drop them. */
 av_log(NULL, AV_LOG_DEBUG,
-"dshow dropping initial (or ending) frame with odd PTS too 
high %"PRId64"\n", curtime);
+"dshow dropping initial (or ending) frame with odd PTS too 
high %"PRId64"\n", sampletime);
 return S_OK;
 }
-curtime += pin->filter->start_time;
+chosentime = sampletime;
 }
+// media sample time is relative to graph start time
+sampletime += pin->filter->start_time;
+if (use_sample_time)
+chosentime += pin->filter->start_time;
 
 buf_size = IMediaSample_GetActualDataLength(sample);
 IMediaSample_GetPointer(sample, &buf);
@@ -338,8 +342,8 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 
 av_log(NULL, AV_LOG_VERBOSE, "dshow passing through packet of type %s size 
%8d "
 "timestamp %"PRId64" orig timestamp %"PRId64" graph timestamp 
%"PRId64" diff %"PRId64" %s\n",
-devtypename, buf_size, curtime, orig_curtime, graphtime, graphtime - 
orig_curtime, ctx->device_name[devtype]);
-pin->filter->callback(priv_data, index, buf, buf_size, curtime, devtype);
+devtypename, buf_size, chosentime, sampletime, graphtime, graphtime - 
sampletime, ctx->device_name[devtype]);
+pin->filter->callback(priv_data, index, buf, buf_size, chosentime, 
devtype);
 
 return S_OK;
 }
-- 
2.28.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 05/13] avdevice/dshow: handle unknown sample time

2021-12-12 Thread Diederick Niehorster
GetTime may return an error indication that the sample has not
timestamps, or may return a NULL start time. In those cases, fall back
to graph time.
Better debug message in case sample dropped: could now be audio or
video frame

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow_pin.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/libavdevice/dshow_pin.c b/libavdevice/dshow_pin.c
index 1d0e880480..310f48c85e 100644
--- a/libavdevice/dshow_pin.c
+++ b/libavdevice/dshow_pin.c
@@ -295,14 +295,15 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 uint8_t *buf;
 int buf_size; /* todo should be a long? */
 int index;
-int64_t chosentime;
-int64_t sampletime;
-int64_t graphtime;
+int64_t chosentime = 0;
+int64_t sampletime = 0;
+int64_t graphtime = 0;
 int use_sample_time = 1;
 const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
 IReferenceClock *clock = pin->filter->clock;
 int64_t dummy;
 struct dshow_ctx *ctx;
+HRESULT hr;
 
 
 dshowdebug("ff_dshow_meminputpin_Receive(%p)\n", this);
@@ -314,22 +315,26 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 s = priv_data;
 ctx = s->priv_data;
 
-IMediaSample_GetTime(sample, &sampletime, &dummy);
+hr = IMediaSample_GetTime(sample, &sampletime, &dummy);
 IReferenceClock_GetTime(clock, &graphtime);
 if (devtype == VideoDevice && !ctx->use_video_device_timestamps) {
 /* PTS from video devices is unreliable. */
 chosentime = graphtime;
 use_sample_time = 0;
 } else {
-if (sampletime > 40LL) {
+if (hr == VFW_E_SAMPLE_TIME_NOT_SET || sampletime == 0) {
+chosentime = graphtime;
+use_sample_time = 0;
+}
+else if (sampletime > 40LL) {
 /* initial frames sometimes start < 0 (shown as a very large 
number here,
like 437650244077016960 which FFmpeg doesn't like).
TODO figure out math. For now just drop them. */
 av_log(NULL, AV_LOG_DEBUG,
 "dshow dropping initial (or ending) frame with odd PTS too 
high %"PRId64"\n", sampletime);
 return S_OK;
-}
-chosentime = sampletime;
+} else
+chosentime = sampletime;
 }
 // media sample time is relative to graph start time
 sampletime += pin->filter->start_time;
-- 
2.28.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 06/13] avdevice/dshow: set no-seek flags

2021-12-12 Thread Diederick Niehorster
avdevice/dshow is a realtime device and as such does not support
seeking. Therefore, its demuxer format should define the
AVFMT_NOBINSEARCH, AVFMT_NOGENSEARCH and AVFMT_NO_BYTE_SEEK flags.
With these flags set, attempting to seek (with, e.g.,
avformat_seek_file()) correctly yields -1 (operation not permitted)
instead of -22 (invalid argument).

This actually seems to apply to many other devices, at least the
gdigrab, v4l2, vfwcap, x11grab, fbdev, kmsgrab and android_camera
devices, from reading the source.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 5e6eb9c85d..0ef3b3d13e 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -1329,6 +1329,6 @@ const AVInputFormat ff_dshow_demuxer = {
 .read_header= dshow_read_header,
 .read_packet= dshow_read_packet,
 .read_close = dshow_read_close,
-.flags  = AVFMT_NOFILE,
+.flags  = AVFMT_NOFILE | AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | 
AVFMT_NO_BYTE_SEEK,
 .priv_class = &dshow_class,
 };
-- 
2.28.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 07/13] avdevice/dshow: implement get_device_list

2021-12-12 Thread Diederick Niehorster
Needed to enable programmatic discovery of DirectShow devices

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 80 +
 1 file changed, 73 insertions(+), 7 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 0ef3b3d13e..8c257ca8e7 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -202,11 +202,14 @@ fail:
  * retrieve the device with type specified by devtype and return the
  * pointer to the object found in *pfilter.
  * If pfilter is NULL, list all device names.
+ * If device_list is not NULL, populate it with found devices instead of
+ * outputting device names to log
  */
 static int
 dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
 enum dshowDeviceType devtype, enum dshowSourceFilterType 
sourcetype,
-IBaseFilter **pfilter, char **device_unique_name)
+IBaseFilter **pfilter, char **device_unique_name,
+AVDeviceInfoList **device_list)
 {
 struct dshow_ctx *ctx = avctx->priv_data;
 IBaseFilter *device_filter = NULL;
@@ -238,6 +241,7 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 IBindCtx *bind_ctx = NULL;
 LPOLESTR olestr = NULL;
 LPMALLOC co_malloc = NULL;
+AVDeviceInfo *device = NULL;
 int i;
 
 r = CoGetMalloc(1, &co_malloc);
@@ -282,11 +286,39 @@ dshow_cycle_devices(AVFormatContext *avctx, 
ICreateDevEnum *devenum,
 // success, loop will end now
 }
 } else {
-av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
-av_log(avctx, AV_LOG_INFO, "Alternative name \"%s\"\n", 
unique_name);
+if (device_list) {
+device = av_mallocz(sizeof(AVDeviceInfo));
+if (!device)
+goto fail1;
+
+device->device_name = av_strdup(friendly_name);
+device->device_description = av_strdup(unique_name);
+if (!device->device_name || !device->device_description)
+goto fail1;
+
+// store to device_list output
+if (av_reallocp_array(&(*device_list)->devices,
+ (*device_list)->nb_devices + 1,
+ sizeof(*(*device_list)->devices)) < 0)
+goto fail1;
+(*device_list)->devices[(*device_list)->nb_devices] = device;
+(*device_list)->nb_devices++;
+device = NULL;  // copied into array, make sure not freed below
+}
+else {
+av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
+av_log(avctx, AV_LOG_INFO, "Alternative name \"%s\"\n", 
unique_name);
+}
 }
 
 fail1:
+if (device) {
+if (device->device_name)
+av_freep(&device->device_name);
+if (device->device_name)
+av_freep(&device->device_description);
+av_free(device);
+}
 if (olestr && co_malloc)
 IMalloc_Free(co_malloc, olestr);
 if (bind_ctx)
@@ -312,6 +344,39 @@ fail1:
 return 0;
 }
 
+static int dshow_get_device_list(AVFormatContext *avctx, AVDeviceInfoList 
*device_list)
+{
+struct dshow_ctx *ctx = avctx->priv_data;
+ICreateDevEnum *devenum = NULL;
+int r;
+int ret = AVERROR(EIO);
+
+if (!device_list)
+return AVERROR(EINVAL);
+
+CoInitialize(0);
+
+r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
+&IID_ICreateDevEnum, (void**)&devenum);
+if (r != S_OK) {
+av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
+goto error;
+}
+
+ret = dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, 
NULL, NULL, &device_list);
+if (ret < S_OK)
+goto error;
+ret = dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, 
NULL, NULL, &device_list);
+
+error:
+if (devenum)
+ICreateDevEnum_Release(devenum);
+
+CoUninitialize();
+
+return ret;
+}
+
 /**
  * Cycle through available formats using the specified pin,
  * try to set parameters specified through AVOptions and if successful
@@ -705,7 +770,7 @@ dshow_list_device_options(AVFormatContext *avctx, 
ICreateDevEnum *devenum,
 char *device_unique_name = NULL;
 int r;
 
-if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, 
&device_filter, &device_unique_name)) < 0)
+if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, 
&device_filter, &device_unique_name, NULL)) < 0)
 return r;
 ctx->device_filter[devtype] = device_filter;
 ctx->device_unique_name[devtype] = device_unique_name;
@@ -765,7 +830,7 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 av_log(avctx, AV_LOG_INFO, "C

[FFmpeg-devel] [PATCH v4 08/13] avdevice/dshow: list_devices: show media type(s) per device

2021-12-12 Thread Diederick Niehorster
the list_devices option of dshow didn't indicate whether a specific
device provides audio or video output. This patch iterates through all
media formats of all pins exposed by the device to see what types it
provides for capture, and prints this to the console for each device.
Importantly, this now allows to find devices that provide both audio and
video, and devices that provide neither.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 103 +---
 1 file changed, 98 insertions(+), 5 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 8c257ca8e7..f25537db5c 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -197,6 +197,79 @@ fail:
 return;
 }
 
+static void dshow_get_device_media_types(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
+ enum dshowSourceFilterType 
sourcetype, IBaseFilter *device_filter,
+ enum AVMediaType **media_types, int 
*nb_media_types)
+{
+struct dshow_ctx *ctx = avctx->priv_data;
+IEnumPins *pins = 0;
+IPin *pin;
+int has_audio = 0, has_video = 0;
+
+if (IBaseFilter_EnumPins(device_filter, &pins) != S_OK)
+return;
+
+while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
+IKsPropertySet *p = NULL;
+PIN_INFO info = { 0 };
+GUID category;
+DWORD r2;
+IEnumMediaTypes *types = NULL;
+AM_MEDIA_TYPE *type;
+
+if (IPin_QueryPinInfo(pin, &info) != S_OK)
+goto next;
+IBaseFilter_Release(info.pFilter);
+
+if (info.dir != PINDIR_OUTPUT)
+goto next;
+if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != 
S_OK)
+goto next;
+if (IKsPropertySet_Get(p, &ROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
+   NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
+goto next;
+if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
+goto next;
+
+if (IPin_EnumMediaTypes(pin, &types) != S_OK)
+goto next;
+
+// enumerate media types exposed by pin
+// NB: don't know if a pin can expose both audio and video, check 'm 
all to be safe
+IEnumMediaTypes_Reset(types);
+while (IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
+if (IsEqualGUID(&type->majortype, &MEDIATYPE_Video)) {
+has_video = 1;
+} else if (IsEqualGUID(&type->majortype, &MEDIATYPE_Audio)) {
+has_audio = 1;
+}
+CoTaskMemFree(type);
+}
+
+next:
+if (types)
+IEnumMediaTypes_Release(types);
+if (p)
+IKsPropertySet_Release(p);
+if (pin)
+IPin_Release(pin);
+}
+
+IEnumPins_Release(pins);
+
+if (has_audio || has_video) {
+int nb_types = has_audio + has_video;
+*media_types = av_malloc_array(nb_types, sizeof(enum AVMediaType));
+if (*media_types) {
+if (has_audio)
+(*media_types)[0] = AVMEDIA_TYPE_AUDIO;
+if (has_video)
+(*media_types)[0 + has_audio] = AVMEDIA_TYPE_VIDEO;
+*nb_media_types = nb_types;
+}
+}
+}
+
 /**
  * Cycle through available devices using the device enumerator devenum,
  * retrieve the device with type specified by devtype and return the
@@ -242,6 +315,8 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 LPOLESTR olestr = NULL;
 LPMALLOC co_malloc = NULL;
 AVDeviceInfo *device = NULL;
+enum AVMediaType *media_types = NULL;
+int nb_media_types = 0;
 int i;
 
 r = CoGetMalloc(1, &co_malloc);
@@ -286,6 +361,12 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 // success, loop will end now
 }
 } else {
+// get media types exposed by pins of device
+if (IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void* ) 
&device_filter) == S_OK) {
+dshow_get_device_media_types(avctx, devtype, sourcetype, 
device_filter, &media_types, &nb_media_types);
+IBaseFilter_Release(device_filter);
+device_filter = NULL;
+}
 if (device_list) {
 device = av_mallocz(sizeof(AVDeviceInfo));
 if (!device)
@@ -306,12 +387,26 @@ dshow_cycle_devices(AVFormatContext *avctx, 
ICreateDevEnum *devenum,
 device = NULL;  // copied into array, make sure not freed below
 }
 else {
-av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
-av_log(avctx, AV_LOG_INFO, "Alternative name \"%s\"\n", 
unique_name);
+av_log(avctx, AV_LOG_INFO, "\"%s\"", friendly_name);
+if (nb_media_types > 0 && media_types) {
+ 

[FFmpeg-devel] [PATCH v4 09/13] avdevice: add info about media types(s) to AVDeviceInfo

2021-12-12 Thread Diederick Niehorster
An avdevice, regardless of whether its category says its an audio or
video device, may provide access to devices providing different media
types, or even single devices providing multiple media types. Also, some
devices may provide no media types. dshow is an example encompassing all
of these cases. Users should be provided with this information, so
AVDeviceInfo is extended to provide it.

Bump avdevice version

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 2 ++
 libavdevice/avdevice.h | 2 ++
 libavdevice/version.h  | 2 +-
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 2ae26ab8e3..712ef1e80c 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -157,6 +157,8 @@ void avdevice_free_list_devices(AVDeviceInfoList 
**device_list)
 if (dev) {
 av_freep(&dev->device_name);
 av_freep(&dev->device_description);
+if (dev->media_types)
+av_freep(&dev->media_types);
 av_free(dev);
 }
 }
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 8370bbc7f2..6f24976dcc 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -457,6 +457,8 @@ void avdevice_capabilities_free(AVDeviceCapabilitiesQuery 
**caps, AVFormatContex
 typedef struct AVDeviceInfo {
 char *device_name;   /**< device name, format depends on 
device */
 char *device_description;/**< human friendly name */
+enum AVMediaType *media_types;   /**< array indicating what media 
types(s), if any, a device can provide. If null, cannot provide any */
+int nb_media_types;  /**< length of media_types array, 0 
if device cannot provide any media types */
 } AVDeviceInfo;
 
 /**
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 914e156ec7..c549768e12 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -28,7 +28,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVDEVICE_VERSION_MAJOR  59
-#define LIBAVDEVICE_VERSION_MINOR   0
+#define LIBAVDEVICE_VERSION_MINOR   1
 #define LIBAVDEVICE_VERSION_MICRO 101
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
-- 
2.28.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 10/13] avdevice/dshow: add media type info to get_device_list

2021-12-12 Thread Diederick Niehorster
The list returned by get_device_list now contains info about what media
type(s), if any, can be provided by each device.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index f25537db5c..fa3a06c077 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -377,6 +377,11 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 if (!device->device_name || !device->device_description)
 goto fail1;
 
+device->nb_media_types = nb_media_types;
+device->media_types = media_types;
+nb_media_types = 0;
+media_types = NULL;
+
 // store to device_list output
 if (av_reallocp_array(&(*device_list)->devices,
  (*device_list)->nb_devices + 1,
@@ -412,6 +417,8 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 av_freep(&device->device_name);
 if (device->device_name)
 av_freep(&device->device_description);
+if (device->media_types)
+av_freep(&device->media_types);
 av_free(device);
 }
 if (olestr && co_malloc)
-- 
2.28.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 11/13] fftools: provide media type info for devices

2021-12-12 Thread Diederick Niehorster
fftools now print info about what media type(s), if any, are provided by
sink and source avdevices.

Signed-off-by: Diederick Niehorster 
---
 fftools/cmdutils.c | 34 --
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 3c8e5a82cd..7d7dcce2f9 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -2244,9 +2244,29 @@ double get_rotation(int32_t *displaymatrix)
 }
 
 #if CONFIG_AVDEVICE
+static void print_device_list(const AVDeviceInfoList *device_list)
+{
+// print devices
+for (int i = 0; i < device_list->nb_devices; i++) {
+const AVDeviceInfo *device = device_list->devices[i];
+printf("%s %s [%s] (", device_list->default_device == i ? "*" : " ",
+device->device_name, device->device_description);
+if (device->nb_media_types > 0 && device->media_types) {
+for (int j = 0; j < device->nb_media_types; ++j) {
+const char* media_type = 
av_get_media_type_string(device->media_types[j]);
+if (j > 0)
+printf(", ");
+printf("%s", media_type ? media_type : "unknown");
+}
+} else {
+printf("none");
+}
+printf(")\n");
+}
+}
 static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts)
 {
-int ret, i;
+int ret;
 AVDeviceInfoList *device_list = NULL;
 
 if (!fmt || !fmt->priv_class  || 
!AV_IS_INPUT_DEVICE(fmt->priv_class->category))
@@ -2258,10 +2278,7 @@ static int print_device_sources(const AVInputFormat 
*fmt, AVDictionary *opts)
 goto fail;
 }
 
-for (i = 0; i < device_list->nb_devices; i++) {
-printf("%c %s [%s]\n", device_list->default_device == i ? '*' : ' ',
-   device_list->devices[i]->device_name, 
device_list->devices[i]->device_description);
-}
+print_device_list(device_list);
 
   fail:
 avdevice_free_list_devices(&device_list);
@@ -2270,7 +2287,7 @@ static int print_device_sources(const AVInputFormat *fmt, 
AVDictionary *opts)
 
 static int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts)
 {
-int ret, i;
+int ret;
 AVDeviceInfoList *device_list = NULL;
 
 if (!fmt || !fmt->priv_class  || 
!AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
@@ -2282,10 +2299,7 @@ static int print_device_sinks(const AVOutputFormat *fmt, 
AVDictionary *opts)
 goto fail;
 }
 
-for (i = 0; i < device_list->nb_devices; i++) {
-printf("%c %s [%s]\n", device_list->default_device == i ? '*' : ' ',
-   device_list->devices[i]->device_name, 
device_list->devices[i]->device_description);
-}
+print_device_list(device_list);
 
   fail:
 avdevice_free_list_devices(&device_list);
-- 
2.28.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 12/13] avdevice/dshow: discover source color range/space/etc

2021-12-12 Thread Diederick Niehorster
Enabled discovering a DirectShow device's color range, space, primaries,
transfer characteristics and chroma location, if the device exposes that
information. Sets them in the stream's codecpars.

Co-authored-by: Valerii Zapodovnikov 
Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 255 +++-
 1 file changed, 254 insertions(+), 1 deletion(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index fa3a06c077..4ad6ae102c 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -29,6 +29,31 @@
 #include "libavcodec/raw.h"
 #include "objidl.h"
 #include "shlwapi.h"
+// NB: technically, we should include dxva.h and use
+// DXVA_ExtendedFormat, but that type is not defined in
+// the MinGW headers. The DXVA2_ExtendedFormat and the
+// contents of its fields is identical to
+// DXVA_ExtendedFormat (see 
https://docs.microsoft.com/en-us/windows/win32/medfound/extended-color-information#color-space-in-media-types)
+// and is provided by MinGW as well, so we use that
+// instead. NB also that per the Microsoft docs, the
+// lowest 8 bits of the structure, i.e. the SampleFormat
+// field, contain AMCONTROL_xxx flags instead of sample
+// format information, and should thus not be used.
+// NB further that various values in the structure's
+// fields (e.g. BT.2020 color space) are not provided
+// for either of the DXVA structs, but are provided in
+// the flags of the corresponding fields of Media Foundation.
+// These may be provided by DirectShow devices (e.g. LAVFilters
+// does so). So we use those values here too (the equivalence is
+// indicated by Microsoft example code: 
https://docs.microsoft.com/en-us/windows/win32/api/dxva2api/ns-dxva2api-dxva2_videodesc)
+typedef DWORD D3DFORMAT;// dxva2api.h header needs these types defined 
before include apparently in WinSDK (not MinGW).
+typedef DWORD D3DPOOL;
+#include "dxva2api.h"
+
+#ifndef AMCONTROL_COLORINFO_PRESENT
+// not defined in some versions of MinGW's dvdmedia.h
+#   define AMCONTROL_COLORINFO_PRESENT 0x0080 // if set, indicates DXVA 
color info is present in the upper (24) bits of the dwControlFlags
+#endif
 
 
 static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
@@ -54,6 +79,192 @@ static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, 
WORD biBitCount)
 return avpriv_find_pix_fmt(avpriv_get_raw_pix_fmt_tags(), biCompression); 
// all others
 }
 
+static enum AVColorRange dshow_color_range(DXVA2_ExtendedFormat *fmt_info)
+{
+switch (fmt_info->NominalRange)
+{
+case DXVA2_NominalRange_Unknown:
+return AVCOL_RANGE_UNSPECIFIED;
+case DXVA2_NominalRange_Normal: // equal to DXVA2_NominalRange_0_255
+return AVCOL_RANGE_JPEG;
+case DXVA2_NominalRange_Wide:   // equal to DXVA2_NominalRange_16_235
+return AVCOL_RANGE_MPEG;
+case DXVA2_NominalRange_48_208:
+// not an ffmpeg color range
+return AVCOL_RANGE_UNSPECIFIED;
+
+// values from MediaFoundation SDK (mfobjects.h)
+case 4: // MFNominalRange_64_127
+// not an ffmpeg color range
+return AVCOL_RANGE_UNSPECIFIED;
+
+default:
+return DXVA2_NominalRange_Unknown;
+}
+}
+
+static enum AVColorSpace dshow_color_space(DXVA2_ExtendedFormat *fmt_info)
+{
+enum AVColorSpace ret = AVCOL_SPC_UNSPECIFIED;
+
+switch (fmt_info->VideoTransferMatrix)
+{
+case DXVA2_VideoTransferMatrix_BT709:
+ret = AVCOL_SPC_BT709;
+break;
+case DXVA2_VideoTransferMatrix_BT601:
+ret = AVCOL_SPC_BT470BG;
+break;
+case DXVA2_VideoTransferMatrix_SMPTE240M:
+ret = AVCOL_SPC_SMPTE240M;
+break;
+
+// values from MediaFoundation SDK (mfobjects.h)
+case 4: // MFVideoTransferMatrix_BT2020_10
+case 5: // MFVideoTransferMatrix_BT2020_12
+if (fmt_info->VideoTransferFunction==12)// 
MFVideoTransFunc_2020_const
+ret = AVCOL_SPC_BT2020_CL;
+else
+ret = AVCOL_SPC_BT2020_NCL;
+break;
+}
+
+if (ret == AVCOL_SPC_UNSPECIFIED)
+{
+// if color space not known from transfer matrix,
+// fall back to using primaries to guess color space
+switch (fmt_info->VideoPrimaries)
+{
+case DXVA2_VideoPrimaries_BT709:
+ret = AVCOL_SPC_BT709;
+break;
+case DXVA2_VideoPrimaries_BT470_2_SysM:
+ret = AVCOL_SPC_FCC;
+break;
+case DXVA2_VideoPrimaries_BT470_2_SysBG:
+case DXVA2_VideoPrimaries_EBU3213:   // this is PAL
+ret = AVCOL_SPC_BT470BG;
+break;
+case DXVA2_VideoPrimaries_SMPTE170M:
+case DXVA2_VideoPrimaries_SMPTE_C:
+ret = AVCOL_SPC_SMPTE170M;
+break;
+case DXVA2_VideoPrimaries_SMPTE240M:
+ret = AVCOL_SPC_SMPTE240M;
+break;
+}
+}
+
+return ret;
+}
+
+static enum AVColorPrimaries dshow_color_prim

[FFmpeg-devel] [PATCH v4 13/13] avdevice/dshow: select format with extended color info

2021-12-12 Thread Diederick Niehorster
Some DirectShow devices (Logitech C920 webcam) expose each DirectShow
format they support twice, once without and once with extended color
information. During format selection, both match, this patch ensures
that the format with extended color information is selected if it is
available, else it falls back to a matching format without such
information. This also necessitated a new code path taken for default
formats of a device (when user didn't request any specific video size,
etc), because the default format may be one without extended color
information when a twin with extended color information is also
available. Getting the extended color information when available is
important as it allows setting the color space, range, primaries,
transfer characteristics and chroma location of the stream provided by
dshow, enabling users to get more correct color automatically out of
their device.

Closes: #9271

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 469 +++-
 1 file changed, 338 insertions(+), 131 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 4ad6ae102c..6f2a3ac1ba 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -23,6 +23,7 @@
 #include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/opt.h"
+#include "libavutil/mem.h"
 #include "libavformat/internal.h"
 #include "libavformat/riff.h"
 #include "avdevice.h"
@@ -690,9 +691,111 @@ error:
 return ret;
 }
 
+static int dshow_should_set_format(AVFormatContext *avctx, enum 
dshowDeviceType devtype)
+{
+struct dshow_ctx *ctx = avctx->priv_data;
+
+return (devtype == VideoDevice && (ctx->framerate ||
+  (ctx->requested_width && 
ctx->requested_height) ||
+   ctx->pixel_format != AV_PIX_FMT_NONE ||
+   ctx->video_codec_id != 
AV_CODEC_ID_RAWVIDEO))
+|| (devtype == AudioDevice && (ctx->channels || ctx->sample_size || 
ctx->sample_rate));
+}
+
+
+struct dshow_format_info {
+enum dshowDeviceType devtype;
+// video
+int64_t framerate;
+enum AVPixelFormat pix_fmt;
+enum AVCodecID codec_id;
+enum AVColorRange col_range;
+enum AVColorSpace col_space;
+enum AVColorPrimaries col_prim;
+enum AVColorTransferCharacteristic col_trc;
+enum AVChromaLocation chroma_loc;
+int width;
+int height;
+// audio
+int sample_rate;
+int sample_size;
+int channels;
+};
+
+// user must av_free the returned pointer
+static struct dshow_format_info *dshow_get_format_info(AM_MEDIA_TYPE *type)
+{
+struct dshow_format_info *fmt_info = NULL;
+BITMAPINFOHEADER *bih;
+DXVA2_ExtendedFormat *extended_format_info = NULL;
+WAVEFORMATEX *fx;
+enum dshowDeviceType devtype;
+int64_t framerate;
+
+if (!type)
+return NULL;
+
+if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
+VIDEOINFOHEADER *v = (void *) type->pbFormat;
+framerate = v->AvgTimePerFrame;
+bih   = &v->bmiHeader;
+devtype   = VideoDevice;
+} else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
+VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
+devtype   = VideoDevice;
+framerate = v->AvgTimePerFrame;
+bih   = &v->bmiHeader;
+if (v->dwControlFlags & AMCONTROL_COLORINFO_PRESENT)
+extended_format_info = (DXVA2_ExtendedFormat *) &v->dwControlFlags;
+} else if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
+fx = (void *) type->pbFormat;
+devtype = AudioDevice;
+} else {
+return NULL;
+}
+
+fmt_info = av_mallocz(sizeof(struct dshow_format_info));
+if (!fmt_info)
+return NULL;
+// initialize fields where unset is not zero
+fmt_info->pix_fmt = AV_PIX_FMT_NONE;
+fmt_info->col_space = AVCOL_SPC_UNSPECIFIED;
+fmt_info->col_prim = AVCOL_PRI_UNSPECIFIED;
+fmt_info->col_trc = AVCOL_TRC_UNSPECIFIED;
+// now get info about format
+fmt_info->devtype = devtype;
+if (devtype == VideoDevice) {
+fmt_info->width = bih->biWidth;
+fmt_info->height = bih->biHeight;
+fmt_info->framerate = framerate;
+fmt_info->pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
+if (fmt_info->pix_fmt == AV_PIX_FMT_NONE) {
+const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), 
NULL };
+fmt_info->codec_id = av_codec_get_id(tags, bih->biCompression);
+}
+else
+fmt_info->codec_id = AV_CODEC_ID_RAWVIDEO;
+
+if (extended_format_info) {
+fmt_info->col_range = dshow_color_range(extended_format_info);
+fmt_info->col_space = dshow_color_space(extended_format_info);
+fmt_info->col_prim = dshow_color_primaries(extended_format_info);
+fmt_info->col_trc = dshow_color_trc(extended