[FFmpeg-devel] [PATCH v3] avformat/mov: Add support for demuxing still HEIC images

2023-10-04 Thread Vignesh Venkatasubramanian via ffmpeg-devel
They are similar to AVIF images (both use the HEIF container).
The only additional work needed is to parse the hvcC box and put
it in the extradata.

With this patch applied, ffmpeg (when built with an HEVC decoder)
is able to decode the files in
https://github.com/nokiatech/heif/tree/gh-pages/content/images

Also add a couple of fate tests with samples from
https://github.com/nokiatech/heif_conformance/tree/master/conformance_files

Partially fixes trac ticket #6521.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h|  2 +
 libavformat/mov.c | 41 ++-
 tests/fate/mov.mak|  6 +++
 .../fate/mov-heic-demux-still-image-1-item| 11 +
 .../mov-heic-demux-still-image-multiple-items | 11 +
 5 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 tests/ref/fate/mov-heic-demux-still-image-1-item
 create mode 100644 tests/ref/fate/mov-heic-demux-still-image-multiple-items

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 3d375d7a46..b30b9da65e 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -327,6 +327,8 @@ typedef struct MOVContext {
 int64_t extent_offset;
 } *avif_info;
 int avif_info_size;
+int64_t hvcC_offset;
+int hvcC_size;
 int interleaved_read;
 } MOVContext;
 
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 294c864fbd..d3747022bd 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1218,7 +1218,8 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 c->isom = 1;
 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char 
*));
 av_dict_set(>fc->metadata, "major_brand", type, 0);
-c->is_still_picture_avif = !strncmp(type, "avif", 4);
+c->is_still_picture_avif = !strncmp(type, "avif", 4) ||
+   !strncmp(type, "mif1", 4);
 minor_ver = avio_rb32(pb); /* minor version */
 av_dict_set_int(>fc->metadata, "minor_version", minor_ver, 0);
 
@@ -4911,6 +4912,19 @@ static int avif_add_stream(MOVContext *c, int item_id)
 st->priv_data = sc;
 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
 st->codecpar->codec_id = AV_CODEC_ID_AV1;
+if (c->hvcC_offset >= 0) {
+int ret;
+int64_t pos = avio_tell(c->fc->pb);
+st->codecpar->codec_id = AV_CODEC_ID_HEVC;
+if (avio_seek(c->fc->pb, c->hvcC_offset, SEEK_SET) != c->hvcC_offset) {
+av_log(c->fc, AV_LOG_ERROR, "Failed to seek to hvcC data.\n");
+return AVERROR_UNKNOWN;
+}
+ret = ff_get_extradata(c->fc, st->codecpar, c->fc->pb, c->hvcC_size);
+if (ret < 0)
+return ret;
+avio_seek(c->fc->pb, pos, SEEK_SET);
+}
 sc->ffindex = st->index;
 c->trak_index = st->index;
 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
@@ -4953,6 +4967,8 @@ static int avif_add_stream(MOVContext *c, int item_id)
 
 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
+c->hvcC_offset = -1;
+c->hvcC_size = 0;
 while (atom.size > 8) {
 uint32_t tag;
 if (avio_feof(pb))
@@ -7827,6 +7843,28 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 return atom.size;
 }
 
+static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+int size = avio_rb32(pb);
+if (avio_rl32(pb) != MKTAG('i','p','c','o'))
+return AVERROR_INVALIDDATA;
+size -= 8;
+while (size > 0) {
+int sub_size, sub_type;
+sub_size = avio_rb32(pb);
+sub_type = avio_rl32(pb);
+sub_size -= 8;
+size -= sub_size + 8;
+if (sub_type == MKTAG('h','v','c','C')) {
+c->hvcC_offset = avio_tell(pb);
+c->hvcC_size = sub_size;
+break;
+}
+avio_skip(pb, sub_size);
+}
+return atom.size;
+}
+
 static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('A','C','L','R'), mov_read_aclr },
 { MKTAG('A','P','R','G'), mov_read_avid },
@@ -7934,6 +7972,7 @@ static const MOVParseTableEntry mov_default_parse_table[] 
= {
 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
 { MKTAG('p','i','t','m'), mov_read_pitm },
 { MKTAG('e','v','c','C'), mov_read_glbl },
+{ MKTAG('i','p','r','p'), mov_read_iprp },
 { 0, NULL }
 };
 
diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak
index 6cb493ceab..a2d3cc8013 100644
--- a/tests/fate/mov.mak
+++ b/tests/fate/mov.mak
@@ -18,6 +18,8 @@ FATE_MOV = fate-mov-3elist \
fate-mov-neg-firstpts-discard-frames \
fate-mov-stream-shorter-than-movie \
fate-mov-pcm-remux \
+   fate-mov-heic-demux-still-image-1-item \
+   fa

[FFmpeg-devel] [PATCH v2] avformat/mov: Add support for demuxing still HEIC images

2023-10-03 Thread Vignesh Venkatasubramanian via ffmpeg-devel
They are similar to AVIF images (both use the HEIF container).
The only additional work needed is to parse the hvcC box and put
it in the extradata.

With this patch applied, ffmpeg (when built with an HEVC decoder)
is able to decode the files in
https://github.com/nokiatech/heif/tree/gh-pages/content/images

Partially fixes trac ticket #6521.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |  2 ++
 libavformat/mov.c  | 41 -
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 3d375d7a46..b30b9da65e 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -327,6 +327,8 @@ typedef struct MOVContext {
 int64_t extent_offset;
 } *avif_info;
 int avif_info_size;
+int64_t hvcC_offset;
+int hvcC_size;
 int interleaved_read;
 } MOVContext;
 
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 1996e0028c..8ee93f321e 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1218,7 +1218,8 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 c->isom = 1;
 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char 
*));
 av_dict_set(>fc->metadata, "major_brand", type, 0);
-c->is_still_picture_avif = !strncmp(type, "avif", 4);
+c->is_still_picture_avif = !strncmp(type, "avif", 4) ||
+   !strncmp(type, "mif1", 4);
 minor_ver = avio_rb32(pb); /* minor version */
 av_dict_set_int(>fc->metadata, "minor_version", minor_ver, 0);
 
@@ -4911,6 +4912,19 @@ static int avif_add_stream(MOVContext *c, int item_id)
 st->priv_data = sc;
 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
 st->codecpar->codec_id = AV_CODEC_ID_AV1;
+if (c->hvcC_offset >= 0) {
+int ret;
+int64_t pos = avio_tell(c->fc->pb);
+st->codecpar->codec_id = AV_CODEC_ID_HEVC;
+if (avio_seek(c->fc->pb, c->hvcC_offset, SEEK_SET) != c->hvcC_offset) {
+av_log(c->fc, AV_LOG_ERROR, "Failed to seek to hvcC data.\n");
+return AVERROR_UNKNOWN;
+}
+ret = ff_get_extradata(c->fc, st->codecpar, c->fc->pb, c->hvcC_size);
+if (ret < 0)
+return ret;
+avio_seek(c->fc->pb, pos, SEEK_SET);
+}
 sc->ffindex = st->index;
 c->trak_index = st->index;
 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
@@ -4953,6 +4967,8 @@ static int avif_add_stream(MOVContext *c, int item_id)
 
 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
+c->hvcC_offset = -1;
+c->hvcC_size = 0;
 while (atom.size > 8) {
 uint32_t tag;
 if (avio_feof(pb))
@@ -7826,6 +7842,28 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 return atom.size;
 }
 
+static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+int size = avio_rb32(pb);
+if (avio_rl32(pb) != MKTAG('i','p','c','o'))
+return AVERROR_INVALIDDATA;
+size -= 8;
+while (size > 0) {
+int sub_size, sub_type;
+sub_size = avio_rb32(pb);
+sub_type = avio_rl32(pb);
+sub_size -= 8;
+size -= sub_size + 8;
+if (sub_type == MKTAG('h','v','c','C')) {
+c->hvcC_offset = avio_tell(pb);
+c->hvcC_size = sub_size;
+break;
+}
+avio_skip(pb, sub_size);
+}
+return atom.size;
+}
+
 static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('A','C','L','R'), mov_read_aclr },
 { MKTAG('A','P','R','G'), mov_read_avid },
@@ -7933,6 +7971,7 @@ static const MOVParseTableEntry mov_default_parse_table[] 
= {
 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
 { MKTAG('p','i','t','m'), mov_read_pitm },
 { MKTAG('e','v','c','C'), mov_read_glbl },
+{ MKTAG('i','p','r','p'), mov_read_iprp },
 { 0, NULL }
 };
 
-- 
2.42.0.582.g8ccd20d70d-goog

___
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] avformat/mov: Disallow more than one meta box for AVIF

2023-10-03 Thread Vignesh Venkatasubramanian via ffmpeg-devel
This is not allowed per the spec.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/mov.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 294c864fbd..a8f57f9281 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4892,6 +4892,8 @@ static int avif_add_stream(MOVContext *c, int item_id)
 {
 MOVStreamContext *sc;
 AVStream *st;
+if (c->fc->nb_streams)
+return AVERROR_INVALIDDATA;
 int item_index = -1;
 for (int i = 0; i < c->avif_info_size; i++)
 if (c->avif_info[i].item_id == item_id) {
-- 
2.42.0.582.g8ccd20d70d-goog

___
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] avcodec/svt-av1: Set force_key_frames only when gop_size == 1

2023-10-03 Thread Vignesh Venkatasubramanian via ffmpeg-devel
SVT-AV1 does not support requesting keyframes at arbitrary points
by setting pic_type to EB_AV1_KEY_PICTURE. So set force_key_frames
to 1 only when gop_size == 1.

Please see the comments in
https://gitlab.com/AOMediaCodec/SVT-AV1/-/issues/2076 for a bit more
details.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavcodec/libsvtav1.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
index 5015169244..8d2c7f3be4 100644
--- a/libavcodec/libsvtav1.c
+++ b/libavcodec/libsvtav1.c
@@ -253,8 +253,13 @@ static int config_enc_params(EbSvtAv1EncConfiguration 
*param,
 // In order for SVT-AV1 to force keyframes by setting pic_type to
 // EB_AV1_KEY_PICTURE on any frame, force_key_frames has to be set. Note
 // that this does not force all frames to be keyframes (it only forces a
-// keyframe with pic_type is set to EB_AV1_KEY_PICTURE).
-param->force_key_frames = 1;
+// keyframe with pic_type is set to EB_AV1_KEY_PICTURE). As of now, SVT-AV1
+// does not support arbitrary keyframe requests by setting pic_type to
+// EB_AV1_KEY_PICTURE, so it is done only when gop_size == 1.
+// FIXME: When SVT-AV1 supports arbitrary keyframe requests, this code 
needs
+// to be updated to set force_key_frames accordingly.
+if (avctx->gop_size == 1)
+param->force_key_frames = 1;
 
 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
 param->frame_rate_numerator   = avctx->framerate.num;
-- 
2.42.0.582.g8ccd20d70d-goog

___
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] avcodec/svt-av1: Set pic_type only when gop_size == 1

2023-09-27 Thread Vignesh Venkatasubramanian via ffmpeg-devel
SVT-AV1 does not support requesting keyframes at arbitrary points
by setting pic_type to EB_AV1_KEY_PICTURE.

This patch changes the following:
 * Set pic_type to EB_AV1_KEY_PICTURE only when gop_size == 1. This
   only has an effect in this case (combined with force_key_frames).
   In all other cases, setting this has no effect.
 * Set force_key_frames to 1 only when gop_size == 1, this is
   needed for pic_type request above to work.

Please see the comments in
https://gitlab.com/AOMediaCodec/SVT-AV1/-/issues/2076 for a bit more
details.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavcodec/libsvtav1.c | 22 +++---
 1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
index 5015169244..3247c30f60 100644
--- a/libavcodec/libsvtav1.c
+++ b/libavcodec/libsvtav1.c
@@ -253,8 +253,11 @@ static int config_enc_params(EbSvtAv1EncConfiguration 
*param,
 // In order for SVT-AV1 to force keyframes by setting pic_type to
 // EB_AV1_KEY_PICTURE on any frame, force_key_frames has to be set. Note
 // that this does not force all frames to be keyframes (it only forces a
-// keyframe with pic_type is set to EB_AV1_KEY_PICTURE).
-param->force_key_frames = 1;
+// keyframe with pic_type is set to EB_AV1_KEY_PICTURE). As of now, SVT-AV1
+// does not support arbitrary keyframe requests by setting pic_type to
+// EB_AV1_KEY_PICTURE, so it is done only when gop_size == 1.
+if (avctx->gop_size == 1)
+param->force_key_frames = 1;
 
 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
 param->frame_rate_numerator   = avctx->framerate.num;
@@ -462,19 +465,8 @@ static int eb_send_frame(AVCodecContext *avctx, const 
AVFrame *frame)
 headerPtr->flags = 0;
 headerPtr->p_app_private = NULL;
 headerPtr->pts   = frame->pts;
-
-switch (frame->pict_type) {
-case AV_PICTURE_TYPE_I:
-headerPtr->pic_type = EB_AV1_KEY_PICTURE;
-break;
-default:
-// Actually means auto, or default.
-headerPtr->pic_type = EB_AV1_INVALID_PICTURE;
-break;
-}
-
-if (avctx->gop_size == 1)
-headerPtr->pic_type = EB_AV1_KEY_PICTURE;
+// EB_AV1_INVALID_PICTURE means auto, or default.
+headerPtr->pic_type = (avctx->gop_size == 1) ? EB_AV1_KEY_PICTURE : 
EB_AV1_INVALID_PICTURE;
 
 svt_av1_enc_send_picture(svt_enc->svt_handle, headerPtr);
 
-- 
2.42.0.515.g380fc7ccd1-goog

___
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] avformat/mov: Add support for demuxing still HEIC images

2023-09-26 Thread Vignesh Venkatasubramanian via ffmpeg-devel
They are similar to AVIF images (both use the HEIF container).
The only additional work needed is to parse the hvcC box and put
it in the extradata.

With this patch applied, ffmpeg (when built with an HEVC decoder)
is able to decode the files in
https://github.com/nokiatech/heif/tree/gh-pages/content/images

Partially fixes trac ticket #6521.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |  2 ++
 libavformat/mov.c  | 38 +-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 3d375d7a46..b30b9da65e 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -327,6 +327,8 @@ typedef struct MOVContext {
 int64_t extent_offset;
 } *avif_info;
 int avif_info_size;
+int64_t hvcC_offset;
+int hvcC_size;
 int interleaved_read;
 } MOVContext;
 
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 1996e0028c..cec9cb5fe1 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1218,7 +1218,8 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 c->isom = 1;
 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char 
*));
 av_dict_set(>fc->metadata, "major_brand", type, 0);
-c->is_still_picture_avif = !strncmp(type, "avif", 4);
+c->is_still_picture_avif = !strncmp(type, "avif", 4) ||
+   !strncmp(type, "mif1", 4);
 minor_ver = avio_rb32(pb); /* minor version */
 av_dict_set_int(>fc->metadata, "minor_version", minor_ver, 0);
 
@@ -4911,6 +4912,16 @@ static int avif_add_stream(MOVContext *c, int item_id)
 st->priv_data = sc;
 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
 st->codecpar->codec_id = AV_CODEC_ID_AV1;
+if (c->hvcC_offset >= 0) {
+int ret;
+int64_t pos = avio_tell(c->fc->pb);
+st->codecpar->codec_id = AV_CODEC_ID_HEVC;
+avio_seek(c->fc->pb, c->hvcC_offset, SEEK_SET);
+ret = ff_get_extradata(c->fc, st->codecpar, c->fc->pb, c->hvcC_size);
+if (ret < 0)
+return ret;
+avio_seek(c->fc->pb, pos, SEEK_SET);
+}
 sc->ffindex = st->index;
 c->trak_index = st->index;
 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
@@ -4953,6 +4964,8 @@ static int avif_add_stream(MOVContext *c, int item_id)
 
 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
+c->hvcC_offset = -1;
+c->hvcC_size = 0;
 while (atom.size > 8) {
 uint32_t tag;
 if (avio_feof(pb))
@@ -7826,6 +7839,28 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 return atom.size;
 }
 
+static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+int size = avio_rb32(pb);
+if (avio_rl32(pb) != MKTAG('i','p','c','o'))
+return AVERROR_INVALIDDATA;
+size -= 8;
+while (size > 0) {
+int sub_size, sub_type;
+sub_size = avio_rb32(pb);
+sub_type = avio_rl32(pb);
+sub_size -= 8;
+size -= sub_size + 8;
+if (sub_type == MKTAG('h','v','c','C')) {
+c->hvcC_offset = avio_tell(pb);
+c->hvcC_size = sub_size;
+break;
+}
+avio_skip(pb, sub_size);
+}
+return atom.size;
+}
+
 static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('A','C','L','R'), mov_read_aclr },
 { MKTAG('A','P','R','G'), mov_read_avid },
@@ -7933,6 +7968,7 @@ static const MOVParseTableEntry mov_default_parse_table[] 
= {
 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
 { MKTAG('p','i','t','m'), mov_read_pitm },
 { MKTAG('e','v','c','C'), mov_read_glbl },
+{ MKTAG('i','p','r','p'), mov_read_iprp },
 { 0, NULL }
 };
 
-- 
2.42.0.515.g380fc7ccd1-goog

___
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] libsvtav1: Add workaround for gop_size == 1

2023-06-26 Thread Vignesh Venkatasubramanian
In some versions of libsvtav1, setting intra_period_length to 0
does not produce the intended result (i.e.) all frames produced
are not keyframes.

Instead handle the gop_size == 1 as a special case by setting
the pic_type to EB_AV1_KEY_PICTURE when encoding each frame so
that all the output frames are keyframes.

SVT-AV1 Bug: https://gitlab.com/AOMediaCodec/SVT-AV1/-/issues/2076

Example command: ffmpeg -f lavfi -i testsrc=duration=1:size=64x64:rate=30 -c:v 
libsvtav1 -g 1 -y test.webm

Before: Only first frame is keyframe.
After: All frames are keyframes.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavcodec/libsvtav1.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
index 718a04d221..f2b73361d8 100644
--- a/libavcodec/libsvtav1.c
+++ b/libavcodec/libsvtav1.c
@@ -242,9 +242,20 @@ static int config_enc_params(EbSvtAv1EncConfiguration 
*param,
 if (avctx->level != FF_LEVEL_UNKNOWN)
 param->level = avctx->level;
 
-if (avctx->gop_size > 0)
+// gop_size == 1 case is handled when encoding each frame by setting
+// pic_type to EB_AV1_KEY_PICTURE. For gop_size > 1, set the
+// intra_period_length. Even though setting intra_period_length to 0 should
+// work in this case, it does not.
+// See: https://gitlab.com/AOMediaCodec/SVT-AV1/-/issues/2076
+if (avctx->gop_size > 1)
 param->intra_period_length  = avctx->gop_size - 1;
 
+// In order for SVT-AV1 to force keyframes by setting pic_type to
+// EB_AV1_KEY_PICTURE on any frame, force_key_frames has to be set. Note
+// that this does not force all frames to be keyframes (it only forces a
+// keyframe with pic_type is set to EB_AV1_KEY_PICTURE).
+param->force_key_frames = 1;
+
 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
 param->frame_rate_numerator   = avctx->framerate.num;
 param->frame_rate_denominator = avctx->framerate.den;
@@ -462,6 +473,9 @@ static int eb_send_frame(AVCodecContext *avctx, const 
AVFrame *frame)
 break;
 }
 
+if (avctx->gop_size == 1)
+headerPtr->pic_type = EB_AV1_KEY_PICTURE;
+
 svt_av1_enc_send_picture(svt_enc->svt_handle, headerPtr);
 
 return 0;
-- 
2.41.0.162.gfafddb0af9-goog

___
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 3/5] avformat/mov: Better check for duplicate iloc

2023-04-25 Thread Vignesh Venkatasubramanian
On Mon, Apr 17, 2023 at 4:18 PM Michael Niedermayer
 wrote:
>
> On Mon, Apr 17, 2023 at 12:36:26PM +0200, Anton Khirnov wrote:
> > Quoting Michael Niedermayer (2023-04-17 00:25:16)
> > > Fixes: memleak
> > > Fixes: 
> > > 45982/clusterfuzz-testcase-minimized-ffmpeg_DEMUXER_fuzzer-6674082962997248
> > >
> > > Found-by: continuous fuzzing process 
> > > https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> > > Signed-off-by: Michael Niedermayer 
> > > ---
> > >  libavformat/mov.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/libavformat/mov.c b/libavformat/mov.c
> > > index 057fd872b10..6853bb324cf 100644
> > > --- a/libavformat/mov.c
> > > +++ b/libavformat/mov.c
> > > @@ -,7 +,7 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> > > *pb, MOVAtom atom)
> > >  return 0;
> > >  }
> > >
> > > -if (c->fc->nb_streams) {
> > > +if (c->fc->nb_streams || c->avif_info) {
> >
> > This first condition is now redundant, is it not?
>
> Iam not sure

I think the second condition alone should be enough here. Either way,
lgtm (if the current patch is more clearer for readers).

> what exactly happens if a trak occurs before
>

If a trak occurs before, then the condition in the line above should
take care of that case (!c->is_still_picture_avif). Because if a trak
was found, it will not be considered a still picture.

> Iam also not sure what happens if multiple meta tags occur triggering
> the avif stream addition, i may be missing something but the code seems
> not to expect that
>

Multiple meta tags are not allowed in the AVIF/HEIF specification.


> Adding the author of this code to CC
>
> thx
>
> [...]
>
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> In a rich man's house there is no place to spit but his face.
> -- Diogenes of Sinope



--
Vignesh
___
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 2/2] avformat/movenc: Add loop parameter to animated AVIF

2023-01-13 Thread Vignesh Venkatasubramanian
On Thu, Jan 12, 2023 at 8:40 PM "zhilizhao(赵志立)"  wrote:
>
>
>
> > On Jan 13, 2023, at 04:45, Vignesh Venkatasubramanian 
> >  wrote:
> >
> > The HEIF specification permits specifying the looping behavior of
> > animated sequences by using the EditList (elst) box. The track
> > duration will be set to the total duration of all the loops (or
> > infinite) and the duration of a single loop will be set in the edit
> > list box.
> >
> > The default behavior is to loop infinitely.
> >
> > Compliance verification:
> > * This was added in libavif recently [1] and the files produced by
> >  ffmpeg after this change have EditList boxes similar to the ones
> >  produced by libavif (and avifdec is able to parse the loop count as
> >  intended).
> > * ComplianceWarden is ok with the produced files.
> > * Chrome is able to play back the produced files.
> >
> > [1] 
> > https://github.com/AOMediaCodec/libavif/commit/4d2776a3af53ae1aefdaed463b75ba12fd9cf8c2
>
> Pushed.
>

Thank you!

> Please use [PATCH v2] next time. It isn’t clear whether it’s the same
> version as another patch or not, until diffed manually.
>

Sorry, will use v2 in the future. The patch was the same except for
adding the missing libavif link in the commit message.

> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> > libavformat/movenc.c | 35 +++
> > libavformat/movenc.h |  1 +
> > 2 files changed, 32 insertions(+), 4 deletions(-)
> >
> > diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > index 36c76f7f60..8d31317838 100644
> > --- a/libavformat/movenc.c
> > +++ b/libavformat/movenc.c
> > @@ -3287,7 +3287,7 @@ static int mov_write_tkhd_tag(AVIOContext *pb, 
> > MOVMuxContext *mov,
> > int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
> >   mov->movie_timescale, 
> > track->timescale,
> >   AV_ROUND_UP);
> > -int version = duration < INT32_MAX ? 0 : 1;
> > +int version;
> > int flags   = MOV_TKHD_FLAG_IN_MOVIE;
> > int group   = 0;
> >
> > @@ -3295,6 +3295,14 @@ static int mov_write_tkhd_tag(AVIOContext *pb, 
> > MOVMuxContext *mov,
> > size_t display_matrix_size;
> > int   i;
> >
> > +if (mov->mode == MODE_AVIF)
> > +if (!mov->avif_loop_count)
> > +duration = INT64_MAX;
> > +else
> > +duration *= mov->avif_loop_count;
> > +
> > + version = duration < INT32_MAX ? 0 : 1;
> > +
> > if (st) {
> > if (mov->per_stream_grouping)
> > group = st->index;
> > @@ -3414,7 +3422,10 @@ static int mov_write_tapt_tag(AVIOContext *pb, 
> > MOVTrack *track)
> > return update_size(pb, pos);
> > }
> >
> > -// This box seems important for the psp playback ... without it the movie 
> > seems to hang
> > +// This box is written in the following cases:
> > +//   * Seems important for the psp playback. Without it the movie seems to 
> > hang.
> > +//   * Used for specifying the looping behavior of animated AVIF (as 
> > specified
> > +//   in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
> > static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
> >   MOVTrack *track)
> > {
> > @@ -3425,6 +3436,7 @@ static int mov_write_edts_tag(AVIOContext *pb, 
> > MOVMuxContext *mov,
> > int entry_size, entry_count, size;
> > int64_t delay, start_ct = track->start_cts;
> > int64_t start_dts = track->start_dts;
> > +int flags = 0;
> >
> > if (track->entry) {
> > if (start_dts != track->cluster[0].dts || start_ct != 
> > track->cluster[0].cts) {
> > @@ -3440,6 +3452,17 @@ static int mov_write_edts_tag(AVIOContext *pb, 
> > MOVMuxContext *mov,
> >
> > delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
> >track->timescale, AV_ROUND_DOWN);
> > +
> > +if (mov->mode == MODE_AVIF) {
> > +delay = 0;
> > +// Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition 
> > of the
> > +// edit list as follows: (flags & 1) equal to 0 specifies that the 
> > edit
> > +// list is not repeated, while (flags & 1) equal to 1 specifies 
> > that the
> > +// edit list is repeated.
> > +

[FFmpeg-devel] [PATCH 2/2] avformat/movenc: Add loop parameter to animated AVIF

2023-01-12 Thread Vignesh Venkatasubramanian
The HEIF specification permits specifying the looping behavior of
animated sequences by using the EditList (elst) box. The track
duration will be set to the total duration of all the loops (or
infinite) and the duration of a single loop will be set in the edit
list box.

The default behavior is to loop infinitely.

Compliance verification:
* This was added in libavif recently [1] and the files produced by
  ffmpeg after this change have EditList boxes similar to the ones
  produced by libavif (and avifdec is able to parse the loop count as
  intended).
* ComplianceWarden is ok with the produced files.
* Chrome is able to play back the produced files.

[1] 
https://github.com/AOMediaCodec/libavif/commit/4d2776a3af53ae1aefdaed463b75ba12fd9cf8c2

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/movenc.c | 35 +++
 libavformat/movenc.h |  1 +
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 36c76f7f60..8d31317838 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -3287,7 +3287,7 @@ static int mov_write_tkhd_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
   mov->movie_timescale, track->timescale,
   AV_ROUND_UP);
-int version = duration < INT32_MAX ? 0 : 1;
+int version;
 int flags   = MOV_TKHD_FLAG_IN_MOVIE;
 int group   = 0;
 
@@ -3295,6 +3295,14 @@ static int mov_write_tkhd_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 size_t display_matrix_size;
 int   i;
 
+if (mov->mode == MODE_AVIF)
+if (!mov->avif_loop_count)
+duration = INT64_MAX;
+else
+duration *= mov->avif_loop_count;
+
+ version = duration < INT32_MAX ? 0 : 1;
+
 if (st) {
 if (mov->per_stream_grouping)
 group = st->index;
@@ -3414,7 +3422,10 @@ static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack 
*track)
 return update_size(pb, pos);
 }
 
-// This box seems important for the psp playback ... without it the movie 
seems to hang
+// This box is written in the following cases:
+//   * Seems important for the psp playback. Without it the movie seems to 
hang.
+//   * Used for specifying the looping behavior of animated AVIF (as specified
+//   in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
 static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
   MOVTrack *track)
 {
@@ -3425,6 +3436,7 @@ static int mov_write_edts_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 int entry_size, entry_count, size;
 int64_t delay, start_ct = track->start_cts;
 int64_t start_dts = track->start_dts;
+int flags = 0;
 
 if (track->entry) {
 if (start_dts != track->cluster[0].dts || start_ct != 
track->cluster[0].cts) {
@@ -3440,6 +3452,17 @@ static int mov_write_edts_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 
 delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
track->timescale, AV_ROUND_DOWN);
+
+if (mov->mode == MODE_AVIF) {
+delay = 0;
+// Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
+// edit list as follows: (flags & 1) equal to 0 specifies that the edit
+// list is not repeated, while (flags & 1) equal to 1 specifies that 
the
+// edit list is repeated.
+flags = mov->avif_loop_count != 1;
+start_ct = 0;
+}
+
 version |= delay < INT32_MAX ? 0 : 1;
 
 entry_size = (version == 1) ? 20 : 12;
@@ -3452,7 +3475,7 @@ static int mov_write_edts_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 avio_wb32(pb, size - 8);
 ffio_wfourcc(pb, "elst");
 avio_w8(pb, version);
-avio_wb24(pb, 0); /* flags */
+avio_wb24(pb, flags); /* flags */
 
 avio_wb32(pb, entry_count);
 if (delay > 0) { /* add an empty edit to delay presentation */
@@ -3469,7 +3492,7 @@ static int mov_write_edts_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 avio_wb32(pb, -1);
 }
 avio_wb32(pb, 0x0001);
-} else {
+} else if (mov->mode != MODE_AVIF) {
 /* Avoid accidentally ending up with start_ct = -1 which has got a
  * special meaning. Normally start_ct should end up positive or zero
  * here, but use FFMIN in case dts is a small positive integer
@@ -3670,6 +3693,9 @@ static int mov_write_trak_tag(AVFormatContext *s, 
AVIOContext *pb, MOVMuxContext
"Not writing any edit list even though one would have been 
required\n");
 }
 
+if (mov->is_animated_avif)
+mov_write_edts_tag(pb, mov, track);
+
 if (track->tref_tag)
 mov_write_tref_tag(pb, track);
 
@@ -7761,6 +7787,7 @@ static const AVCodecTag codec_f4v_tags[] = {
 
 s

Re: [FFmpeg-devel] [PATCH 2/2] avformat/movenc: Add loop parameter to animated AVIF

2023-01-12 Thread Vignesh Venkatasubramanian
On Fri, Jan 6, 2023 at 1:45 AM "zhilizhao(赵志立)"  wrote:
>
>
>
> > On Jan 6, 2023, at 01:34, Vignesh Venkatasubramanian 
> >  wrote:
> >
> > On Thu, Jan 5, 2023 at 1:45 AM "zhilizhao(赵志立)"  
> > wrote:
> >>
> >>
> >>
> >>> On Jan 5, 2023, at 06:16, Vignesh Venkatasubramanian 
> >>>  wrote:
> >>>
> >>> The HEIF specification permits specifying the looping behavior of
> >>> animated sequences by using the EditList (elst) box. The track
> >>> duration will be set to the total duration of all the loops (or
> >>> infinite) and the duration of a single loop will be set in the edit
> >>> list box.
> >>>
> >>> The default behavior is to loop infinitely.
> >>>
> >>> Compliance verification:
> >>> * This was added in libavif recently [1] and the files produced by
> >>> ffmpeg after this change have EditList boxes similar to the ones
> >>> produced by libavif (and avifdec is able to parse the loop count as
> >>> intended).
> >>> * ComplianceWarden is ok with the produced files.
> >>> * Chrome is able to play back the produced files.
> >>>
> >>> Signed-off-by: Vignesh Venkatasubramanian 
> >>> ---
> >>> libavformat/movenc.c | 35 +++
> >>> libavformat/movenc.h |  1 +
> >>> 2 files changed, 32 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> >>> index 36c76f7f60..8d31317838 100644
> >>> --- a/libavformat/movenc.c
> >>> +++ b/libavformat/movenc.c
> >>> @@ -3287,7 +3287,7 @@ static int mov_write_tkhd_tag(AVIOContext *pb, 
> >>> MOVMuxContext *mov,
> >>>int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
> >>>  mov->movie_timescale, 
> >>> track->timescale,
> >>>  AV_ROUND_UP);
> >>> -int version = duration < INT32_MAX ? 0 : 1;
> >>> +int version;
> >>>int flags   = MOV_TKHD_FLAG_IN_MOVIE;
> >>>int group   = 0;
> >>>
> >>> @@ -3295,6 +3295,14 @@ static int mov_write_tkhd_tag(AVIOContext *pb, 
> >>> MOVMuxContext *mov,
> >>>size_t display_matrix_size;
> >>>int   i;
> >>>
> >>> +if (mov->mode == MODE_AVIF)
> >>> +if (!mov->avif_loop_count)
> >>> +duration = INT64_MAX;
> >>> +else
> >>> +duration *= mov->avif_loop_count;
> >>> +
> >>> + version = duration < INT32_MAX ? 0 : 1;
> >>> +
> >>>if (st) {
> >>>if (mov->per_stream_grouping)
> >>>group = st->index;
> >>> @@ -3414,7 +3422,10 @@ static int mov_write_tapt_tag(AVIOContext *pb, 
> >>> MOVTrack *track)
> >>>return update_size(pb, pos);
> >>> }
> >>>
> >>> -// This box seems important for the psp playback ... without it the 
> >>> movie seems to hang
> >>> +// This box is written in the following cases:
> >>> +//   * Seems important for the psp playback. Without it the movie seems 
> >>> to hang.
> >>> +//   * Used for specifying the looping behavior of animated AVIF (as 
> >>> specified
> >>> +//   in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
> >>> static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
> >>>  MOVTrack *track)
> >>> {
> >>> @@ -3425,6 +3436,7 @@ static int mov_write_edts_tag(AVIOContext *pb, 
> >>> MOVMuxContext *mov,
> >>>int entry_size, entry_count, size;
> >>>int64_t delay, start_ct = track->start_cts;
> >>>int64_t start_dts = track->start_dts;
> >>> +int flags = 0;
> >>>
> >>>if (track->entry) {
> >>>if (start_dts != track->cluster[0].dts || start_ct != 
> >>> track->cluster[0].cts) {
> >>> @@ -3440,6 +3452,17 @@ static int mov_write_edts_tag(AVIOContext *pb, 
> >>> MOVMuxContext *mov,
> >>>
> >>>delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
> >>>   track->timescale, AV_ROUND_DOWN);
> >>&g

Re: [FFmpeg-devel] [PATCH 2/2] avformat/movenc: Add loop parameter to animated AVIF

2023-01-05 Thread Vignesh Venkatasubramanian
On Thu, Jan 5, 2023 at 1:45 AM "zhilizhao(赵志立)"  wrote:
>
>
>
> > On Jan 5, 2023, at 06:16, Vignesh Venkatasubramanian 
> >  wrote:
> >
> > The HEIF specification permits specifying the looping behavior of
> > animated sequences by using the EditList (elst) box. The track
> > duration will be set to the total duration of all the loops (or
> > infinite) and the duration of a single loop will be set in the edit
> > list box.
> >
> > The default behavior is to loop infinitely.
> >
> > Compliance verification:
> > * This was added in libavif recently [1] and the files produced by
> >  ffmpeg after this change have EditList boxes similar to the ones
> >  produced by libavif (and avifdec is able to parse the loop count as
> >  intended).
> > * ComplianceWarden is ok with the produced files.
> > * Chrome is able to play back the produced files.
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> > libavformat/movenc.c | 35 +++
> > libavformat/movenc.h |  1 +
> > 2 files changed, 32 insertions(+), 4 deletions(-)
> >
> > diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > index 36c76f7f60..8d31317838 100644
> > --- a/libavformat/movenc.c
> > +++ b/libavformat/movenc.c
> > @@ -3287,7 +3287,7 @@ static int mov_write_tkhd_tag(AVIOContext *pb, 
> > MOVMuxContext *mov,
> > int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
> >   mov->movie_timescale, 
> > track->timescale,
> >   AV_ROUND_UP);
> > -int version = duration < INT32_MAX ? 0 : 1;
> > +int version;
> > int flags   = MOV_TKHD_FLAG_IN_MOVIE;
> > int group   = 0;
> >
> > @@ -3295,6 +3295,14 @@ static int mov_write_tkhd_tag(AVIOContext *pb, 
> > MOVMuxContext *mov,
> > size_t display_matrix_size;
> > int   i;
> >
> > +if (mov->mode == MODE_AVIF)
> > +if (!mov->avif_loop_count)
> > +duration = INT64_MAX;
> > +else
> > +duration *= mov->avif_loop_count;
> > +
> > + version = duration < INT32_MAX ? 0 : 1;
> > +
> > if (st) {
> > if (mov->per_stream_grouping)
> > group = st->index;
> > @@ -3414,7 +3422,10 @@ static int mov_write_tapt_tag(AVIOContext *pb, 
> > MOVTrack *track)
> > return update_size(pb, pos);
> > }
> >
> > -// This box seems important for the psp playback ... without it the movie 
> > seems to hang
> > +// This box is written in the following cases:
> > +//   * Seems important for the psp playback. Without it the movie seems to 
> > hang.
> > +//   * Used for specifying the looping behavior of animated AVIF (as 
> > specified
> > +//   in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
> > static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
> >   MOVTrack *track)
> > {
> > @@ -3425,6 +3436,7 @@ static int mov_write_edts_tag(AVIOContext *pb, 
> > MOVMuxContext *mov,
> > int entry_size, entry_count, size;
> > int64_t delay, start_ct = track->start_cts;
> > int64_t start_dts = track->start_dts;
> > +int flags = 0;
> >
> > if (track->entry) {
> > if (start_dts != track->cluster[0].dts || start_ct != 
> > track->cluster[0].cts) {
> > @@ -3440,6 +3452,17 @@ static int mov_write_edts_tag(AVIOContext *pb, 
> > MOVMuxContext *mov,
> >
> > delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
> >track->timescale, AV_ROUND_DOWN);
> > +
> > +if (mov->mode == MODE_AVIF) {
> > +delay = 0;
> > +// Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition 
> > of the
> > +// edit list as follows: (flags & 1) equal to 0 specifies that the 
> > edit
> > +// list is not repeated, while (flags & 1) equal to 1 specifies 
> > that the
> > +// edit list is repeated.
> > +flags = mov->avif_loop_count != 1;
> > +start_ct = 0;
> > +}
> > +
> > version |= delay < INT32_MAX ? 0 : 1;
> >
> > entry_size = (version == 1) ? 20 : 12;
> > @@ -3452,7 +3475,7 @@ static int mov_write_edts_tag(AVIOContext *pb, 
> > MOVMuxContext *mov,
> > avio_wb32(pb, size - 8);
> > ffio_wfourcc(pb, "elst");
> > avio_w8

Re: [FFmpeg-devel] [PATCH 1/2] avformat/movenc: Add movie_timescale option to AVIF

2023-01-05 Thread Vignesh Venkatasubramanian
On Thu, Jan 5, 2023 at 1:34 AM "zhilizhao(赵志立)"  wrote:
>
>
>
> > On Jan 5, 2023, at 06:16, Vignesh Venkatasubramanian 
> >  wrote:
> >
> > Allow specifying the movie_timescale options to AVIF ouptut.
> >
> > This also makes sure that when movie_timescale is not specified,
> > the default value of 1000 is used instead of 0. Animated AVIF
> > files which don't specify the movie_timescale will have the
> > correct duration written in the track and movie headers after this
> > change (instead of writing 0).
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> > libavformat/movenc.c | 6 ++
> > 1 file changed, 6 insertions(+)
> >
> > diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > index 7d49892283..36c76f7f60 100644
> > --- a/libavformat/movenc.c
> > +++ b/libavformat/movenc.c
> > @@ -7758,6 +7758,11 @@ static const AVCodecTag codec_f4v_tags[] = {
> > };
> >
> > #if CONFIG_AVIF_MUXER
> > +
> > +static const AVOption avif_options[] = {
> > +{ "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, 
> > movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, 
> > AV_OPT_FLAG_ENCODING_PARAM},
> > +{ NULL },
> > +};
>
> If there is a chance to add more options which is shared with
> mov_isobmff_muxer_class, define a common option to avoid
> duplication. Otherwise keep it as this.
>

As of now, this is the only one that's being repeated. I think we can
make a common option if we decide to copy over more from the
mov_isobmff_muxer_class.

> > static const AVCodecTag codec_avif_tags[] = {
> > { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
> > { AV_CODEC_ID_NONE, 0 },
> > @@ -7767,6 +7772,7 @@ static const AVCodecTag *const codec_avif_tags_list[] 
> > = { codec_avif_tags, NULL
> > static const AVClass mov_avif_muxer_class = {
> > .class_name = "avif muxer",
> > .item_name  = av_default_item_name,
> > +.option = avif_options,
> > .version= LIBAVUTIL_VERSION_INT,
> > };
> > #endif
> > --
> > 2.39.0.314.g84b9a713c41-goog
> >
> > ___
> > 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".
>


-- 
Vignesh
___
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/2] avformat/movenc: Add loop parameter to animated AVIF

2023-01-04 Thread Vignesh Venkatasubramanian
The HEIF specification permits specifying the looping behavior of
animated sequences by using the EditList (elst) box. The track
duration will be set to the total duration of all the loops (or
infinite) and the duration of a single loop will be set in the edit
list box.

The default behavior is to loop infinitely.

Compliance verification:
* This was added in libavif recently [1] and the files produced by
  ffmpeg after this change have EditList boxes similar to the ones
  produced by libavif (and avifdec is able to parse the loop count as
  intended).
* ComplianceWarden is ok with the produced files.
* Chrome is able to play back the produced files.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/movenc.c | 35 +++
 libavformat/movenc.h |  1 +
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 36c76f7f60..8d31317838 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -3287,7 +3287,7 @@ static int mov_write_tkhd_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
   mov->movie_timescale, track->timescale,
   AV_ROUND_UP);
-int version = duration < INT32_MAX ? 0 : 1;
+int version;
 int flags   = MOV_TKHD_FLAG_IN_MOVIE;
 int group   = 0;
 
@@ -3295,6 +3295,14 @@ static int mov_write_tkhd_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 size_t display_matrix_size;
 int   i;
 
+if (mov->mode == MODE_AVIF)
+if (!mov->avif_loop_count)
+duration = INT64_MAX;
+else
+duration *= mov->avif_loop_count;
+
+ version = duration < INT32_MAX ? 0 : 1;
+
 if (st) {
 if (mov->per_stream_grouping)
 group = st->index;
@@ -3414,7 +3422,10 @@ static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack 
*track)
 return update_size(pb, pos);
 }
 
-// This box seems important for the psp playback ... without it the movie 
seems to hang
+// This box is written in the following cases:
+//   * Seems important for the psp playback. Without it the movie seems to 
hang.
+//   * Used for specifying the looping behavior of animated AVIF (as specified
+//   in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
 static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
   MOVTrack *track)
 {
@@ -3425,6 +3436,7 @@ static int mov_write_edts_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 int entry_size, entry_count, size;
 int64_t delay, start_ct = track->start_cts;
 int64_t start_dts = track->start_dts;
+int flags = 0;
 
 if (track->entry) {
 if (start_dts != track->cluster[0].dts || start_ct != 
track->cluster[0].cts) {
@@ -3440,6 +3452,17 @@ static int mov_write_edts_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 
 delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
track->timescale, AV_ROUND_DOWN);
+
+if (mov->mode == MODE_AVIF) {
+delay = 0;
+// Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
+// edit list as follows: (flags & 1) equal to 0 specifies that the edit
+// list is not repeated, while (flags & 1) equal to 1 specifies that 
the
+// edit list is repeated.
+flags = mov->avif_loop_count != 1;
+start_ct = 0;
+}
+
 version |= delay < INT32_MAX ? 0 : 1;
 
 entry_size = (version == 1) ? 20 : 12;
@@ -3452,7 +3475,7 @@ static int mov_write_edts_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 avio_wb32(pb, size - 8);
 ffio_wfourcc(pb, "elst");
 avio_w8(pb, version);
-avio_wb24(pb, 0); /* flags */
+avio_wb24(pb, flags); /* flags */
 
 avio_wb32(pb, entry_count);
 if (delay > 0) { /* add an empty edit to delay presentation */
@@ -3469,7 +3492,7 @@ static int mov_write_edts_tag(AVIOContext *pb, 
MOVMuxContext *mov,
 avio_wb32(pb, -1);
 }
 avio_wb32(pb, 0x0001);
-} else {
+} else if (mov->mode != MODE_AVIF) {
 /* Avoid accidentally ending up with start_ct = -1 which has got a
  * special meaning. Normally start_ct should end up positive or zero
  * here, but use FFMIN in case dts is a small positive integer
@@ -3670,6 +3693,9 @@ static int mov_write_trak_tag(AVFormatContext *s, 
AVIOContext *pb, MOVMuxContext
"Not writing any edit list even though one would have been 
required\n");
 }
 
+if (mov->is_animated_avif)
+mov_write_edts_tag(pb, mov, track);
+
 if (track->tref_tag)
 mov_write_tref_tag(pb, track);
 
@@ -7761,6 +7787,7 @@ static const AVCodecTag codec_f4v_tags[] = {
 
 static const AVOption avif_options[] = {
 { "movie_timescale", "set 

[FFmpeg-devel] [PATCH 1/2] avformat/movenc: Add movie_timescale option to AVIF

2023-01-04 Thread Vignesh Venkatasubramanian
Allow specifying the movie_timescale options to AVIF ouptut.

This also makes sure that when movie_timescale is not specified,
the default value of 1000 is used instead of 0. Animated AVIF
files which don't specify the movie_timescale will have the
correct duration written in the track and movie headers after this
change (instead of writing 0).

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/movenc.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 7d49892283..36c76f7f60 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -7758,6 +7758,11 @@ static const AVCodecTag codec_f4v_tags[] = {
 };
 
 #if CONFIG_AVIF_MUXER
+
+static const AVOption avif_options[] = {
+{ "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, 
movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, 
AV_OPT_FLAG_ENCODING_PARAM},
+{ NULL },
+};
 static const AVCodecTag codec_avif_tags[] = {
 { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
 { AV_CODEC_ID_NONE, 0 },
@@ -7767,6 +7772,7 @@ static const AVCodecTag *const codec_avif_tags_list[] = { 
codec_avif_tags, NULL
 static const AVClass mov_avif_muxer_class = {
 .class_name = "avif muxer",
 .item_name  = av_default_item_name,
+.option = avif_options,
 .version= LIBAVUTIL_VERSION_INT,
 };
 #endif
-- 
2.39.0.314.g84b9a713c41-goog

___
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] avcodec/libaomdec: fix pix_fmt w/AVCOL_SPC_RGB

2022-10-25 Thread Vignesh Venkatasubramanian
On Tue, Oct 25, 2022 at 11:28 AM James Zern
 wrote:
>
> Signed-off-by: James Zern 
> ---
>  libavcodec/libaomdec.c | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/libaomdec.c b/libavcodec/libaomdec.c
> index 378d638a89..53982559d9 100644
> --- a/libavcodec/libaomdec.c
> +++ b/libavcodec/libaomdec.c
> @@ -113,15 +113,19 @@ static int set_pix_fmt(AVCodecContext *avctx, struct 
> aom_image *img)
>  case AOM_IMG_FMT_I444:
>  case AOM_IMG_FMT_I44416:
>  if (img->bit_depth == 8) {
> -avctx->pix_fmt = AV_PIX_FMT_YUV444P;
> +avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
> + AV_PIX_FMT_GBRP : AV_PIX_FMT_YUV444P;
>  avctx->profile = FF_PROFILE_AV1_HIGH;
>  return 0;
>  } else if (img->bit_depth == 10) {
>  avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
> +avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
> + AV_PIX_FMT_GBRP10 : AV_PIX_FMT_YUV444P10;
>  avctx->profile = FF_PROFILE_AV1_HIGH;
>  return 0;
>  } else if (img->bit_depth == 12) {
> -avctx->pix_fmt = AV_PIX_FMT_YUV444P12;
> +avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
> + AV_PIX_FMT_GBRP12 : AV_PIX_FMT_YUV444P12;
>  avctx->profile = FF_PROFILE_AV1_PROFESSIONAL;
>  return 0;
>  } else {
> --
> 2.38.0.135.g90850a2211-goog
>
> ___
> 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".

lgtm.

I can confirm that AV1 files with gbrp pixel format play back properly
with ffplay with this patch (without this patch it does not look
right).


--
Vignesh
___
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] avformat/movenc: Write auxi box for animated AVIF with alpha

2022-09-20 Thread Vignesh Venkatasubramanian
On Tue, Sep 20, 2022 at 12:38 PM James Zern  wrote:
>
> On Mon, Sep 19, 2022 at 4:03 PM Vignesh Venkatasubramanian
>  wrote:
> >
> > According to the HEIF specification Section 7.5.3.1, tracks with
>
> It might be worth adding ISO/IEC 23008-12 for added precision.
>

Done.

> > handler_type 'auxv' must contain a 'auxi' box in its
> > SampleEntry to notify the nature of the auxiliary track to the
> > decoder.
> >
> > The content is the same as the 'auxC' box. So paramterize and re-use
>
> parameterize
>

oops, fixed.

> > the existing function.
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  libavformat/movenc.c | 27 +++
> >  1 file changed, 15 insertions(+), 12 deletions(-)
> >
>
> lgtm.



-- 
Vignesh
___
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] avformat/movenc: Write auxi box for animated AVIF with alpha

2022-09-20 Thread Vignesh Venkatasubramanian
According to the HEIF specification (ISO/IEC 23008-12) Section
7.5.3.1, tracks with handler_type 'auxv' must contain a 'auxi' box
in its SampleEntry to notify the nature of the auxiliary track to the
decoder.

The content is the same as the 'auxC' box. So parameterize and re-use
the existing function.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/movenc.c | 27 +++
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index c8b2e141cb..754f95912a 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2179,6 +2179,16 @@ static int mov_write_ccst_tag(AVIOContext *pb)
 return update_size(pb, pos);
 }
 
+static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
+{
+int64_t pos = avio_tell(pb);
+avio_wb32(pb, 0); /* size */
+ffio_wfourcc(pb, aux_type);
+avio_wb32(pb, 0); /* Version & flags */
+avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
+return update_size(pb, pos);
+}
+
 static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, 
MOVMuxContext *mov, MOVTrack *track)
 {
 int ret = AVERROR_BUG;
@@ -2363,8 +2373,11 @@ static int mov_write_video_tag(AVFormatContext *s, 
AVIOContext *pb, MOVMuxContex
 if (avid)
 avio_wb32(pb, 0);
 
-if (track->mode == MODE_AVIF)
+if (track->mode == MODE_AVIF) {
 mov_write_ccst_tag(pb);
+if (s->nb_streams > 0 && track == >tracks[1])
+mov_write_aux_tag(pb, "auxi");
+}
 
 return update_size(pb, pos);
 }
@@ -3044,16 +3057,6 @@ static int mov_write_pixi_tag(AVIOContext *pb, 
MOVMuxContext *mov, AVFormatConte
 return update_size(pb, pos);
 }
 
-static int mov_write_auxC_tag(AVIOContext *pb)
-{
-int64_t pos = avio_tell(pb);
-avio_wb32(pb, 0); /* size */
-ffio_wfourcc(pb, "auxC");
-avio_wb32(pb, 0); /* Version & flags */
-avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
-return update_size(pb, pos);
-}
-
 static int mov_write_ipco_tag(AVIOContext *pb, MOVMuxContext *mov, 
AVFormatContext *s)
 {
 int64_t pos = avio_tell(pb);
@@ -3066,7 +3069,7 @@ static int mov_write_ipco_tag(AVIOContext *pb, 
MOVMuxContext *mov, AVFormatConte
 if (!i)
 mov_write_colr_tag(pb, >tracks[0], 0);
 else
-mov_write_auxC_tag(pb);
+mov_write_aux_tag(pb, "auxC");
 }
 return update_size(pb, pos);
 }
-- 
2.37.3.968.ga6b4b080e4-goog

___
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] avformat/movenc: Write auxi box for animated AVIF with alpha

2022-09-19 Thread Vignesh Venkatasubramanian
According to the HEIF specification Section 7.5.3.1, tracks with
handler_type 'auxv' must contain a 'auxi' box in its
SampleEntry to notify the nature of the auxiliary track to the
decoder.

The content is the same as the 'auxC' box. So paramterize and re-use
the existing function.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/movenc.c | 27 +++
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index c8b2e141cb..754f95912a 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2179,6 +2179,16 @@ static int mov_write_ccst_tag(AVIOContext *pb)
 return update_size(pb, pos);
 }
 
+static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
+{
+int64_t pos = avio_tell(pb);
+avio_wb32(pb, 0); /* size */
+ffio_wfourcc(pb, aux_type);
+avio_wb32(pb, 0); /* Version & flags */
+avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
+return update_size(pb, pos);
+}
+
 static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, 
MOVMuxContext *mov, MOVTrack *track)
 {
 int ret = AVERROR_BUG;
@@ -2363,8 +2373,11 @@ static int mov_write_video_tag(AVFormatContext *s, 
AVIOContext *pb, MOVMuxContex
 if (avid)
 avio_wb32(pb, 0);
 
-if (track->mode == MODE_AVIF)
+if (track->mode == MODE_AVIF) {
 mov_write_ccst_tag(pb);
+if (s->nb_streams > 0 && track == >tracks[1])
+mov_write_aux_tag(pb, "auxi");
+}
 
 return update_size(pb, pos);
 }
@@ -3044,16 +3057,6 @@ static int mov_write_pixi_tag(AVIOContext *pb, 
MOVMuxContext *mov, AVFormatConte
 return update_size(pb, pos);
 }
 
-static int mov_write_auxC_tag(AVIOContext *pb)
-{
-int64_t pos = avio_tell(pb);
-avio_wb32(pb, 0); /* size */
-ffio_wfourcc(pb, "auxC");
-avio_wb32(pb, 0); /* Version & flags */
-avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
-return update_size(pb, pos);
-}
-
 static int mov_write_ipco_tag(AVIOContext *pb, MOVMuxContext *mov, 
AVFormatContext *s)
 {
 int64_t pos = avio_tell(pb);
@@ -3066,7 +3069,7 @@ static int mov_write_ipco_tag(AVIOContext *pb, 
MOVMuxContext *mov, AVFormatConte
 if (!i)
 mov_write_colr_tag(pb, >tracks[0], 0);
 else
-mov_write_auxC_tag(pb);
+mov_write_aux_tag(pb, "auxC");
 }
 return update_size(pb, pos);
 }
-- 
2.37.3.968.ga6b4b080e4-goog

___
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] avcodec/libvpxenc: add -min-gf-interval

2022-09-19 Thread Vignesh Venkatasubramanian
On Tue, Sep 13, 2022 at 5:28 PM James Zern
 wrote:
>
> this maps to the vpxenc argument with the same name and the
> VP9E_SET_MIN_GF_INTERVAL codec control
>
> Signed-off-by: James Zern 
> ---
>  doc/encoders.texi  |  2 ++
>  libavcodec/libvpxenc.c | 11 +++
>  libavcodec/version.h   |  2 +-
>  3 files changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/doc/encoders.texi b/doc/encoders.texi
> index ac71f50ad2..5a5579d5e5 100644
> --- a/doc/encoders.texi
> +++ b/doc/encoders.texi
> @@ -2176,6 +2176,8 @@ Set altref noise reduction filter type: backward, 
> forward, centered.
>  Set altref noise reduction filter strength.
>  @item rc-lookahead, lag-in-frames (@emph{lag-in-frames})
>  Set number of frames to look ahead for frametype and ratecontrol.
> +@item min-gf-interval
> +Set minimum golden/alternate reference frame interval (VP9 only).
>  @end table
>
>  @item error-resilient
> diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
> index 09b56aae2a..667cffc200 100644
> --- a/libavcodec/libvpxenc.c
> +++ b/libavcodec/libvpxenc.c
> @@ -131,6 +131,7 @@ typedef struct VPxEncoderContext {
>  int tune_content;
>  int corpus_complexity;
>  int tpl_model;
> +int min_gf_interval;
>  AVFifo *hdr10_plus_fifo;
>  /**
>   * If the driver does not support ROI then warn the first time we
> @@ -186,6 +187,9 @@ static const char *const ctlidstr[] = {
>  #ifdef VPX_CTRL_VP9E_SET_TPL
>  [VP9E_SET_TPL] = "VP9E_SET_TPL",
>  #endif
> +#ifdef VPX_CTRL_VP9E_SET_MIN_GF_INTERVAL
> +[VP9E_SET_MIN_GF_INTERVAL] = "VP9E_SET_MIN_GF_INTERVAL",
> +#endif
>  #endif
>  };
>
> @@ -1173,6 +1177,10 @@ static av_cold int vpx_init(AVCodecContext *avctx,
>  #ifdef VPX_CTRL_VP9E_SET_TPL
>  if (ctx->tpl_model >= 0)
>  codecctl_int(avctx, VP9E_SET_TPL, ctx->tpl_model);
> +#endif
> +#ifdef VPX_CTRL_VP9E_SET_MIN_GF_INTERVAL
> +if (ctx->min_gf_interval >= 0)
> +codecctl_int(avctx, VP9E_SET_MIN_GF_INTERVAL, 
> ctx->min_gf_interval);
>  #endif
>  }
>  #endif
> @@ -1911,6 +1919,9 @@ static const AVOption vp9_options[] = {
>  #endif
>  #ifdef VPX_CTRL_VP9E_SET_TPL
>  { "enable-tpl",  "Enable temporal dependency model", 
> OFFSET(tpl_model), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE },
> +#endif
> +#ifdef VPX_CTRL_VP9E_SET_MIN_GF_INTERVAL
> +{ "min-gf-interval", "Minimum golden/alternate reference frame 
> interval", OFFSET(min_gf_interval), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 
> INT_MAX, VE },
>  #endif
>  LEGACY_OPTIONS
>  { NULL }
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index 2328be4b26..7e89daf017 100644
> --- a/libavcodec/version.h
> +++ b/libavcodec/version.h
> @@ -30,7 +30,7 @@
>  #include "version_major.h"
>
>  #define LIBAVCODEC_VERSION_MINOR  43
> -#define LIBAVCODEC_VERSION_MICRO 100
> +#define LIBAVCODEC_VERSION_MICRO 101
>
>  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> LIBAVCODEC_VERSION_MINOR, \
> --
> 2.37.2.789.g6183377224-goog
>
> ___
> 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".

lgtm.

-- 
Vignesh
___
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] avcodec/libvpx: fix assembling vp9 packets with alpha channel

2022-08-23 Thread Vignesh Venkatasubramanian
On Sun, Aug 21, 2022 at 10:21 AM James Almer  wrote:
>
> There's no warranty that vpx_codec_encode() will generate a list with the same
> amount of packets for both the yuv planes encoder and the alpha plane encoder,
> so queueing packets based on what the main encoder returns will fail when the
> amount of packets in both lists differ.
> Queue all data packets for every vpx_codec_encode() call from both encoders
> before attempting to assemble output AVPackets out of them.
>
> Fixes ticket #9884
>

lgtm. thanks for fixing this!

> Signed-off-by: James Almer 
> ---
>  libavcodec/libvpxenc.c | 83 --
>  1 file changed, 40 insertions(+), 43 deletions(-)
>
> diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
> index 5b7c7735a1..e08df5fb96 100644
> --- a/libavcodec/libvpxenc.c
> +++ b/libavcodec/libvpxenc.c
> @@ -56,8 +56,6 @@
>  struct FrameListData {
>  void *buf;   /**< compressed data buffer */
>  size_t sz;   /**< length of compressed data */
> -void *buf_alpha;
> -size_t sz_alpha;
>  int64_t pts; /**< time stamp to show frame
>(in timebase units) */
>  unsigned long duration;  /**< duration to show frame
> @@ -87,6 +85,7 @@ typedef struct VPxEncoderContext {
>  int have_sse; /**< true if we have pending sse[] */
>  uint64_t frame_number;
>  struct FrameListData *coded_frame_list;
> +struct FrameListData *alpha_coded_frame_list;
>
>  int cpu_used;
>  int sharpness;
> @@ -311,8 +310,6 @@ static void coded_frame_add(void *list, struct 
> FrameListData *cx_frame)
>  static av_cold void free_coded_frame(struct FrameListData *cx_frame)
>  {
>  av_freep(_frame->buf);
> -if (cx_frame->buf_alpha)
> -av_freep(_frame->buf_alpha);
>  av_freep(_frame);
>  }
>
> @@ -446,6 +443,7 @@ static av_cold int vpx_free(AVCodecContext *avctx)
>  av_freep(>twopass_stats.buf);
>  av_freep(>stats_out);
>  free_frame_list(ctx->coded_frame_list);
> +free_frame_list(ctx->alpha_coded_frame_list);
>  if (ctx->hdr10_plus_fifo)
>  free_hdr10_plus_fifo(>hdr10_plus_fifo);
>  return 0;
> @@ -1205,7 +1203,6 @@ static av_cold int vpx_init(AVCodecContext *avctx,
>
>  static inline void cx_pktcpy(struct FrameListData *dst,
>   const struct vpx_codec_cx_pkt *src,
> - const struct vpx_codec_cx_pkt *src_alpha,
>   VPxContext *ctx)
>  {
>  dst->pts  = src->data.frame.pts;
> @@ -1229,13 +1226,6 @@ static inline void cx_pktcpy(struct FrameListData *dst,
>  } else {
>  dst->frame_number = -1;   /* sanity marker */
>  }
> -if (src_alpha) {
> -dst->buf_alpha = src_alpha->data.frame.buf;
> -dst->sz_alpha = src_alpha->data.frame.sz;
> -} else {
> -dst->buf_alpha = NULL;
> -dst->sz_alpha = 0;
> -}
>  }
>
>  /**
> @@ -1246,7 +1236,7 @@ static inline void cx_pktcpy(struct FrameListData *dst,
>   * @return a negative AVERROR on error
>   */
>  static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
> -  AVPacket *pkt)
> +  struct FrameListData *alpha_cx_frame, AVPacket *pkt)
>  {
>  VPxContext *ctx = avctx->priv_data;
>  int ret = ff_get_encode_buffer(avctx, pkt, cx_frame->sz, 0);
> @@ -1279,16 +1269,16 @@ static int storeframe(AVCodecContext *avctx, struct 
> FrameListData *cx_frame,
>  avctx->error[i] += cx_frame->sse[i + 1];
>  cx_frame->have_sse = 0;
>  }
> -if (cx_frame->sz_alpha > 0) {
> +if (alpha_cx_frame) {
>  side_data = av_packet_new_side_data(pkt,
>  
> AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
> -cx_frame->sz_alpha + 8);
> +alpha_cx_frame->sz + 8);
>  if (!side_data) {
>  av_packet_unref(pkt);
>  return AVERROR(ENOMEM);
>  }
>  AV_WB64(side_data, 1);
> -memcpy(side_data + 8, cx_frame->buf_alpha, cx_frame->sz_alpha);
> +memcpy(side_data + 8, alpha_cx_frame->buf, alpha_cx_frame->sz);
>  }
>  if (cx_frame->frame_number != -1) {
>  if (ctx->hdr10_plus_fifo) {
> @@ -1309,40 +1299,37 @@ static int storeframe(AVCodecContext *avctx, struct 
> FrameListData *cx_frame,
>   * @return AVERROR(EINVAL) on output size error
>   * @return AVERROR(ENOMEM) on coded frame queue data allocation error
>   */
> -static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out)
> +static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder,
> +struct FrameListData **frame_list, AVPacket *pkt_out)
>  {
>  VPxContext *ctx = avctx->priv_data;
>  const struct vpx_codec_cx_pkt *pkt;
> -const struct 

[FFmpeg-devel] [PATCH 1/2] avformat/mov: Rework the AVIF parser to handle multiple items

2022-07-28 Thread Vignesh Venkatasubramanian
Stores the item ids of all the items found in the file and
processes the primary item at the end of the meta box. This patch
does not change any behavior. It sets up the code for parsing
alpha channel (and possibly images with 'grid') in follow up
patches.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |   6 ++
 libavformat/mov.c  | 143 +++--
 2 files changed, 92 insertions(+), 57 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index f05c2d9c28..9d8646d2ea 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -318,6 +318,12 @@ typedef struct MOVContext {
 uint32_t max_stts_delta;
 int is_still_picture_avif;
 int primary_item_id;
+struct {
+int item_id;
+int extent_length;
+int64_t extent_offset;
+} *avif_info;
+int avif_info_size;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index a09a762d91..6ee6ed0950 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4698,6 +4698,69 @@ static int mov_read_custom(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return ret;
 }
 
+static int avif_add_stream(MOVContext *c, int item_id)
+{
+MOVStreamContext *sc;
+AVStream *st;
+int item_index = -1;
+for (int i = 0; i < c->avif_info_size; i++)
+if (c->avif_info[i].item_id == item_id) {
+item_index = i;
+break;
+}
+if (item_index < 0)
+return AVERROR_INVALIDDATA;
+st = avformat_new_stream(c->fc, NULL);
+if (!st)
+return AVERROR(ENOMEM);
+st->id = c->fc->nb_streams;
+sc = av_mallocz(sizeof(MOVStreamContext));
+if (!sc)
+return AVERROR(ENOMEM);
+
+st->priv_data = sc;
+st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+st->codecpar->codec_id = AV_CODEC_ID_AV1;
+sc->ffindex = st->index;
+c->trak_index = st->index;
+st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
+st->time_base.num = st->time_base.den = 1;
+st->nb_frames = 1;
+sc->time_scale = 1;
+sc = st->priv_data;
+sc->pb = c->fc->pb;
+sc->pb_is_copied = 1;
+
+// Populate the necessary fields used by mov_build_index.
+sc->stsc_count = 1;
+sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
+if (!sc->stsc_data)
+return AVERROR(ENOMEM);
+sc->stsc_data[0].first = 1;
+sc->stsc_data[0].count = 1;
+sc->stsc_data[0].id = 1;
+sc->chunk_count = 1;
+sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
+if (!sc->chunk_offsets)
+return AVERROR(ENOMEM);
+sc->sample_count = 1;
+sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
+if (!sc->sample_sizes)
+return AVERROR(ENOMEM);
+sc->stts_count = 1;
+sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
+if (!sc->stts_data)
+return AVERROR(ENOMEM);
+sc->stts_data[0].count = 1;
+// Not used for still images. But needed by mov_build_index.
+sc->stts_data[0].duration = 0;
+sc->sample_sizes[0] = c->avif_info[item_index].extent_length;
+sc->chunk_offsets[0] = c->avif_info[item_index].extent_offset;
+
+mov_build_index(c, st);
+return 0;
+}
+
 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
 while (atom.size > 8) {
@@ -4707,9 +4770,23 @@ static int mov_read_meta(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 tag = avio_rl32(pb);
 atom.size -= 4;
 if (tag == MKTAG('h','d','l','r')) {
+int ret;
 avio_seek(pb, -8, SEEK_CUR);
 atom.size += 8;
-return mov_read_default(c, pb, atom);
+if ((ret = mov_read_default(c, pb, atom)) < 0)
+return ret;
+if (c->is_still_picture_avif) {
+int ret;
+// Add a stream for the YUV planes (primary item).
+if ((ret = avif_add_stream(c, c->primary_item_id)) < 0)
+return ret;
+// For still AVIF images, the meta box contains all the
+// necessary information that would generally be provided by 
the
+// moov box. So simply mark that we have found the moov box so
+// that parsing can continue.
+c->found_moov = 1;
+}
+return ret;
 }
 }
 return 0;
@@ -7478,8 +7555,6 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 int item_count, extent_count;
 uint64_t base_offset, extent_offset, extent_length;
 uint8_t value;
-AVStream *st;
-MOVStreamContext *sc;
 
 if (!c->is_still_picture_avif) {
 // * For non-avif, we simply ignore the iloc box.
@@ -7493,27 +756

Re: [FFmpeg-devel] [PATCH 1/2] avformat/mov: Rework the AVIF parser to handle multiple items

2022-07-28 Thread Vignesh Venkatasubramanian
On Wed, Jul 27, 2022 at 12:40 PM Andreas Rheinhardt
 wrote:
>
> Vignesh Venkatasubramanian:
> > Stores the item ids of all the items found in the file and
> > processes the primary item at the end of the meta box. This patch
> > does not change any behavior. It sets up the code for parsing
> > alpha channel (and possibly images with 'grid') in follow up
> > patches.
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  libavformat/isom.h |   4 ++
> >  libavformat/mov.c  | 146 -
> >  2 files changed, 95 insertions(+), 55 deletions(-)
> >
> > diff --git a/libavformat/isom.h b/libavformat/isom.h
> > index f05c2d9c28..d8b262e915 100644
> > --- a/libavformat/isom.h
> > +++ b/libavformat/isom.h
> > @@ -318,6 +318,10 @@ typedef struct MOVContext {
> >  uint32_t max_stts_delta;
> >  int is_still_picture_avif;
> >  int primary_item_id;
> > +int *avif_item_ids;
> > +int avif_item_ids_size;
> > +int *avif_extent_lengths;
> > +int64_t *avif_extent_offsets;
>
> Why are these three different buffers instead of one buffer of struct {
> int avif_item_ids; int avif_extent_lengths; int64_t avif_extent_offsets;}?
>

Ah good point. Updated to use a struct and a size field.

> >  } MOVContext;
> >
> >  int ff_mp4_read_descr_len(AVIOContext *pb);
> > diff --git a/libavformat/mov.c b/libavformat/mov.c
> > index a09a762d91..fc6a691da4 100644
> > --- a/libavformat/mov.c
> > +++ b/libavformat/mov.c
> > @@ -4698,6 +4698,69 @@ static int mov_read_custom(MOVContext *c, 
> > AVIOContext *pb, MOVAtom atom)
> >  return ret;
> >  }
> >
> > +static int avif_add_stream(MOVContext *c, int item_id)
> > +{
> > +MOVStreamContext *sc;
> > +AVStream *st;
> > +int item_index = -1;
> > +for (int i = 0; i < c->avif_item_ids_size; i++)
> > +if (c->avif_item_ids[i] == item_id) {
> > +item_index = i;
> > +break;
> > +}
> > +if (item_index < 0)
> > +return AVERROR_INVALIDDATA;
> > +st = avformat_new_stream(c->fc, NULL);
> > +if (!st)
> > +return AVERROR(ENOMEM);
> > +st->id = c->fc->nb_streams;
> > +sc = av_mallocz(sizeof(MOVStreamContext));
> > +if (!sc)
> > +return AVERROR(ENOMEM);
> > +
> > +st->priv_data = sc;
> > +st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
> > +st->codecpar->codec_id = AV_CODEC_ID_AV1;
> > +sc->ffindex = st->index;
> > +c->trak_index = st->index;
> > +st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
> > +st->time_base.num = st->time_base.den = 1;
> > +st->nb_frames = 1;
> > +sc->time_scale = 1;
> > +sc = st->priv_data;
> > +sc->pb = c->fc->pb;
> > +sc->pb_is_copied = 1;
> > +
> > +// Populate the necessary fields used by mov_build_index.
> > +sc->stsc_count = 1;
> > +sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
> > +if (!sc->stsc_data)
> > +return AVERROR(ENOMEM);
> > +sc->stsc_data[0].first = 1;
> > +sc->stsc_data[0].count = 1;
> > +sc->stsc_data[0].id = 1;
> > +sc->chunk_count = 1;
> > +sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
> > +if (!sc->chunk_offsets)
> > +return AVERROR(ENOMEM);
> > +sc->sample_count = 1;
> > +sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
> > +if (!sc->sample_sizes)
> > +return AVERROR(ENOMEM);
> > +sc->stts_count = 1;
> > +sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
> > +if (!sc->stts_data)
> > +return AVERROR(ENOMEM);
> > +sc->stts_data[0].count = 1;
> > +// Not used for still images. But needed by mov_build_index.
> > +sc->stts_data[0].duration = 0;
> > +sc->sample_sizes[0] = c->avif_extent_lengths[item_index];
> > +sc->chunk_offsets[0] = c->avif_extent_offsets[item_index];
> > +
> > +mov_build_index(c, st);
> > +return 0;
> > +}
> > +
> >  static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> >  {
> >  while (atom.size > 8) {
> > @@ -4707,9 +4770,23 @@ static int mov_read_meta(MOVContext *c, AVIOContext 
> > *pb, 

Re: [FFmpeg-devel] [PATCH 1/2] avformat/mov: Rework the AVIF parser to handle multiple items

2022-07-27 Thread Vignesh Venkatasubramanian
On Tue, Jul 26, 2022 at 12:02 PM James Zern
 wrote:
>
> On Fri, Jul 22, 2022 at 11:21 AM Vignesh Venkatasubramanian
>  wrote:
> >
> > On Wed, Jul 13, 2022 at 9:12 AM Vignesh Venkatasubramanian
> >  wrote:
> > >
> > > On Mon, Jul 11, 2022 at 3:25 PM James Zern
> > >  wrote:
> > > >
> > > > On Thu, Jun 30, 2022 at 2:04 PM Vignesh Venkatasubramanian
> > > >  wrote:
> > > > >
> > > > > Stores the item ids of all the items found in the file and
> > > > > processes the primary item at the end of the meta box. This patch
> > > > > does not change any behavior. It sets up the code for parsing
> > > > > alpha channel (and possibly images with 'grid') in follow up
> > > > > patches.
> > > > >
> > > > > Signed-off-by: Vignesh Venkatasubramanian 
> > > > > ---
> > > > >  libavformat/isom.h |   4 ++
> > > > >  libavformat/mov.c  | 148 
> > > > > -
> > > > >  2 files changed, 97 insertions(+), 55 deletions(-)
> > > > >
> > > > > [...]
> > > >
> > > > @@ -4692,9 +4755,25 @@ static int mov_read_meta(MOVContext *c,
> > > > AVIOContext *pb, MOVAtom atom)
> > > >  tag = avio_rl32(pb);
> > > >  atom.size -= 4;
> > > >  if (tag == MKTAG('h','d','l','r')) {
> > > > +int ret;
> > > >  avio_seek(pb, -8, SEEK_CUR);
> > > >  atom.size += 8;
> > > > -return mov_read_default(c, pb, atom);
> > > > +ret = mov_read_default(c, pb, atom);
> > > > +if (ret < 0)
> > > >
> > > > In some other cases these two lines are combined, if ((ret = ...
> > > >
> > >
> > > Done.
> > >
> > > > +return ret;
> > > > +if (c->is_still_picture_avif) {
> > > > +int ret;
> > > > +// Add a stream for the YUV planes (primary item).
> > > > +ret = avif_add_stream(c, c->primary_item_id);
> > > > +if (ret)
> > > >
> > > > This could be updated too and use '< 0' to match other code.
> > > >
> > >
> > > Done.
> > >
> > > > +return ret;
> > > > +// For still AVIF images, the meta box contains all the
> > > > +// necessary information that would generally be
> > > > provided by the
> > > > +// moov box. So simply mark that we have found the 
> > > > moov box so
> > > > +// that parsing can continue.
> > > > +c->found_moov = 1;
> > > > +}
> > > > +return ret;
> > > >  }
> > > > ___
> > > > 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".
> > >
> > >
> > >
> > > --
> > > Vignesh
> >
> > Any further comments on this one?
> >
> > Please note that i have abandoned the second patch in this list. But
> > this one is still up for merging.
> >
>
> This looks like it needs to be rebased. I'll take a look after that.

Done.

> ___
> 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".



-- 
Vignesh
___
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/2] avformat/mov: Rework the AVIF parser to handle multiple items

2022-07-27 Thread Vignesh Venkatasubramanian
Stores the item ids of all the items found in the file and
processes the primary item at the end of the meta box. This patch
does not change any behavior. It sets up the code for parsing
alpha channel (and possibly images with 'grid') in follow up
patches.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |   4 ++
 libavformat/mov.c  | 146 -
 2 files changed, 95 insertions(+), 55 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index f05c2d9c28..d8b262e915 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -318,6 +318,10 @@ typedef struct MOVContext {
 uint32_t max_stts_delta;
 int is_still_picture_avif;
 int primary_item_id;
+int *avif_item_ids;
+int avif_item_ids_size;
+int *avif_extent_lengths;
+int64_t *avif_extent_offsets;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index a09a762d91..fc6a691da4 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4698,6 +4698,69 @@ static int mov_read_custom(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return ret;
 }
 
+static int avif_add_stream(MOVContext *c, int item_id)
+{
+MOVStreamContext *sc;
+AVStream *st;
+int item_index = -1;
+for (int i = 0; i < c->avif_item_ids_size; i++)
+if (c->avif_item_ids[i] == item_id) {
+item_index = i;
+break;
+}
+if (item_index < 0)
+return AVERROR_INVALIDDATA;
+st = avformat_new_stream(c->fc, NULL);
+if (!st)
+return AVERROR(ENOMEM);
+st->id = c->fc->nb_streams;
+sc = av_mallocz(sizeof(MOVStreamContext));
+if (!sc)
+return AVERROR(ENOMEM);
+
+st->priv_data = sc;
+st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+st->codecpar->codec_id = AV_CODEC_ID_AV1;
+sc->ffindex = st->index;
+c->trak_index = st->index;
+st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
+st->time_base.num = st->time_base.den = 1;
+st->nb_frames = 1;
+sc->time_scale = 1;
+sc = st->priv_data;
+sc->pb = c->fc->pb;
+sc->pb_is_copied = 1;
+
+// Populate the necessary fields used by mov_build_index.
+sc->stsc_count = 1;
+sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
+if (!sc->stsc_data)
+return AVERROR(ENOMEM);
+sc->stsc_data[0].first = 1;
+sc->stsc_data[0].count = 1;
+sc->stsc_data[0].id = 1;
+sc->chunk_count = 1;
+sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
+if (!sc->chunk_offsets)
+return AVERROR(ENOMEM);
+sc->sample_count = 1;
+sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
+if (!sc->sample_sizes)
+return AVERROR(ENOMEM);
+sc->stts_count = 1;
+sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
+if (!sc->stts_data)
+return AVERROR(ENOMEM);
+sc->stts_data[0].count = 1;
+// Not used for still images. But needed by mov_build_index.
+sc->stts_data[0].duration = 0;
+sc->sample_sizes[0] = c->avif_extent_lengths[item_index];
+sc->chunk_offsets[0] = c->avif_extent_offsets[item_index];
+
+mov_build_index(c, st);
+return 0;
+}
+
 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
 while (atom.size > 8) {
@@ -4707,9 +4770,23 @@ static int mov_read_meta(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 tag = avio_rl32(pb);
 atom.size -= 4;
 if (tag == MKTAG('h','d','l','r')) {
+int ret;
 avio_seek(pb, -8, SEEK_CUR);
 atom.size += 8;
-return mov_read_default(c, pb, atom);
+if ((ret = mov_read_default(c, pb, atom)) < 0)
+return ret;
+if (c->is_still_picture_avif) {
+int ret;
+// Add a stream for the YUV planes (primary item).
+if ((ret = avif_add_stream(c, c->primary_item_id)) < 0)
+return ret;
+// For still AVIF images, the meta box contains all the
+// necessary information that would generally be provided by 
the
+// moov box. So simply mark that we have found the moov box so
+// that parsing can continue.
+c->found_moov = 1;
+}
+return ret;
 }
 }
 return 0;
@@ -7478,8 +7555,6 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 int item_count, extent_count;
 uint64_t base_offset, extent_offset, extent_length;
 uint8_t value;
-AVStream *st;
-MOVStreamContext *sc;
 
 if (!c->is_still_picture_avif) {
 // * For non-avif, we simply ignore the iloc box.
@@ -7493,27 +7568,6 @@ static int mov_rea

Re: [FFmpeg-devel] [PATCH 1/2] avformat/mov: Rework the AVIF parser to handle multiple items

2022-07-22 Thread Vignesh Venkatasubramanian
On Wed, Jul 13, 2022 at 9:12 AM Vignesh Venkatasubramanian
 wrote:
>
> On Mon, Jul 11, 2022 at 3:25 PM James Zern
>  wrote:
> >
> > On Thu, Jun 30, 2022 at 2:04 PM Vignesh Venkatasubramanian
> >  wrote:
> > >
> > > Stores the item ids of all the items found in the file and
> > > processes the primary item at the end of the meta box. This patch
> > > does not change any behavior. It sets up the code for parsing
> > > alpha channel (and possibly images with 'grid') in follow up
> > > patches.
> > >
> > > Signed-off-by: Vignesh Venkatasubramanian 
> > > ---
> > >  libavformat/isom.h |   4 ++
> > >  libavformat/mov.c  | 148 -
> > >  2 files changed, 97 insertions(+), 55 deletions(-)
> > >
> > > [...]
> >
> > @@ -4692,9 +4755,25 @@ static int mov_read_meta(MOVContext *c,
> > AVIOContext *pb, MOVAtom atom)
> >  tag = avio_rl32(pb);
> >  atom.size -= 4;
> >  if (tag == MKTAG('h','d','l','r')) {
> > +int ret;
> >  avio_seek(pb, -8, SEEK_CUR);
> >  atom.size += 8;
> > -return mov_read_default(c, pb, atom);
> > +ret = mov_read_default(c, pb, atom);
> > +if (ret < 0)
> >
> > In some other cases these two lines are combined, if ((ret = ...
> >
>
> Done.
>
> > +return ret;
> > +if (c->is_still_picture_avif) {
> > +int ret;
> > +// Add a stream for the YUV planes (primary item).
> > +ret = avif_add_stream(c, c->primary_item_id);
> > +if (ret)
> >
> > This could be updated too and use '< 0' to match other code.
> >
>
> Done.
>
> > +return ret;
> > +// For still AVIF images, the meta box contains all the
> > +// necessary information that would generally be
> > provided by the
> > +// moov box. So simply mark that we have found the moov 
> > box so
> > +// that parsing can continue.
> > +c->found_moov = 1;
> > +}
> > +return ret;
> >  }
> > ___
> > 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".
>
>
>
> --
> Vignesh

Any further comments on this one?

Please note that i have abandoned the second patch in this list. But
this one is still up for merging.

-- 
Vignesh
___
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] avfilter/xstack: Add support for fixed size grid

2022-07-13 Thread Vignesh Venkatasubramanian
On Wed, Jul 13, 2022 at 9:08 AM Paul B Mahol  wrote:
>
>
> It is merged already.

Oops, sorry about that. Thanks for merging!

-- 
Vignesh
___
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 1/2] avformat/mov: Rework the AVIF parser to handle multiple items

2022-07-13 Thread Vignesh Venkatasubramanian
On Mon, Jul 11, 2022 at 3:25 PM James Zern
 wrote:
>
> On Thu, Jun 30, 2022 at 2:04 PM Vignesh Venkatasubramanian
>  wrote:
> >
> > Stores the item ids of all the items found in the file and
> > processes the primary item at the end of the meta box. This patch
> > does not change any behavior. It sets up the code for parsing
> > alpha channel (and possibly images with 'grid') in follow up
> > patches.
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  libavformat/isom.h |   4 ++
> >  libavformat/mov.c  | 148 -
> >  2 files changed, 97 insertions(+), 55 deletions(-)
> >
> > [...]
>
> @@ -4692,9 +4755,25 @@ static int mov_read_meta(MOVContext *c,
> AVIOContext *pb, MOVAtom atom)
>  tag = avio_rl32(pb);
>  atom.size -= 4;
>  if (tag == MKTAG('h','d','l','r')) {
> +int ret;
>  avio_seek(pb, -8, SEEK_CUR);
>  atom.size += 8;
> -return mov_read_default(c, pb, atom);
> +ret = mov_read_default(c, pb, atom);
> +if (ret < 0)
>
> In some other cases these two lines are combined, if ((ret = ...
>

Done.

> +return ret;
> +if (c->is_still_picture_avif) {
> +int ret;
> +// Add a stream for the YUV planes (primary item).
> +ret = avif_add_stream(c, c->primary_item_id);
> +if (ret)
>
> This could be updated too and use '< 0' to match other code.
>

Done.

> +return ret;
> +// For still AVIF images, the meta box contains all the
> +// necessary information that would generally be
> provided by the
> +// moov box. So simply mark that we have found the moov box 
> so
> +// that parsing can continue.
> +c->found_moov = 1;
> +}
> +return ret;
>  }
> ___
> 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".



-- 
Vignesh
___
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/2] avformat/mov: Rework the AVIF parser to handle multiple items

2022-07-13 Thread Vignesh Venkatasubramanian
Stores the item ids of all the items found in the file and
processes the primary item at the end of the meta box. This patch
does not change any behavior. It sets up the code for parsing
alpha channel (and possibly images with 'grid') in follow up
patches.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |   4 ++
 libavformat/mov.c  | 146 -
 2 files changed, 95 insertions(+), 55 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index f05c2d9c28..d8b262e915 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -318,6 +318,10 @@ typedef struct MOVContext {
 uint32_t max_stts_delta;
 int is_still_picture_avif;
 int primary_item_id;
+int *avif_item_ids;
+int avif_item_ids_size;
+int *avif_extent_lengths;
+int64_t *avif_extent_offsets;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 88669faa70..cd87088f3e 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4683,6 +4683,69 @@ static int mov_read_custom(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return ret;
 }
 
+static int avif_add_stream(MOVContext *c, int item_id)
+{
+MOVStreamContext *sc;
+AVStream *st;
+int item_index = -1;
+for (int i = 0; i < c->avif_item_ids_size; i++)
+if (c->avif_item_ids[i] == item_id) {
+item_index = i;
+break;
+}
+if (item_index < 0)
+return AVERROR_INVALIDDATA;
+st = avformat_new_stream(c->fc, NULL);
+if (!st)
+return AVERROR(ENOMEM);
+st->id = c->fc->nb_streams;
+sc = av_mallocz(sizeof(MOVStreamContext));
+if (!sc)
+return AVERROR(ENOMEM);
+
+st->priv_data = sc;
+st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+st->codecpar->codec_id = AV_CODEC_ID_AV1;
+sc->ffindex = st->index;
+c->trak_index = st->index;
+st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
+st->time_base.num = st->time_base.den = 1;
+st->nb_frames = 1;
+sc->time_scale = 1;
+sc = st->priv_data;
+sc->pb = c->fc->pb;
+sc->pb_is_copied = 1;
+
+// Populate the necessary fields used by mov_build_index.
+sc->stsc_count = 1;
+sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
+if (!sc->stsc_data)
+return AVERROR(ENOMEM);
+sc->stsc_data[0].first = 1;
+sc->stsc_data[0].count = 1;
+sc->stsc_data[0].id = 1;
+sc->chunk_count = 1;
+sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
+if (!sc->chunk_offsets)
+return AVERROR(ENOMEM);
+sc->sample_count = 1;
+sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
+if (!sc->sample_sizes)
+return AVERROR(ENOMEM);
+sc->stts_count = 1;
+sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
+if (!sc->stts_data)
+return AVERROR(ENOMEM);
+sc->stts_data[0].count = 1;
+// Not used for still images. But needed by mov_build_index.
+sc->stts_data[0].duration = 0;
+sc->sample_sizes[0] = c->avif_extent_lengths[item_index];
+sc->chunk_offsets[0] = c->avif_extent_offsets[item_index];
+
+mov_build_index(c, st);
+return 0;
+}
+
 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
 while (atom.size > 8) {
@@ -4692,9 +4755,23 @@ static int mov_read_meta(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 tag = avio_rl32(pb);
 atom.size -= 4;
 if (tag == MKTAG('h','d','l','r')) {
+int ret;
 avio_seek(pb, -8, SEEK_CUR);
 atom.size += 8;
-return mov_read_default(c, pb, atom);
+if ((ret = mov_read_default(c, pb, atom)) < 0)
+return ret;
+if (c->is_still_picture_avif) {
+int ret;
+// Add a stream for the YUV planes (primary item).
+if ((ret = avif_add_stream(c, c->primary_item_id)) < 0)
+return ret;
+// For still AVIF images, the meta box contains all the
+// necessary information that would generally be provided by 
the
+// moov box. So simply mark that we have found the moov box so
+// that parsing can continue.
+c->found_moov = 1;
+}
+return ret;
 }
 }
 return 0;
@@ -7483,8 +7560,6 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 int item_count, extent_count;
 uint64_t base_offset, extent_offset, extent_length;
 uint8_t value;
-AVStream *st;
-MOVStreamContext *sc;
 
 if (!c->is_still_picture_avif) {
 // * For non-avif, we simply ignore the iloc box.
@@ -7498,27 +7573,6 @@ static int mov_rea

Re: [FFmpeg-devel] [PATCH] avfilter/xstack: Add support for fixed size grid

2022-07-13 Thread Vignesh Venkatasubramanian
On Wed, Jun 29, 2022 at 10:15 AM Vignesh Venkatasubramanian
 wrote:
>
> On Wed, Jun 29, 2022 at 12:24 AM Paul B Mahol  wrote:
> >
> >
> >
> > On Wed, Jun 29, 2022 at 9:21 AM Paul B Mahol  wrote:
> >>
> >>
> >>
> >> On Tue, Jun 28, 2022 at 9:01 PM Vignesh Venkatasubramanian 
> >>  wrote:
> >>>
> >>> Add a short hand parameter for making a fixed size grid. The existing
> >>> xstack layout parameter syntax gets tedious if all one wants is a
> >>> matrix like grid of the input streams. Add a grid option to the xstack
> >>> filter that simplifies this use case by simply specifying the number of
> >>> rows and columns instead of specific x/y co-ordinate for each stream.
> >>
> >>
> >> Use SIZE AVOption for grid size option.
> >> As already done in tile filter.
>
> Ah, i did not know about this option. Updated.
>
> >
> >
> > Also there is no need to always force same size of frames in grid, can 
> > either force same width or same height.
> >
>
> I have relaxed the condition to "images within the same row must have
> same height (similar to hstack) and all rows must have the same width
> (similar to vstack)".
>
> > By default it can use grid option, (just set grid default to 2x1, and 
> > remove default layout setup thing)
>
> Done.
>
> >>
> >>
> >>
> >>
> >>>
> >>>
> >>> Also updating the filter documentation to explain the new option.
> >>>
> >>> Signed-off-by: Vignesh Venkatasubramanian 
> >>> ---
> >>>  doc/filters.texi   | 19 +--
> >>>  libavfilter/vf_stack.c | 73 --
> >>>  2 files changed, 81 insertions(+), 11 deletions(-)
> >>>
> >>> diff --git a/doc/filters.texi b/doc/filters.texi
> >>> index e525e87b3c..9d800a0fd6 100644
> >>> --- a/doc/filters.texi
> >>> +++ b/doc/filters.texi
> >>> @@ -24381,8 +24381,23 @@ the output video frame will be filled. 
> >>> Similarly, videos can overlap each
> >>>  other if their position doesn't leave enough space for the full frame of
> >>>  adjoining videos.
> >>>
> >>> -For 2 inputs, a default layout of @code{0_0|w0_0} is set. In all other 
> >>> cases,
> >>> -a layout must be set by the user.
> >>> +For 2 inputs, a default layout of @code{0_0|w0_0} is set. In all other 
> >>> cases, a
> >>> +layout or a grid must be set by the user. Either grid or layout option 
> >>> can be
> >>> +specified at a time. Specifying both will result in an error.
> >>> +
> >>> +@item grid
> >>> +Specify a fixed size grid of inputs.
> >>> +This option is used to create a fixed size grid of the input streams.  
> >>> The
> >>> +option is of the form x (e.g. 2x4). There must be  *
> >>> + input streams and they will be arranged as a grid with  
> >>> rows and
> >>> + columns. When using this option, all the input streams must 
> >>> have the
> >>> +same width and height.
> >>> +
> >>> +Either grid or layout option can be specified at a time. Specifying both 
> >>> will
> >>> +result in an error.
> >>> +
> >>> +If grid is set, then inputs option is ignored and is implicitly set to
> >>> +*.
> >>>
> >>>  @item shortest
> >>>  If set to 1, force the output to terminate when the shortest input
> >>> diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c
> >>> index aa32a1bf5e..b38a193355 100644
> >>> --- a/libavfilter/vf_stack.c
> >>> +++ b/libavfilter/vf_stack.c
> >>> @@ -48,6 +48,9 @@ typedef struct StackContext {
> >>>  int is_vertical;
> >>>  int is_horizontal;
> >>>  int nb_planes;
> >>> +char *grid;
> >>> +int nb_grid_rows;
> >>> +int nb_grid_columns;
> >>>  uint8_t fillcolor[4];
> >>>  char *fillcolor_str;
> >>>  int fillcolor_enable;
> >>> @@ -85,14 +88,6 @@ static av_cold int init(AVFilterContext *ctx)
> >>>  if (!strcmp(ctx->filter->name, "hstack"))
> >>>  s->is_horizontal = 1;
> >>>
> >>> -s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames));
> >>> 

Re: [FFmpeg-devel] [PATCH 2/2] avformat/mov: Support parsing of still AVIF Alpha Channel

2022-07-12 Thread Vignesh Venkatasubramanian
On Tue, Jul 5, 2022 at 9:54 AM Anton Khirnov  wrote:
>
> Quoting Vignesh Venkatasubramanian (2022-07-02 23:15:35)
> > > As for encoding, not fully sure how it should be integrated, if any
> > > encoders actually at this moment do proper alpha coding, or do all API
> > > clients have to separately encode with one context the primary image,
> > > and the alpha with another?
> >
> > I am not sure about other codecs, but in the case of AVIF/AV1, the
> > encoder does not understand/support alpha channels. The only way to do
> > it is to use two separate encoders.
>
> Can this not be handled in our encoder wrapper?
>

By encoder wrapper, you mean codec wrappers in libavcodec like
libaomenc.c right ? Yes, it is possible to do this in the encoder
wrapper by keeping multiple instances of the encoder. But each encoder
wrapper has to be updated to support it. AV1, for example, has three
different encoders that can be used as of today (aom, rav1e and
svt-av1).

> We should strive as much as possible to shield our callers from
> codec-specific implementation details.
>
> --
> 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".



-- 
Vignesh
___
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 2/2] avformat/mov: Support parsing of still AVIF Alpha Channel

2022-07-03 Thread Vignesh Venkatasubramanian
On Sun, Jul 3, 2022 at 5:18 AM Jan Ekström  wrote:
>
> On Sun, Jul 3, 2022 at 12:15 AM Vignesh Venkatasubramanian
>  wrote:
> >
> > On Sat, Jul 2, 2022 at 12:35 PM Jan Ekström  wrote:
> > >
> > > On Sat, Jul 2, 2022 at 7:32 PM Vignesh Venkatasubramanian
> > >  wrote:
> > > >
> > > > On Sat, Jul 2, 2022 at 2:35 AM Anton Khirnov  wrote:
> > > > >
> > > > > Quoting Vignesh Venkatasubramanian (2022-06-30 23:04:34)
> > > > > > Parse the alpha channel for still AVIF images and expose it as a
> > > > > > separate track. This is the simplest way of supporting AVIF alpha
> > > > > > channel in a codec independent manner (similar to how ffmpeg
> > > > > > supports animated AVIF with alpha channel).
> > > > > >
> > > > > > One can use the alphamerge filter to get a transparent image with
> > > > > > a single command. For example:
> > > > > >
> > > > > > ffmpeg -i image_with_alpha.avif -filter_complex alphamerge 
> > > > > > image_with_alpha.png
> > > > > >
> > > > > > Signed-off-by: Vignesh Venkatasubramanian 
> > > > > > ---
> > > > > >  libavformat/isom.h |  1 +
> > > > > >  libavformat/mov.c  | 66 
> > > > > > ++
> > > > > >  2 files changed, 67 insertions(+)
> > > > >
> > > > > I am against this patch, this is a digusting hack.
> > > > >
> > > > > These are not two streams, it is a single stream and should be exposed
> > > > > as such.
> > > > >
> > > >
> > > > Yes, while it is a hack, it is also the simplest way of supporting
> > > > AVIF images with alpha. Since AVIF alpha images require two separate
> > > > decoders, i could not think of any other solution that does not
> > > > involve modifying the underlying av1 codec itself.
> > > >
> > > > If there are any alternative solutions where we can expose a single
> > > > stream that needs two codecs, then i am open to implementing that.
> > > >
> > > > Otherwise, this solution improves the current situation where there is
> > > > no way for the user to extract the alpha channel (albeit in a hacky
> > > > way).
> > >
> > > I have discussed this on IRC,
> >
> > Thank you for discussing this!
> >
> > > and as far as I can see we have multiple
> > > cases where an additional image has to be decoded by a separate
> > > decoder context to get alpha, namely:
> > >
> > > - vp8/9 (currently handled by AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL)
> > > - HEIF-like formats (such as AVIF), which are codec agnostic (you can
> > > put JPEG, HEVC, AV1 etc into HEIF)
> > >
> > > This means the logic (preferably) should not be codec-specific, and
> > > would allow to implement at least two separate
> > >
> > > My proposal - which Anton didn't really like - was to add a side data
> > > entry AV_PKT_DATA_AUXILIARY_IMAGE , which could have type (ALPHA,
> > > DEPTH etc) as well as the relevant packet(s) - as well as if any of
> > > specifications define codec initialization data, that. Then
> > > libavcodec/decode or so could initialize a secondary decoder context
> > > for alpha images and add the third plane if parameters match what's
> > > required.
> > >
> >
> > My only concern about this solution is that, while the demuxer can
> > easily put the alpha data in the side data, we will then have to
> > modify the decoder (in case of HEIF, we will have to change each
> > underlying codec like av1, hevc, jpeg, etc) to support handling of
> > this side data. I was just hoping it would be nicer if we can have
> > something simpler without having to change every individual libavcodec
> > implementation. ffmpeg already has a way to cleanly initialize codecs
> > and pass data to them, so it would be nicer if we can leverage that
> > somehow instead of making each libavcodec implementation handle this
> > side data type.
>
> Yes This is why I specifically noted that general decode logic should
> be modified, not separate decoders. Just like the recent ICC profile
> <-> color space information patch set by Niklas.
>

Ah okay, i see what you are saying now. This makes sense. I am also in
favor of this solution then.

We can abandon this second patch for now and i will see if i can
implement the side data based solution.

The first patch in this series is still a refactor that will be useful
for the future. So i will leave that open for review.

> It is clearly a thing that is going to get utilized by multiple
> things, so having it specific to specific codecs makes no sense :) .

Yes, sounds good!

>
> Jan
> ___
> 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".



-- 
Vignesh
___
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 2/2] avformat/mov: Support parsing of still AVIF Alpha Channel

2022-07-02 Thread Vignesh Venkatasubramanian
On Sat, Jul 2, 2022 at 12:35 PM Jan Ekström  wrote:
>
> On Sat, Jul 2, 2022 at 7:32 PM Vignesh Venkatasubramanian
>  wrote:
> >
> > On Sat, Jul 2, 2022 at 2:35 AM Anton Khirnov  wrote:
> > >
> > > Quoting Vignesh Venkatasubramanian (2022-06-30 23:04:34)
> > > > Parse the alpha channel for still AVIF images and expose it as a
> > > > separate track. This is the simplest way of supporting AVIF alpha
> > > > channel in a codec independent manner (similar to how ffmpeg
> > > > supports animated AVIF with alpha channel).
> > > >
> > > > One can use the alphamerge filter to get a transparent image with
> > > > a single command. For example:
> > > >
> > > > ffmpeg -i image_with_alpha.avif -filter_complex alphamerge 
> > > > image_with_alpha.png
> > > >
> > > > Signed-off-by: Vignesh Venkatasubramanian 
> > > > ---
> > > >  libavformat/isom.h |  1 +
> > > >  libavformat/mov.c  | 66 ++
> > > >  2 files changed, 67 insertions(+)
> > >
> > > I am against this patch, this is a digusting hack.
> > >
> > > These are not two streams, it is a single stream and should be exposed
> > > as such.
> > >
> >
> > Yes, while it is a hack, it is also the simplest way of supporting
> > AVIF images with alpha. Since AVIF alpha images require two separate
> > decoders, i could not think of any other solution that does not
> > involve modifying the underlying av1 codec itself.
> >
> > If there are any alternative solutions where we can expose a single
> > stream that needs two codecs, then i am open to implementing that.
> >
> > Otherwise, this solution improves the current situation where there is
> > no way for the user to extract the alpha channel (albeit in a hacky
> > way).
>
> I have discussed this on IRC,

Thank you for discussing this!

> and as far as I can see we have multiple
> cases where an additional image has to be decoded by a separate
> decoder context to get alpha, namely:
>
> - vp8/9 (currently handled by AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL)
> - HEIF-like formats (such as AVIF), which are codec agnostic (you can
> put JPEG, HEVC, AV1 etc into HEIF)
>
> This means the logic (preferably) should not be codec-specific, and
> would allow to implement at least two separate
>
> My proposal - which Anton didn't really like - was to add a side data
> entry AV_PKT_DATA_AUXILIARY_IMAGE , which could have type (ALPHA,
> DEPTH etc) as well as the relevant packet(s) - as well as if any of
> specifications define codec initialization data, that. Then
> libavcodec/decode or so could initialize a secondary decoder context
> for alpha images and add the third plane if parameters match what's
> required.
>

My only concern about this solution is that, while the demuxer can
easily put the alpha data in the side data, we will then have to
modify the decoder (in case of HEIF, we will have to change each
underlying codec like av1, hevc, jpeg, etc) to support handling of
this side data. I was just hoping it would be nicer if we can have
something simpler without having to change every individual libavcodec
implementation. ffmpeg already has a way to cleanly initialize codecs
and pass data to them, so it would be nicer if we can leverage that
somehow instead of making each libavcodec implementation handle this
side data type.

For example, the proposed solution is what we do for the VP8 alpha
demuxing and there is already some fragmentation. The libvpx based vp8
decoder supports alpha channel decoding while the native ffmpeg vp8
decoder does not support it. So, a user has to explicitly pass -c:v
libvpx-vp8 to be able to decode files with alpha channel properly.

> This would also make remux possible, since containers that do not
> support such auxiliary images would ignore the alpha plane, and those
> that do would properly pass it through.
>

The remux is possible in the multi-stream approach/hack as well. But I
do see your point.

> As for encoding, not fully sure how it should be integrated, if any
> encoders actually at this moment do proper alpha coding, or do all API
> clients have to separately encode with one context the primary image,
> and the alpha with another?

I am not sure about other codecs, but in the case of AVIF/AV1, the
encoder does not understand/support alpha channels. The only way to do
it is to use two separate encoders.

> That said, the multi-stream implementation
> is already merged on the muxer side, so that can be utilized in the
> mean time, even though the auxiliary images are not technically a
> separate str

Re: [FFmpeg-devel] [PATCH 2/2] avformat/mov: Support parsing of still AVIF Alpha Channel

2022-07-02 Thread Vignesh Venkatasubramanian
On Sat, Jul 2, 2022 at 2:35 AM Anton Khirnov  wrote:
>
> Quoting Vignesh Venkatasubramanian (2022-06-30 23:04:34)
> > Parse the alpha channel for still AVIF images and expose it as a
> > separate track. This is the simplest way of supporting AVIF alpha
> > channel in a codec independent manner (similar to how ffmpeg
> > supports animated AVIF with alpha channel).
> >
> > One can use the alphamerge filter to get a transparent image with
> > a single command. For example:
> >
> > ffmpeg -i image_with_alpha.avif -filter_complex alphamerge 
> > image_with_alpha.png
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  libavformat/isom.h |  1 +
> >  libavformat/mov.c  | 66 ++
> >  2 files changed, 67 insertions(+)
>
> I am against this patch, this is a digusting hack.
>
> These are not two streams, it is a single stream and should be exposed
> as such.
>

Yes, while it is a hack, it is also the simplest way of supporting
AVIF images with alpha. Since AVIF alpha images require two separate
decoders, i could not think of any other solution that does not
involve modifying the underlying av1 codec itself.

If there are any alternative solutions where we can expose a single
stream that needs two codecs, then i am open to implementing that.

Otherwise, this solution improves the current situation where there is
no way for the user to extract the alpha channel (albeit in a hacky
way).

> --
> Anton Khirnov



-- 
Vignesh
___
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/2] avformat/mov: Support parsing of still AVIF Alpha Channel

2022-06-30 Thread Vignesh Venkatasubramanian
Parse the alpha channel for still AVIF images and expose it as a
separate track. This is the simplest way of supporting AVIF alpha
channel in a codec independent manner (similar to how ffmpeg
supports animated AVIF with alpha channel).

One can use the alphamerge filter to get a transparent image with
a single command. For example:

ffmpeg -i image_with_alpha.avif -filter_complex alphamerge image_with_alpha.png

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |  1 +
 libavformat/mov.c  | 66 ++
 2 files changed, 67 insertions(+)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index d8b262e915..62b95b40ff 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -318,6 +318,7 @@ typedef struct MOVContext {
 uint32_t max_stts_delta;
 int is_still_picture_avif;
 int primary_item_id;
+int alpha_item_id;
 int *avif_item_ids;
 int avif_item_ids_size;
 int *avif_extent_lengths;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 9df5055d4e..72b17b618d 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4758,6 +4758,7 @@ static int mov_read_meta(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 int ret;
 avio_seek(pb, -8, SEEK_CUR);
 atom.size += 8;
+c->alpha_item_id = -1;
 ret = mov_read_default(c, pb, atom);
 if (ret < 0)
 return ret;
@@ -4767,6 +4768,12 @@ static int mov_read_meta(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 ret = avif_add_stream(c, c->primary_item_id);
 if (ret)
 return ret;
+if (c->alpha_item_id != -1) {
+// Add a stream for the Alpha plane.
+ret = avif_add_stream(c, c->alpha_item_id);
+if (ret)
+return ret;
+}
 // For still AVIF images, the meta box contains all the
 // necessary information that would generally be provided by 
the
 // moov box. So simply mark that we have found the moov box so
@@ -7556,6 +7563,64 @@ static int mov_read_pitm(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 return atom.size;
 }
 
+static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+int entry_count, size, version, flags;
+int index = 0, auxC_alpha_index = -1;
+size = avio_rb32(pb);
+if (avio_rl32(pb) != MKTAG('i','p','c','o'))
+return AVERROR_INVALIDDATA;
+size -= 8;
+while (size > 0) {
+int sub_size, sub_type;
+sub_size = avio_rb32(pb);
+sub_type = avio_rl32(pb);
+sub_size -= 8;
+size -= sub_size + 8;
+index++;
+if (sub_type == MKTAG('a','u','x','C')) {
+const char *expected_alpha_urn = 
"urn:mpeg:mpegB:cicp:systems:auxiliary:alpha";
+avio_rb32(pb);  // version & flags.
+sub_size -= 4;
+if (sub_size >= strlen(expected_alpha_urn) + 1) {
+char alpha_urn[44];
+avio_read(pb, alpha_urn, 44);
+sub_size -= 44;
+if (!strncmp(alpha_urn, expected_alpha_urn, 44)) {
+auxC_alpha_index = index;
+}
+}
+}
+avio_skip(pb, sub_size);
+}
+if (auxC_alpha_index == -1)
+return atom.size;
+
+// ipma.
+size = avio_rb32(pb);
+if (avio_rl32(pb) != MKTAG('i','p','m','a'))
+return AVERROR_INVALIDDATA;
+version = avio_r8(pb);
+flags = avio_rb24(pb);
+entry_count = avio_rb32(pb);
+for (int i = 0; i < entry_count; i++) {
+int item_id, association_count;
+item_id = (version < 1) ? avio_rb16(pb) : avio_rb32(pb);
+association_count = avio_r8(pb);
+for (int j = 0; j < association_count; j++) {
+int property_index;
+if (flags & 1)
+property_index = avio_rb16(pb) & 0x7fff;
+else
+property_index = avio_r8(pb) & 0x7f;
+if (property_index == auxC_alpha_index) {
+c->alpha_item_id = item_id;
+}
+}
+}
+return atom.size;
+}
+
 static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
 int version, offset_size, length_size, base_offset_size, index_size;
@@ -7732,6 +7797,7 @@ static const MOVParseTableEntry mov_default_parse_table[] 
= {
 { MKTAG('i','l','o','c'), mov_read_iloc },
 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
 { MKTAG('p','i','t','m'), mov_read_pitm },
+{ MKTAG('i','p','r','p'), mov_read_iprp },
 { 0, NULL }
 };
 
-- 
2.37.0.rc0.161.g10f37bed90-goog

___
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/2] avformat/mov: Rework the AVIF parser to handle multiple items

2022-06-30 Thread Vignesh Venkatasubramanian
Stores the item ids of all the items found in the file and
processes the primary item at the end of the meta box. This patch
does not change any behavior. It sets up the code for parsing
alpha channel (and possibly images with 'grid') in follow up
patches.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |   4 ++
 libavformat/mov.c  | 148 -
 2 files changed, 97 insertions(+), 55 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index f05c2d9c28..d8b262e915 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -318,6 +318,10 @@ typedef struct MOVContext {
 uint32_t max_stts_delta;
 int is_still_picture_avif;
 int primary_item_id;
+int *avif_item_ids;
+int avif_item_ids_size;
+int *avif_extent_lengths;
+int64_t *avif_extent_offsets;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 88669faa70..9df5055d4e 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4683,6 +4683,69 @@ static int mov_read_custom(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return ret;
 }
 
+static int avif_add_stream(MOVContext *c, int item_id)
+{
+MOVStreamContext *sc;
+AVStream *st;
+int item_index = -1;
+for (int i = 0; i < c->avif_item_ids_size; i++)
+if (c->avif_item_ids[i] == item_id) {
+item_index = i;
+break;
+}
+if (item_index < 0)
+return AVERROR_INVALIDDATA;
+st = avformat_new_stream(c->fc, NULL);
+if (!st)
+return AVERROR(ENOMEM);
+st->id = c->fc->nb_streams;
+sc = av_mallocz(sizeof(MOVStreamContext));
+if (!sc)
+return AVERROR(ENOMEM);
+
+st->priv_data = sc;
+st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+st->codecpar->codec_id = AV_CODEC_ID_AV1;
+sc->ffindex = st->index;
+c->trak_index = st->index;
+st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
+st->time_base.num = st->time_base.den = 1;
+st->nb_frames = 1;
+sc->time_scale = 1;
+sc = st->priv_data;
+sc->pb = c->fc->pb;
+sc->pb_is_copied = 1;
+
+// Populate the necessary fields used by mov_build_index.
+sc->stsc_count = 1;
+sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
+if (!sc->stsc_data)
+return AVERROR(ENOMEM);
+sc->stsc_data[0].first = 1;
+sc->stsc_data[0].count = 1;
+sc->stsc_data[0].id = 1;
+sc->chunk_count = 1;
+sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
+if (!sc->chunk_offsets)
+return AVERROR(ENOMEM);
+sc->sample_count = 1;
+sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
+if (!sc->sample_sizes)
+return AVERROR(ENOMEM);
+sc->stts_count = 1;
+sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
+if (!sc->stts_data)
+return AVERROR(ENOMEM);
+sc->stts_data[0].count = 1;
+// Not used for still images. But needed by mov_build_index.
+sc->stts_data[0].duration = 0;
+sc->sample_sizes[0] = c->avif_extent_lengths[item_index];
+sc->chunk_offsets[0] = c->avif_extent_offsets[item_index];
+
+mov_build_index(c, st);
+return 0;
+}
+
 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
 while (atom.size > 8) {
@@ -4692,9 +4755,25 @@ static int mov_read_meta(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 tag = avio_rl32(pb);
 atom.size -= 4;
 if (tag == MKTAG('h','d','l','r')) {
+int ret;
 avio_seek(pb, -8, SEEK_CUR);
 atom.size += 8;
-return mov_read_default(c, pb, atom);
+ret = mov_read_default(c, pb, atom);
+if (ret < 0)
+return ret;
+if (c->is_still_picture_avif) {
+int ret;
+// Add a stream for the YUV planes (primary item).
+ret = avif_add_stream(c, c->primary_item_id);
+if (ret)
+return ret;
+// For still AVIF images, the meta box contains all the
+// necessary information that would generally be provided by 
the
+// moov box. So simply mark that we have found the moov box so
+// that parsing can continue.
+c->found_moov = 1;
+}
+return ret;
 }
 }
 return 0;
@@ -7483,8 +7562,6 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 int item_count, extent_count;
 uint64_t base_offset, extent_offset, extent_length;
 uint8_t value;
-AVStream *st;
-MOVStreamContext *sc;
 
 if (!c->is_still_picture_avif) {
 // * For non-avif, we simply ignore the iloc box.
@@

Re: [FFmpeg-devel] [PATCH] avfilter/xstack: Add support for fixed size grid

2022-06-29 Thread Vignesh Venkatasubramanian
On Wed, Jun 29, 2022 at 12:24 AM Paul B Mahol  wrote:
>
>
>
> On Wed, Jun 29, 2022 at 9:21 AM Paul B Mahol  wrote:
>>
>>
>>
>> On Tue, Jun 28, 2022 at 9:01 PM Vignesh Venkatasubramanian 
>>  wrote:
>>>
>>> Add a short hand parameter for making a fixed size grid. The existing
>>> xstack layout parameter syntax gets tedious if all one wants is a
>>> matrix like grid of the input streams. Add a grid option to the xstack
>>> filter that simplifies this use case by simply specifying the number of
>>> rows and columns instead of specific x/y co-ordinate for each stream.
>>
>>
>> Use SIZE AVOption for grid size option.
>> As already done in tile filter.

Ah, i did not know about this option. Updated.

>
>
> Also there is no need to always force same size of frames in grid, can either 
> force same width or same height.
>

I have relaxed the condition to "images within the same row must have
same height (similar to hstack) and all rows must have the same width
(similar to vstack)".

> By default it can use grid option, (just set grid default to 2x1, and remove 
> default layout setup thing)

Done.

>>
>>
>>
>>
>>>
>>>
>>> Also updating the filter documentation to explain the new option.
>>>
>>> Signed-off-by: Vignesh Venkatasubramanian 
>>> ---
>>>  doc/filters.texi   | 19 +--
>>>  libavfilter/vf_stack.c | 73 --
>>>  2 files changed, 81 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/doc/filters.texi b/doc/filters.texi
>>> index e525e87b3c..9d800a0fd6 100644
>>> --- a/doc/filters.texi
>>> +++ b/doc/filters.texi
>>> @@ -24381,8 +24381,23 @@ the output video frame will be filled. Similarly, 
>>> videos can overlap each
>>>  other if their position doesn't leave enough space for the full frame of
>>>  adjoining videos.
>>>
>>> -For 2 inputs, a default layout of @code{0_0|w0_0} is set. In all other 
>>> cases,
>>> -a layout must be set by the user.
>>> +For 2 inputs, a default layout of @code{0_0|w0_0} is set. In all other 
>>> cases, a
>>> +layout or a grid must be set by the user. Either grid or layout option can 
>>> be
>>> +specified at a time. Specifying both will result in an error.
>>> +
>>> +@item grid
>>> +Specify a fixed size grid of inputs.
>>> +This option is used to create a fixed size grid of the input streams.  The
>>> +option is of the form x (e.g. 2x4). There must be  *
>>> + input streams and they will be arranged as a grid with  
>>> rows and
>>> + columns. When using this option, all the input streams must have 
>>> the
>>> +same width and height.
>>> +
>>> +Either grid or layout option can be specified at a time. Specifying both 
>>> will
>>> +result in an error.
>>> +
>>> +If grid is set, then inputs option is ignored and is implicitly set to
>>> +*.
>>>
>>>  @item shortest
>>>  If set to 1, force the output to terminate when the shortest input
>>> diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c
>>> index aa32a1bf5e..b38a193355 100644
>>> --- a/libavfilter/vf_stack.c
>>> +++ b/libavfilter/vf_stack.c
>>> @@ -48,6 +48,9 @@ typedef struct StackContext {
>>>  int is_vertical;
>>>  int is_horizontal;
>>>  int nb_planes;
>>> +char *grid;
>>> +int nb_grid_rows;
>>> +int nb_grid_columns;
>>>  uint8_t fillcolor[4];
>>>  char *fillcolor_str;
>>>  int fillcolor_enable;
>>> @@ -85,14 +88,6 @@ static av_cold int init(AVFilterContext *ctx)
>>>  if (!strcmp(ctx->filter->name, "hstack"))
>>>  s->is_horizontal = 1;
>>>
>>> -s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames));
>>> -if (!s->frames)
>>> -return AVERROR(ENOMEM);
>>> -
>>> -s->items = av_calloc(s->nb_inputs, sizeof(*s->items));
>>> -if (!s->items)
>>> -return AVERROR(ENOMEM);
>>> -
>>>  if (!strcmp(ctx->filter->name, "xstack")) {
>>>  if (strcmp(s->fillcolor_str, "none") &&
>>>  av_parse_color(s->fillcolor, s->fillcolor_str, -1, ctx) >= 0) {
>>> @@ -100,7 +95,21 @@ static av_cold int init(AVFilterContext *ctx)
>>>  } el

[FFmpeg-devel] [PATCH] avfilter/xstack: Add support for fixed size grid

2022-06-29 Thread Vignesh Venkatasubramanian
Add a short hand parameter for making a fixed size grid. The existing
xstack layout parameter syntax gets tedious if all one wants is a
matrix like grid of the input streams. Add a grid option to the xstack
filter that simplifies this use case by simply specifying the number of
rows and columns instead of specific x/y co-ordinate for each stream.

Also updating the filter documentation to explain the new option.

Signed-off-by: Vignesh Venkatasubramanian 
---
 doc/filters.texi   | 22 ++--
 libavfilter/vf_stack.c | 81 +++---
 2 files changed, 88 insertions(+), 15 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index e525e87b3c..5a889895c6 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -24381,8 +24381,26 @@ the output video frame will be filled. Similarly, 
videos can overlap each
 other if their position doesn't leave enough space for the full frame of
 adjoining videos.
 
-For 2 inputs, a default layout of @code{0_0|w0_0} is set. In all other cases,
-a layout must be set by the user.
+For 2 inputs, a default layout of @code{0_0|w0_0} (equivalent to
+@code{grid=2x1}) is set. In all other cases, a layout or a grid must be set by
+the user. Either @code{grid} or @code{layout} can be specified at a time.
+Specifying both will result in an error.
+
+@item grid
+Specify a fixed size grid of inputs.
+This option is used to create a fixed size grid of the input streams. Set the
+grid size in the form @code{COLUMNSxROWS}. There must be @code{ROWS * COLUMNS}
+input streams and they will be arranged as a grid with @code{ROWS} rows and
+@code{COLUMNS} columns. When using this option, each input stream within a row
+must have the same height and all the rows must have the same width.
+
+If @code{grid} is set, then @code{inputs} option is ignored and is implicitly
+set to @code{ROWS * COLUMNS}.
+
+For 2 inputs, a default grid of @code{2x1} (equivalent to
+@code{layout=0_0|w0_0}) is set. In all other cases, a layout or a grid must be
+set by the user. Either @code{grid} or @code{layout} can be specified at a 
time.
+Specifying both will result in an error.
 
 @item shortest
 If set to 1, force the output to terminate when the shortest input
diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c
index aa32a1bf5e..d583d21dbe 100644
--- a/libavfilter/vf_stack.c
+++ b/libavfilter/vf_stack.c
@@ -48,6 +48,8 @@ typedef struct StackContext {
 int is_vertical;
 int is_horizontal;
 int nb_planes;
+int nb_grid_columns;
+int nb_grid_rows;
 uint8_t fillcolor[4];
 char *fillcolor_str;
 int fillcolor_enable;
@@ -85,33 +87,43 @@ static av_cold int init(AVFilterContext *ctx)
 if (!strcmp(ctx->filter->name, "hstack"))
 s->is_horizontal = 1;
 
-s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames));
-if (!s->frames)
-return AVERROR(ENOMEM);
-
-s->items = av_calloc(s->nb_inputs, sizeof(*s->items));
-if (!s->items)
-return AVERROR(ENOMEM);
-
 if (!strcmp(ctx->filter->name, "xstack")) {
+int is_grid;
 if (strcmp(s->fillcolor_str, "none") &&
 av_parse_color(s->fillcolor, s->fillcolor_str, -1, ctx) >= 0) {
 s->fillcolor_enable = 1;
 } else {
 s->fillcolor_enable = 0;
 }
-if (!s->layout) {
+is_grid = s->nb_grid_rows && s->nb_grid_columns;
+if (s->layout && is_grid) {
+av_log(ctx, AV_LOG_ERROR, "Both layout and grid were specified. 
Only one is allowed.\n");
+return AVERROR(EINVAL);
+}
+if (!s->layout && !is_grid) {
 if (s->nb_inputs == 2) {
-s->layout = av_strdup("0_0|w0_0");
-if (!s->layout)
-return AVERROR(ENOMEM);
+s->nb_grid_rows = 1;
+s->nb_grid_columns = 2;
+is_grid = 1;
 } else {
-av_log(ctx, AV_LOG_ERROR, "No layout specified.\n");
+av_log(ctx, AV_LOG_ERROR, "No layout or grid specified.\n");
 return AVERROR(EINVAL);
 }
 }
+if (is_grid) {
+  s->nb_inputs = s->nb_grid_rows * s->nb_grid_columns;
+}
 }
 
+s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames));
+if (!s->frames)
+return AVERROR(ENOMEM);
+
+s->items = av_calloc(s->nb_inputs, sizeof(*s->items));
+if (!s->items)
+return AVERROR(ENOMEM);
+
+
 for (i = 0; i < s->nb_inputs; i++) {
 AVFilterPad pad = { 0 };
 
@@ -244,6 +256,48 @@ static int config_output(AVFilterLink *outlink)
 width += ctx->inputs[i]->w;
 }
 }
+} else if (s->nb_grid_rows && s->

[FFmpeg-devel] [PATCH] avfilter/xstack: Add support for fixed size grid

2022-06-28 Thread Vignesh Venkatasubramanian
Add a short hand parameter for making a fixed size grid. The existing
xstack layout parameter syntax gets tedious if all one wants is a
matrix like grid of the input streams. Add a grid option to the xstack
filter that simplifies this use case by simply specifying the number of
rows and columns instead of specific x/y co-ordinate for each stream.

Also updating the filter documentation to explain the new option.

Signed-off-by: Vignesh Venkatasubramanian 
---
 doc/filters.texi   | 19 +--
 libavfilter/vf_stack.c | 73 --
 2 files changed, 81 insertions(+), 11 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index e525e87b3c..9d800a0fd6 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -24381,8 +24381,23 @@ the output video frame will be filled. Similarly, 
videos can overlap each
 other if their position doesn't leave enough space for the full frame of
 adjoining videos.
 
-For 2 inputs, a default layout of @code{0_0|w0_0} is set. In all other cases,
-a layout must be set by the user.
+For 2 inputs, a default layout of @code{0_0|w0_0} is set. In all other cases, a
+layout or a grid must be set by the user. Either grid or layout option can be
+specified at a time. Specifying both will result in an error.
+
+@item grid
+Specify a fixed size grid of inputs.
+This option is used to create a fixed size grid of the input streams.  The
+option is of the form x (e.g. 2x4). There must be  *
+ input streams and they will be arranged as a grid with  rows 
and
+ columns. When using this option, all the input streams must have the
+same width and height.
+
+Either grid or layout option can be specified at a time. Specifying both will
+result in an error.
+
+If grid is set, then inputs option is ignored and is implicitly set to
+*.
 
 @item shortest
 If set to 1, force the output to terminate when the shortest input
diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c
index aa32a1bf5e..b38a193355 100644
--- a/libavfilter/vf_stack.c
+++ b/libavfilter/vf_stack.c
@@ -48,6 +48,9 @@ typedef struct StackContext {
 int is_vertical;
 int is_horizontal;
 int nb_planes;
+char *grid;
+int nb_grid_rows;
+int nb_grid_columns;
 uint8_t fillcolor[4];
 char *fillcolor_str;
 int fillcolor_enable;
@@ -85,14 +88,6 @@ static av_cold int init(AVFilterContext *ctx)
 if (!strcmp(ctx->filter->name, "hstack"))
 s->is_horizontal = 1;
 
-s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames));
-if (!s->frames)
-return AVERROR(ENOMEM);
-
-s->items = av_calloc(s->nb_inputs, sizeof(*s->items));
-if (!s->items)
-return AVERROR(ENOMEM);
-
 if (!strcmp(ctx->filter->name, "xstack")) {
 if (strcmp(s->fillcolor_str, "none") &&
 av_parse_color(s->fillcolor, s->fillcolor_str, -1, ctx) >= 0) {
@@ -100,7 +95,21 @@ static av_cold int init(AVFilterContext *ctx)
 } else {
 s->fillcolor_enable = 0;
 }
-if (!s->layout) {
+if (s->grid && s->layout) {
+av_log(ctx, AV_LOG_ERROR, "Both layout and grid were specified. 
Only one is allowed.\n");
+return AVERROR(EINVAL);
+}
+if (s->grid) {
+if (sscanf(s->grid, "%dx%d", >nb_grid_rows, 
>nb_grid_columns) != 2) {
+av_log(ctx, AV_LOG_ERROR, "grid string is not of the form 
rowsxcolumns.\n");
+return AVERROR(EINVAL);
+}
+s->nb_inputs = s->nb_grid_rows * s->nb_grid_columns;
+} else {
+s->nb_grid_rows = 0;
+s->nb_grid_columns = 0;
+}
+if (!s->layout && !s->grid) {
 if (s->nb_inputs == 2) {
 s->layout = av_strdup("0_0|w0_0");
 if (!s->layout)
@@ -112,6 +121,15 @@ static av_cold int init(AVFilterContext *ctx)
 }
 }
 
+s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames));
+if (!s->frames)
+return AVERROR(ENOMEM);
+
+s->items = av_calloc(s->nb_inputs, sizeof(*s->items));
+if (!s->items)
+return AVERROR(ENOMEM);
+
+
 for (i = 0; i < s->nb_inputs; i++) {
 AVFilterPad pad = { 0 };
 
@@ -244,6 +262,42 @@ static int config_output(AVFilterLink *outlink)
 width += ctx->inputs[i]->w;
 }
 }
+} else if (s->nb_grid_rows > 0 && s->nb_grid_columns > 0) {
+int inw = 0, inh = 0;
+int k = 0;
+for (i = 0; i < s->nb_grid_rows; i++, inh += height) {
+inw = 0;
+for (int j = 0; j < s->nb_grid_columns; j++, k++, inw += width) {
+AVFilterLink *inlink = ctx->inputs[k];
+

Re: [FFmpeg-devel] [PATCH] avformat/mov: Only read the primary item for AVIF

2022-06-28 Thread Vignesh Venkatasubramanian
On Tue, Jun 28, 2022 at 11:21 AM James Zern
 wrote:
>
> On Mon, Jun 13, 2022 at 9:32 AM Vignesh Venkatasubramanian
>  wrote:
> >
> > On Fri, Jun 10, 2022 at 10:34 AM Vignesh Venkatasubramanian
> >  wrote:
> > >
> > > On Thu, Jun 9, 2022 at 12:50 AM Gyan Doshi  wrote:
> > > >
> > > >
> > > >
> > > > On 2022-06-08 10:51 pm, Vignesh Venkatasubramanian wrote:
> > > > > On Thu, Jun 2, 2022 at 1:35 PM James Zern  wrote:
> > > > >> On Wed, Jun 1, 2022 at 1:38 PM Vignesh Venkatasubramanian
> > > > >>  wrote:
> > > > >>> On Wed, Jun 1, 2022 at 10:30 AM James Zern  wrote:
> > > > >>>> On Sun, Apr 24, 2022 at 11:35 AM Vignesh Venkatasubramanian
> > > > >>>>  wrote:
> > > > >>>>> Update the still AVIF parser to only read the primary item. With 
> > > > >>>>> this
> > > > >>>>> patch, AVIF still images with exif/icc/alpha channel will no 
> > > > >>>>> longer
> > > > >>>>> fail to parse.
> > > > >>>>>
> > > > >>>>> For example, this patch enables parsing of files in:
> > > > >>>>> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> > > > >>>>>
> > > > >>>> Can some of the failing files or similar ones be added to fate?
> > > > >>> There are no fate tests for AVIF parsing as of now. I was thinking
> > > > >>> about adding some for the muxing. But i am not sure what can be done
> > > > >>> here for the parsing.
> > > > >>>
> > > > >> Thanks. Are there any for general mov/mp4 parsing that could be
> > > > >> extended? This looks good otherwise.
> > > > >  From what i see, most of the mov tests only seem to be for muxing. 
> > > > > I'm
> > > > > not entirely certain about how to add a test for AVIF parsing. If
> > > > > anybody has an idea, i'd be open to adding it.
> > > >
> > > > Basic test would use the framemd5 muxer to compare demuxed packets with
> > > > a reference.
> > > > See fate-ffmpeg-streamloop
> > > >
> > >
> > > Thank you i have added a couple of fate tests.
> > >
> > > I am not sure how to add the AVIF files to the fate test server. I
> > > have them on Google Drive here:
> > >
> > > https://drive.google.com/file/d/1diZoM0Ew7Co3Yh5w5y1J-3IiBYVmUv9J/view?usp=sharing
> > > https://drive.google.com/file/d/1DdrD1mW36evt40a4RkeLYpx-oojmbc3z/view?usp=sharing
> > >
> > > These links should be publicly available without any sign in required.
> > > Please let me know if there is another preferred way of sharing test
> > > files and i can share it that way.
> > >
> >
> > Also, i forgot to mention that these files have to be uploaded under a
> > new directory called "avif" in the fate server.
> >
>
> Can you send a separate patch with the tests disabled and marked by a
> TODO to enable them after the files are uploaded?
> https://ffmpeg.org/developer.html#Adding-files-to-the-fate_002dsuite-dataset

I have updated this patch to comment out the actual tests (with a
FIXME note). I can send separate patch once the files are added to the
server to uncomment the tests and remove the FIXME.

> ___
> 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".



-- 
Vignesh
___
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] avformat/mov: Only read the primary item for AVIF

2022-06-28 Thread Vignesh Venkatasubramanian
Update the still AVIF parser to only read the primary item. With this
patch, AVIF still images with exif/icc/alpha channel will no longer
fail to parse.

For example, this patch enables parsing of files in:
https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft

Adding two fate tests:
1) demuxing of still image with 1 item - this test will pass regardlesss
   of this patch.
2) demuxing of still image with 2 items - this test will fail without
   this patch and will pass with patch applied.

Partially fixes trac ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h|  1 +
 libavformat/mov.c | 41 ++-
 tests/fate/mov.mak| 13 ++
 .../fate/mov-avif-demux-still-image-1-item| 11 +
 .../mov-avif-demux-still-image-multiple-items | 11 +
 5 files changed, 57 insertions(+), 20 deletions(-)
 create mode 100644 tests/ref/fate/mov-avif-demux-still-image-1-item
 create mode 100644 tests/ref/fate/mov-avif-demux-still-image-multiple-items

diff --git a/libavformat/isom.h b/libavformat/isom.h
index cf36f04d5b..f05c2d9c28 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -317,6 +317,7 @@ typedef struct MOVContext {
 uint32_t mfra_size;
 uint32_t max_stts_delta;
 int is_still_picture_avif;
+int primary_item_id;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index c6fbe511c0..88669faa70 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7470,6 +7470,13 @@ static int rb_size(AVIOContext *pb, uint64_t* value, int 
size)
 return size;
 }
 
+static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+avio_rb32(pb);  // version & flags.
+c->primary_item_id = avio_rb16(pb);
+return atom.size;
+}
+
 static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
 int version, offset_size, length_size, base_offset_size, index_size;
@@ -7526,34 +7533,25 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return AVERROR_PATCHWELCOME;
 }
 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
-if (item_count > 1) {
-// For still AVIF images, we only support one item. Second item will
-// generally be found for AVIF images with alpha channel. We don't
-// support them as of now.
-av_log(c->fc, AV_LOG_ERROR, "iloc: item_count > 1 not supported.\n");
-return AVERROR_PATCHWELCOME;
-}
 
 // Populate the necessary fields used by mov_build_index.
-sc->stsc_count = item_count;
-sc->stsc_data = av_malloc_array(item_count, sizeof(*sc->stsc_data));
+sc->stsc_count = 1;
+sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
 if (!sc->stsc_data)
 return AVERROR(ENOMEM);
 sc->stsc_data[0].first = 1;
 sc->stsc_data[0].count = 1;
 sc->stsc_data[0].id = 1;
-sc->chunk_count = item_count;
-sc->chunk_offsets =
-av_malloc_array(item_count, sizeof(*sc->chunk_offsets));
+sc->chunk_count = 1;
+sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
 if (!sc->chunk_offsets)
 return AVERROR(ENOMEM);
-sc->sample_count = item_count;
-sc->sample_sizes =
-av_malloc_array(item_count, sizeof(*sc->sample_sizes));
+sc->sample_count = 1;
+sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
 if (!sc->sample_sizes)
 return AVERROR(ENOMEM);
-sc->stts_count = item_count;
-sc->stts_data = av_malloc_array(item_count, sizeof(*sc->stts_data));
+sc->stts_count = 1;
+sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
 if (!sc->stts_data)
 return AVERROR(ENOMEM);
 sc->stts_data[0].count = 1;
@@ -7561,7 +7559,7 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 sc->stts_data[0].duration = 0;
 
 for (int i = 0; i < item_count; i++) {
-(version < 2) ? avio_rb16(pb) : avio_rb32(pb);  // item_id;
+int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
 if (version > 0)
 avio_rb16(pb);  // construction_method.
 avio_rb16(pb);  // data_reference_index.
@@ -7577,8 +7575,10 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 if (rb_size(pb, _offset, offset_size) < 0 ||
 rb_size(pb, _length, length_size) < 0)
 return AVERROR_INVALIDDATA;
-sc->sample_sizes[0] = extent_length;
-sc->chunk_offsets[0] = base_offset + extent_offset;
+if (item_id == c->primary_item_id) {
+sc->sample_sizes[0] = extent_length;
+sc->chunk_offsets[0] = base_offset

Re: [FFmpeg-devel] [PATCH] avformat/movenc: Support alpha channel for AVIF

2022-06-27 Thread Vignesh Venkatasubramanian
On Mon, Jun 27, 2022 at 9:48 AM James Almer  wrote:
>
> On 6/27/2022 1:43 PM, Vignesh Venkatasubramanian wrote:
> > On Tue, Jun 21, 2022 at 10:12 AM Vignesh Venkatasubramanian
> >  wrote:
> >>
> >> On Mon, Jun 13, 2022 at 10:17 AM James Zern
> >>  wrote:
> >>>
> >>> On Wed, Jun 1, 2022 at 11:06 AM Vignesh Venkatasubramanian
> >>>  wrote:
> >>>>
> >>>> AVIF specification allows for alpha channel as an auxiliary item (in
> >>>> case of still images) or as an auxiliary track (in case of animated
> >>>> images).  Add support for both of these. The AVIF muxer will take
> >>>> exactly two streams (when alpha is present) as input (first one being
> >>>> the YUV planes and the second one being the alpha plane).
> >>>>
> >>>> The input has to come from two different images (one of it color and
> >>>> the other one being alpha), or it can come from a single file
> >>>> source with the alpha channel extracted using the "alphaextract"
> >>>> filter.
> >>>>
> >>>> Example using alphaextract:
> >>>> ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map 
> >>>> "[a]" -still-picture 1 avif_with_alpha.avif
> >>>>
> >>>> Example using two sources (first source can be in any pixel format and
> >>>> the second source has to be in monochrome grey pixel format):
> >>>> ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy 
> >>>> avif_with_alpha.avif
> >>>>
> >>>> The generated files pass the compliance checks in Compliance Warden:
> >>>> https://github.com/gpac/ComplianceWarden
> >>>>
> >>>> libavif (the reference avif library) is able to decode the files
> >>>> generated using this patch.
> >>>>
> >>>> They also play back properly (with transparent background) in:
> >>>> 1) Chrome
> >>>> 2) Firefox (only still AVIF, no animation support)
> >>>>
> >>>> Signed-off-by: Vignesh Venkatasubramanian 
> >>>> ---
> >>>>   libavformat/movenc.c | 188 +--
> >>>>   libavformat/movenc.h |   4 +-
> >>>>   2 files changed, 130 insertions(+), 62 deletions(-)
> >>>>
> >>>
> >>> lgtm.
> >>> ___
> >>> 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".
> >>
> >> Any more comments on this? If not can this be merged please? :)
> >>
> >
> > Another ping on this please.
> >
> >> --
> >> Vignesh
>
> I thought James Zern had push access, which is why i didn't apply it as
> soon as he reviewed it. Sorry.
>
> Pushed it now.
>

Thanks!
 ___
> 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".



-- 
Vignesh
___
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] avformat/mov: Only read the primary item for AVIF

2022-06-27 Thread Vignesh Venkatasubramanian
On Tue, Jun 21, 2022 at 10:12 AM Vignesh Venkatasubramanian
 wrote:
>
> On Mon, Jun 13, 2022 at 9:32 AM Vignesh Venkatasubramanian
>  wrote:
> >
> > On Fri, Jun 10, 2022 at 10:34 AM Vignesh Venkatasubramanian
> >  wrote:
> > >
> > > On Thu, Jun 9, 2022 at 12:50 AM Gyan Doshi  wrote:
> > > >
> > > >
> > > >
> > > > On 2022-06-08 10:51 pm, Vignesh Venkatasubramanian wrote:
> > > > > On Thu, Jun 2, 2022 at 1:35 PM James Zern  wrote:
> > > > >> On Wed, Jun 1, 2022 at 1:38 PM Vignesh Venkatasubramanian
> > > > >>  wrote:
> > > > >>> On Wed, Jun 1, 2022 at 10:30 AM James Zern  wrote:
> > > > >>>> On Sun, Apr 24, 2022 at 11:35 AM Vignesh Venkatasubramanian
> > > > >>>>  wrote:
> > > > >>>>> Update the still AVIF parser to only read the primary item. With 
> > > > >>>>> this
> > > > >>>>> patch, AVIF still images with exif/icc/alpha channel will no 
> > > > >>>>> longer
> > > > >>>>> fail to parse.
> > > > >>>>>
> > > > >>>>> For example, this patch enables parsing of files in:
> > > > >>>>> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> > > > >>>>>
> > > > >>>> Can some of the failing files or similar ones be added to fate?
> > > > >>> There are no fate tests for AVIF parsing as of now. I was thinking
> > > > >>> about adding some for the muxing. But i am not sure what can be done
> > > > >>> here for the parsing.
> > > > >>>
> > > > >> Thanks. Are there any for general mov/mp4 parsing that could be
> > > > >> extended? This looks good otherwise.
> > > > >  From what i see, most of the mov tests only seem to be for muxing. 
> > > > > I'm
> > > > > not entirely certain about how to add a test for AVIF parsing. If
> > > > > anybody has an idea, i'd be open to adding it.
> > > >
> > > > Basic test would use the framemd5 muxer to compare demuxed packets with
> > > > a reference.
> > > > See fate-ffmpeg-streamloop
> > > >
> > >
> > > Thank you i have added a couple of fate tests.
> > >
> > > I am not sure how to add the AVIF files to the fate test server. I
> > > have them on Google Drive here:
> > >
> > > https://drive.google.com/file/d/1diZoM0Ew7Co3Yh5w5y1J-3IiBYVmUv9J/view?usp=sharing
> > > https://drive.google.com/file/d/1DdrD1mW36evt40a4RkeLYpx-oojmbc3z/view?usp=sharing
> > >
> > > These links should be publicly available without any sign in required.
> > > Please let me know if there is another preferred way of sharing test
> > > files and i can share it that way.
> > >
> >
> > Also, i forgot to mention that these files have to be uploaded under a
> > new directory called "avif" in the fate server.
> >
> > > Also for the record, these files were created by remuxing an existing
> > > file in the fate suite.
> > >
> > > still_image.avif - contains the first frame from
> > > av1-test-vectors/av1-1-b8-02-allintra.ivf
> > > still_image_exif.avif - contains the first frame from
> > > av1-test-vectors/av1-1-b8-02-allintra.ivf with dummy exif data.
> > >
> > > > Regards,
> > > > Gyan
> > > > ___
> > > > 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".
> > >
> > >
> > >
> > > --
> > > Vignesh
> >
> >
> >
> > --
> > Vignesh
>
> Ping on this please.
>
> --
> Vignesh

Another ping on this please. :)

-- 
Vignesh
___
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] avformat/movenc: Support alpha channel for AVIF

2022-06-27 Thread Vignesh Venkatasubramanian
On Tue, Jun 21, 2022 at 10:12 AM Vignesh Venkatasubramanian
 wrote:
>
> On Mon, Jun 13, 2022 at 10:17 AM James Zern
>  wrote:
> >
> > On Wed, Jun 1, 2022 at 11:06 AM Vignesh Venkatasubramanian
> >  wrote:
> > >
> > > AVIF specification allows for alpha channel as an auxiliary item (in
> > > case of still images) or as an auxiliary track (in case of animated
> > > images).  Add support for both of these. The AVIF muxer will take
> > > exactly two streams (when alpha is present) as input (first one being
> > > the YUV planes and the second one being the alpha plane).
> > >
> > > The input has to come from two different images (one of it color and
> > > the other one being alpha), or it can come from a single file
> > > source with the alpha channel extracted using the "alphaextract"
> > > filter.
> > >
> > > Example using alphaextract:
> > > ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map 
> > > "[a]" -still-picture 1 avif_with_alpha.avif
> > >
> > > Example using two sources (first source can be in any pixel format and
> > > the second source has to be in monochrome grey pixel format):
> > > ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy 
> > > avif_with_alpha.avif
> > >
> > > The generated files pass the compliance checks in Compliance Warden:
> > > https://github.com/gpac/ComplianceWarden
> > >
> > > libavif (the reference avif library) is able to decode the files
> > > generated using this patch.
> > >
> > > They also play back properly (with transparent background) in:
> > > 1) Chrome
> > > 2) Firefox (only still AVIF, no animation support)
> > >
> > > Signed-off-by: Vignesh Venkatasubramanian 
> > > ---
> > >  libavformat/movenc.c | 188 +--
> > >  libavformat/movenc.h |   4 +-
> > >  2 files changed, 130 insertions(+), 62 deletions(-)
> > >
> >
> > lgtm.
> > ___
> > 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".
>
> Any more comments on this? If not can this be merged please? :)
>

Another ping on this please.

> --
> Vignesh



-- 
Vignesh
___
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] avformat/mov: Only read the primary item for AVIF

2022-06-21 Thread Vignesh Venkatasubramanian
On Mon, Jun 13, 2022 at 9:32 AM Vignesh Venkatasubramanian
 wrote:
>
> On Fri, Jun 10, 2022 at 10:34 AM Vignesh Venkatasubramanian
>  wrote:
> >
> > On Thu, Jun 9, 2022 at 12:50 AM Gyan Doshi  wrote:
> > >
> > >
> > >
> > > On 2022-06-08 10:51 pm, Vignesh Venkatasubramanian wrote:
> > > > On Thu, Jun 2, 2022 at 1:35 PM James Zern  wrote:
> > > >> On Wed, Jun 1, 2022 at 1:38 PM Vignesh Venkatasubramanian
> > > >>  wrote:
> > > >>> On Wed, Jun 1, 2022 at 10:30 AM James Zern  wrote:
> > > >>>> On Sun, Apr 24, 2022 at 11:35 AM Vignesh Venkatasubramanian
> > > >>>>  wrote:
> > > >>>>> Update the still AVIF parser to only read the primary item. With 
> > > >>>>> this
> > > >>>>> patch, AVIF still images with exif/icc/alpha channel will no longer
> > > >>>>> fail to parse.
> > > >>>>>
> > > >>>>> For example, this patch enables parsing of files in:
> > > >>>>> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> > > >>>>>
> > > >>>> Can some of the failing files or similar ones be added to fate?
> > > >>> There are no fate tests for AVIF parsing as of now. I was thinking
> > > >>> about adding some for the muxing. But i am not sure what can be done
> > > >>> here for the parsing.
> > > >>>
> > > >> Thanks. Are there any for general mov/mp4 parsing that could be
> > > >> extended? This looks good otherwise.
> > > >  From what i see, most of the mov tests only seem to be for muxing. I'm
> > > > not entirely certain about how to add a test for AVIF parsing. If
> > > > anybody has an idea, i'd be open to adding it.
> > >
> > > Basic test would use the framemd5 muxer to compare demuxed packets with
> > > a reference.
> > > See fate-ffmpeg-streamloop
> > >
> >
> > Thank you i have added a couple of fate tests.
> >
> > I am not sure how to add the AVIF files to the fate test server. I
> > have them on Google Drive here:
> >
> > https://drive.google.com/file/d/1diZoM0Ew7Co3Yh5w5y1J-3IiBYVmUv9J/view?usp=sharing
> > https://drive.google.com/file/d/1DdrD1mW36evt40a4RkeLYpx-oojmbc3z/view?usp=sharing
> >
> > These links should be publicly available without any sign in required.
> > Please let me know if there is another preferred way of sharing test
> > files and i can share it that way.
> >
>
> Also, i forgot to mention that these files have to be uploaded under a
> new directory called "avif" in the fate server.
>
> > Also for the record, these files were created by remuxing an existing
> > file in the fate suite.
> >
> > still_image.avif - contains the first frame from
> > av1-test-vectors/av1-1-b8-02-allintra.ivf
> > still_image_exif.avif - contains the first frame from
> > av1-test-vectors/av1-1-b8-02-allintra.ivf with dummy exif data.
> >
> > > Regards,
> > > Gyan
> > > ___
> > > 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".
> >
> >
> >
> > --
> > Vignesh
>
>
>
> --
> Vignesh

Ping on this please.

-- 
Vignesh
___
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] avformat/movenc: Support alpha channel for AVIF

2022-06-21 Thread Vignesh Venkatasubramanian
On Mon, Jun 13, 2022 at 10:17 AM James Zern
 wrote:
>
> On Wed, Jun 1, 2022 at 11:06 AM Vignesh Venkatasubramanian
>  wrote:
> >
> > AVIF specification allows for alpha channel as an auxiliary item (in
> > case of still images) or as an auxiliary track (in case of animated
> > images).  Add support for both of these. The AVIF muxer will take
> > exactly two streams (when alpha is present) as input (first one being
> > the YUV planes and the second one being the alpha plane).
> >
> > The input has to come from two different images (one of it color and
> > the other one being alpha), or it can come from a single file
> > source with the alpha channel extracted using the "alphaextract"
> > filter.
> >
> > Example using alphaextract:
> > ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map "[a]" 
> > -still-picture 1 avif_with_alpha.avif
> >
> > Example using two sources (first source can be in any pixel format and
> > the second source has to be in monochrome grey pixel format):
> > ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy avif_with_alpha.avif
> >
> > The generated files pass the compliance checks in Compliance Warden:
> > https://github.com/gpac/ComplianceWarden
> >
> > libavif (the reference avif library) is able to decode the files
> > generated using this patch.
> >
> > They also play back properly (with transparent background) in:
> > 1) Chrome
> > 2) Firefox (only still AVIF, no animation support)
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  libavformat/movenc.c | 188 +--
> >  libavformat/movenc.h |   4 +-
> >  2 files changed, 130 insertions(+), 62 deletions(-)
> >
>
> lgtm.
> ___
> 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".

Any more comments on this? If not can this be merged please? :)

-- 
Vignesh
___
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] avformat/mov: Only read the primary item for AVIF

2022-06-13 Thread Vignesh Venkatasubramanian
On Fri, Jun 10, 2022 at 10:34 AM Vignesh Venkatasubramanian
 wrote:
>
> On Thu, Jun 9, 2022 at 12:50 AM Gyan Doshi  wrote:
> >
> >
> >
> > On 2022-06-08 10:51 pm, Vignesh Venkatasubramanian wrote:
> > > On Thu, Jun 2, 2022 at 1:35 PM James Zern  wrote:
> > >> On Wed, Jun 1, 2022 at 1:38 PM Vignesh Venkatasubramanian
> > >>  wrote:
> > >>> On Wed, Jun 1, 2022 at 10:30 AM James Zern  wrote:
> > >>>> On Sun, Apr 24, 2022 at 11:35 AM Vignesh Venkatasubramanian
> > >>>>  wrote:
> > >>>>> Update the still AVIF parser to only read the primary item. With this
> > >>>>> patch, AVIF still images with exif/icc/alpha channel will no longer
> > >>>>> fail to parse.
> > >>>>>
> > >>>>> For example, this patch enables parsing of files in:
> > >>>>> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> > >>>>>
> > >>>> Can some of the failing files or similar ones be added to fate?
> > >>> There are no fate tests for AVIF parsing as of now. I was thinking
> > >>> about adding some for the muxing. But i am not sure what can be done
> > >>> here for the parsing.
> > >>>
> > >> Thanks. Are there any for general mov/mp4 parsing that could be
> > >> extended? This looks good otherwise.
> > >  From what i see, most of the mov tests only seem to be for muxing. I'm
> > > not entirely certain about how to add a test for AVIF parsing. If
> > > anybody has an idea, i'd be open to adding it.
> >
> > Basic test would use the framemd5 muxer to compare demuxed packets with
> > a reference.
> > See fate-ffmpeg-streamloop
> >
>
> Thank you i have added a couple of fate tests.
>
> I am not sure how to add the AVIF files to the fate test server. I
> have them on Google Drive here:
>
> https://drive.google.com/file/d/1diZoM0Ew7Co3Yh5w5y1J-3IiBYVmUv9J/view?usp=sharing
> https://drive.google.com/file/d/1DdrD1mW36evt40a4RkeLYpx-oojmbc3z/view?usp=sharing
>
> These links should be publicly available without any sign in required.
> Please let me know if there is another preferred way of sharing test
> files and i can share it that way.
>

Also, i forgot to mention that these files have to be uploaded under a
new directory called "avif" in the fate server.

> Also for the record, these files were created by remuxing an existing
> file in the fate suite.
>
> still_image.avif - contains the first frame from
> av1-test-vectors/av1-1-b8-02-allintra.ivf
> still_image_exif.avif - contains the first frame from
> av1-test-vectors/av1-1-b8-02-allintra.ivf with dummy exif data.
>
> > Regards,
> > Gyan
> > ___
> > 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".
>
>
>
> --
> Vignesh



-- 
Vignesh
___
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] avformat/movenc: Support alpha channel for AVIF

2022-06-13 Thread Vignesh Venkatasubramanian
On Mon, Jun 6, 2022 at 9:29 AM Vignesh Venkatasubramanian
 wrote:
>
> On Wed, Jun 1, 2022 at 12:47 PM Vignesh Venkatasubramanian
>  wrote:
> >
> > On Wed, Jun 1, 2022 at 11:52 AM xyesbee  wrote:
> > >
> > > Why can it not accept it as one but two distinct streams? Why the extra 
> > > hurdle of alphaextract? YUVA pixel format exists though.
> >
> > Yes, while the YUVA pixel formats exist, AVIF specification requires
> > alpha channel to be a separate track (i.e.) we would need two AV1
> > encoders to make an AVIF image with alpha channel (one for the YUV
> > planes and one for the alpha plane encoded as a monochrome frame). The
> > underlying AV1 codec does not support the YUVA pixel format. So, in
> > order to be able to encode an AVIF image with alpha channel, we would
> > have to separate the alpha channel with the alphaextract filter and
> > pass it to a separate AV1 encoder.
> >
> > If you already have the alpha channel as a separate input, then you
> > can simply pass it along as a second input stream and there will be no
> > need to use the alphaextract filter. I pointed out the use of
> > alphaextract filter simply because it is the simplest way to re-encode
> > existing PNG images with alpha channel into AVIF.
> >
> > An alternative solution is to use the YUVA pixel format and internally
> > use two AV1 encoders in the libaom wrapper. But that requires more
> > changes and does not really make things any better. If you have a
> > better solution, please let me know and I can update this.
> >
> > >  Original Message 
> > > On Jun 1, 2022, 11:35 PM, Vignesh Venkatasubramanian wrote:
> > >
> > > > AVIF specification allows for alpha channel as an auxiliary item (in
> > > > case of still images) or as an auxiliary track (in case of animated
> > > > images). Add support for both of these. The AVIF muxer will take
> > > > exactly two streams (when alpha is present) as input (first one being
> > > > the YUV planes and the second one being the alpha plane).
> > > >
> > > > The input has to come from two different images (one of it color and
> > > > the other one being alpha), or it can come from a single file
> > > > source with the alpha channel extracted using the "alphaextract"
> > > > filter.
> > > >
> > > > Example using alphaextract:
> > > > ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map 
> > > > "[a]" -still-picture 1 avif_with_alpha.avif
> > > >
> > > > Example using two sources (first source can be in any pixel format and
> > > > the second source has to be in monochrome grey pixel format):
> > > > ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy 
> > > > avif_with_alpha.avif
> > > >
> > > > The generated files pass the compliance checks in Compliance Warden:
> > > > https://github.com/gpac/ComplianceWarden
> > > >
> > > > libavif (the reference avif library) is able to decode the files
> > > > generated using this patch.
> > > >
> > > > They also play back properly (with transparent background) in:
> > > > 1) Chrome
> > > > 2) Firefox (only still AVIF, no animation support)
> > > >
> > > > Signed-off-by: Vignesh Venkatasubramanian 
> > > > ---
> > > > libavformat/movenc.c | 188 +--
> > > > libavformat/movenc.h | 4 +-
> > > > 2 files changed, 130 insertions(+), 62 deletions(-)
> > > >
> > > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > > > index de971f94e8..02eb4d0e9a 100644
> > > > --- a/libavformat/movenc.c
> > > > +++ b/libavformat/movenc.c
> > > > @@ -2852,7 +2852,7 @@ static int mov_write_hdlr_tag(AVFormatContext *s, 
> > > > AVIOContext *pb, MOVTrack *tra
> > > > hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
> > > > if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
> > > > if (track->mode == MODE_AVIF) {
> > > > - hdlr_type = "pict";
> > > > + hdlr_type = (track == >tracks[0]) ? "pict" : "auxv";
> > > > descr = "PictureHandler";
> > > > } else {
> > > > hdlr_type = "vide";
> > > > @@ -2940,57 +2940,83 @@ static int mov_write_iloc_tag(AVIOContext *pb, 
> >

Re: [FFmpeg-devel] [PATCH] avformat/mov: Only read the primary item for AVIF

2022-06-10 Thread Vignesh Venkatasubramanian
On Fri, Jun 10, 2022 at 10:33 AM Andreas Rheinhardt
 wrote:
>
> Vignesh Venkatasubramanian:
> > Update the still AVIF parser to only read the primary item. With this
> > patch, AVIF still images with exif/icc/alpha channel will no longer
> > fail to parse.
> >
> > For example, this patch enables parsing of files in:
> > https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> >
> > Adding two fate tests:
> > 1) demuxing of still image with 1 item - this test will pass regardlesss
> >of this patch.
> > 2) demuxing of still image with 2 items - this test will fail without
> >this patch and will pass with patch applied.
> >
> > Partially fixes trac ticket #7621
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  libavformat/isom.h|  1 +
> >  libavformat/mov.c | 41 ++-
> >  tests/fate/mov.mak|  9 
> >  .../fate/mov-avif-demux-still-image-1-item| 11 +
> >  .../mov-avif-demux-still-image-multiple-items | 11 +
> >  5 files changed, 53 insertions(+), 20 deletions(-)
> >  create mode 100644 tests/ref/fate/mov-avif-demux-still-image-1-item
> >  create mode 100644 tests/ref/fate/mov-avif-demux-still-image-multiple-items
> >
> > diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak
> > index 2fae054423..842c7f9aa1 100644
> > --- a/tests/fate/mov.mak
> > +++ b/tests/fate/mov.mak
> > @@ -17,6 +17,8 @@ FATE_MOV = fate-mov-3elist \
> > fate-mov-bbi-elst-starts-b \
> > fate-mov-neg-firstpts-discard-frames \
> > fate-mov-stream-shorter-than-movie \
> > +   fate-mov-avif-demux-still-image-1-item \
> > +   fate-mov-avif-demux-still-image-multiple-items \
> >
> >  FATE_MOV_FFPROBE = fate-mov-neg-firstpts-discard \
> > fate-mov-neg-firstpts-discard-vorbis \
> > @@ -138,6 +140,13 @@ FATE_MOV_FFMPEG_FFPROBE-$(call TRANSCODE, TTML SUBRIP, 
> > MP4 MOV, SRT_DEMUXER TTML
> >  fate-mov-mp4-ttml-stpp: CMD = transcode srt 
> > $(TARGET_SAMPLES)/sub/SubRip_capability_tester.srt mp4 "-map 0:s -c:s ttml 
> > -time_base:s 1:1000" "-map 0 -c copy" "-of json -show_entries 
> > packet:stream=index,codec_type,codec_tag_string,codec_tag,codec_name,time_base,start_time,duration_ts,duration,nb_frames,nb_read_packets:stream_tags"
> >  fate-mov-mp4-ttml-dfxp: CMD = transcode srt 
> > $(TARGET_SAMPLES)/sub/SubRip_capability_tester.srt mp4 "-map 0:s -c:s ttml 
> > -time_base:s 1:1000 -tag:s dfxp -strict unofficial" "-map 0 -c copy" "-of 
> > json -show_entries 
> > packet:stream=index,codec_type,codec_tag_string,codec_tag,codec_name,time_base,start_time,duration_ts,duration,nb_frames,nb_read_packets:stream_tags"
> >
> > +# avif demuxing - still image with 1 item.
> > +fate-mov-avif-demux-still-image-1-item: CMD = framemd5 -i 
> > $(TARGET_SAMPLES)/avif/still_image.avif -c:v copy
> > +
> > +# avif demuxing - still image with multiple items. only the primary item 
> > will be
> > +# parsed.
> > +fate-mov-avif-demux-still-image-multiple-items: CMD = framemd5 -i 
> > $(TARGET_SAMPLES)/avif/still_image_exif.avif -c:v copy
>
> Can we create such files with our muxer? In this case one could use a
> remux test, i.e. a test that creates the file and the demuxes the just
> created file.
>

Unfortunately, the file with exif cannot be created using the ffmpeg's
muxer as of now. So we will have to get that externally (i made that
with MP4Box).

The other still image file however can be creating using our muxer. I
will add another test that does remuxing for the 1-item case in a
separate patch if that's alright (since it's not directly related to
what this patch is doing). I was also going to add some fate tests for
animated AVIF muxing/parsing, so i will include that in the other
patch as well.

> > +
> >  # Resulting remux should have:
> >  # 1. first audio stream with AV_DISPOSITION_HEARING_IMPAIRED
> >  # 2. second audio stream with AV_DISPOSITION_VISUAL_IMPAIRED | DESCRIPTIONS
> > diff --git a/tests/ref/fate/mov-avif-demux-still-image-1-item 
> > b/tests/ref/fate/mov-avif-demux-still-image-1-item
> > new file mode 100644
> > index 00..93773afd4e
> > --- /dev/null
> > +++ b/tests/ref/fate/mov-avif-demux-still-image-1-item
> > @@ -0,0 +1,11 @@
> > +#format: frame checksums
> > +#version: 2
> > +#hash: MD5
> > +#extradata 0,  13, 
> > b52ae298d37128862ef1918cf916239c
> > +

Re: [FFmpeg-devel] [PATCH] avformat/mov: Only read the primary item for AVIF

2022-06-10 Thread Vignesh Venkatasubramanian
On Thu, Jun 9, 2022 at 12:50 AM Gyan Doshi  wrote:
>
>
>
> On 2022-06-08 10:51 pm, Vignesh Venkatasubramanian wrote:
> > On Thu, Jun 2, 2022 at 1:35 PM James Zern  wrote:
> >> On Wed, Jun 1, 2022 at 1:38 PM Vignesh Venkatasubramanian
> >>  wrote:
> >>> On Wed, Jun 1, 2022 at 10:30 AM James Zern  wrote:
> >>>> On Sun, Apr 24, 2022 at 11:35 AM Vignesh Venkatasubramanian
> >>>>  wrote:
> >>>>> Update the still AVIF parser to only read the primary item. With this
> >>>>> patch, AVIF still images with exif/icc/alpha channel will no longer
> >>>>> fail to parse.
> >>>>>
> >>>>> For example, this patch enables parsing of files in:
> >>>>> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> >>>>>
> >>>> Can some of the failing files or similar ones be added to fate?
> >>> There are no fate tests for AVIF parsing as of now. I was thinking
> >>> about adding some for the muxing. But i am not sure what can be done
> >>> here for the parsing.
> >>>
> >> Thanks. Are there any for general mov/mp4 parsing that could be
> >> extended? This looks good otherwise.
> >  From what i see, most of the mov tests only seem to be for muxing. I'm
> > not entirely certain about how to add a test for AVIF parsing. If
> > anybody has an idea, i'd be open to adding it.
>
> Basic test would use the framemd5 muxer to compare demuxed packets with
> a reference.
> See fate-ffmpeg-streamloop
>

Thank you i have added a couple of fate tests.

I am not sure how to add the AVIF files to the fate test server. I
have them on Google Drive here:

https://drive.google.com/file/d/1diZoM0Ew7Co3Yh5w5y1J-3IiBYVmUv9J/view?usp=sharing
https://drive.google.com/file/d/1DdrD1mW36evt40a4RkeLYpx-oojmbc3z/view?usp=sharing

These links should be publicly available without any sign in required.
Please let me know if there is another preferred way of sharing test
files and i can share it that way.

Also for the record, these files were created by remuxing an existing
file in the fate suite.

still_image.avif - contains the first frame from
av1-test-vectors/av1-1-b8-02-allintra.ivf
still_image_exif.avif - contains the first frame from
av1-test-vectors/av1-1-b8-02-allintra.ivf with dummy exif data.

> Regards,
> Gyan
> ___
> 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".



-- 
Vignesh
___
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] avformat/mov: Only read the primary item for AVIF

2022-06-10 Thread Vignesh Venkatasubramanian
Update the still AVIF parser to only read the primary item. With this
patch, AVIF still images with exif/icc/alpha channel will no longer
fail to parse.

For example, this patch enables parsing of files in:
https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft

Adding two fate tests:
1) demuxing of still image with 1 item - this test will pass regardlesss
   of this patch.
2) demuxing of still image with 2 items - this test will fail without
   this patch and will pass with patch applied.

Partially fixes trac ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h|  1 +
 libavformat/mov.c | 41 ++-
 tests/fate/mov.mak|  9 
 .../fate/mov-avif-demux-still-image-1-item| 11 +
 .../mov-avif-demux-still-image-multiple-items | 11 +
 5 files changed, 53 insertions(+), 20 deletions(-)
 create mode 100644 tests/ref/fate/mov-avif-demux-still-image-1-item
 create mode 100644 tests/ref/fate/mov-avif-demux-still-image-multiple-items

diff --git a/libavformat/isom.h b/libavformat/isom.h
index cf36f04d5b..f05c2d9c28 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -317,6 +317,7 @@ typedef struct MOVContext {
 uint32_t mfra_size;
 uint32_t max_stts_delta;
 int is_still_picture_avif;
+int primary_item_id;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index d7be593a86..9310a393fe 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7445,6 +7445,13 @@ static int rb_size(AVIOContext *pb, uint64_t* value, int 
size)
 return size;
 }
 
+static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+avio_rb32(pb);  // version & flags.
+c->primary_item_id = avio_rb16(pb);
+return atom.size;
+}
+
 static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
 int version, offset_size, length_size, base_offset_size, index_size;
@@ -7501,34 +7508,25 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return AVERROR_PATCHWELCOME;
 }
 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
-if (item_count > 1) {
-// For still AVIF images, we only support one item. Second item will
-// generally be found for AVIF images with alpha channel. We don't
-// support them as of now.
-av_log(c->fc, AV_LOG_ERROR, "iloc: item_count > 1 not supported.\n");
-return AVERROR_PATCHWELCOME;
-}
 
 // Populate the necessary fields used by mov_build_index.
-sc->stsc_count = item_count;
-sc->stsc_data = av_malloc_array(item_count, sizeof(*sc->stsc_data));
+sc->stsc_count = 1;
+sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
 if (!sc->stsc_data)
 return AVERROR(ENOMEM);
 sc->stsc_data[0].first = 1;
 sc->stsc_data[0].count = 1;
 sc->stsc_data[0].id = 1;
-sc->chunk_count = item_count;
-sc->chunk_offsets =
-av_malloc_array(item_count, sizeof(*sc->chunk_offsets));
+sc->chunk_count = 1;
+sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
 if (!sc->chunk_offsets)
 return AVERROR(ENOMEM);
-sc->sample_count = item_count;
-sc->sample_sizes =
-av_malloc_array(item_count, sizeof(*sc->sample_sizes));
+sc->sample_count = 1;
+sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
 if (!sc->sample_sizes)
 return AVERROR(ENOMEM);
-sc->stts_count = item_count;
-sc->stts_data = av_malloc_array(item_count, sizeof(*sc->stts_data));
+sc->stts_count = 1;
+sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
 if (!sc->stts_data)
 return AVERROR(ENOMEM);
 sc->stts_data[0].count = 1;
@@ -7536,7 +7534,7 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 sc->stts_data[0].duration = 0;
 
 for (int i = 0; i < item_count; i++) {
-(version < 2) ? avio_rb16(pb) : avio_rb32(pb);  // item_id;
+int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
 if (version > 0)
 avio_rb16(pb);  // construction_method.
 avio_rb16(pb);  // data_reference_index.
@@ -7552,8 +7550,10 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 if (rb_size(pb, _offset, offset_size) < 0 ||
 rb_size(pb, _length, length_size) < 0)
 return AVERROR_INVALIDDATA;
-sc->sample_sizes[0] = extent_length;
-sc->chunk_offsets[0] = base_offset + extent_offset;
+if (item_id == c->primary_item_id) {
+sc->sample_sizes[0] = extent_length;
+sc->chunk_offsets[0] = base_offset

Re: [FFmpeg-devel] [PATCH] avformat/mov: Only read the primary item for AVIF

2022-06-08 Thread Vignesh Venkatasubramanian
On Thu, Jun 2, 2022 at 1:35 PM James Zern  wrote:
>
> On Wed, Jun 1, 2022 at 1:38 PM Vignesh Venkatasubramanian
>  wrote:
> >
> > On Wed, Jun 1, 2022 at 10:30 AM James Zern  wrote:
> > >
> > > On Sun, Apr 24, 2022 at 11:35 AM Vignesh Venkatasubramanian
> > >  wrote:
> > > >
> > > > Update the still AVIF parser to only read the primary item. With this
> > > > patch, AVIF still images with exif/icc/alpha channel will no longer
> > > > fail to parse.
> > > >
> > > > For example, this patch enables parsing of files in:
> > > > https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> > > >
> > >
> > > Can some of the failing files or similar ones be added to fate?
> >
> > There are no fate tests for AVIF parsing as of now. I was thinking
> > about adding some for the muxing. But i am not sure what can be done
> > here for the parsing.
> >
>
> Thanks. Are there any for general mov/mp4 parsing that could be
> extended? This looks good otherwise.

>From what i see, most of the mov tests only seem to be for muxing. I'm
not entirely certain about how to add a test for AVIF parsing. If
anybody has an idea, i'd be open to adding it.


--
Vignesh
___
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] avformat/movenc: Support alpha channel for AVIF

2022-06-06 Thread Vignesh Venkatasubramanian
On Wed, Jun 1, 2022 at 12:47 PM Vignesh Venkatasubramanian
 wrote:
>
> On Wed, Jun 1, 2022 at 11:52 AM xyesbee  wrote:
> >
> > Why can it not accept it as one but two distinct streams? Why the extra 
> > hurdle of alphaextract? YUVA pixel format exists though.
>
> Yes, while the YUVA pixel formats exist, AVIF specification requires
> alpha channel to be a separate track (i.e.) we would need two AV1
> encoders to make an AVIF image with alpha channel (one for the YUV
> planes and one for the alpha plane encoded as a monochrome frame). The
> underlying AV1 codec does not support the YUVA pixel format. So, in
> order to be able to encode an AVIF image with alpha channel, we would
> have to separate the alpha channel with the alphaextract filter and
> pass it to a separate AV1 encoder.
>
> If you already have the alpha channel as a separate input, then you
> can simply pass it along as a second input stream and there will be no
> need to use the alphaextract filter. I pointed out the use of
> alphaextract filter simply because it is the simplest way to re-encode
> existing PNG images with alpha channel into AVIF.
>
> An alternative solution is to use the YUVA pixel format and internally
> use two AV1 encoders in the libaom wrapper. But that requires more
> changes and does not really make things any better. If you have a
> better solution, please let me know and I can update this.
>
> >  Original Message 
> > On Jun 1, 2022, 11:35 PM, Vignesh Venkatasubramanian wrote:
> >
> > > AVIF specification allows for alpha channel as an auxiliary item (in
> > > case of still images) or as an auxiliary track (in case of animated
> > > images). Add support for both of these. The AVIF muxer will take
> > > exactly two streams (when alpha is present) as input (first one being
> > > the YUV planes and the second one being the alpha plane).
> > >
> > > The input has to come from two different images (one of it color and
> > > the other one being alpha), or it can come from a single file
> > > source with the alpha channel extracted using the "alphaextract"
> > > filter.
> > >
> > > Example using alphaextract:
> > > ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map 
> > > "[a]" -still-picture 1 avif_with_alpha.avif
> > >
> > > Example using two sources (first source can be in any pixel format and
> > > the second source has to be in monochrome grey pixel format):
> > > ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy 
> > > avif_with_alpha.avif
> > >
> > > The generated files pass the compliance checks in Compliance Warden:
> > > https://github.com/gpac/ComplianceWarden
> > >
> > > libavif (the reference avif library) is able to decode the files
> > > generated using this patch.
> > >
> > > They also play back properly (with transparent background) in:
> > > 1) Chrome
> > > 2) Firefox (only still AVIF, no animation support)
> > >
> > > Signed-off-by: Vignesh Venkatasubramanian 
> > > ---
> > > libavformat/movenc.c | 188 +--
> > > libavformat/movenc.h | 4 +-
> > > 2 files changed, 130 insertions(+), 62 deletions(-)
> > >
> > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > > index de971f94e8..02eb4d0e9a 100644
> > > --- a/libavformat/movenc.c
> > > +++ b/libavformat/movenc.c
> > > @@ -2852,7 +2852,7 @@ static int mov_write_hdlr_tag(AVFormatContext *s, 
> > > AVIOContext *pb, MOVTrack *tra
> > > hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
> > > if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
> > > if (track->mode == MODE_AVIF) {
> > > - hdlr_type = "pict";
> > > + hdlr_type = (track == >tracks[0]) ? "pict" : "auxv";
> > > descr = "PictureHandler";
> > > } else {
> > > hdlr_type = "vide";
> > > @@ -2940,57 +2940,83 @@ static int mov_write_iloc_tag(AVIOContext *pb, 
> > > MOVMuxContext *mov, AVFormatConte
> > > avio_wb32(pb, 0); /* Version & flags */
> > > avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
> > > avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
> > > - avio_wb16(pb, 1); /* item_count */
> > > + avio_wb16(pb, s->nb_streams); /* item_count */
> > >
> > > - avio_wb16(pb, 1); /* item_id */
> > > - avio_

Re: [FFmpeg-devel] [PATCH] avformat/mov: Only read the primary item for AVIF

2022-06-01 Thread Vignesh Venkatasubramanian
On Wed, Jun 1, 2022 at 10:30 AM James Zern  wrote:
>
> On Sun, Apr 24, 2022 at 11:35 AM Vignesh Venkatasubramanian
>  wrote:
> >
> > Update the still AVIF parser to only read the primary item. With this
> > patch, AVIF still images with exif/icc/alpha channel will no longer
> > fail to parse.
> >
> > For example, this patch enables parsing of files in:
> > https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> >
>
> Can some of the failing files or similar ones be added to fate?

There are no fate tests for AVIF parsing as of now. I was thinking
about adding some for the muxing. But i am not sure what can be done
here for the parsing.

-- 
Vignesh
___
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] avformat/movenc: Support alpha channel for AVIF

2022-06-01 Thread Vignesh Venkatasubramanian
On Wed, Jun 1, 2022 at 11:52 AM xyesbee  wrote:
>
> Why can it not accept it as one but two distinct streams? Why the extra 
> hurdle of alphaextract? YUVA pixel format exists though.

Yes, while the YUVA pixel formats exist, AVIF specification requires
alpha channel to be a separate track (i.e.) we would need two AV1
encoders to make an AVIF image with alpha channel (one for the YUV
planes and one for the alpha plane encoded as a monochrome frame). The
underlying AV1 codec does not support the YUVA pixel format. So, in
order to be able to encode an AVIF image with alpha channel, we would
have to separate the alpha channel with the alphaextract filter and
pass it to a separate AV1 encoder.

If you already have the alpha channel as a separate input, then you
can simply pass it along as a second input stream and there will be no
need to use the alphaextract filter. I pointed out the use of
alphaextract filter simply because it is the simplest way to re-encode
existing PNG images with alpha channel into AVIF.

An alternative solution is to use the YUVA pixel format and internally
use two AV1 encoders in the libaom wrapper. But that requires more
changes and does not really make things any better. If you have a
better solution, please let me know and I can update this.

>  Original Message 
> On Jun 1, 2022, 11:35 PM, Vignesh Venkatasubramanian wrote:
>
> > AVIF specification allows for alpha channel as an auxiliary item (in
> > case of still images) or as an auxiliary track (in case of animated
> > images). Add support for both of these. The AVIF muxer will take
> > exactly two streams (when alpha is present) as input (first one being
> > the YUV planes and the second one being the alpha plane).
> >
> > The input has to come from two different images (one of it color and
> > the other one being alpha), or it can come from a single file
> > source with the alpha channel extracted using the "alphaextract"
> > filter.
> >
> > Example using alphaextract:
> > ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map "[a]" 
> > -still-picture 1 avif_with_alpha.avif
> >
> > Example using two sources (first source can be in any pixel format and
> > the second source has to be in monochrome grey pixel format):
> > ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy avif_with_alpha.avif
> >
> > The generated files pass the compliance checks in Compliance Warden:
> > https://github.com/gpac/ComplianceWarden
> >
> > libavif (the reference avif library) is able to decode the files
> > generated using this patch.
> >
> > They also play back properly (with transparent background) in:
> > 1) Chrome
> > 2) Firefox (only still AVIF, no animation support)
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> > libavformat/movenc.c | 188 +--
> > libavformat/movenc.h | 4 +-
> > 2 files changed, 130 insertions(+), 62 deletions(-)
> >
> > diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > index de971f94e8..02eb4d0e9a 100644
> > --- a/libavformat/movenc.c
> > +++ b/libavformat/movenc.c
> > @@ -2852,7 +2852,7 @@ static int mov_write_hdlr_tag(AVFormatContext *s, 
> > AVIOContext *pb, MOVTrack *tra
> > hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
> > if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
> > if (track->mode == MODE_AVIF) {
> > - hdlr_type = "pict";
> > + hdlr_type = (track == >tracks[0]) ? "pict" : "auxv";
> > descr = "PictureHandler";
> > } else {
> > hdlr_type = "vide";
> > @@ -2940,57 +2940,83 @@ static int mov_write_iloc_tag(AVIOContext *pb, 
> > MOVMuxContext *mov, AVFormatConte
> > avio_wb32(pb, 0); /* Version & flags */
> > avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
> > avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
> > - avio_wb16(pb, 1); /* item_count */
> > + avio_wb16(pb, s->nb_streams); /* item_count */
> >
> > - avio_wb16(pb, 1); /* item_id */
> > - avio_wb16(pb, 0); /* data_reference_index */
> > - avio_wb16(pb, 1); /* extent_count */
> > - mov->avif_extent_pos = avio_tell(pb);
> > - avio_wb32(pb, 0); /* extent_offset (written later) */
> > - // For animated AVIF, we simply write the first packet's size.
> > - avio_wb32(pb, mov->avif_extent_length); /* extent_length */
> > + for (int i = 0; i < s->nb_streams; i++) {
> > + avio_wb16(pb, i + 1); /* item_id */
> > + avio_wb16(pb, 0); /* data_reference_index */
> &

[FFmpeg-devel] [PATCH] avformat/movenc: Support alpha channel for AVIF

2022-06-01 Thread Vignesh Venkatasubramanian
AVIF specification allows for alpha channel as an auxiliary item (in
case of still images) or as an auxiliary track (in case of animated
images).  Add support for both of these. The AVIF muxer will take
exactly two streams (when alpha is present) as input (first one being
the YUV planes and the second one being the alpha plane).

The input has to come from two different images (one of it color and
the other one being alpha), or it can come from a single file
source with the alpha channel extracted using the "alphaextract"
filter.

Example using alphaextract:
ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map "[a]" 
-still-picture 1 avif_with_alpha.avif

Example using two sources (first source can be in any pixel format and
the second source has to be in monochrome grey pixel format):
ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy avif_with_alpha.avif

The generated files pass the compliance checks in Compliance Warden:
https://github.com/gpac/ComplianceWarden

libavif (the reference avif library) is able to decode the files
generated using this patch.

They also play back properly (with transparent background) in:
1) Chrome
2) Firefox (only still AVIF, no animation support)

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/movenc.c | 188 +--
 libavformat/movenc.h |   4 +-
 2 files changed, 130 insertions(+), 62 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index de971f94e8..02eb4d0e9a 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2852,7 +2852,7 @@ static int mov_write_hdlr_tag(AVFormatContext *s, 
AVIOContext *pb, MOVTrack *tra
 hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
 if (track->mode == MODE_AVIF) {
-hdlr_type = "pict";
+hdlr_type = (track == >tracks[0]) ? "pict" : "auxv";
 descr = "PictureHandler";
 } else {
 hdlr_type = "vide";
@@ -2940,57 +2940,83 @@ static int mov_write_iloc_tag(AVIOContext *pb, 
MOVMuxContext *mov, AVFormatConte
 avio_wb32(pb, 0); /* Version & flags */
 avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
 avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
-avio_wb16(pb, 1); /* item_count */
+avio_wb16(pb, s->nb_streams); /* item_count */
 
-avio_wb16(pb, 1); /* item_id */
-avio_wb16(pb, 0); /* data_reference_index */
-avio_wb16(pb, 1); /* extent_count */
-mov->avif_extent_pos = avio_tell(pb);
-avio_wb32(pb, 0); /* extent_offset (written later) */
-// For animated AVIF, we simply write the first packet's size.
-avio_wb32(pb, mov->avif_extent_length); /* extent_length */
+for (int i = 0; i < s->nb_streams; i++) {
+avio_wb16(pb, i + 1); /* item_id */
+avio_wb16(pb, 0); /* data_reference_index */
+avio_wb16(pb, 1); /* extent_count */
+mov->avif_extent_pos[i] = avio_tell(pb);
+avio_wb32(pb, 0); /* extent_offset (written later) */
+// For animated AVIF, we simply write the first packet's size.
+avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
+}
 
 return update_size(pb, pos);
 }
 
 static int mov_write_iinf_tag(AVIOContext *pb, MOVMuxContext *mov, 
AVFormatContext *s)
 {
-int64_t infe_pos;
 int64_t iinf_pos = avio_tell(pb);
 avio_wb32(pb, 0); /* size */
 ffio_wfourcc(pb, "iinf");
 avio_wb32(pb, 0); /* Version & flags */
-avio_wb16(pb, 1); /* entry_count */
+avio_wb16(pb, s->nb_streams); /* entry_count */
 
-infe_pos = avio_tell(pb);
-avio_wb32(pb, 0); /* size */
-ffio_wfourcc(pb, "infe");
-avio_w8(pb, 0x2); /* Version */
-avio_wb24(pb, 0); /* flags */
-avio_wb16(pb, 1); /* item_id */
-avio_wb16(pb, 0); /* item_protection_index */
-avio_write(pb, "av01", 4); /* item_type */
-avio_write(pb, "Color\0", 6); /* item_name */
-update_size(pb, infe_pos);
+for (int i = 0; i < s->nb_streams; i++) {
+int64_t infe_pos = avio_tell(pb);
+avio_wb32(pb, 0); /* size */
+ffio_wfourcc(pb, "infe");
+avio_w8(pb, 0x2); /* Version */
+avio_wb24(pb, 0); /* flags */
+avio_wb16(pb, i + 1); /* item_id */
+avio_wb16(pb, 0); /* item_protection_index */
+avio_write(pb, "av01", 4); /* item_type */
+avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
+update_size(pb, infe_pos);
+}
 
 return update_size(pb, iinf_pos);
 }
 
-static int mov_write_ispe_tag(AVIOContext *pb, MOVMuxContext *mov, 
AVFormatContext *s)
+
+static int mov_write_iref_tag(AVIOContext *pb, MOVMuxC

Re: [FFmpeg-devel] [PATCH] avformat/movenc: Support alpha channel for AVIF

2022-06-01 Thread Vignesh Venkatasubramanian
On Wed, Jun 1, 2022 at 10:52 AM James Zern  wrote:
>
> On Wed, May 18, 2022 at 2:56 PM Vignesh Venkatasubramanian
>  wrote:
> >
> > AVIF specification allows for alpha channel as an auxillary item (in
>
> auxiliary
>

Done.

> > case of still images) or as an auxillary track (in case of animated
> > images).  Add support for both of these. The AVIF muxer will take
> > exactly two streams (when alpha is present) as input (first one being
> > the YUV planes and the second one being the alpha plane).
> >
> > The input has to come from two different images (one of it color and
> > the other one being alpha), or it can come from a single file
> > source with the alpha channel extracted using the "alphaextract"
> > filter.
> >
> > Example using alphaextract:
> > ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map "[a]" 
> > -still-picture 1 avif_with_alpha.avif
> >
> > Example using two sources (first source can be in any pixel format and
> > the second source has to be in monochrome grey pixel format):
> > ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy avif_with_alpha.avif
> >
> > The generated files pass the compliance checks in Compliance Warden:
> > https://github.com/gpac/ComplianceWarden
> >
> > libavif (the reference avif library) is able to decode the files
> > generated using this patch.
> >
> > They also play back properly (with transparent background) in:
> > 1) Chrome
> > 2) Firefox (only still AVIF, no animation support)
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  libavformat/movenc.c | 185 +--
> >  libavformat/movenc.h |   4 +-
> >  2 files changed, 128 insertions(+), 61 deletions(-)
> >
> > diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > index de971f94e8..00e42b7abb 100644
> > --- a/libavformat/movenc.c
> > +++ b/libavformat/movenc.c
> > @@ -2852,7 +2852,7 @@ static int mov_write_hdlr_tag(AVFormatContext *s, 
> > AVIOContext *pb, MOVTrack *tra
> >  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
> >  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
> >  if (track->mode == MODE_AVIF) {
> > -hdlr_type = "pict";
> > +hdlr_type = (track == >tracks[0]) ? "pict" : "auxv";
> >  descr = "PictureHandler";
> >  } else {
> >  hdlr_type = "vide";
> > @@ -2940,57 +2940,83 @@ static int mov_write_iloc_tag(AVIOContext *pb, 
> > MOVMuxContext *mov, AVFormatConte
> >  avio_wb32(pb, 0); /* Version & flags */
> >  avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
> >  avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
> > -avio_wb16(pb, 1); /* item_count */
> > +avio_wb16(pb, s->nb_streams); /* item_count */
>
> This assumes at most 2 streams for AVIF, the use of nb_streams here and
> elsewhere carry any risk for other formats?
>

For AVIF, we check and ensure we only have at most 2 streams in
mov_init. iloc box is written only for AVIF as of now. So there is no
risk for other formats.

> > [...]
> >
> > @@ -6874,14 +6920,23 @@ static int mov_init(AVFormatContext *s)
> >
> >  /* AVIF output must have exactly one video stream */
>
> This is no longer true.
>

Updated.

> >  if (mov->mode == MODE_AVIF) {
> > -if (s->nb_streams > 1) {
> > -av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one 
> > stream\n");
> > +if (s->nb_streams > 2) {
> > +av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or 
> > two streams\n");
> >  return AVERROR(EINVAL);
> >  }
> > -if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) {
> > -av_log(s, AV_LOG_ERROR, "AVIF output requires one video 
> > stream\n");
> > +if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
> > +(s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != 
> > AVMEDIA_TYPE_VIDEO)) {
> > +av_log(s, AV_LOG_ERROR, "AVIF output supports only video 
> > streams\n");
> >  return AVERROR(EINVAL);
> >  }
> > +if (s->nb_streams > 1) {
> > +const AVPixFm

Re: [FFmpeg-devel] [PATCH] avformat/movenc: Support alpha channel for AVIF

2022-05-31 Thread Vignesh Venkatasubramanian
On Thu, May 19, 2022 at 9:08 AM Vignesh Venkatasubramanian
 wrote:
>
> On Wed, May 18, 2022 at 7:36 PM Bang He  wrote:
> >
> > error happened:
> >
> > ./ffmpeg -i alpha.png -filter_complex [0:v]alphaextract[a] -map 0 -map [a]
> > -still-picture 1 avif_with_alpha.avif
> > ffmpeg version N-106936-gff5ea89da2 Copyright (c) 2000-2022 the FFmpeg
> > developers
> >   built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)
> >   configuration: --disable-ffplay --disable-ffprobe --enable-gpl
> > --enable-nonfree --prefix=/home/bang/Desktop/out
> >   libavutil  57. 24.101 / 57. 24.101
> >   libavcodec 59. 28.100 / 59. 28.100
> >   libavformat59. 24.100 / 59. 24.100
> >   libavdevice59.  6.100 / 59.  6.100
> >   libavfilter 8. 38.100 /  8. 38.100
> >   libswscale  6.  6.100 /  6.  6.100
> >   libswresample   4.  6.100 /  4.  6.100
> >   libpostproc56.  5.100 / 56.  5.100
> > Unrecognized option 'still-picture'.
> > Error splitting the argument list: Option not found
> >
>
> You would have to build ffmpeg with libaom enabled for AVIF encoding
> to work (since AVIF is backed by an AV1 encoder). From the logs you
> posted, it seems like you don't have an AV1 encoder available in your
> ffmpeg build.
>
> The "-still-picture" flag was added in ab05e9a7f2. Please make sure
> that you are sync'ed past that to pick up that option.
>
> > On Thu, May 19, 2022 at 5:56 AM Vignesh Venkatasubramanian <
> > vigneshv-at-google@ffmpeg.org> wrote:
> >
> > > AVIF specification allows for alpha channel as an auxillary item (in
> > > case of still images) or as an auxillary track (in case of animated
> > > images).  Add support for both of these. The AVIF muxer will take
> > > exactly two streams (when alpha is present) as input (first one being
> > > the YUV planes and the second one being the alpha plane).
> > >
> > > The input has to come from two different images (one of it color and
> > > the other one being alpha), or it can come from a single file
> > > source with the alpha channel extracted using the "alphaextract"
> > > filter.
> > >
> > > Example using alphaextract:
> > > ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map
> > > "[a]" -still-picture 1 avif_with_alpha.avif
> > >
> > > Example using two sources (first source can be in any pixel format and
> > > the second source has to be in monochrome grey pixel format):
> > > ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy
> > > avif_with_alpha.avif
> > >
> > > The generated files pass the compliance checks in Compliance Warden:
> > > https://github.com/gpac/ComplianceWarden
> > >
> > > libavif (the reference avif library) is able to decode the files
> > > generated using this patch.
> > >
> > > They also play back properly (with transparent background) in:
> > > 1) Chrome
> > > 2) Firefox (only still AVIF, no animation support)
> > >
> > > Signed-off-by: Vignesh Venkatasubramanian 
> > > ---
> > >  libavformat/movenc.c | 185 +--
> > >  libavformat/movenc.h |   4 +-
> > >  2 files changed, 128 insertions(+), 61 deletions(-)
> > >
> > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > > index de971f94e8..00e42b7abb 100644
> > > --- a/libavformat/movenc.c
> > > +++ b/libavformat/movenc.c
> > > @@ -2852,7 +2852,7 @@ static int mov_write_hdlr_tag(AVFormatContext *s,
> > > AVIOContext *pb, MOVTrack *tra
> > >  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
> > >  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
> > >  if (track->mode == MODE_AVIF) {
> > > -hdlr_type = "pict";
> > > +hdlr_type = (track == >tracks[0]) ? "pict" : "auxv";
> > >  descr = "PictureHandler";
> > >  } else {
> > >  hdlr_type = "vide";
> > > @@ -2940,57 +2940,83 @@ static int mov_write_iloc_tag(AVIOContext *pb,
> > > MOVMuxContext *mov, AVFormatConte
> > >  avio_wb32(pb, 0); /* Version & flags */
> > >  avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
> > >  avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
> > > -avio_wb16(pb, 1); /

Re: [FFmpeg-devel] [PATCH] avcodec/libaomenc: Expose the allintra usage mode

2022-05-31 Thread Vignesh Venkatasubramanian
On Wed, May 18, 2022 at 10:37 AM Vignesh Venkatasubramanian
 wrote:
>
> libaom added an usage=allintra mode for doing better with still
> images. Expose that in the ffmpeg's wrapper. This is especially
> useful for encoding still AVIF images.
>
> Signed-off-by: Vignesh Venkatasubramanian 
> ---
>  libavcodec/libaomenc.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> index 0411773bbf..7877b7b5c7 100644
> --- a/libavcodec/libaomenc.c
> +++ b/libavcodec/libaomenc.c
> @@ -1300,6 +1300,7 @@ static const AVOption options[] = {
>  { "usage",   "Quality and compression efficiency vs speed 
> trade-off", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, 
> "usage"},
>  { "good","Good quality",  0, AV_OPT_TYPE_CONST, {.i64 = 
> 0 /* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, "usage"},
>  { "realtime","Realtime encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 
> 1 /* AOM_USAGE_REALTIME */}, 0, 0, VE, "usage"},
> +{ "allintra","All Intra encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 
> 2 /* AOM_USAGE_ALL_INTRA */},0, 0, VE, "usage"},
>  { "tune","The metric that the encoder tunes for. 
> Automatically chosen by the encoder by default", OFFSET(tune), 
> AV_OPT_TYPE_INT, {.i64 = -1}, -1, AOM_TUNE_SSIM, VE, "tune"},
>  { "psnr",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
> AOM_TUNE_PSNR}, 0, 0, VE, "tune"},
>  { "ssim",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
> AOM_TUNE_SSIM}, 0, 0, VE, "tune"},
> --
> 2.36.1.124.g0e6072fb45-goog
>

Can this be merged please?

-- 
Vignesh
___
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] avformat/mov: Only read the primary item for AVIF

2022-05-31 Thread Vignesh Venkatasubramanian
On Thu, May 19, 2022 at 9:13 AM Vignesh Venkatasubramanian
 wrote:
>
> On Mon, May 16, 2022 at 9:59 AM Vignesh Venkatasubramanian
>  wrote:
> >
> > Update the still AVIF parser to only read the primary item. With this
> > patch, AVIF still images with exif/icc/alpha channel will no longer
> > fail to parse.
> >
> > For example, this patch enables parsing of files in:
> > https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> >
> > Partially fixes trac ticket #7621
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  libavformat/isom.h |  1 +
> >  libavformat/mov.c  | 41 +
> >  2 files changed, 22 insertions(+), 20 deletions(-)
> >
> > diff --git a/libavformat/isom.h b/libavformat/isom.h
> > index cf36f04d5b..f05c2d9c28 100644
> > --- a/libavformat/isom.h
> > +++ b/libavformat/isom.h
> > @@ -317,6 +317,7 @@ typedef struct MOVContext {
> >  uint32_t mfra_size;
> >  uint32_t max_stts_delta;
> >  int is_still_picture_avif;
> > +int primary_item_id;
> >  } MOVContext;
> >
> >  int ff_mp4_read_descr_len(AVIOContext *pb);
> > diff --git a/libavformat/mov.c b/libavformat/mov.c
> > index d7be593a86..9310a393fe 100644
> > --- a/libavformat/mov.c
> > +++ b/libavformat/mov.c
> > @@ -7445,6 +7445,13 @@ static int rb_size(AVIOContext *pb, uint64_t* value, 
> > int size)
> >  return size;
> >  }
> >
> > +static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> > +{
> > +avio_rb32(pb);  // version & flags.
> > +c->primary_item_id = avio_rb16(pb);
> > +return atom.size;
> > +}
> > +
> >  static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> >  {
> >  int version, offset_size, length_size, base_offset_size, index_size;
> > @@ -7501,34 +7508,25 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> > *pb, MOVAtom atom)
> >  return AVERROR_PATCHWELCOME;
> >  }
> >  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
> > -if (item_count > 1) {
> > -// For still AVIF images, we only support one item. Second item 
> > will
> > -// generally be found for AVIF images with alpha channel. We don't
> > -// support them as of now.
> > -av_log(c->fc, AV_LOG_ERROR, "iloc: item_count > 1 not 
> > supported.\n");
> > -return AVERROR_PATCHWELCOME;
> > -}
> >
> >  // Populate the necessary fields used by mov_build_index.
> > -sc->stsc_count = item_count;
> > -sc->stsc_data = av_malloc_array(item_count, sizeof(*sc->stsc_data));
> > +sc->stsc_count = 1;
> > +sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
> >  if (!sc->stsc_data)
> >  return AVERROR(ENOMEM);
> >  sc->stsc_data[0].first = 1;
> >  sc->stsc_data[0].count = 1;
> >  sc->stsc_data[0].id = 1;
> > -sc->chunk_count = item_count;
> > -sc->chunk_offsets =
> > -av_malloc_array(item_count, sizeof(*sc->chunk_offsets));
> > +sc->chunk_count = 1;
> > +sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
> >  if (!sc->chunk_offsets)
> >  return AVERROR(ENOMEM);
> > -sc->sample_count = item_count;
> > -sc->sample_sizes =
> > -av_malloc_array(item_count, sizeof(*sc->sample_sizes));
> > +sc->sample_count = 1;
> > +sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
> >  if (!sc->sample_sizes)
> >  return AVERROR(ENOMEM);
> > -sc->stts_count = item_count;
> > -sc->stts_data = av_malloc_array(item_count, sizeof(*sc->stts_data));
> > +sc->stts_count = 1;
> > +sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
> >  if (!sc->stts_data)
> >  return AVERROR(ENOMEM);
> >  sc->stts_data[0].count = 1;
> > @@ -7536,7 +7534,7 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> > *pb, MOVAtom atom)
> >  sc->stts_data[0].duration = 0;
> >
> >  for (int i = 0; i < item_count; i++) {
> > -(version < 2) ? avio_rb16(pb) : avio_rb32(pb);  // item_id;
> > +int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
> >  if (version > 0)
> >  avio_rb16(pb);  // construction_method.
> >  avio_rb16(

Re: [FFmpeg-devel] [PATCH] avformat/mov: Only read the primary item for AVIF

2022-05-19 Thread Vignesh Venkatasubramanian
On Mon, May 16, 2022 at 9:59 AM Vignesh Venkatasubramanian
 wrote:
>
> Update the still AVIF parser to only read the primary item. With this
> patch, AVIF still images with exif/icc/alpha channel will no longer
> fail to parse.
>
> For example, this patch enables parsing of files in:
> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
>
> Partially fixes trac ticket #7621
>
> Signed-off-by: Vignesh Venkatasubramanian 
> ---
>  libavformat/isom.h |  1 +
>  libavformat/mov.c  | 41 +
>  2 files changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/libavformat/isom.h b/libavformat/isom.h
> index cf36f04d5b..f05c2d9c28 100644
> --- a/libavformat/isom.h
> +++ b/libavformat/isom.h
> @@ -317,6 +317,7 @@ typedef struct MOVContext {
>  uint32_t mfra_size;
>  uint32_t max_stts_delta;
>  int is_still_picture_avif;
> +int primary_item_id;
>  } MOVContext;
>
>  int ff_mp4_read_descr_len(AVIOContext *pb);
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index d7be593a86..9310a393fe 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -7445,6 +7445,13 @@ static int rb_size(AVIOContext *pb, uint64_t* value, 
> int size)
>  return size;
>  }
>
> +static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> +{
> +avio_rb32(pb);  // version & flags.
> +c->primary_item_id = avio_rb16(pb);
> +return atom.size;
> +}
> +
>  static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>  {
>  int version, offset_size, length_size, base_offset_size, index_size;
> @@ -7501,34 +7508,25 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> *pb, MOVAtom atom)
>  return AVERROR_PATCHWELCOME;
>  }
>  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
> -if (item_count > 1) {
> -// For still AVIF images, we only support one item. Second item will
> -// generally be found for AVIF images with alpha channel. We don't
> -// support them as of now.
> -av_log(c->fc, AV_LOG_ERROR, "iloc: item_count > 1 not supported.\n");
> -return AVERROR_PATCHWELCOME;
> -}
>
>  // Populate the necessary fields used by mov_build_index.
> -sc->stsc_count = item_count;
> -sc->stsc_data = av_malloc_array(item_count, sizeof(*sc->stsc_data));
> +sc->stsc_count = 1;
> +sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
>  if (!sc->stsc_data)
>  return AVERROR(ENOMEM);
>  sc->stsc_data[0].first = 1;
>  sc->stsc_data[0].count = 1;
>  sc->stsc_data[0].id = 1;
> -sc->chunk_count = item_count;
> -sc->chunk_offsets =
> -av_malloc_array(item_count, sizeof(*sc->chunk_offsets));
> +sc->chunk_count = 1;
> +sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
>  if (!sc->chunk_offsets)
>  return AVERROR(ENOMEM);
> -sc->sample_count = item_count;
> -sc->sample_sizes =
> -av_malloc_array(item_count, sizeof(*sc->sample_sizes));
> +sc->sample_count = 1;
> +sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
>  if (!sc->sample_sizes)
>  return AVERROR(ENOMEM);
> -sc->stts_count = item_count;
> -sc->stts_data = av_malloc_array(item_count, sizeof(*sc->stts_data));
> +sc->stts_count = 1;
> +sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
>  if (!sc->stts_data)
>  return AVERROR(ENOMEM);
>  sc->stts_data[0].count = 1;
> @@ -7536,7 +7534,7 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> *pb, MOVAtom atom)
>  sc->stts_data[0].duration = 0;
>
>  for (int i = 0; i < item_count; i++) {
> -(version < 2) ? avio_rb16(pb) : avio_rb32(pb);  // item_id;
> +int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
>  if (version > 0)
>  avio_rb16(pb);  // construction_method.
>  avio_rb16(pb);  // data_reference_index.
> @@ -7552,8 +7550,10 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> *pb, MOVAtom atom)
>  if (rb_size(pb, _offset, offset_size) < 0 ||
>  rb_size(pb, _length, length_size) < 0)
>  return AVERROR_INVALIDDATA;
> -sc->sample_sizes[0] = extent_length;
> -sc->chunk_offsets[0] = base_offset + extent_offset;
> +if (item_id == c->primary_item_id) {
> +sc->sample_sizes[0] = extent_length;
> +sc->chunk_of

Re: [FFmpeg-devel] [PATCH] avformat/img2: Add support for AVIF mux in image2

2022-05-19 Thread Vignesh Venkatasubramanian
On Thu, May 19, 2022 at 1:55 AM Gyan Doshi  wrote:
>
>
>
> On 2022-05-19 09:57 am, Gyan Doshi wrote:
> >
> >
> > On 2022-05-18 01:06 am, James Zern wrote:
> >> On Mon, May 16, 2022 at 10:40 AM Vignesh Venkatasubramanian
> >>  wrote:
> >>> Add support for AVIF muxing in the image2 muxer.
> >>>
> >>> Tested with this example:
> >>> ffmpeg -lavfi testsrc=duration=1:size=320x320 -g 1 -flags
> >>> global_header -c:v libaom-av1 -f image2 img-%2d.avif
> >>>
> >>> Signed-off-by: Vignesh Venkatasubramanian 
> >>> ---
> >>>   libavformat/img2enc.c | 4 +++-
> >>>   1 file changed, 3 insertions(+), 1 deletion(-)
> >>>
> >> lgtm.
> >
> > Will apply.
>
> Applied as dd99d34d67e2612a8f133f8a86db9f64b4dfa20d
>

Thank you!

> Regards,
> Gyan
> ___
> 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".



-- 
Vignesh
___
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] avformat/movenc: Support alpha channel for AVIF

2022-05-19 Thread Vignesh Venkatasubramanian
On Wed, May 18, 2022 at 7:36 PM Bang He  wrote:
>
> error happened:
>
> ./ffmpeg -i alpha.png -filter_complex [0:v]alphaextract[a] -map 0 -map [a]
> -still-picture 1 avif_with_alpha.avif
> ffmpeg version N-106936-gff5ea89da2 Copyright (c) 2000-2022 the FFmpeg
> developers
>   built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)
>   configuration: --disable-ffplay --disable-ffprobe --enable-gpl
> --enable-nonfree --prefix=/home/bang/Desktop/out
>   libavutil  57. 24.101 / 57. 24.101
>   libavcodec 59. 28.100 / 59. 28.100
>   libavformat59. 24.100 / 59. 24.100
>   libavdevice59.  6.100 / 59.  6.100
>   libavfilter 8. 38.100 /  8. 38.100
>   libswscale  6.  6.100 /  6.  6.100
>   libswresample   4.  6.100 /  4.  6.100
>   libpostproc56.  5.100 / 56.  5.100
> Unrecognized option 'still-picture'.
> Error splitting the argument list: Option not found
>

You would have to build ffmpeg with libaom enabled for AVIF encoding
to work (since AVIF is backed by an AV1 encoder). From the logs you
posted, it seems like you don't have an AV1 encoder available in your
ffmpeg build.

The "-still-picture" flag was added in ab05e9a7f2. Please make sure
that you are sync'ed past that to pick up that option.

> On Thu, May 19, 2022 at 5:56 AM Vignesh Venkatasubramanian <
> vigneshv-at-google@ffmpeg.org> wrote:
>
> > AVIF specification allows for alpha channel as an auxillary item (in
> > case of still images) or as an auxillary track (in case of animated
> > images).  Add support for both of these. The AVIF muxer will take
> > exactly two streams (when alpha is present) as input (first one being
> > the YUV planes and the second one being the alpha plane).
> >
> > The input has to come from two different images (one of it color and
> > the other one being alpha), or it can come from a single file
> > source with the alpha channel extracted using the "alphaextract"
> > filter.
> >
> > Example using alphaextract:
> > ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map
> > "[a]" -still-picture 1 avif_with_alpha.avif
> >
> > Example using two sources (first source can be in any pixel format and
> > the second source has to be in monochrome grey pixel format):
> > ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy
> > avif_with_alpha.avif
> >
> > The generated files pass the compliance checks in Compliance Warden:
> > https://github.com/gpac/ComplianceWarden
> >
> > libavif (the reference avif library) is able to decode the files
> > generated using this patch.
> >
> > They also play back properly (with transparent background) in:
> > 1) Chrome
> > 2) Firefox (only still AVIF, no animation support)
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  libavformat/movenc.c | 185 +--
> >  libavformat/movenc.h |   4 +-
> >  2 files changed, 128 insertions(+), 61 deletions(-)
> >
> > diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > index de971f94e8..00e42b7abb 100644
> > --- a/libavformat/movenc.c
> > +++ b/libavformat/movenc.c
> > @@ -2852,7 +2852,7 @@ static int mov_write_hdlr_tag(AVFormatContext *s,
> > AVIOContext *pb, MOVTrack *tra
> >  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
> >  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
> >  if (track->mode == MODE_AVIF) {
> > -hdlr_type = "pict";
> > +hdlr_type = (track == >tracks[0]) ? "pict" : "auxv";
> >  descr = "PictureHandler";
> >  } else {
> >  hdlr_type = "vide";
> > @@ -2940,57 +2940,83 @@ static int mov_write_iloc_tag(AVIOContext *pb,
> > MOVMuxContext *mov, AVFormatConte
> >  avio_wb32(pb, 0); /* Version & flags */
> >  avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
> >  avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
> > -avio_wb16(pb, 1); /* item_count */
> > +avio_wb16(pb, s->nb_streams); /* item_count */
> >
> > -avio_wb16(pb, 1); /* item_id */
> > -avio_wb16(pb, 0); /* data_reference_index */
> > -avio_wb16(pb, 1); /* extent_count */
> > -mov->avif_extent_pos = avio_tell(pb);
> > -avio_wb32(pb, 0); /* extent_offset (written later) */
> > -// For animated AVIF, we simply write the first packet's size.
> > -avio_wb32(pb, mov->avif_extent_length); /* extent_length *

[FFmpeg-devel] [PATCH] avformat/movenc: Support alpha channel for AVIF

2022-05-18 Thread Vignesh Venkatasubramanian
AVIF specification allows for alpha channel as an auxillary item (in
case of still images) or as an auxillary track (in case of animated
images).  Add support for both of these. The AVIF muxer will take
exactly two streams (when alpha is present) as input (first one being
the YUV planes and the second one being the alpha plane).

The input has to come from two different images (one of it color and
the other one being alpha), or it can come from a single file
source with the alpha channel extracted using the "alphaextract"
filter.

Example using alphaextract:
ffmpeg -i rgba.png -filter_complex "[0:v]alphaextract[a]" -map 0 -map "[a]" 
-still-picture 1 avif_with_alpha.avif

Example using two sources (first source can be in any pixel format and
the second source has to be in monochrome grey pixel format):
ffmpeg -i color.avif -i grey.avif -map 0 -map 1 -c copy avif_with_alpha.avif

The generated files pass the compliance checks in Compliance Warden:
https://github.com/gpac/ComplianceWarden

libavif (the reference avif library) is able to decode the files
generated using this patch.

They also play back properly (with transparent background) in:
1) Chrome
2) Firefox (only still AVIF, no animation support)

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/movenc.c | 185 +--
 libavformat/movenc.h |   4 +-
 2 files changed, 128 insertions(+), 61 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index de971f94e8..00e42b7abb 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2852,7 +2852,7 @@ static int mov_write_hdlr_tag(AVFormatContext *s, 
AVIOContext *pb, MOVTrack *tra
 hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
 if (track->mode == MODE_AVIF) {
-hdlr_type = "pict";
+hdlr_type = (track == >tracks[0]) ? "pict" : "auxv";
 descr = "PictureHandler";
 } else {
 hdlr_type = "vide";
@@ -2940,57 +2940,83 @@ static int mov_write_iloc_tag(AVIOContext *pb, 
MOVMuxContext *mov, AVFormatConte
 avio_wb32(pb, 0); /* Version & flags */
 avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
 avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
-avio_wb16(pb, 1); /* item_count */
+avio_wb16(pb, s->nb_streams); /* item_count */
 
-avio_wb16(pb, 1); /* item_id */
-avio_wb16(pb, 0); /* data_reference_index */
-avio_wb16(pb, 1); /* extent_count */
-mov->avif_extent_pos = avio_tell(pb);
-avio_wb32(pb, 0); /* extent_offset (written later) */
-// For animated AVIF, we simply write the first packet's size.
-avio_wb32(pb, mov->avif_extent_length); /* extent_length */
+for (int i = 0; i < s->nb_streams; i++) {
+avio_wb16(pb, i + 1); /* item_id */
+avio_wb16(pb, 0); /* data_reference_index */
+avio_wb16(pb, 1); /* extent_count */
+mov->avif_extent_pos[i] = avio_tell(pb);
+avio_wb32(pb, 0); /* extent_offset (written later) */
+// For animated AVIF, we simply write the first packet's size.
+avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
+}
 
 return update_size(pb, pos);
 }
 
 static int mov_write_iinf_tag(AVIOContext *pb, MOVMuxContext *mov, 
AVFormatContext *s)
 {
-int64_t infe_pos;
 int64_t iinf_pos = avio_tell(pb);
 avio_wb32(pb, 0); /* size */
 ffio_wfourcc(pb, "iinf");
 avio_wb32(pb, 0); /* Version & flags */
-avio_wb16(pb, 1); /* entry_count */
+avio_wb16(pb, s->nb_streams); /* entry_count */
 
-infe_pos = avio_tell(pb);
-avio_wb32(pb, 0); /* size */
-ffio_wfourcc(pb, "infe");
-avio_w8(pb, 0x2); /* Version */
-avio_wb24(pb, 0); /* flags */
-avio_wb16(pb, 1); /* item_id */
-avio_wb16(pb, 0); /* item_protection_index */
-avio_write(pb, "av01", 4); /* item_type */
-avio_write(pb, "Color\0", 6); /* item_name */
-update_size(pb, infe_pos);
+for (int i = 0; i < s->nb_streams; i++) {
+int64_t infe_pos = avio_tell(pb);
+avio_wb32(pb, 0); /* size */
+ffio_wfourcc(pb, "infe");
+avio_w8(pb, 0x2); /* Version */
+avio_wb24(pb, 0); /* flags */
+avio_wb16(pb, i + 1); /* item_id */
+avio_wb16(pb, 0); /* item_protection_index */
+avio_write(pb, "av01", 4); /* item_type */
+avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
+update_size(pb, infe_pos);
+}
 
 return update_size(pb, iinf_pos);
 }
 
-static int mov_write_ispe_tag(AVIOContext *pb, MOVMuxContext *mov, 
AVFormatContext *s)
+
+static int mov_write_iref_tag(AVIOContext *pb, MOVMuxC

[FFmpeg-devel] [PATCH] avcodec/libaomenc: Expose the allintra usage mode

2022-05-18 Thread Vignesh Venkatasubramanian
libaom added an usage=allintra mode for doing better with still
images. Expose that in the ffmpeg's wrapper. This is especially
useful for encoding still AVIF images.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavcodec/libaomenc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 0411773bbf..7877b7b5c7 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -1300,6 +1300,7 @@ static const AVOption options[] = {
 { "usage",   "Quality and compression efficiency vs speed 
trade-off", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, 
"usage"},
 { "good","Good quality",  0, AV_OPT_TYPE_CONST, {.i64 = 0 
/* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, "usage"},
 { "realtime","Realtime encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 1 
/* AOM_USAGE_REALTIME */}, 0, 0, VE, "usage"},
+{ "allintra","All Intra encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 2 
/* AOM_USAGE_ALL_INTRA */},0, 0, VE, "usage"},
 { "tune","The metric that the encoder tunes for. Automatically 
chosen by the encoder by default", OFFSET(tune), AV_OPT_TYPE_INT, {.i64 = -1}, 
-1, AOM_TUNE_SSIM, VE, "tune"},
 { "psnr",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
AOM_TUNE_PSNR}, 0, 0, VE, "tune"},
 { "ssim",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
AOM_TUNE_SSIM}, 0, 0, VE, "tune"},
-- 
2.36.1.124.g0e6072fb45-goog

___
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] avcodec/libaomenc: Expose the allintra usage mode

2022-05-18 Thread Vignesh Venkatasubramanian
On Wed, May 18, 2022 at 10:01 AM James Almer  wrote:
>
>
>
> On 5/18/2022 1:39 PM, Vignesh Venkatasubramanian wrote:
> > libaom added an usage=allintra mode for doing better with still
> > images. Expose that in the ffmpeg's wrapper. This is especially
> > useful for encoding still AVIF images.
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >   libavcodec/libaomenc.c | 3 +++
> >   1 file changed, 3 insertions(+)
> >
> > diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> > index 0411773bbf..d93d1b5e3c 100644
> > --- a/libavcodec/libaomenc.c
> > +++ b/libavcodec/libaomenc.c
> > @@ -1300,6 +1300,9 @@ static const AVOption options[] = {
> >   { "usage",   "Quality and compression efficiency vs speed 
> > trade-off", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, 
> > "usage"},
> >   { "good","Good quality",  0, AV_OPT_TYPE_CONST, {.i64 
> > = 0 /* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, "usage"},
> >   { "realtime","Realtime encoding", 0, AV_OPT_TYPE_CONST, {.i64 
> > = 1 /* AOM_USAGE_REALTIME */}, 0, 0, VE, "usage"},
> > +#ifdef AOM_USAGE_ALL_INTRA
>
> There's no need to wrap this if you're not using the actual define below.
> Realtime above was added without a wrapper because libaom versions that
> don't support usage == 1 just ignore the value if given (or error out).
> I expect the same for this allintra one.
>
> It's better from an API pov that lavc always accepts the "allintra"
> constant value for the usage avoption, and not depend on the libaom
> version used at link time.
>

Makes sense. Removed the #ifdef.

> > +{ "allintra","All Intra encoding", 0, AV_OPT_TYPE_CONST, {.i64 
> > = 2 /* AOM_USAGE_ALL_INTRA */},0, 0, VE, "usage"},
> > +#endif
> >   { "tune","The metric that the encoder tunes for. 
> > Automatically chosen by the encoder by default", OFFSET(tune), 
> > AV_OPT_TYPE_INT, {.i64 = -1}, -1, AOM_TUNE_SSIM, VE, "tune"},
> >   { "psnr",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
> > AOM_TUNE_PSNR}, 0, 0, VE, "tune"},
> >   { "ssim",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
> > AOM_TUNE_SSIM}, 0, 0, VE, "tune"},
> ___
> 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".



-- 
Vignesh
___
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] avcodec/libaomenc: Expose the allintra usage mode

2022-05-18 Thread Vignesh Venkatasubramanian
libaom added an usage=allintra mode for doing better with still
images. Expose that in the ffmpeg's wrapper. This is especially
useful for encoding still AVIF images.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavcodec/libaomenc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 0411773bbf..d93d1b5e3c 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -1300,6 +1300,9 @@ static const AVOption options[] = {
 { "usage",   "Quality and compression efficiency vs speed 
trade-off", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, 
"usage"},
 { "good","Good quality",  0, AV_OPT_TYPE_CONST, {.i64 = 0 
/* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, "usage"},
 { "realtime","Realtime encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 1 
/* AOM_USAGE_REALTIME */}, 0, 0, VE, "usage"},
+#ifdef AOM_USAGE_ALL_INTRA
+{ "allintra","All Intra encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 2 
/* AOM_USAGE_ALL_INTRA */},0, 0, VE, "usage"},
+#endif
 { "tune","The metric that the encoder tunes for. Automatically 
chosen by the encoder by default", OFFSET(tune), AV_OPT_TYPE_INT, {.i64 = -1}, 
-1, AOM_TUNE_SSIM, VE, "tune"},
 { "psnr",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
AOM_TUNE_PSNR}, 0, 0, VE, "tune"},
 { "ssim",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
AOM_TUNE_SSIM}, 0, 0, VE, "tune"},
-- 
2.36.1.124.g0e6072fb45-goog

___
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] avcodec/libaomenc: Expose the allintra usage mode

2022-05-18 Thread Vignesh Venkatasubramanian
On Wed, May 18, 2022 at 2:29 AM Gyan Doshi  wrote:
>
>
>
> On 2022-05-17 11:54 pm, Vignesh Venkatasubramanian wrote:
> > libaom added an usage=allintra mode for doing better with still
> > images. Expose that in the ffmpeg's wrapper. This is especially
> > useful for encoding still AVIF images.
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >   libavcodec/libaomenc.c | 7 +--
> >   1 file changed, 5 insertions(+), 2 deletions(-)
> >
> > diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> > index 0411773bbf..7a601c120e 100644
> > --- a/libavcodec/libaomenc.c
> > +++ b/libavcodec/libaomenc.c
> > @@ -1298,8 +1298,11 @@ static const AVOption options[] = {
> >   { "enable-intrabc",  "Enable intra block copy prediction mode", 
> > OFFSET(enable_intrabc), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
> >   { "enable-restoration", "Enable Loop Restoration filtering", 
> > OFFSET(enable_restoration), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
> >   { "usage",   "Quality and compression efficiency vs speed 
> > trade-off", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, 
> > "usage"},
> > -{ "good","Good quality",  0, AV_OPT_TYPE_CONST, {.i64 
> > = 0 /* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, "usage"},
> > -{ "realtime","Realtime encoding", 0, AV_OPT_TYPE_CONST, {.i64 
> > = 1 /* AOM_USAGE_REALTIME */}, 0, 0, VE, "usage"},
> > +{ "good","Good quality",   0, AV_OPT_TYPE_CONST, {.i64 
> > = 0 /* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, "usage"},
> > +{ "realtime","Realtime encoding",  0, AV_OPT_TYPE_CONST, {.i64 
> > = 1 /* AOM_USAGE_REALTIME */}, 0, 0, VE, "usage"},
>
> Don't mix cosmetic changes with code changes. Should be a separate patch.
>

Removed from this patch.

> Regards,
> Gyan
>
> > +#ifdef AOM_USAGE_ALL_INTRA
> > +{ "allintra","All Intra encoding", 0, AV_OPT_TYPE_CONST, {.i64 
> > = 2 /* AOM_USAGE_ALL_INTRA */},0, 0, VE, "usage"},
> > +#endif
> >   { "tune","The metric that the encoder tunes for. 
> > Automatically chosen by the encoder by default", OFFSET(tune), 
> > AV_OPT_TYPE_INT, {.i64 = -1}, -1, AOM_TUNE_SSIM, VE, "tune"},
> >   { "psnr",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
> > AOM_TUNE_PSNR}, 0, 0, VE, "tune"},
> >   { "ssim",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
> > AOM_TUNE_SSIM}, 0, 0, VE, "tune"},
>
> ___
> 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".



-- 
Vignesh
___
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] avcodec/libaomenc: Expose the allintra usage mode

2022-05-17 Thread Vignesh Venkatasubramanian
libaom added an usage=allintra mode for doing better with still
images. Expose that in the ffmpeg's wrapper. This is especially
useful for encoding still AVIF images.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavcodec/libaomenc.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 0411773bbf..7a601c120e 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -1298,8 +1298,11 @@ static const AVOption options[] = {
 { "enable-intrabc",  "Enable intra block copy prediction mode", 
OFFSET(enable_intrabc), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
 { "enable-restoration", "Enable Loop Restoration filtering", 
OFFSET(enable_restoration), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
 { "usage",   "Quality and compression efficiency vs speed 
trade-off", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, 
"usage"},
-{ "good","Good quality",  0, AV_OPT_TYPE_CONST, {.i64 = 0 
/* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, "usage"},
-{ "realtime","Realtime encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 1 
/* AOM_USAGE_REALTIME */}, 0, 0, VE, "usage"},
+{ "good","Good quality",   0, AV_OPT_TYPE_CONST, {.i64 = 0 
/* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, "usage"},
+{ "realtime","Realtime encoding",  0, AV_OPT_TYPE_CONST, {.i64 = 1 
/* AOM_USAGE_REALTIME */}, 0, 0, VE, "usage"},
+#ifdef AOM_USAGE_ALL_INTRA
+{ "allintra","All Intra encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 2 
/* AOM_USAGE_ALL_INTRA */},0, 0, VE, "usage"},
+#endif
 { "tune","The metric that the encoder tunes for. Automatically 
chosen by the encoder by default", OFFSET(tune), AV_OPT_TYPE_INT, {.i64 = -1}, 
-1, AOM_TUNE_SSIM, VE, "tune"},
 { "psnr",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
AOM_TUNE_PSNR}, 0, 0, VE, "tune"},
 { "ssim",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
AOM_TUNE_SSIM}, 0, 0, VE, "tune"},
-- 
2.36.0.550.gb090851708-goog

___
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] avformat/img2: Add support for AVIF mux in image2

2022-05-16 Thread Vignesh Venkatasubramanian
Add support for AVIF muxing in the image2 muxer.

Tested with this example:
ffmpeg -lavfi testsrc=duration=1:size=320x320 -g 1 -flags global_header -c:v 
libaom-av1 -f image2 img-%2d.avif

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/img2enc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index 5ed97bb833..0015297ec2 100644
--- a/libavformat/img2enc.c
+++ b/libavformat/img2enc.c
@@ -58,6 +58,8 @@ static int write_header(AVFormatContext *s)
 img->muxer = "gif";
 } else if (st->codecpar->codec_id == AV_CODEC_ID_FITS) {
 img->muxer = "fits";
+} else if (st->codecpar->codec_id == AV_CODEC_ID_AV1) {
+img->muxer = "avif";
 } else if (st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) {
 const char *str = strrchr(s->url, '.');
 img->split_planes = str
@@ -265,7 +267,7 @@ const AVOutputFormat ff_image2_muxer = {
 .long_name  = NULL_IF_CONFIG_SMALL("image2 sequence"),
 .extensions = 
"bmp,dpx,exr,jls,jpeg,jpg,jxl,ljpg,pam,pbm,pcx,pfm,pgm,pgmyuv,"
   
"png,ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,"
-  "im24,sunras,vbn,xbm,xface,pix,y",
+  "im24,sunras,vbn,xbm,xface,pix,y,avif",
 .priv_data_size = sizeof(VideoMuxData),
 .video_codec= AV_CODEC_ID_MJPEG,
 .write_header   = write_header,
-- 
2.36.0.550.gb090851708-goog

___
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] avformat/mov: Only read the primary item for AVIF

2022-05-16 Thread Vignesh Venkatasubramanian
Update the still AVIF parser to only read the primary item. With this
patch, AVIF still images with exif/icc/alpha channel will no longer
fail to parse.

For example, this patch enables parsing of files in:
https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft

Partially fixes trac ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |  1 +
 libavformat/mov.c  | 41 +
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index cf36f04d5b..f05c2d9c28 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -317,6 +317,7 @@ typedef struct MOVContext {
 uint32_t mfra_size;
 uint32_t max_stts_delta;
 int is_still_picture_avif;
+int primary_item_id;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index d7be593a86..9310a393fe 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7445,6 +7445,13 @@ static int rb_size(AVIOContext *pb, uint64_t* value, int 
size)
 return size;
 }
 
+static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+avio_rb32(pb);  // version & flags.
+c->primary_item_id = avio_rb16(pb);
+return atom.size;
+}
+
 static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
 int version, offset_size, length_size, base_offset_size, index_size;
@@ -7501,34 +7508,25 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return AVERROR_PATCHWELCOME;
 }
 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
-if (item_count > 1) {
-// For still AVIF images, we only support one item. Second item will
-// generally be found for AVIF images with alpha channel. We don't
-// support them as of now.
-av_log(c->fc, AV_LOG_ERROR, "iloc: item_count > 1 not supported.\n");
-return AVERROR_PATCHWELCOME;
-}
 
 // Populate the necessary fields used by mov_build_index.
-sc->stsc_count = item_count;
-sc->stsc_data = av_malloc_array(item_count, sizeof(*sc->stsc_data));
+sc->stsc_count = 1;
+sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
 if (!sc->stsc_data)
 return AVERROR(ENOMEM);
 sc->stsc_data[0].first = 1;
 sc->stsc_data[0].count = 1;
 sc->stsc_data[0].id = 1;
-sc->chunk_count = item_count;
-sc->chunk_offsets =
-av_malloc_array(item_count, sizeof(*sc->chunk_offsets));
+sc->chunk_count = 1;
+sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
 if (!sc->chunk_offsets)
 return AVERROR(ENOMEM);
-sc->sample_count = item_count;
-sc->sample_sizes =
-av_malloc_array(item_count, sizeof(*sc->sample_sizes));
+sc->sample_count = 1;
+sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
 if (!sc->sample_sizes)
 return AVERROR(ENOMEM);
-sc->stts_count = item_count;
-sc->stts_data = av_malloc_array(item_count, sizeof(*sc->stts_data));
+sc->stts_count = 1;
+sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
 if (!sc->stts_data)
 return AVERROR(ENOMEM);
 sc->stts_data[0].count = 1;
@@ -7536,7 +7534,7 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 sc->stts_data[0].duration = 0;
 
 for (int i = 0; i < item_count; i++) {
-(version < 2) ? avio_rb16(pb) : avio_rb32(pb);  // item_id;
+int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
 if (version > 0)
 avio_rb16(pb);  // construction_method.
 avio_rb16(pb);  // data_reference_index.
@@ -7552,8 +7550,10 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 if (rb_size(pb, _offset, offset_size) < 0 ||
 rb_size(pb, _length, length_size) < 0)
 return AVERROR_INVALIDDATA;
-sc->sample_sizes[0] = extent_length;
-sc->chunk_offsets[0] = base_offset + extent_offset;
+if (item_id == c->primary_item_id) {
+sc->sample_sizes[0] = extent_length;
+sc->chunk_offsets[0] = base_offset + extent_offset;
+}
 }
 }
 
@@ -7670,6 +7670,7 @@ static const MOVParseTableEntry mov_default_parse_table[] 
= {
 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
 { MKTAG('i','l','o','c'), mov_read_iloc },
+{ MKTAG('p','i','t','m'), mov_read_pitm },
 { 0, NULL }
 };
 
-- 
2.36.0.550.gb090851708-goog

___
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/movenc: Add support for AVIF muxing

2022-05-12 Thread Vignesh Venkatasubramanian
Add an AVIF muxer by re-using the existing the mov/mp4 muxer.

AVIF Specification: https://aomediacodec.github.io/av1-avif

Sample usage for still image:
ffmpeg -i image.png -c:v libaom-av1 -still-picture 1 image.avif

Sample usage for animated AVIF image:
ffmpeg -i video.mp4 animated.avif

We can re-use any of the AV1 encoding options that will make
sense for image encoding (like bitrate, tiles, encoding speed,
etc).

The files generated by this muxer has been verified to be valid
AVIF files by the following:
1) Displays on Chrome (both still and animated images).
2) Displays on Firefox (only still images, firefox does not support
   animated AVIF yet).
3) Verified to be valid by Compliance Warden:
   https://github.com/gpac/ComplianceWarden

Fixes the encoder/muxer part of Trac Ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 configure|   1 +
 libavformat/allformats.c |   1 +
 libavformat/movenc.c | 341 ---
 libavformat/movenc.h |   5 +
 4 files changed, 323 insertions(+), 25 deletions(-)

diff --git a/configure b/configure
index 196873c4aa..2992f9760e 100755
--- a/configure
+++ b/configure
@@ -3404,6 +3404,7 @@ asf_stream_muxer_select="asf_muxer"
 av1_demuxer_select="av1_frame_merge_bsf av1_parser"
 avi_demuxer_select="riffdec exif"
 avi_muxer_select="riffenc"
+avif_muxer_select="mov_muxer"
 caf_demuxer_select="iso_media"
 caf_muxer_select="iso_media"
 dash_muxer_select="mp4_muxer"
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 63876c468f..1802536633 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
 extern const AVInputFormat  ff_av1_demuxer;
 extern const AVInputFormat  ff_avi_demuxer;
 extern const AVOutputFormat ff_avi_muxer;
+extern const AVOutputFormat ff_avif_muxer;
 extern const AVInputFormat  ff_avisynth_demuxer;
 extern const AVOutputFormat ff_avm2_muxer;
 extern const AVInputFormat  ff_avr_demuxer;
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 271db99b46..a07c0ae2b4 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1335,7 +1335,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack 
*track)
 
 avio_wb32(pb, 0);
 ffio_wfourcc(pb, "av1C");
-ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
+ff_isom_write_av1c(pb, track->vos_data, track->vos_len, track->mode != 
MODE_AVIF);
 return update_size(pb, pos);
 }
 
@@ -2037,12 +2037,13 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
 }
 }
 
-/* We should only ever be called by MOV or MP4. */
-av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
+/* We should only ever be called for MOV, MP4 and AVIF. */
+av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
+   track->mode == MODE_AVIF);
 
 avio_wb32(pb, 0); /* size */
 ffio_wfourcc(pb, "colr");
-if (track->mode == MODE_MP4)
+if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
 ffio_wfourcc(pb, "nclx");
 else
 ffio_wfourcc(pb, "nclc");
@@ -2052,7 +2053,7 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
 avio_wb16(pb, track->par->color_primaries);
 avio_wb16(pb, track->par->color_trc);
 avio_wb16(pb, track->par->color_space);
-if (track->mode == MODE_MP4) {
+if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
 int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
 avio_w8(pb, full_range << 7);
 }
@@ -2118,7 +2119,7 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
   || (track->par->width == 1440 && track->par->height == 1080)
   || (track->par->width == 1920 && track->par->height == 1080);
 
-if (track->mode == MODE_MOV &&
+if ((track->mode == MODE_AVIF || track->mode == MODE_MOV) &&
 (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
 av_strlcpy(compressor_name, encoder->value, 32);
 } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
@@ -2139,6 +2140,25 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
 }
 }
 
+static int mov_write_ccst_tag(AVIOContext *pb)
+{
+int64_t pos = avio_tell(pb);
+// Write sane defaults:
+// all_ref_pics_intra = 0 : all samples can use any type of reference.
+// intra_pred_used = 1 : intra prediction may or may not be used.
+// max_ref_per_pic = 15 : reserved value to indicate that any number of
+//   

Re: [FFmpeg-devel] [PATCH 3/3] avformat/movenc: Add support for AVIF muxing

2022-05-12 Thread Vignesh Venkatasubramanian
On Thu, May 12, 2022 at 3:27 AM Gyan Doshi  wrote:
>
>
>
> On 2022-05-11 10:55 pm, Gyan Doshi wrote:
> >
> >
> > On 2022-05-11 10:24 pm, Vignesh Venkatasubramanian wrote:
> >> On Wed, May 4, 2022 at 10:15 AM Vignesh Venkatasubramanian
> >>  wrote:
> >>> Add an AVIF muxer by re-using the existing the mov/mp4 muxer.
> >>>
> >>> AVIF Specification: https://aomediacodec.github.io/av1-avif
> >>>
> >>> Sample usage for still image:
> >>> ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif
>
> I see an option for av1 encoder called still-picture but no avif-image.
>

Sorry this flag was updated as a result of a review comment in an
earlier patch. I forgot to update this commit message. Updated now.
"still-picture" flag is what you want to set for the still images.

> Muxing works and files do play back, however for animated AVIF,  the
> demuxer complains
> "Invalid mvhd time scale 0, defaulting to 1".
>

I was going by playback in Chrome/Firefox and Compliance Warden's [1]
validation. I have updated the muxer to use the track's timescale if
movie_timescale is not set. The demuxer no longer warns about the
timescale.


> Regards,
> Gyan
>
>
> >>>
> >>> Sample usage for animated AVIF image:
> >>> ffmpeg -i video.mp4 animated.avif
> >>>
> >>> We can re-use any of the AV1 encoding options that will make
> >>> sense for image encoding (like bitrate, tiles, encoding speed,
> >>> etc).
> >>>
> >>> The files generated by this muxer has been verified to be valid
> >>> AVIF files by the following:
> >>> 1) Displays on Chrome (both still and animated images).
> >>> 2) Displays on Firefox (only still images, firefox does not support
> >>> animated AVIF yet).
> >>> 3) Verified to be valid by Compliance Warden:
> >>> https://github.com/gpac/ComplianceWarden
> >>>
> >>> Fixes the encoder/muxer part of Trac Ticket #7621
> >>>
> >>> Signed-off-by: Vignesh Venkatasubramanian 
> >>> ---
> >>>   configure|   1 +
> >>>   libavformat/allformats.c |   1 +
> >>>   libavformat/movenc.c | 333
> >>> ---
> >>>   libavformat/movenc.h |   5 +
> >>>   4 files changed, 316 insertions(+), 24 deletions(-)
> >>>
> >>> diff --git a/configure b/configure
> >>> index 196873c4aa..2992f9760e 100755
> >>> --- a/configure
> >>> +++ b/configure
> >>> @@ -3404,6 +3404,7 @@ asf_stream_muxer_select="asf_muxer"
> >>>   av1_demuxer_select="av1_frame_merge_bsf av1_parser"
> >>>   avi_demuxer_select="riffdec exif"
> >>>   avi_muxer_select="riffenc"
> >>> +avif_muxer_select="mov_muxer"
> >>>   caf_demuxer_select="iso_media"
> >>>   caf_muxer_select="iso_media"
> >>>   dash_muxer_select="mp4_muxer"
> >>> diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> >>> index 63876c468f..1802536633 100644
> >>> --- a/libavformat/allformats.c
> >>> +++ b/libavformat/allformats.c
> >>> @@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
> >>>   extern const AVInputFormat  ff_av1_demuxer;
> >>>   extern const AVInputFormat  ff_avi_demuxer;
> >>>   extern const AVOutputFormat ff_avi_muxer;
> >>> +extern const AVOutputFormat ff_avif_muxer;
> >>>   extern const AVInputFormat  ff_avisynth_demuxer;
> >>>   extern const AVOutputFormat ff_avm2_muxer;
> >>>   extern const AVInputFormat  ff_avr_demuxer;
> >>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> >>> index 271db99b46..1a20fe17ca 100644
> >>> --- a/libavformat/movenc.c
> >>> +++ b/libavformat/movenc.c
> >>> @@ -1335,7 +1335,7 @@ static int mov_write_av1c_tag(AVIOContext *pb,
> >>> MOVTrack *track)
> >>>
> >>>   avio_wb32(pb, 0);
> >>>   ffio_wfourcc(pb, "av1C");
> >>> -ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
> >>> +ff_isom_write_av1c(pb, track->vos_data, track->vos_len,
> >>> track->mode != MODE_AVIF);
> >>>   return update_size(pb, pos);
> >>>   }
> >>>
> >>> @@ -2037,12 +2037,13 @@ static int mov_write_colr_tag(AVIOC

Re: [FFmpeg-devel] [PATCH 3/3] avformat/movenc: Add support for AVIF muxing

2022-05-11 Thread Vignesh Venkatasubramanian
On Wed, May 4, 2022 at 10:15 AM Vignesh Venkatasubramanian
 wrote:
>
> Add an AVIF muxer by re-using the existing the mov/mp4 muxer.
>
> AVIF Specification: https://aomediacodec.github.io/av1-avif
>
> Sample usage for still image:
> ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif
>
> Sample usage for animated AVIF image:
> ffmpeg -i video.mp4 animated.avif
>
> We can re-use any of the AV1 encoding options that will make
> sense for image encoding (like bitrate, tiles, encoding speed,
> etc).
>
> The files generated by this muxer has been verified to be valid
> AVIF files by the following:
> 1) Displays on Chrome (both still and animated images).
> 2) Displays on Firefox (only still images, firefox does not support
>animated AVIF yet).
> 3) Verified to be valid by Compliance Warden:
>https://github.com/gpac/ComplianceWarden
>
> Fixes the encoder/muxer part of Trac Ticket #7621
>
> Signed-off-by: Vignesh Venkatasubramanian 
> ---
>  configure|   1 +
>  libavformat/allformats.c |   1 +
>  libavformat/movenc.c | 333 ---
>  libavformat/movenc.h |   5 +
>  4 files changed, 316 insertions(+), 24 deletions(-)
>
> diff --git a/configure b/configure
> index 196873c4aa..2992f9760e 100755
> --- a/configure
> +++ b/configure
> @@ -3404,6 +3404,7 @@ asf_stream_muxer_select="asf_muxer"
>  av1_demuxer_select="av1_frame_merge_bsf av1_parser"
>  avi_demuxer_select="riffdec exif"
>  avi_muxer_select="riffenc"
> +avif_muxer_select="mov_muxer"
>  caf_demuxer_select="iso_media"
>  caf_muxer_select="iso_media"
>  dash_muxer_select="mp4_muxer"
> diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> index 63876c468f..1802536633 100644
> --- a/libavformat/allformats.c
> +++ b/libavformat/allformats.c
> @@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
>  extern const AVInputFormat  ff_av1_demuxer;
>  extern const AVInputFormat  ff_avi_demuxer;
>  extern const AVOutputFormat ff_avi_muxer;
> +extern const AVOutputFormat ff_avif_muxer;
>  extern const AVInputFormat  ff_avisynth_demuxer;
>  extern const AVOutputFormat ff_avm2_muxer;
>  extern const AVInputFormat  ff_avr_demuxer;
> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> index 271db99b46..1a20fe17ca 100644
> --- a/libavformat/movenc.c
> +++ b/libavformat/movenc.c
> @@ -1335,7 +1335,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack 
> *track)
>
>  avio_wb32(pb, 0);
>  ffio_wfourcc(pb, "av1C");
> -ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
> +ff_isom_write_av1c(pb, track->vos_data, track->vos_len, track->mode != 
> MODE_AVIF);
>  return update_size(pb, pos);
>  }
>
> @@ -2037,12 +2037,13 @@ static int mov_write_colr_tag(AVIOContext *pb, 
> MOVTrack *track, int prefer_icc)
>  }
>  }
>
> -/* We should only ever be called by MOV or MP4. */
> -av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
> +/* We should only ever be called for MOV, MP4 and AVIF. */
> +av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
> +   track->mode == MODE_AVIF);
>
>  avio_wb32(pb, 0); /* size */
>  ffio_wfourcc(pb, "colr");
> -if (track->mode == MODE_MP4)
> +if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
>  ffio_wfourcc(pb, "nclx");
>  else
>  ffio_wfourcc(pb, "nclc");
> @@ -2052,7 +2053,7 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
> *track, int prefer_icc)
>  avio_wb16(pb, track->par->color_primaries);
>  avio_wb16(pb, track->par->color_trc);
>  avio_wb16(pb, track->par->color_space);
> -if (track->mode == MODE_MP4) {
> +if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
>  int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
>  avio_w8(pb, full_range << 7);
>  }
> @@ -2118,7 +2119,7 @@ static void find_compressor(char * compressor_name, int 
> len, MOVTrack *track)
>|| (track->par->width == 1440 && track->par->height == 
> 1080)
>|| (track->par->width == 1920 && track->par->height == 
> 1080);
>
> -if (track->mode == MODE_MOV &&
> +if ((track->mode == MODE_AVIF || track->mode == MODE_MOV) &&
>  (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
>  av_strlcpy(compressor_name, encode

Re: [FFmpeg-devel] [PATCH] avformat/mov: Only read the primary item for AVIF

2022-05-09 Thread Vignesh Venkatasubramanian
On Mon, May 2, 2022 at 2:39 PM Vignesh Venkatasubramanian
 wrote:
>
> On Sun, Apr 24, 2022 at 11:35 AM Vignesh Venkatasubramanian
>  wrote:
> >
> > Update the still AVIF parser to only read the primary item. With this
> > patch, AVIF still images with exif/icc/alpha channel will no longer
> > fail to parse.
> >
> > For example, this patch enables parsing of files in:
> > https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> >
> > Partially fixes trac ticket #7621
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  libavformat/isom.h |  1 +
> >  libavformat/mov.c  | 41 +
> >  2 files changed, 22 insertions(+), 20 deletions(-)
> >
> > diff --git a/libavformat/isom.h b/libavformat/isom.h
> > index cf36f04d5b..f05c2d9c28 100644
> > --- a/libavformat/isom.h
> > +++ b/libavformat/isom.h
> > @@ -317,6 +317,7 @@ typedef struct MOVContext {
> >  uint32_t mfra_size;
> >  uint32_t max_stts_delta;
> >  int is_still_picture_avif;
> > +int primary_item_id;
> >  } MOVContext;
> >
> >  int ff_mp4_read_descr_len(AVIOContext *pb);
> > diff --git a/libavformat/mov.c b/libavformat/mov.c
> > index 3e83e54a77..6be0f317ca 100644
> > --- a/libavformat/mov.c
> > +++ b/libavformat/mov.c
> > @@ -7449,6 +7449,13 @@ static int rb_size(AVIOContext *pb, uint64_t* value, 
> > int size)
> >  return size;
> >  }
> >
> > +static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> > +{
> > +avio_rb32(pb);  // version & flags.
> > +c->primary_item_id = avio_rb16(pb);
> > +return atom.size;
> > +}
> > +
> >  static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> >  {
> >  int version, offset_size, length_size, base_offset_size, index_size;
> > @@ -7505,34 +7512,25 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> > *pb, MOVAtom atom)
> >  return AVERROR_PATCHWELCOME;
> >  }
> >  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
> > -if (item_count > 1) {
> > -// For still AVIF images, we only support one item. Second item 
> > will
> > -// generally be found for AVIF images with alpha channel. We don't
> > -// support them as of now.
> > -av_log(c->fc, AV_LOG_ERROR, "iloc: item_count > 1 not 
> > supported.\n");
> > -return AVERROR_PATCHWELCOME;
> > -}
> >
> >  // Populate the necessary fields used by mov_build_index.
> > -sc->stsc_count = item_count;
> > -sc->stsc_data = av_malloc_array(item_count, sizeof(*sc->stsc_data));
> > +sc->stsc_count = 1;
> > +sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
> >  if (!sc->stsc_data)
> >  return AVERROR(ENOMEM);
> >  sc->stsc_data[0].first = 1;
> >  sc->stsc_data[0].count = 1;
> >  sc->stsc_data[0].id = 1;
> > -sc->chunk_count = item_count;
> > -sc->chunk_offsets =
> > -av_malloc_array(item_count, sizeof(*sc->chunk_offsets));
> > +sc->chunk_count = 1;
> > +sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
> >  if (!sc->chunk_offsets)
> >  return AVERROR(ENOMEM);
> > -sc->sample_count = item_count;
> > -sc->sample_sizes =
> > -av_malloc_array(item_count, sizeof(*sc->sample_sizes));
> > +sc->sample_count = 1;
> > +sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
> >  if (!sc->sample_sizes)
> >  return AVERROR(ENOMEM);
> > -sc->stts_count = item_count;
> > -sc->stts_data = av_malloc_array(item_count, sizeof(*sc->stts_data));
> > +sc->stts_count = 1;
> > +sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
> >  if (!sc->stts_data)
> >  return AVERROR(ENOMEM);
> >  sc->stts_data[0].count = 1;
> > @@ -7540,7 +7538,7 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> > *pb, MOVAtom atom)
> >  sc->stts_data[0].duration = 0;
> >
> >  for (int i = 0; i < item_count; i++) {
> > -(version < 2) ? avio_rb16(pb) : avio_rb32(pb);  // item_id;
> > +int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
> >  if (version > 0)
> >  avio_rb16(pb);  // construction_method.
> >  avio_rb16(

[FFmpeg-devel] [PATCH 3/3] avformat/movenc: Add support for AVIF muxing

2022-05-04 Thread Vignesh Venkatasubramanian
Add an AVIF muxer by re-using the existing the mov/mp4 muxer.

AVIF Specification: https://aomediacodec.github.io/av1-avif

Sample usage for still image:
ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif

Sample usage for animated AVIF image:
ffmpeg -i video.mp4 animated.avif

We can re-use any of the AV1 encoding options that will make
sense for image encoding (like bitrate, tiles, encoding speed,
etc).

The files generated by this muxer has been verified to be valid
AVIF files by the following:
1) Displays on Chrome (both still and animated images).
2) Displays on Firefox (only still images, firefox does not support
   animated AVIF yet).
3) Verified to be valid by Compliance Warden:
   https://github.com/gpac/ComplianceWarden

Fixes the encoder/muxer part of Trac Ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 configure|   1 +
 libavformat/allformats.c |   1 +
 libavformat/movenc.c | 333 ---
 libavformat/movenc.h |   5 +
 4 files changed, 316 insertions(+), 24 deletions(-)

diff --git a/configure b/configure
index 196873c4aa..2992f9760e 100755
--- a/configure
+++ b/configure
@@ -3404,6 +3404,7 @@ asf_stream_muxer_select="asf_muxer"
 av1_demuxer_select="av1_frame_merge_bsf av1_parser"
 avi_demuxer_select="riffdec exif"
 avi_muxer_select="riffenc"
+avif_muxer_select="mov_muxer"
 caf_demuxer_select="iso_media"
 caf_muxer_select="iso_media"
 dash_muxer_select="mp4_muxer"
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 63876c468f..1802536633 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
 extern const AVInputFormat  ff_av1_demuxer;
 extern const AVInputFormat  ff_avi_demuxer;
 extern const AVOutputFormat ff_avi_muxer;
+extern const AVOutputFormat ff_avif_muxer;
 extern const AVInputFormat  ff_avisynth_demuxer;
 extern const AVOutputFormat ff_avm2_muxer;
 extern const AVInputFormat  ff_avr_demuxer;
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 271db99b46..1a20fe17ca 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1335,7 +1335,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack 
*track)
 
 avio_wb32(pb, 0);
 ffio_wfourcc(pb, "av1C");
-ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
+ff_isom_write_av1c(pb, track->vos_data, track->vos_len, track->mode != 
MODE_AVIF);
 return update_size(pb, pos);
 }
 
@@ -2037,12 +2037,13 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
 }
 }
 
-/* We should only ever be called by MOV or MP4. */
-av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
+/* We should only ever be called for MOV, MP4 and AVIF. */
+av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
+   track->mode == MODE_AVIF);
 
 avio_wb32(pb, 0); /* size */
 ffio_wfourcc(pb, "colr");
-if (track->mode == MODE_MP4)
+if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
 ffio_wfourcc(pb, "nclx");
 else
 ffio_wfourcc(pb, "nclc");
@@ -2052,7 +2053,7 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
 avio_wb16(pb, track->par->color_primaries);
 avio_wb16(pb, track->par->color_trc);
 avio_wb16(pb, track->par->color_space);
-if (track->mode == MODE_MP4) {
+if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
 int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
 avio_w8(pb, full_range << 7);
 }
@@ -2118,7 +2119,7 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
   || (track->par->width == 1440 && track->par->height == 1080)
   || (track->par->width == 1920 && track->par->height == 1080);
 
-if (track->mode == MODE_MOV &&
+if ((track->mode == MODE_AVIF || track->mode == MODE_MOV) &&
 (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
 av_strlcpy(compressor_name, encoder->value, 32);
 } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
@@ -2139,6 +2140,25 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
 }
 }
 
+static int mov_write_ccst_tag(AVIOContext *pb)
+{
+int64_t pos = avio_tell(pb);
+// Write sane defaults:
+// all_ref_pics_intra = 0 : all samples can use any type of reference.
+// intra_pred_used = 1 : intra prediction may or may not be used.
+// max_ref_per_pic = 15 : reserved value to indicate that any number of
+//reference im

Re: [FFmpeg-devel] [PATCH 3/3] avformat/movenc: Add support for AVIF muxing

2022-05-04 Thread Vignesh Venkatasubramanian
On Wed, May 4, 2022 at 10:10 AM "zhilizhao(赵志立)"  wrote:
>
>
>
> > On May 5, 2022, at 12:45 AM, Vignesh Venkatasubramanian 
> >  wrote:
> >
> >>>
> >>> -mov_write_track_udta_tag(pb, mov, st);
> >>> +if (track->mode != MODE_AVIF)
> >>> +mov_write_track_udta_tag(pb, mov, st);
> >>
> >> Please check if the check can be removed. mov_write_track_udta_tag() does 
> >> nothing
> >> for mode other than MOV/MP4.
> >>
> >
> > mov_write_track_udta_tag() writes itunes meta and loci tags when mode
> > is not MOV/MP4. So this check is necessary.
> >
>
> I think you are referring to ‘mov_write_udta_tag', not
> ‘mov_write_track_udta_tag', no?

Ah yes you are right. mov_write_track_udta_tag doesn't do anything for
non-MOV/MP4. I have removed the check.

> ___
> 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".



-- 
Vignesh
___
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/movenc: Add support for AVIF muxing

2022-05-04 Thread Vignesh Venkatasubramanian
Add an AVIF muxer by re-using the existing the mov/mp4 muxer.

AVIF Specification: https://aomediacodec.github.io/av1-avif

Sample usage for still image:
ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif

Sample usage for animated AVIF image:
ffmpeg -i video.mp4 animated.avif

We can re-use any of the AV1 encoding options that will make
sense for image encoding (like bitrate, tiles, encoding speed,
etc).

The files generated by this muxer has been verified to be valid
AVIF files by the following:
1) Displays on Chrome (both still and animated images).
2) Displays on Firefox (only still images, firefox does not support
   animated AVIF yet).
3) Verified to be valid by Compliance Warden:
   https://github.com/gpac/ComplianceWarden

Fixes the encoder/muxer part of Trac Ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 configure|   1 +
 libavformat/allformats.c |   1 +
 libavformat/movenc.c | 336 ---
 libavformat/movenc.h |   5 +
 4 files changed, 318 insertions(+), 25 deletions(-)

diff --git a/configure b/configure
index 196873c4aa..2992f9760e 100755
--- a/configure
+++ b/configure
@@ -3404,6 +3404,7 @@ asf_stream_muxer_select="asf_muxer"
 av1_demuxer_select="av1_frame_merge_bsf av1_parser"
 avi_demuxer_select="riffdec exif"
 avi_muxer_select="riffenc"
+avif_muxer_select="mov_muxer"
 caf_demuxer_select="iso_media"
 caf_muxer_select="iso_media"
 dash_muxer_select="mp4_muxer"
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 63876c468f..1802536633 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
 extern const AVInputFormat  ff_av1_demuxer;
 extern const AVInputFormat  ff_avi_demuxer;
 extern const AVOutputFormat ff_avi_muxer;
+extern const AVOutputFormat ff_avif_muxer;
 extern const AVInputFormat  ff_avisynth_demuxer;
 extern const AVOutputFormat ff_avm2_muxer;
 extern const AVInputFormat  ff_avr_demuxer;
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 271db99b46..b1c8b0fd81 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1335,7 +1335,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack 
*track)
 
 avio_wb32(pb, 0);
 ffio_wfourcc(pb, "av1C");
-ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
+ff_isom_write_av1c(pb, track->vos_data, track->vos_len, track->mode != 
MODE_AVIF);
 return update_size(pb, pos);
 }
 
@@ -2037,12 +2037,13 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
 }
 }
 
-/* We should only ever be called by MOV or MP4. */
-av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
+/* We should only ever be called for MOV, MP4 and AVIF. */
+av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
+   track->mode == MODE_AVIF);
 
 avio_wb32(pb, 0); /* size */
 ffio_wfourcc(pb, "colr");
-if (track->mode == MODE_MP4)
+if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
 ffio_wfourcc(pb, "nclx");
 else
 ffio_wfourcc(pb, "nclc");
@@ -2052,7 +2053,7 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
 avio_wb16(pb, track->par->color_primaries);
 avio_wb16(pb, track->par->color_trc);
 avio_wb16(pb, track->par->color_space);
-if (track->mode == MODE_MP4) {
+if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
 int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
 avio_w8(pb, full_range << 7);
 }
@@ -2118,7 +2119,7 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
   || (track->par->width == 1440 && track->par->height == 1080)
   || (track->par->width == 1920 && track->par->height == 1080);
 
-if (track->mode == MODE_MOV &&
+if ((track->mode == MODE_AVIF || track->mode == MODE_MOV) &&
 (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
 av_strlcpy(compressor_name, encoder->value, 32);
 } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
@@ -2139,6 +2140,25 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
 }
 }
 
+static int mov_write_ccst_tag(AVIOContext *pb)
+{
+int64_t pos = avio_tell(pb);
+// Write sane defaults:
+// all_ref_pics_intra = 0 : all samples can use any type of reference.
+// intra_pred_used = 1 : intra prediction may or may not be used.
+// max_ref_per_pic = 15 : reserved value to indicate that any number of
+//reference im

Re: [FFmpeg-devel] [PATCH 3/3] avformat/movenc: Add support for AVIF muxing

2022-05-04 Thread Vignesh Venkatasubramanian
On Tue, May 3, 2022 at 7:46 PM "zhilizhao(赵志立)"  wrote:
>
>

Thanks for the review!

>
> > On May 3, 2022, at 5:35 AM, Vignesh Venkatasubramanian 
> >  wrote:
> >
> > Add an AVIF muxer by re-using the existing the mov/mp4 muxer.
> >
> > AVIF Specification: https://aomediacodec.github.io/av1-avif
> >
> > Sample usage for still image:
> > ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif
> >
> > Sample usage for animated AVIF image:
> > ffmpeg -i video.mp4 animated.avif
> >
> > We can re-use any of the AV1 encoding options that will make
> > sense for image encoding (like bitrate, tiles, encoding speed,
> > etc).
> >
> > The files generated by this muxer has been verified to be valid
> > AVIF files by the following:
> > 1) Displays on Chrome (both still and animated images).
> > 2) Displays on Firefox (only still images, firefox does not support
> >   animated AVIF yet).
> > 3) Verified to be valid by Compliance Warden:
> >   https://github.com/gpac/ComplianceWarden
> >
> > Fixes the encoder/muxer part of Trac Ticket #7621
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> > configure|   1 +
> > libavformat/allformats.c |   1 +
> > libavformat/movenc.c | 335 ---
> > libavformat/movenc.h |   5 +
> > 4 files changed, 317 insertions(+), 25 deletions(-)
> >
> >
>
> […]
>
> > static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, 
> > MOVMuxContext *mov, MOVTrack *track)
> > {
> > int ret = AVERROR_BUG;
> > @@ -2156,6 +2176,8 @@ static int mov_write_video_tag(AVFormatContext *s, 
> > AVIOContext *pb, MOVMuxContex
> > avio_wb32(pb, 0); /* size */
> > if (mov->encryption_scheme != MOV_ENC_NONE) {
> > ffio_wfourcc(pb, "encv");
> > +} else if (track->mode == MODE_AVIF) {
> > +ffio_wfourcc(pb, "av01");
>
> Can the ‘else’ path handle the case?
>

You are right. Removed the "else if" case.

> > } else {
> > avio_wl32(pb, track->tag); // store it byteswapped
> > }
> > @@ -2272,7 +2294,7 @@ static int mov_write_video_tag(AVFormatContext *s, 
> > AVIOContext *pb, MOVMuxContex
> > else
> > av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. 
> > Format is not MOV.\n");
> > }
> > -if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
> > +if (track->mode == MODE_MOV || track->mode == MODE_MP4 || track->mode 
> > == MODE_AVIF) {
> > int has_color_info = track->par->color_primaries != 
> > AVCOL_PRI_UNSPECIFIED &&
> >  track->par->color_trc != AVCOL_TRC_UNSPECIFIED 
> > &&
> >  track->par->color_space != 
> > AVCOL_SPC_UNSPECIFIED;
> > @@ -2324,6 +2346,9 @@ static int mov_write_video_tag(AVFormatContext *s, 
> > AVIOContext *pb, MOVMuxContex
> > if (avid)
> > avio_wb32(pb, 0);
> >
> > +if (track->mode == MODE_AVIF)
> > +mov_write_ccst_tag(pb);
> > +
> > return update_size(pb, pos);
> > }
> >
> > @@ -2825,7 +2850,10 @@ static int mov_write_hdlr_tag(AVFormatContext *s, 
> > AVIOContext *pb, MOVTrack *tra
> >
> > if (track) {
> > hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
> > -if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
> > +if (track->mode == MODE_AVIF) {
> > +hdlr_type = "pict";
> > +descr = "PictureHandler";
> > +} else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
>
> I prefer put check inside the ‘if (track->par->codec_type == 
> AVMEDIA_TYPE_VIDEO)’.
> It’s a special case of ‘AVMEDIA_TYPE_VIDEO’.
>

Done.

> > hdlr_type = "vide";
> > descr = "VideoHandler";
> > } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
> > @@ -2892,6 +2920,128 @@ static int mov_write_hdlr_tag(AVFormatContext *s, 
> > AVIOContext *pb, MOVTrack *tra
> > return update_size(pb, pos);
> > }
> >
> > +static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
> > +{
> > +int64_t pos = avio_tell(pb);
> > +avio_wb32(pb, 0); /* size */
> > +ffio_wfourcc(pb, "pitm");
> > +avio_wb32(pb, 0); /* Ve

Re: [FFmpeg-devel] [PATCH] avformat/mov: Only read the primary item for AVIF

2022-05-02 Thread Vignesh Venkatasubramanian
On Sun, Apr 24, 2022 at 11:35 AM Vignesh Venkatasubramanian
 wrote:
>
> Update the still AVIF parser to only read the primary item. With this
> patch, AVIF still images with exif/icc/alpha channel will no longer
> fail to parse.
>
> For example, this patch enables parsing of files in:
> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
>
> Partially fixes trac ticket #7621
>
> Signed-off-by: Vignesh Venkatasubramanian 
> ---
>  libavformat/isom.h |  1 +
>  libavformat/mov.c  | 41 +
>  2 files changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/libavformat/isom.h b/libavformat/isom.h
> index cf36f04d5b..f05c2d9c28 100644
> --- a/libavformat/isom.h
> +++ b/libavformat/isom.h
> @@ -317,6 +317,7 @@ typedef struct MOVContext {
>  uint32_t mfra_size;
>  uint32_t max_stts_delta;
>  int is_still_picture_avif;
> +int primary_item_id;
>  } MOVContext;
>
>  int ff_mp4_read_descr_len(AVIOContext *pb);
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index 3e83e54a77..6be0f317ca 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -7449,6 +7449,13 @@ static int rb_size(AVIOContext *pb, uint64_t* value, 
> int size)
>  return size;
>  }
>
> +static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> +{
> +avio_rb32(pb);  // version & flags.
> +c->primary_item_id = avio_rb16(pb);
> +return atom.size;
> +}
> +
>  static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>  {
>  int version, offset_size, length_size, base_offset_size, index_size;
> @@ -7505,34 +7512,25 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> *pb, MOVAtom atom)
>  return AVERROR_PATCHWELCOME;
>  }
>  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
> -if (item_count > 1) {
> -// For still AVIF images, we only support one item. Second item will
> -// generally be found for AVIF images with alpha channel. We don't
> -// support them as of now.
> -av_log(c->fc, AV_LOG_ERROR, "iloc: item_count > 1 not supported.\n");
> -return AVERROR_PATCHWELCOME;
> -}
>
>  // Populate the necessary fields used by mov_build_index.
> -sc->stsc_count = item_count;
> -sc->stsc_data = av_malloc_array(item_count, sizeof(*sc->stsc_data));
> +sc->stsc_count = 1;
> +sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
>  if (!sc->stsc_data)
>  return AVERROR(ENOMEM);
>  sc->stsc_data[0].first = 1;
>  sc->stsc_data[0].count = 1;
>  sc->stsc_data[0].id = 1;
> -sc->chunk_count = item_count;
> -sc->chunk_offsets =
> -av_malloc_array(item_count, sizeof(*sc->chunk_offsets));
> +sc->chunk_count = 1;
> +sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
>  if (!sc->chunk_offsets)
>  return AVERROR(ENOMEM);
> -sc->sample_count = item_count;
> -sc->sample_sizes =
> -av_malloc_array(item_count, sizeof(*sc->sample_sizes));
> +sc->sample_count = 1;
> +sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
>  if (!sc->sample_sizes)
>  return AVERROR(ENOMEM);
> -sc->stts_count = item_count;
> -sc->stts_data = av_malloc_array(item_count, sizeof(*sc->stts_data));
> +sc->stts_count = 1;
> +sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
>  if (!sc->stts_data)
>  return AVERROR(ENOMEM);
>  sc->stts_data[0].count = 1;
> @@ -7540,7 +7538,7 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> *pb, MOVAtom atom)
>  sc->stts_data[0].duration = 0;
>
>  for (int i = 0; i < item_count; i++) {
> -(version < 2) ? avio_rb16(pb) : avio_rb32(pb);  // item_id;
> +int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
>  if (version > 0)
>  avio_rb16(pb);  // construction_method.
>  avio_rb16(pb);  // data_reference_index.
> @@ -7556,8 +7554,10 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
> *pb, MOVAtom atom)
>  if (rb_size(pb, _offset, offset_size) < 0 ||
>  rb_size(pb, _length, length_size) < 0)
>  return AVERROR_INVALIDDATA;
> -sc->sample_sizes[0] = extent_length;
> -sc->chunk_offsets[0] = base_offset + extent_offset;
> +if (item_id == c->primary_item_id) {
> +sc->sample_sizes[0] = extent_length;
> +sc->chunk_offset

[FFmpeg-devel] [PATCH 1/3] avcodec/libaomenc: Add parameter for avif single image encoding

2022-05-02 Thread Vignesh Venkatasubramanian
Add a parameter to libaom-av1 encoder to enforce some of the single
image constraints in the AV1 encoder. Setting this flag will limit
the encoder to producing exactly one frame and the sequence header
that is produced by the encoder will be conformant to the AVIF
specification [1].

Part of Fixing Trac ticket #7621

[1] https://aomediacodec.github.io/av1-avif

Signed-off-by:: Vignesh Venkatasubramanian 
---
 libavcodec/libaomenc.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 054903e6e2..0411773bbf 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -100,6 +100,7 @@ typedef struct AOMEncoderContext {
 int enable_restoration;
 int usage;
 int tune;
+int still_picture;
 int enable_rect_partitions;
 int enable_1to4_partitions;
 int enable_ab_partitions;
@@ -747,6 +748,18 @@ static av_cold int aom_init(AVCodecContext *avctx,
 if (res < 0)
 return res;
 
+if (ctx->still_picture) {
+// Set the maximum number of frames to 1. This will let libaom set
+// still_picture and reduced_still_picture_header to 1 in the Sequence
+// Header as required by AVIF still images.
+enccfg.g_limit = 1;
+// Reduce memory usage for still images.
+enccfg.g_lag_in_frames = 0;
+// All frames will be key frames.
+enccfg.kf_max_dist = 0;
+enccfg.kf_mode = AOM_KF_DISABLED;
+}
+
 /* Construct Encoder Context */
 res = aom_codec_enc_init(>encoder, iface, , flags);
 if (res != AOM_CODEC_OK) {
@@ -1291,6 +1304,7 @@ static const AVOption options[] = {
 { "psnr",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
AOM_TUNE_PSNR}, 0, 0, VE, "tune"},
 { "ssim",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
AOM_TUNE_SSIM}, 0, 0, VE, "tune"},
 FF_AV1_PROFILE_OPTS
+{ "still-picture", "Encode in single frame mode (typically used for still 
AVIF images).", OFFSET(still_picture), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, VE 
},
 { "enable-rect-partitions", "Enable rectangular partitions", 
OFFSET(enable_rect_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
 { "enable-1to4-partitions", "Enable 1:4/4:1 partitions", 
OFFSET(enable_1to4_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
 { "enable-ab-partitions",   "Enable ab shape partitions",
OFFSET(enable_ab_partitions),   AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
-- 
2.36.0.464.gb9c8b46e94-goog

___
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/av1: Add a parameter to av1c to omit seq header

2022-05-02 Thread Vignesh Venkatasubramanian
Add a parameter to omit seq header when generating the av1C atom.

For now, this does not change any behavior. This will be used by a
follow-up patch to add AVIF support.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/av1.c | 7 +--
 libavformat/av1.h | 4 +++-
 libavformat/matroskaenc.c | 4 ++--
 libavformat/movenc.c  | 2 +-
 4 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/libavformat/av1.c b/libavformat/av1.c
index 79065d0c9f..b6eaf50627 100644
--- a/libavformat/av1.c
+++ b/libavformat/av1.c
@@ -395,7 +395,8 @@ int ff_av1_parse_seq_header(AV1SequenceParameters *seq, 
const uint8_t *buf, int
 return is_av1c ? 0 : AVERROR_INVALIDDATA;
 }
 
-int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
+int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size,
+   int write_seq_header)
 {
 AVIOContext *meta_pb;
 AV1SequenceParameters seq_params;
@@ -485,7 +486,9 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, 
int size)
 flush_put_bits();
 
 avio_write(pb, header, sizeof(header));
-avio_write(pb, seq, seq_size);
+if (write_seq_header) {
+avio_write(pb, seq, seq_size);
+}
 
 meta_size = avio_get_dyn_buf(meta_pb, );
 if (meta_size)
diff --git a/libavformat/av1.h b/libavformat/av1.h
index f57dabe986..a393fbb78f 100644
--- a/libavformat/av1.h
+++ b/libavformat/av1.h
@@ -96,9 +96,11 @@ int ff_av1_parse_seq_header(AV1SequenceParameters *seq, 
const uint8_t *buf, int
  * @param pb pointer to the AVIOContext where the av1C box shall be written
  * @param buf input data buffer
  * @param size size in bytes of the input data buffer
+ * @param write_seq_header If 1, Sequence Header OBU will be written inside the
+ *   av1C box. Otherwise, Sequence Header OBU will be omitted.
  *
  * @return >= 0 in case of success, a negative AVERROR code in case of failure
  */
-int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size);
+int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size, int 
write_seq_header);
 
 #endif /* AVFORMAT_AV1_H */
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 3b8ca11f28..d789a618a4 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -1089,7 +1089,7 @@ static int mkv_write_native_codecprivate(AVFormatContext 
*s, AVIOContext *pb,
 case AV_CODEC_ID_AV1:
 if (par->extradata_size)
 return ff_isom_write_av1c(dyn_cp, par->extradata,
-  par->extradata_size);
+  par->extradata_size, 1);
 else
 put_ebml_void(pb, 4 + 3);
 break;
@@ -2665,7 +2665,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, 
const AVPacket *pkt)
 ret = avio_open_dyn_buf(_cp);
 if (ret < 0)
 return ret;
-ff_isom_write_av1c(dyn_cp, side_data, side_data_size);
+ff_isom_write_av1c(dyn_cp, side_data, side_data_size, 1);
 codecpriv_size = avio_get_dyn_buf(dyn_cp, );
 if ((ret = dyn_cp->error) < 0 ||
 !codecpriv_size && (ret = AVERROR_INVALIDDATA)) {
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index c2aed6329f..271db99b46 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1335,7 +1335,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack 
*track)
 
 avio_wb32(pb, 0);
 ffio_wfourcc(pb, "av1C");
-ff_isom_write_av1c(pb, track->vos_data, track->vos_len);
+ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
 return update_size(pb, pos);
 }
 
-- 
2.36.0.464.gb9c8b46e94-goog

___
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/movenc: Add support for AVIF muxing

2022-05-02 Thread Vignesh Venkatasubramanian
Add an AVIF muxer by re-using the existing the mov/mp4 muxer.

AVIF Specification: https://aomediacodec.github.io/av1-avif

Sample usage for still image:
ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif

Sample usage for animated AVIF image:
ffmpeg -i video.mp4 animated.avif

We can re-use any of the AV1 encoding options that will make
sense for image encoding (like bitrate, tiles, encoding speed,
etc).

The files generated by this muxer has been verified to be valid
AVIF files by the following:
1) Displays on Chrome (both still and animated images).
2) Displays on Firefox (only still images, firefox does not support
   animated AVIF yet).
3) Verified to be valid by Compliance Warden:
   https://github.com/gpac/ComplianceWarden

Fixes the encoder/muxer part of Trac Ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 configure|   1 +
 libavformat/allformats.c |   1 +
 libavformat/movenc.c | 335 ---
 libavformat/movenc.h |   5 +
 4 files changed, 317 insertions(+), 25 deletions(-)

diff --git a/configure b/configure
index 196873c4aa..2992f9760e 100755
--- a/configure
+++ b/configure
@@ -3404,6 +3404,7 @@ asf_stream_muxer_select="asf_muxer"
 av1_demuxer_select="av1_frame_merge_bsf av1_parser"
 avi_demuxer_select="riffdec exif"
 avi_muxer_select="riffenc"
+avif_muxer_select="mov_muxer"
 caf_demuxer_select="iso_media"
 caf_muxer_select="iso_media"
 dash_muxer_select="mp4_muxer"
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 63876c468f..1802536633 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
 extern const AVInputFormat  ff_av1_demuxer;
 extern const AVInputFormat  ff_avi_demuxer;
 extern const AVOutputFormat ff_avi_muxer;
+extern const AVOutputFormat ff_avif_muxer;
 extern const AVInputFormat  ff_avisynth_demuxer;
 extern const AVOutputFormat ff_avm2_muxer;
 extern const AVInputFormat  ff_avr_demuxer;
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 271db99b46..aa24ed1a73 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1335,7 +1335,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack 
*track)
 
 avio_wb32(pb, 0);
 ffio_wfourcc(pb, "av1C");
-ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
+ff_isom_write_av1c(pb, track->vos_data, track->vos_len, track->mode != 
MODE_AVIF);
 return update_size(pb, pos);
 }
 
@@ -2037,12 +2037,13 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
 }
 }
 
-/* We should only ever be called by MOV or MP4. */
-av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
+/* We should only ever be called for MOV, MP4 and AVIF. */
+av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
+   track->mode == MODE_AVIF);
 
 avio_wb32(pb, 0); /* size */
 ffio_wfourcc(pb, "colr");
-if (track->mode == MODE_MP4)
+if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
 ffio_wfourcc(pb, "nclx");
 else
 ffio_wfourcc(pb, "nclc");
@@ -2052,7 +2053,7 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
 avio_wb16(pb, track->par->color_primaries);
 avio_wb16(pb, track->par->color_trc);
 avio_wb16(pb, track->par->color_space);
-if (track->mode == MODE_MP4) {
+if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
 int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
 avio_w8(pb, full_range << 7);
 }
@@ -2118,7 +2119,7 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
   || (track->par->width == 1440 && track->par->height == 1080)
   || (track->par->width == 1920 && track->par->height == 1080);
 
-if (track->mode == MODE_MOV &&
+if ((track->mode == MODE_AVIF || track->mode == MODE_MOV) &&
 (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
 av_strlcpy(compressor_name, encoder->value, 32);
 } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
@@ -2139,6 +2140,25 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
 }
 }
 
+static int mov_write_ccst_tag(AVIOContext *pb)
+{
+int64_t pos = avio_tell(pb);
+// Write sane defaults:
+// all_ref_pics_intra = 0 : all samples can use any type of reference.
+// intra_pred_used = 1 : intra prediction may or may not be used.
+// max_ref_per_pic = 15 : reserved value to indicate that any number of
+//reference im

Re: [FFmpeg-devel] [PATCH 3/3] avformat/movenc: Add support for AVIF muxing

2022-05-02 Thread Vignesh Venkatasubramanian
On Mon, May 2, 2022 at 10:28 AM James Zern
 wrote:
>
> On Wed, Apr 13, 2022 at 1:40 PM Vignesh Venkatasubramanian
>  wrote:
> >
> > Add an AVIF muxer by re-using the existing the mov/mp4 muxer.
> >
> > AVIF Specification: https://aomediacodec.github.io/av1-avif
> >
> > Sample usage for still image:
> > ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif
> >
> > Sample usage for animated AVIF image:
> > ffmpeg -i video.mp4 animated.avif
> >
> > We can re-use any of the AV1 encoding options that will make
> > sense for image encoding (like bitrate, tiles, encoding speed,
> > etc).
> >
> > The files generated by this muxer has been verified to be valid
> > AVIF files by the following:
> > 1) Displays on Chrome (both still and animated images).
> > 2) Displays on Firefox (only still images, firefox does not support
> >animated AVIF yet).
> > 3) Verified to be valid by Compliance Warden:
> >https://github.com/gpac/ComplianceWarden
> >
> > Fixes the encoder/muxer part of Trac Ticket #7621
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  configure|   1 +
> >  libavformat/allformats.c |   1 +
> >  libavformat/movenc.c | 337 ---
> >  libavformat/movenc.h |   5 +
> >  4 files changed, 319 insertions(+), 25 deletions(-)
> >
>
> It would be good to have a Changelog entry after the ticket is fixed.
>

Acknowledged. Will do.

> > [...]
> > @@ -2823,7 +2848,10 @@ static int mov_write_hdlr_tag(AVFormatContext *s, 
> > AVIOContext *pb, MOVTrack *tra
> >
> >  if (track) {
> >  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
> > -if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
> > +if (track->mode == MODE_AVIF) {
> > +hdlr_type = "pict";
> > +descr = "ffmpeg";
>
> Should this be PictureHandler or blank? What's written for heic?
>

Hmm, i used the string "ffmpeg" because libavif was writing "libavif"
[1]. But i think it makes sense to be consistent with the other types
here. I have updated the string to be "PictureHandler".

[1] 
https://github.com/AOMediaCodec/libavif/blob/45b6b1b88b54de6031c15b4f9dbee10f86244d1b/src/write.c#L456

> > [...]
> > +static int mov_write_ispe_tag(AVIOContext *pb, MOVMuxContext *mov, 
> > AVFormatContext *s)
> > +{
> > +int64_t pos = avio_tell(pb);
> > +avio_wb32(pb, 0); /* size */
> > +ffio_wfourcc(pb, "ispe");
> > +avio_wb32(pb, 0); /* Version & flags */
> > +avio_wb32(pb, s->streams[0]->codecpar->width); /* image_width */
> > +avio_wb32(pb, s->streams[0]->codecpar->height); /* image_height */
> > +return update_size(pb, pos);
> > +}
> > +
> > +
>
> This extra line could be removed.

Removed.

>
> > [...]
> > +/* AVIF output must have exactly one video stream */
> > +if (mov->mode == MODE_AVIF) {
> > +if (s->nb_streams > 1) {
> > +av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one 
> > stream\n");
> > +return AVERROR(EINVAL);
> > +}
> > +if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) {
> > +av_log(s, AV_LOG_ERROR, "AVIF output requires one video 
> > stream\n");
> > +return AVERROR(EINVAL);
> > +}
> > +}
> > +
> > +
>
> This one too.

Removed.


> ___
> 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".



--
Vignesh
___
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 3/3] avformat/movenc: Add support for AVIF muxing

2022-04-29 Thread Vignesh Venkatasubramanian
On Thu, Apr 21, 2022 at 9:38 AM Vignesh Venkatasubramanian
 wrote:
>
> On Wed, Apr 13, 2022 at 2:35 PM Vignesh Venkatasubramanian
>  wrote:
> >
> > On Wed, Apr 13, 2022 at 2:04 PM Andreas Rheinhardt
> >  wrote:
> > >
> > > Vignesh Venkatasubramanian:
> > > > On Mon, Mar 21, 2022 at 1:46 PM Andreas Rheinhardt
> > > >  wrote:
> > > >>
> > > >> Vignesh Venkatasubramanian:
> > > >>> Add an AVIF muxer by re-using the existing the mov/mp4 muxer.
> > > >>>
> > > >>> AVIF Specifiation: https://aomediacodec.github.io/av1-avif
> > > >>>
> > > >>> Sample usage for still image:
> > > >>> ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif
> > > >>>
> > > >>> Sample usage for animated AVIF image:
> > > >>> ffmpeg -i video.mp4 animated.avif
> > > >>>
> > > >>> We can re-use any of the AV1 encoding options that will make
> > > >>> sense for image encoding (like bitrate, tiles, encoding speed,
> > > >>> etc).
> > > >>>
> > > >>> The files generated by this muxer has been verified to be valid
> > > >>> AVIF files by the following:
> > > >>> 1) Displays on Chrome (both still and animated images).
> > > >>> 2) Displays on Firefox (only still images, firefox does not support
> > > >>>animated AVIF yet).
> > > >>> 3) Verfied to be valid by Compliance Warden:
> > > >>>https://github.com/gpac/ComplianceWarden
> > > >>>
> > > >>> Fixes the encoder/muxer part of Trac Ticket #7621
> > > >>>
> > > >>> Signed-off-by: Vignesh Venkatasubramanian 
> > > >>> ---
> > > >>>  configure|   1 +
> > > >>>  libavformat/allformats.c |   1 +
> > > >>>  libavformat/movenc.c | 341 
> > > >>> ---
> > > >>>  libavformat/movenc.h |   5 +
> > > >>>  4 files changed, 322 insertions(+), 26 deletions(-)
> > > >>>
> > > >>> diff --git a/configure b/configure
> > > >>> index 8c69ab0c86..6d7020e96b 100755
> > > >>> --- a/configure
> > > >>> +++ b/configure
> > > >>> @@ -3390,6 +3390,7 @@ asf_stream_muxer_select="asf_muxer"
> > > >>>  av1_demuxer_select="av1_frame_merge_bsf av1_parser"
> > > >>>  avi_demuxer_select="riffdec exif"
> > > >>>  avi_muxer_select="riffenc"
> > > >>> +avif_muxer_select="mov_muxer"
> > > >>>  caf_demuxer_select="iso_media"
> > > >>>  caf_muxer_select="iso_media"
> > > >>>  dash_muxer_select="mp4_muxer"
> > > >>> diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> > > >>> index d066a7745b..400c17afbd 100644
> > > >>> --- a/libavformat/allformats.c
> > > >>> +++ b/libavformat/allformats.c
> > > >>> @@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
> > > >>>  extern const AVInputFormat  ff_av1_demuxer;
> > > >>>  extern const AVInputFormat  ff_avi_demuxer;
> > > >>>  extern const AVOutputFormat ff_avi_muxer;
> > > >>> +extern const AVOutputFormat ff_avif_muxer;
> > > >>>  extern const AVInputFormat  ff_avisynth_demuxer;
> > > >>>  extern const AVOutputFormat ff_avm2_muxer;
> > > >>>  extern const AVInputFormat  ff_avr_demuxer;
> > > >>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > > >>> index 1a746a67fd..ff41579300 100644
> > > >>> --- a/libavformat/movenc.c
> > > >>> +++ b/libavformat/movenc.c
> > > >>> @@ -1303,7 +1303,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, 
> > > >>> MOVTrack *track)
> > > >>>
> > > >>>  avio_wb32(pb, 0);
> > > >>>  ffio_wfourcc(pb, "av1C");
> > > >>> -ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
> > > >>> +ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 
> > > >>> track->mode != MODE_AVIF);
>

Re: [FFmpeg-devel] [PATCH] avformat/mov: Add support for still image AVIF parsing

2022-04-24 Thread Vignesh Venkatasubramanian
On Thu, Apr 21, 2022 at 9:16 AM Vignesh Venkatasubramanian
 wrote:
>
> On Thu, Apr 21, 2022 at 2:08 AM Gyan Doshi  wrote:
> >
> >
> >
> > On 2022-04-20 09:54 am, Gyan Doshi wrote:
> > >
> > >
> > > On 2022-04-20 02:49 am, Paul B Mahol wrote:
> > >> On Tue, Apr 19, 2022 at 10:57 PM Vignesh Venkatasubramanian <
> > >> vigneshv-at-google@ffmpeg.org> wrote:
> > >>
> > >>> Add support for parsing AVIF still images. This patches supports
> > >>> AVIF still images that have exactly 1 item (i.e.) no alpha channel.
> > >>> Essentially, we will have to parse the "iloc" box and populate
> > >>> the mov index.
> > >>>
> > >>> With this patch, we can decode still AVIF images like so:
> > >>> ffmpeg -i image.avif image.png
> > >>>
> > >>> Partially fixes trac ticket #7621
> > >>>
> > >> LGTM
> > >
> > > Will push tomorrow if no one else has.
> >
> > Can you provide a sample AVIF image and command that this patch allows
> > decoding of?
> >
> > I tried a couple of samples from Netflix[1] and MS[2] and none worked,
> > even with forcing MOV demuxer ("moov atom not found" or "error reading
> > header").
>
> Thanks for verifying. The test files you tried are invalid/not
> supported by this patch. Please see the explanation below.
>
> >
> > [1]: http://download.opencontent.netflix.com/?prefix=AV1/Chimera/AVIF/
>
> These files are not valid AVIF since they don't have the major brand
> set to "mif1" and not "avif". They are also missing a few other
> mandatory boxes. libavif (the reference AVIF library) also is not able
> to parse these files. These files were likely made when the AVIF
> specification was not yet finalized.
>
> $ ./avifdec --info Chimera-AV1-8bit-1280x720-3363kbps-100.avif
> ERROR: Failed to decode image: BMFF parsing failed
> Diagnostics:
>  * [Strict] Item ID 1 of type 'av01' is missing mandatory pixi property
>
> > [2]:
> > https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> >
>
> These files have EXIF metadata and will contain more than one item
> entry in the iloc box. This patch does not support that (however, i
> have a follow-up patch to fix this). The files in this directory
> return AVERROR_PATCHWELCOME as intended.
>

The follow-up patch for supporting the files in the "Microsoft"
subdirectory is here:
http://ffmpeg.org/pipermail/ffmpeg-devel/2022-April/295647.html

> For a set of working AVIF files that are supported by this patch you
> can try the files under "Link-U" and "Netflix" subdirectories of this repo:
>
> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Link-U
>
> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Netflix/avif
>
> The command is as mentioned in the commit message:
> ./ffmpeg -i  output.png
>
> Please let me know if you have more questions. Thank you!
>
>
> > Regards,
> > Gyan
> >
> >
> > ___
> > 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".
>
>
>
> --
> Vignesh



-- 
Vignesh
___
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] avformat/mov: Add support for still image AVIF parsing

2022-04-24 Thread Vignesh Venkatasubramanian
On Sat, Apr 23, 2022 at 1:14 AM Gyan Doshi  wrote:
>
> Removed some trailing whitespace, edited commit msg and pushed as
> 499e245b856733c3bbcd3ba23b406729343ed5fe
>

Thanks for merging!

> Consider adding avif to extensions in the AVInputFormat

Sorry this was an oversight. I thought I had already done this. I have
sent another patch to do this:
http://ffmpeg.org/pipermail/ffmpeg-devel/2022-April/295648.html

>
> Regards,
> Gyan
>
> On 2022-04-23 12:29 am, Vignesh Venkatasubramanian wrote:
> > Add support for parsing AVIF still images. This patches supports
> > AVIF still images that have exactly 1 item (i.e.) no alpha channel.
> > Essentially, we will have to parse the "iloc" box and populate
> > the mov index.
> >
> > With this patch, we can decode still AVIF images like so:
> > ffmpeg -i image.avif image.png
> >
> > Partially fixes trac ticket #7621
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >   libavformat/isom.h |   1 +
> >   libavformat/mov.c  | 141 +
> >   2 files changed, 142 insertions(+)
> >
> > diff --git a/libavformat/isom.h b/libavformat/isom.h
> > index 5caf42b15d..02d681e3ae 100644
> > --- a/libavformat/isom.h
> > +++ b/libavformat/isom.h
> > @@ -315,6 +315,7 @@ typedef struct MOVContext {
> >   int have_read_mfra_size;
> >   uint32_t mfra_size;
> >   uint32_t max_stts_delta;
> > +int is_still_picture_avif;
> >   } MOVContext;
> >
> >   int ff_mp4_read_descr_len(AVIOContext *pb);
> > diff --git a/libavformat/mov.c b/libavformat/mov.c
> > index 6c847de164..39feb9fba6 100644
> > --- a/libavformat/mov.c
> > +++ b/libavformat/mov.c
> > @@ -1136,6 +1136,7 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext 
> > *pb, MOVAtom atom)
> >   c->isom = 1;
> >   av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: 
> > %.4s\n",(char *));
> >   av_dict_set(>fc->metadata, "major_brand", type, 0);
> > +c->is_still_picture_avif = !strncmp(type, "avif", 4);
> >   minor_ver = avio_rb32(pb); /* minor version */
> >   av_dict_set_int(>fc->metadata, "minor_version", minor_ver, 0);
> >
> > @@ -7430,6 +7431,145 @@ static int mov_read_SAND(MOVContext *c, AVIOContext 
> > *pb, MOVAtom atom)
> >   return 0;
> >   }
> >
> > +static int rb_size(AVIOContext *pb, uint64_t* value, int size)
> > +{
> > +if (size == 0)
> > +*value = 0;
> > +else if (size == 1)
> > +*value = avio_r8(pb);
> > +else if (size == 2)
> > +*value = avio_rb16(pb);
> > +else if (size == 4)
> > +*value = avio_rb32(pb);
> > +else if (size == 8)
> > +*value = avio_rb64(pb);
> > +else
> > +return -1;
> > +return size;
> > +}
> > +
> > +static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> > +{
> > +int version, offset_size, length_size, base_offset_size, index_size;
> > +int item_count, extent_count;
> > +uint64_t base_offset, extent_offset, extent_length;
> > +uint8_t value;
> > +AVStream *st;
> > +MOVStreamContext *sc;
> > +
> > +if (!c->is_still_picture_avif) {
> > +// * For non-avif, we simply ignore the iloc box.
> > +// * For animated avif, we don't care about the iloc box as all the
> > +//   necessary information can be found in the moov box.
> > +return 0;
> > +}
> > +
> > +if (c->fc->nb_streams) {
> > +av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
> > +return 0;
> > +}
> > +
> > +st = avformat_new_stream(c->fc, NULL);
> > +if (!st)
> > +return AVERROR(ENOMEM);
> > +st->id = c->fc->nb_streams;
> > +sc = av_mallocz(sizeof(MOVStreamContext));
> > +if (!sc)
> > +return AVERROR(ENOMEM);
> > +
> > +st->priv_data = sc;
> > +st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
> > +st->codecpar->codec_id = AV_CODEC_ID_AV1;
> > +sc->ffindex = st->index;
> > +c->trak_index = st->index;
> > +st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
> > +st->time_base.num = st->time_base.den = 1;
> > +st->nb_frames = 1;
> > +sc->time_scale = 1;
> > +sc = st->priv_data;
> > + 

[FFmpeg-devel] [PATCH] avformat/mov: Add avif to list of supported extensions

2022-04-24 Thread Vignesh Venkatasubramanian
AVIF still and animations are now supported by the MOV parser.
Add the "avif" extension to the list of supported extensions to
AVInputFormat.

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/mov.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 3e83e54a77..26aeeaea0c 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -9036,7 +9036,7 @@ const AVInputFormat ff_mov_demuxer = {
 .long_name  = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
 .priv_class = _class,
 .priv_data_size = sizeof(MOVContext),
-.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
+.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif",
 .flags_internal = FF_FMT_INIT_CLEANUP,
 .read_probe = mov_probe,
 .read_header= mov_read_header,
-- 
2.36.0.rc2.479.g8af0fa9b8e-goog

___
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] avformat/mov: Only read the primary item for AVIF

2022-04-24 Thread Vignesh Venkatasubramanian
Update the still AVIF parser to only read the primary item. With this
patch, AVIF still images with exif/icc/alpha channel will no longer
fail to parse.

For example, this patch enables parsing of files in:
https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft

Partially fixes trac ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |  1 +
 libavformat/mov.c  | 41 +
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index cf36f04d5b..f05c2d9c28 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -317,6 +317,7 @@ typedef struct MOVContext {
 uint32_t mfra_size;
 uint32_t max_stts_delta;
 int is_still_picture_avif;
+int primary_item_id;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 3e83e54a77..6be0f317ca 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7449,6 +7449,13 @@ static int rb_size(AVIOContext *pb, uint64_t* value, int 
size)
 return size;
 }
 
+static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+avio_rb32(pb);  // version & flags.
+c->primary_item_id = avio_rb16(pb);
+return atom.size;
+}
+
 static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
 int version, offset_size, length_size, base_offset_size, index_size;
@@ -7505,34 +7512,25 @@ static int mov_read_iloc(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return AVERROR_PATCHWELCOME;
 }
 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
-if (item_count > 1) {
-// For still AVIF images, we only support one item. Second item will
-// generally be found for AVIF images with alpha channel. We don't
-// support them as of now.
-av_log(c->fc, AV_LOG_ERROR, "iloc: item_count > 1 not supported.\n");
-return AVERROR_PATCHWELCOME;
-}
 
 // Populate the necessary fields used by mov_build_index.
-sc->stsc_count = item_count;
-sc->stsc_data = av_malloc_array(item_count, sizeof(*sc->stsc_data));
+sc->stsc_count = 1;
+sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
 if (!sc->stsc_data)
 return AVERROR(ENOMEM);
 sc->stsc_data[0].first = 1;
 sc->stsc_data[0].count = 1;
 sc->stsc_data[0].id = 1;
-sc->chunk_count = item_count;
-sc->chunk_offsets =
-av_malloc_array(item_count, sizeof(*sc->chunk_offsets));
+sc->chunk_count = 1;
+sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
 if (!sc->chunk_offsets)
 return AVERROR(ENOMEM);
-sc->sample_count = item_count;
-sc->sample_sizes =
-av_malloc_array(item_count, sizeof(*sc->sample_sizes));
+sc->sample_count = 1;
+sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
 if (!sc->sample_sizes)
 return AVERROR(ENOMEM);
-sc->stts_count = item_count;
-sc->stts_data = av_malloc_array(item_count, sizeof(*sc->stts_data));
+sc->stts_count = 1;
+sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
 if (!sc->stts_data)
 return AVERROR(ENOMEM);
 sc->stts_data[0].count = 1;
@@ -7540,7 +7538,7 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 sc->stts_data[0].duration = 0;
 
 for (int i = 0; i < item_count; i++) {
-(version < 2) ? avio_rb16(pb) : avio_rb32(pb);  // item_id;
+int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
 if (version > 0)
 avio_rb16(pb);  // construction_method.
 avio_rb16(pb);  // data_reference_index.
@@ -7556,8 +7554,10 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 if (rb_size(pb, _offset, offset_size) < 0 ||
 rb_size(pb, _length, length_size) < 0)
 return AVERROR_INVALIDDATA;
-sc->sample_sizes[0] = extent_length;
-sc->chunk_offsets[0] = base_offset + extent_offset;
+if (item_id == c->primary_item_id) {
+sc->sample_sizes[0] = extent_length;
+sc->chunk_offsets[0] = base_offset + extent_offset;
+}
 }
 }
 
@@ -7674,6 +7674,7 @@ static const MOVParseTableEntry mov_default_parse_table[] 
= {
 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
 { MKTAG('i','l','o','c'), mov_read_iloc },
+{ MKTAG('p','i','t','m'), mov_read_pitm },
 { 0, NULL }
 };
 
-- 
2.36.0.rc2.479.g8af0fa9b8e-goog

___
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] avformat/mov: Add support for still image AVIF parsing

2022-04-22 Thread Vignesh Venkatasubramanian
Add support for parsing AVIF still images. This patches supports
AVIF still images that have exactly 1 item (i.e.) no alpha channel.
Essentially, we will have to parse the "iloc" box and populate
the mov index.

With this patch, we can decode still AVIF images like so:
ffmpeg -i image.avif image.png

Partially fixes trac ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |   1 +
 libavformat/mov.c  | 141 +
 2 files changed, 142 insertions(+)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 5caf42b15d..02d681e3ae 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -315,6 +315,7 @@ typedef struct MOVContext {
 int have_read_mfra_size;
 uint32_t mfra_size;
 uint32_t max_stts_delta;
+int is_still_picture_avif;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 6c847de164..39feb9fba6 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1136,6 +1136,7 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 c->isom = 1;
 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char 
*));
 av_dict_set(>fc->metadata, "major_brand", type, 0);
+c->is_still_picture_avif = !strncmp(type, "avif", 4);
 minor_ver = avio_rb32(pb); /* minor version */
 av_dict_set_int(>fc->metadata, "minor_version", minor_ver, 0);
 
@@ -7430,6 +7431,145 @@ static int mov_read_SAND(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return 0;
 }
 
+static int rb_size(AVIOContext *pb, uint64_t* value, int size)
+{
+if (size == 0)
+*value = 0;
+else if (size == 1)
+*value = avio_r8(pb);
+else if (size == 2)
+*value = avio_rb16(pb);
+else if (size == 4)
+*value = avio_rb32(pb);
+else if (size == 8)
+*value = avio_rb64(pb);
+else
+return -1;
+return size;
+}
+
+static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+int version, offset_size, length_size, base_offset_size, index_size;
+int item_count, extent_count;
+uint64_t base_offset, extent_offset, extent_length;
+uint8_t value;
+AVStream *st;
+MOVStreamContext *sc;
+
+if (!c->is_still_picture_avif) {
+// * For non-avif, we simply ignore the iloc box.
+// * For animated avif, we don't care about the iloc box as all the
+//   necessary information can be found in the moov box.
+return 0;
+}
+
+if (c->fc->nb_streams) {
+av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
+return 0;
+}
+
+st = avformat_new_stream(c->fc, NULL);
+if (!st)
+return AVERROR(ENOMEM);
+st->id = c->fc->nb_streams;
+sc = av_mallocz(sizeof(MOVStreamContext));
+if (!sc)
+return AVERROR(ENOMEM);
+
+st->priv_data = sc;
+st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+st->codecpar->codec_id = AV_CODEC_ID_AV1;
+sc->ffindex = st->index;
+c->trak_index = st->index;
+st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
+st->time_base.num = st->time_base.den = 1;
+st->nb_frames = 1;
+sc->time_scale = 1;
+sc = st->priv_data;
+sc->pb = c->fc->pb;
+sc->pb_is_copied = 1;
+
+version = avio_r8(pb);
+avio_rb24(pb);  // flags.
+
+value = avio_r8(pb);
+offset_size = (value >> 4) & 0xF;
+length_size = value & 0xF;
+value = avio_r8(pb);
+base_offset_size = (value >> 4) & 0xF;
+index_size = !version ? 0 : (value & 0xF);
+if (index_size) {
+av_log(c->fc, AV_LOG_ERROR, "iloc: index_size != 0 not supported.\n");
+return AVERROR_PATCHWELCOME;
+}
+item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
+if (item_count > 1) {
+// For still AVIF images, we only support one item. Second item will
+// generally be found for AVIF images with alpha channel. We don't
+// support them as of now.
+av_log(c->fc, AV_LOG_ERROR, "iloc: item_count > 1 not supported.\n");
+return AVERROR_PATCHWELCOME;
+}
+
+// Populate the necessary fields used by mov_build_index.
+sc->stsc_count = item_count;
+sc->stsc_data = av_malloc_array(item_count, sizeof(*sc->stsc_data));
+if (!sc->stsc_data)
+return AVERROR(ENOMEM);
+sc->stsc_data[0].first = 1;
+sc->stsc_data[0].count = 1;
+sc->stsc_data[0].id = 1;
+sc->chunk_count = item_count;
+sc->chunk_offsets =
+av_malloc_array(item_count, sizeof(*sc->chunk_offsets));
+if (!sc->chunk_offsets)
+return AVERROR(ENOMEM);
+sc->sample_count = item_count;
+sc->sample_sizes =
+  

Re: [FFmpeg-devel] [PATCH] avformat/mov: Add support for still image AVIF parsing

2022-04-22 Thread Vignesh Venkatasubramanian
On Thu, Apr 21, 2022 at 9:18 PM Gyan Doshi  wrote:
>
>
>
> On 2022-04-21 09:46 pm, Vignesh Venkatasubramanian wrote:
> > On Thu, Apr 21, 2022 at 2:08 AM Gyan Doshi  wrote:
> >>
> >>
> >> On 2022-04-20 09:54 am, Gyan Doshi wrote:
> >>>
> >>> On 2022-04-20 02:49 am, Paul B Mahol wrote:
> >>>> On Tue, Apr 19, 2022 at 10:57 PM Vignesh Venkatasubramanian <
> >>>> vigneshv-at-google@ffmpeg.org> wrote:
> >>>>
> >>>>> Add support for parsing AVIF still images. This patches supports
> >>>>> AVIF still images that have exactly 1 item (i.e.) no alpha channel.
> >>>>> Essentially, we will have to parse the "iloc" box and populate
> >>>>> the mov index.
> >>>>>
> >>>>> With this patch, we can decode still AVIF images like so:
> >>>>> ffmpeg -i image.avif image.png
> >>>>>
> >>>>> Partially fixes trac ticket #7621
> >>>>>
> >>>> LGTM
> >>> Will push tomorrow if no one else has.
> >> Can you provide a sample AVIF image and command that this patch allows
> >> decoding of?
> >>
> >> I tried a couple of samples from Netflix[1] and MS[2] and none worked,
> >> even with forcing MOV demuxer ("moov atom not found" or "error reading
> >> header").
> > Thanks for verifying. The test files you tried are invalid/not
> > supported by this patch. Please see the explanation below.
> >
> >> [1]: http://download.opencontent.netflix.com/?prefix=AV1/Chimera/AVIF/
> > These files are not valid AVIF since they don't have the major brand
> > set to "mif1" and not "avif". They are also missing a few other
> > mandatory boxes. libavif (the reference AVIF library) also is not able
> > to parse these files. These files were likely made when the AVIF
> > specification was not yet finalized.
> >
> > $ ./avifdec --info Chimera-AV1-8bit-1280x720-3363kbps-100.avif
> > ERROR: Failed to decode image: BMFF parsing failed
> > Diagnostics:
> >   * [Strict] Item ID 1 of type 'av01' is missing mandatory pixi property
> >
> >> [2]:
> >> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
> >>
> > These files have EXIF metadata and will contain more than one item
> > entry in the iloc box. This patch does not support that (however, i
> > have a follow-up patch to fix this). The files in this directory
> > return AVERROR_PATCHWELCOME as intended.
> >
> > For a set of working AVIF files that are supported by this patch you
> > can try the files under "Link-U" and "Netflix" subdirectories of this repo:
> >
> > https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Link-U
> >
> > https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Netflix/avif
> Ok, these work.
>
> > The command is as mentioned in the commit message:
> > ./ffmpeg -i  output.png
> >
> > Please let me know if you have more questions. Thank you!
>
> Add informative log msgs in the patchwelcome blocks.
>

Done.

> Are there plans to add support for transforms like cropping, rotation?
>

I have follow-up patches for fixing some of the AVERROR_PATCHWELCOME
cases. I don't have working code for transforms. It is something that
i will look into in the future once the basic AVIF encode/decode
support lands in ffmpeg.

> Regards,
> Gyan
> ___
> 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".



-- 
Vignesh
___
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 3/3] avformat/movenc: Add support for AVIF muxing

2022-04-21 Thread Vignesh Venkatasubramanian
On Wed, Apr 13, 2022 at 2:35 PM Vignesh Venkatasubramanian
 wrote:
>
> On Wed, Apr 13, 2022 at 2:04 PM Andreas Rheinhardt
>  wrote:
> >
> > Vignesh Venkatasubramanian:
> > > On Mon, Mar 21, 2022 at 1:46 PM Andreas Rheinhardt
> > >  wrote:
> > >>
> > >> Vignesh Venkatasubramanian:
> > >>> Add an AVIF muxer by re-using the existing the mov/mp4 muxer.
> > >>>
> > >>> AVIF Specifiation: https://aomediacodec.github.io/av1-avif
> > >>>
> > >>> Sample usage for still image:
> > >>> ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif
> > >>>
> > >>> Sample usage for animated AVIF image:
> > >>> ffmpeg -i video.mp4 animated.avif
> > >>>
> > >>> We can re-use any of the AV1 encoding options that will make
> > >>> sense for image encoding (like bitrate, tiles, encoding speed,
> > >>> etc).
> > >>>
> > >>> The files generated by this muxer has been verified to be valid
> > >>> AVIF files by the following:
> > >>> 1) Displays on Chrome (both still and animated images).
> > >>> 2) Displays on Firefox (only still images, firefox does not support
> > >>>animated AVIF yet).
> > >>> 3) Verfied to be valid by Compliance Warden:
> > >>>https://github.com/gpac/ComplianceWarden
> > >>>
> > >>> Fixes the encoder/muxer part of Trac Ticket #7621
> > >>>
> > >>> Signed-off-by: Vignesh Venkatasubramanian 
> > >>> ---
> > >>>  configure|   1 +
> > >>>  libavformat/allformats.c |   1 +
> > >>>  libavformat/movenc.c | 341 ---
> > >>>  libavformat/movenc.h |   5 +
> > >>>  4 files changed, 322 insertions(+), 26 deletions(-)
> > >>>
> > >>> diff --git a/configure b/configure
> > >>> index 8c69ab0c86..6d7020e96b 100755
> > >>> --- a/configure
> > >>> +++ b/configure
> > >>> @@ -3390,6 +3390,7 @@ asf_stream_muxer_select="asf_muxer"
> > >>>  av1_demuxer_select="av1_frame_merge_bsf av1_parser"
> > >>>  avi_demuxer_select="riffdec exif"
> > >>>  avi_muxer_select="riffenc"
> > >>> +avif_muxer_select="mov_muxer"
> > >>>  caf_demuxer_select="iso_media"
> > >>>  caf_muxer_select="iso_media"
> > >>>  dash_muxer_select="mp4_muxer"
> > >>> diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> > >>> index d066a7745b..400c17afbd 100644
> > >>> --- a/libavformat/allformats.c
> > >>> +++ b/libavformat/allformats.c
> > >>> @@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
> > >>>  extern const AVInputFormat  ff_av1_demuxer;
> > >>>  extern const AVInputFormat  ff_avi_demuxer;
> > >>>  extern const AVOutputFormat ff_avi_muxer;
> > >>> +extern const AVOutputFormat ff_avif_muxer;
> > >>>  extern const AVInputFormat  ff_avisynth_demuxer;
> > >>>  extern const AVOutputFormat ff_avm2_muxer;
> > >>>  extern const AVInputFormat  ff_avr_demuxer;
> > >>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > >>> index 1a746a67fd..ff41579300 100644
> > >>> --- a/libavformat/movenc.c
> > >>> +++ b/libavformat/movenc.c
> > >>> @@ -1303,7 +1303,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, 
> > >>> MOVTrack *track)
> > >>>
> > >>>  avio_wb32(pb, 0);
> > >>>  ffio_wfourcc(pb, "av1C");
> > >>> -ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
> > >>> +ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 
> > >>> track->mode != MODE_AVIF);
> > >>>  return update_size(pb, pos);
> > >>>  }
> > >>>
> > >>> @@ -2004,12 +2004,13 @@ static int mov_write_colr_tag(AVIOContext *pb, 
> > >>> MOVTrack *track, int prefer_icc)
> > >>>  }
> > >>>  }
> > >>>
> > >>> -/* We should only ever be called by MOV or MP4. */
> > >>> -av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
> >

Re: [FFmpeg-devel] [PATCH] avformat/mov: Add support for still image AVIF parsing

2022-04-21 Thread Vignesh Venkatasubramanian
On Thu, Apr 21, 2022 at 2:08 AM Gyan Doshi  wrote:
>
>
>
> On 2022-04-20 09:54 am, Gyan Doshi wrote:
> >
> >
> > On 2022-04-20 02:49 am, Paul B Mahol wrote:
> >> On Tue, Apr 19, 2022 at 10:57 PM Vignesh Venkatasubramanian <
> >> vigneshv-at-google@ffmpeg.org> wrote:
> >>
> >>> Add support for parsing AVIF still images. This patches supports
> >>> AVIF still images that have exactly 1 item (i.e.) no alpha channel.
> >>> Essentially, we will have to parse the "iloc" box and populate
> >>> the mov index.
> >>>
> >>> With this patch, we can decode still AVIF images like so:
> >>> ffmpeg -i image.avif image.png
> >>>
> >>> Partially fixes trac ticket #7621
> >>>
> >> LGTM
> >
> > Will push tomorrow if no one else has.
>
> Can you provide a sample AVIF image and command that this patch allows
> decoding of?
>
> I tried a couple of samples from Netflix[1] and MS[2] and none worked,
> even with forcing MOV demuxer ("moov atom not found" or "error reading
> header").

Thanks for verifying. The test files you tried are invalid/not
supported by this patch. Please see the explanation below.

>
> [1]: http://download.opencontent.netflix.com/?prefix=AV1/Chimera/AVIF/

These files are not valid AVIF since they don't have the major brand
set to "mif1" and not "avif". They are also missing a few other
mandatory boxes. libavif (the reference AVIF library) also is not able
to parse these files. These files were likely made when the AVIF
specification was not yet finalized.

$ ./avifdec --info Chimera-AV1-8bit-1280x720-3363kbps-100.avif
ERROR: Failed to decode image: BMFF parsing failed
Diagnostics:
 * [Strict] Item ID 1 of type 'av01' is missing mandatory pixi property

> [2]:
> https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Microsoft
>

These files have EXIF metadata and will contain more than one item
entry in the iloc box. This patch does not support that (however, i
have a follow-up patch to fix this). The files in this directory
return AVERROR_PATCHWELCOME as intended.

For a set of working AVIF files that are supported by this patch you
can try the files under "Link-U" and "Netflix" subdirectories of this repo:

https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Link-U

https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Netflix/avif

The command is as mentioned in the commit message:
./ffmpeg -i  output.png

Please let me know if you have more questions. Thank you!


> Regards,
> Gyan
>
>
> ___
> 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".



--
Vignesh
___
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] avformat/mov: Add support for still image AVIF parsing

2022-04-19 Thread Vignesh Venkatasubramanian
Add support for parsing AVIF still images. This patches supports
AVIF still images that have exactly 1 item (i.e.) no alpha channel.
Essentially, we will have to parse the "iloc" box and populate
the mov index.

With this patch, we can decode still AVIF images like so:
ffmpeg -i image.avif image.png

Partially fixes trac ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 libavformat/isom.h |   1 +
 libavformat/mov.c  | 137 +
 2 files changed, 138 insertions(+)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 5caf42b15d..02d681e3ae 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -315,6 +315,7 @@ typedef struct MOVContext {
 int have_read_mfra_size;
 uint32_t mfra_size;
 uint32_t max_stts_delta;
+int is_still_picture_avif;
 } MOVContext;
 
 int ff_mp4_read_descr_len(AVIOContext *pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 6c847de164..e925690584 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1136,6 +1136,7 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 c->isom = 1;
 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char 
*));
 av_dict_set(>fc->metadata, "major_brand", type, 0);
+c->is_still_picture_avif = !strncmp(type, "avif", 4);
 minor_ver = avio_rb32(pb); /* minor version */
 av_dict_set_int(>fc->metadata, "minor_version", minor_ver, 0);
 
@@ -7430,6 +7431,141 @@ static int mov_read_SAND(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return 0;
 }
 
+static int rb_size(AVIOContext *pb, uint64_t* value, int size)
+{
+if (size == 0)
+*value = 0;
+else if (size == 1)
+*value = avio_r8(pb);
+else if (size == 2)
+*value = avio_rb16(pb);
+else if (size == 4)
+*value = avio_rb32(pb);
+else if (size == 8)
+*value = avio_rb64(pb);
+else
+return -1;
+return size;
+}
+
+static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+int version, offset_size, length_size, base_offset_size, index_size;
+int item_count, extent_count;
+uint64_t base_offset, extent_offset, extent_length;
+uint8_t value;
+AVStream *st;
+MOVStreamContext *sc;
+
+if (!c->is_still_picture_avif) {
+// * For non-avif, we simply ignore the iloc box.
+// * For animated avif, we don't care about the iloc box as all the
+//   necessary information can be found in the moov box.
+return 0;
+}
+
+if (c->fc->nb_streams) {
+av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
+return 0;
+}
+
+st = avformat_new_stream(c->fc, NULL);
+if (!st)
+return AVERROR(ENOMEM);
+st->id = c->fc->nb_streams;
+sc = av_mallocz(sizeof(MOVStreamContext));
+if (!sc)
+return AVERROR(ENOMEM);
+
+st->priv_data = sc;
+st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+st->codecpar->codec_id = AV_CODEC_ID_AV1;
+sc->ffindex = st->index;
+c->trak_index = st->index;
+st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
+st->time_base.num = st->time_base.den = 1;
+st->nb_frames = 1;
+sc->time_scale = 1;
+sc = st->priv_data;
+sc->pb = c->fc->pb;
+sc->pb_is_copied = 1;
+
+version = avio_r8(pb);
+avio_rb24(pb);  // flags.
+
+value = avio_r8(pb);
+offset_size = (value >> 4) & 0xF;
+length_size = value & 0xF;
+value = avio_r8(pb);
+base_offset_size = (value >> 4) & 0xF;
+index_size = !version ? 0 : (value & 0xF);
+if (index_size)
+return AVERROR_PATCHWELCOME;
+item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
+if (item_count > 1) {
+// For still AVIF images, we only support one item. Second item will
+// generally be found for AVIF images with alpha channel. We don't
+// support them as of now.
+return AVERROR_PATCHWELCOME;
+}
+
+// Populate the necessary fields used by mov_build_index.
+sc->stsc_count = item_count;
+sc->stsc_data = av_malloc_array(item_count, sizeof(*sc->stsc_data));
+if (!sc->stsc_data)
+return AVERROR(ENOMEM);
+sc->stsc_data[0].first = 1;
+sc->stsc_data[0].count = 1;
+sc->stsc_data[0].id = 1;
+sc->chunk_count = item_count;
+sc->chunk_offsets =
+av_malloc_array(item_count, sizeof(*sc->chunk_offsets));
+if (!sc->chunk_offsets)
+return AVERROR(ENOMEM);
+sc->sample_count = item_count;
+sc->sample_sizes =
+av_malloc_array(item_count, sizeof(*sc->sample_sizes));
+if (!sc->sample_sizes)
+return AVERROR(ENOMEM);
+sc->stts_count = item_count;
+sc->stts_data = av_malloc_array(i

Re: [FFmpeg-devel] [PATCH] avformat/mov: Add support for still image AVIF parsing

2022-04-19 Thread Vignesh Venkatasubramanian
On Tue, Apr 19, 2022 at 1:18 PM Paul B Mahol  wrote:
>
>
>
> On Mon, Mar 28, 2022 at 9:12 PM Vignesh Venkatasubramanian 
>  wrote:
>>
>> Add support for parsing AVIF still images. This patches supports
>> AVIF still images that have exactly 1 item (i.e.) no alpha channel.
>> Essentially, we will have to parse the "iloc" box and populate
>> the mov index.
>>
>> With this patch, we can decode still AVIF images like so:
>> ffmpeg -i image.avif image.png
>>
>> Partially fixes trac ticket #7621
>>
>> Signed-off-by: Vignesh Venkatasubramanian 
>> ---
>>  libavformat/isom.h |   1 +
>>  libavformat/mov.c  | 148 +
>>  2 files changed, 149 insertions(+)
>>
>> diff --git a/libavformat/isom.h b/libavformat/isom.h
>> index 5caf42b15d..02d681e3ae 100644
>> --- a/libavformat/isom.h
>> +++ b/libavformat/isom.h
>> @@ -315,6 +315,7 @@ typedef struct MOVContext {
>>  int have_read_mfra_size;
>>  uint32_t mfra_size;
>>  uint32_t max_stts_delta;
>> +int is_still_picture_avif;
>>  } MOVContext;
>>
>>  int ff_mp4_read_descr_len(AVIOContext *pb);
>> diff --git a/libavformat/mov.c b/libavformat/mov.c
>> index 6c847de164..fb6d071b95 100644
>> --- a/libavformat/mov.c
>> +++ b/libavformat/mov.c
>> @@ -1136,6 +1136,7 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext 
>> *pb, MOVAtom atom)
>>  c->isom = 1;
>>  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char 
>> *));
>>  av_dict_set(>fc->metadata, "major_brand", type, 0);
>> +c->is_still_picture_avif = !strncmp(type, "avif", 4);
>>  minor_ver = avio_rb32(pb); /* minor version */
>>  av_dict_set_int(>fc->metadata, "minor_version", minor_ver, 0);
>>
>> @@ -7430,6 +7431,152 @@ static int mov_read_SAND(MOVContext *c, AVIOContext 
>> *pb, MOVAtom atom)
>>  return 0;
>>  }
>>
>> +static int rb_size(AVIOContext *pb, uint64_t* value, int size)
>> +{
>> +if (size == 0) {
>> +*value = 0;
>> +} else if (size == 1) {
>> +*value = avio_r8(pb);
>> +} else if (size == 2) {
>> +*value = avio_rb16(pb);
>> +} else if (size == 4) {
>> +*value = avio_rb32(pb);
>> +} else if (size == 8) {
>> +*value = avio_rb64(pb);
>> +} else {
>> +return -1;
>> +}
>> +return size;
>> +}
>> +
>> +static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>> +{
>> +int version, offset_size, length_size, base_offset_size, index_size;
>> +int item_count, extent_count;
>> +uint64_t base_offset, extent_offset, extent_length;
>> +uint8_t value;
>> +AVStream *st;
>> +MOVStreamContext *sc;
>> +
>> +if (!c->is_still_picture_avif) {
>> +// * For non-avif, we simply ignore the iloc box.
>> +// * For animated avif, we don't care about the iloc box as all the
>> +//   necessary information can be found in the moov box.
>> +return 0;
>> +}
>> +
>> +if (c->fc->nb_streams) {
>> +av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
>> +return 0;
>> +}
>> +
>> +st = avformat_new_stream(c->fc, NULL);
>> +if (!st) {
>> +return AVERROR(ENOMEM);
>> +}
>
>
> Here  and everywhere else, remove excessive {/}, they are not needed for one 
> liners.
>

Done.

>> +st->id = c->fc->nb_streams;
>> +sc = av_mallocz(sizeof(MOVStreamContext));
>> +if (!sc) {
>> +return AVERROR(ENOMEM);
>> +}
>> +
>> +st->priv_data = sc;
>> +st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>> +st->codecpar->codec_id = AV_CODEC_ID_AV1;
>> +sc->ffindex = st->index;
>> +c->trak_index = st->index;
>> +st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
>> +st->time_base.num = st->time_base.den = 1;
>> +st->nb_frames = 1;
>> +sc->time_scale = 1;
>> +sc = st->priv_data;
>> +sc->pb = c->fc->pb;
>> +sc->pb_is_copied = 1;
>> +
>> +version = avio_r8(pb);
>> +avio_rb24(pb);  // flags.
>> +
>> +value = avio_r8(pb);
>> +offset_size = (value >> 4) & 0xF;
>> +length_size = value & 0xF;
>>

Re: [FFmpeg-devel] [PATCH] avformat/mov: Add support for still image AVIF parsing

2022-04-18 Thread Vignesh Venkatasubramanian
On Mon, Mar 28, 2022 at 12:11 PM Vignesh Venkatasubramanian
 wrote:
>
> Add support for parsing AVIF still images. This patches supports
> AVIF still images that have exactly 1 item (i.e.) no alpha channel.
> Essentially, we will have to parse the "iloc" box and populate
> the mov index.
>
> With this patch, we can decode still AVIF images like so:
> ffmpeg -i image.avif image.png
>
> Partially fixes trac ticket #7621
>
> Signed-off-by: Vignesh Venkatasubramanian 
> ---
>  libavformat/isom.h |   1 +
>  libavformat/mov.c  | 148 +
>  2 files changed, 149 insertions(+)
>
> diff --git a/libavformat/isom.h b/libavformat/isom.h
> index 5caf42b15d..02d681e3ae 100644
> --- a/libavformat/isom.h
> +++ b/libavformat/isom.h
> @@ -315,6 +315,7 @@ typedef struct MOVContext {
>  int have_read_mfra_size;
>  uint32_t mfra_size;
>  uint32_t max_stts_delta;
> +int is_still_picture_avif;
>  } MOVContext;
>
>  int ff_mp4_read_descr_len(AVIOContext *pb);
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index 6c847de164..fb6d071b95 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -1136,6 +1136,7 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext 
> *pb, MOVAtom atom)
>  c->isom = 1;
>  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char 
> *));
>  av_dict_set(>fc->metadata, "major_brand", type, 0);
> +c->is_still_picture_avif = !strncmp(type, "avif", 4);
>  minor_ver = avio_rb32(pb); /* minor version */
>  av_dict_set_int(>fc->metadata, "minor_version", minor_ver, 0);
>
> @@ -7430,6 +7431,152 @@ static int mov_read_SAND(MOVContext *c, AVIOContext 
> *pb, MOVAtom atom)
>  return 0;
>  }
>
> +static int rb_size(AVIOContext *pb, uint64_t* value, int size)
> +{
> +if (size == 0) {
> +*value = 0;
> +} else if (size == 1) {
> +*value = avio_r8(pb);
> +} else if (size == 2) {
> +*value = avio_rb16(pb);
> +} else if (size == 4) {
> +*value = avio_rb32(pb);
> +} else if (size == 8) {
> +*value = avio_rb64(pb);
> +} else {
> +return -1;
> +}
> +return size;
> +}
> +
> +static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> +{
> +int version, offset_size, length_size, base_offset_size, index_size;
> +int item_count, extent_count;
> +uint64_t base_offset, extent_offset, extent_length;
> +uint8_t value;
> +AVStream *st;
> +MOVStreamContext *sc;
> +
> +if (!c->is_still_picture_avif) {
> +// * For non-avif, we simply ignore the iloc box.
> +// * For animated avif, we don't care about the iloc box as all the
> +//   necessary information can be found in the moov box.
> +return 0;
> +}
> +
> +if (c->fc->nb_streams) {
> +av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
> +return 0;
> +}
> +
> +st = avformat_new_stream(c->fc, NULL);
> +if (!st) {
> +return AVERROR(ENOMEM);
> +}
> +st->id = c->fc->nb_streams;
> +sc = av_mallocz(sizeof(MOVStreamContext));
> +if (!sc) {
> +return AVERROR(ENOMEM);
> +}
> +
> +st->priv_data = sc;
> +st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
> +st->codecpar->codec_id = AV_CODEC_ID_AV1;
> +sc->ffindex = st->index;
> +c->trak_index = st->index;
> +st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
> +st->time_base.num = st->time_base.den = 1;
> +st->nb_frames = 1;
> +sc->time_scale = 1;
> +sc = st->priv_data;
> +sc->pb = c->fc->pb;
> +sc->pb_is_copied = 1;
> +
> +version = avio_r8(pb);
> +avio_rb24(pb);  // flags.
> +
> +value = avio_r8(pb);
> +offset_size = (value >> 4) & 0xF;
> +length_size = value & 0xF;
> +value = avio_r8(pb);
> +base_offset_size = (value >> 4) & 0xF;
> +index_size = !version ? 0 : (value & 0xF);
> +if (index_size) {
> +return AVERROR_PATCHWELCOME;
> +}
> +item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
> +if (item_count > 1) {
> +// For still AVIF images, we only support one item. Second item will
> +// generally be found for AVIF images with alpha channel. We don't
> +// support them as of now.
> +return AVERROR_PATCHWELCOME;
> +}
> +
> +// Populate the necessary fields used by mov_build_i

Re: [FFmpeg-devel] [PATCH 3/3] avformat/movenc: Add support for AVIF muxing

2022-04-13 Thread Vignesh Venkatasubramanian
On Wed, Apr 13, 2022 at 2:04 PM Andreas Rheinhardt
 wrote:
>
> Vignesh Venkatasubramanian:
> > On Mon, Mar 21, 2022 at 1:46 PM Andreas Rheinhardt
> >  wrote:
> >>
> >> Vignesh Venkatasubramanian:
> >>> Add an AVIF muxer by re-using the existing the mov/mp4 muxer.
> >>>
> >>> AVIF Specifiation: https://aomediacodec.github.io/av1-avif
> >>>
> >>> Sample usage for still image:
> >>> ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif
> >>>
> >>> Sample usage for animated AVIF image:
> >>> ffmpeg -i video.mp4 animated.avif
> >>>
> >>> We can re-use any of the AV1 encoding options that will make
> >>> sense for image encoding (like bitrate, tiles, encoding speed,
> >>> etc).
> >>>
> >>> The files generated by this muxer has been verified to be valid
> >>> AVIF files by the following:
> >>> 1) Displays on Chrome (both still and animated images).
> >>> 2) Displays on Firefox (only still images, firefox does not support
> >>>animated AVIF yet).
> >>> 3) Verfied to be valid by Compliance Warden:
> >>>https://github.com/gpac/ComplianceWarden
> >>>
> >>> Fixes the encoder/muxer part of Trac Ticket #7621
> >>>
> >>> Signed-off-by: Vignesh Venkatasubramanian 
> >>> ---
> >>>  configure|   1 +
> >>>  libavformat/allformats.c |   1 +
> >>>  libavformat/movenc.c | 341 ---
> >>>  libavformat/movenc.h |   5 +
> >>>  4 files changed, 322 insertions(+), 26 deletions(-)
> >>>
> >>> diff --git a/configure b/configure
> >>> index 8c69ab0c86..6d7020e96b 100755
> >>> --- a/configure
> >>> +++ b/configure
> >>> @@ -3390,6 +3390,7 @@ asf_stream_muxer_select="asf_muxer"
> >>>  av1_demuxer_select="av1_frame_merge_bsf av1_parser"
> >>>  avi_demuxer_select="riffdec exif"
> >>>  avi_muxer_select="riffenc"
> >>> +avif_muxer_select="mov_muxer"
> >>>  caf_demuxer_select="iso_media"
> >>>  caf_muxer_select="iso_media"
> >>>  dash_muxer_select="mp4_muxer"
> >>> diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> >>> index d066a7745b..400c17afbd 100644
> >>> --- a/libavformat/allformats.c
> >>> +++ b/libavformat/allformats.c
> >>> @@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
> >>>  extern const AVInputFormat  ff_av1_demuxer;
> >>>  extern const AVInputFormat  ff_avi_demuxer;
> >>>  extern const AVOutputFormat ff_avi_muxer;
> >>> +extern const AVOutputFormat ff_avif_muxer;
> >>>  extern const AVInputFormat  ff_avisynth_demuxer;
> >>>  extern const AVOutputFormat ff_avm2_muxer;
> >>>  extern const AVInputFormat  ff_avr_demuxer;
> >>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> >>> index 1a746a67fd..ff41579300 100644
> >>> --- a/libavformat/movenc.c
> >>> +++ b/libavformat/movenc.c
> >>> @@ -1303,7 +1303,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, 
> >>> MOVTrack *track)
> >>>
> >>>  avio_wb32(pb, 0);
> >>>  ffio_wfourcc(pb, "av1C");
> >>> -ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
> >>> +ff_isom_write_av1c(pb, track->vos_data, track->vos_len, track->mode 
> >>> != MODE_AVIF);
> >>>  return update_size(pb, pos);
> >>>  }
> >>>
> >>> @@ -2004,12 +2004,13 @@ static int mov_write_colr_tag(AVIOContext *pb, 
> >>> MOVTrack *track, int prefer_icc)
> >>>  }
> >>>  }
> >>>
> >>> -/* We should only ever be called by MOV or MP4. */
> >>> -av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
> >>> +/* We should only ever be called for MOV, MP4 and AVIF. */
> >>> +av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
> >>> +   track->mode == MODE_AVIF);
> >>>
> >>>  avio_wb32(pb, 0); /* size */
> >>>  ffio_wfourcc(pb, "colr");
> >>> -if (track->mode == MODE_MP4)
> >>> +if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)

Re: [FFmpeg-devel] [PATCH 3/3] avformat/movenc: Add support for AVIF muxing

2022-04-13 Thread Vignesh Venkatasubramanian
On Wed, Apr 13, 2022 at 2:01 PM Andreas Rheinhardt
 wrote:
>
> Vignesh Venkatasubramanian:
> > Add an AVIF muxer by re-using the existing the mov/mp4 muxer.
> >
> > AVIF Specification: https://aomediacodec.github.io/av1-avif
> >
> > Sample usage for still image:
> > ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif
> >
> > Sample usage for animated AVIF image:
> > ffmpeg -i video.mp4 animated.avif
> >
> > We can re-use any of the AV1 encoding options that will make
> > sense for image encoding (like bitrate, tiles, encoding speed,
> > etc).
> >
> > The files generated by this muxer has been verified to be valid
> > AVIF files by the following:
> > 1) Displays on Chrome (both still and animated images).
> > 2) Displays on Firefox (only still images, firefox does not support
> >animated AVIF yet).
> > 3) Verified to be valid by Compliance Warden:
> >    https://github.com/gpac/ComplianceWarden
> >
> > Fixes the encoder/muxer part of Trac Ticket #7621
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  configure|   1 +
> >  libavformat/allformats.c |   1 +
> >  libavformat/movenc.c | 337 ---
> >  libavformat/movenc.h |   5 +
> >  4 files changed, 319 insertions(+), 25 deletions(-)
> >
> > +static int avif_write_trailer(AVFormatContext *s)
> > +{
> > +AVIOContext *pb = s->pb;
> > +MOVMuxContext *mov = s->priv_data;
> > +int64_t pos_backup, mdat_pos;
> > +uint8_t *buf;
> > +int buf_size, moov_size;
> > +
> > +if (mov->moov_written) return 0;
>
> Can it happen that moov_written is true? What happens if it is? (I
> presume the file to be invalid.)
>

This is more of a sanity check. I don't think this will ever happen
(as long as write_trailer is not called more than once). If you
prefer, i can remove it.

> > +
> > +mov->is_animated_avif = s->streams[0]->nb_frames > 1;
> > +mov_write_identification(pb, s);
> > +mov_write_meta_tag(pb, mov, s);
> > +
> > +moov_size = get_moov_size(s);
> > +mov->tracks[0].data_offset = avio_tell(pb) + moov_size + 8;
> > +
> > +if (mov->is_animated_avif) {
> > +int ret;
> > +if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
> > +return ret;
> > +}
> > +
> > +buf_size = avio_get_dyn_buf(mov->mdat_buf, );
> > +avio_wb32(pb, buf_size + 8);
> > +ffio_wfourcc(pb, "mdat");
> > +mdat_pos = avio_tell(pb);
> > +
> > +if (mdat_pos != (uint32_t)mdat_pos) {
> > +av_log(s, AV_LOG_ERROR, "mdat offset does not fit in 32 bits\n");
> > +return AVERROR_INVALIDDATA;
> > +}
> > +
> > +avio_write(pb, buf, buf_size);
> > +
> > +// write extent offset.
> > +pos_backup = avio_tell(pb);
> > +avio_seek(pb, mov->avif_extent_pos, SEEK_SET);
> > +avio_wb32(pb, mdat_pos); /* rewrite offset */
> > +avio_seek(pb, pos_backup, SEEK_SET);
> > +
> > +return 0;
> > +}
> > +
>
> - 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".



-- 
Vignesh
___
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 3/3] avformat/movenc: Add support for AVIF muxing

2022-04-13 Thread Vignesh Venkatasubramanian
On Wed, Apr 13, 2022 at 10:22 AM James Zern  wrote:
>
> On Mon, Mar 28, 2022 at 1:49 PM Vignesh Venkatasubramanian
>  wrote:
> >
> > Add an AVIF muxer by re-using the existing the mov/mp4 muxer.
> >
> > AVIF Specifiation: https://aomediacodec.github.io/av1-avif
> >
>
> Specification
>

Fixed.

> > Sample usage for still image:
> > ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif
> >
> > Sample usage for animated AVIF image:
> > ffmpeg -i video.mp4 animated.avif
> >
> > We can re-use any of the AV1 encoding options that will make
> > sense for image encoding (like bitrate, tiles, encoding speed,
> > etc).
> >
> > The files generated by this muxer has been verified to be valid
> > AVIF files by the following:
> > 1) Displays on Chrome (both still and animated images).
> > 2) Displays on Firefox (only still images, firefox does not support
> >animated AVIF yet).
> > 3) Verfied to be valid by Compliance Warden:
>
> Verified
>

Fixed.

> >https://github.com/gpac/ComplianceWarden
> >
> > Fixes the encoder/muxer part of Trac Ticket #7621
> >
> > Signed-off-by: Vignesh Venkatasubramanian 
> > ---
> >  configure|   1 +
> >  libavformat/allformats.c |   1 +
> >  libavformat/movenc.c | 337 ---
> >  libavformat/movenc.h |   5 +
> >  4 files changed, 319 insertions(+), 25 deletions(-)
> >
>
> There might be some other issues, you can try tools/patcheck.
>

Thanks, i ran this and only found a couple of other "} before else-if"
warnings. In those cases, i was just being consistent with the code
around it.

> > [...]
> > @@ -5068,6 +5231,31 @@ static int mov_write_ftyp_tag(AVIOContext *pb, 
> > AVFormatContext *s)
> >  // compatible brand a second time.
> >  if (mov->mode == MODE_ISM) {
> >  ffio_wfourcc(pb, "piff");
> > +} else if (mov->mode == MODE_AVIF) {
> > +const AVPixFmtDescriptor *pix_fmt_desc =
> > +av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
> > +const int depth = pix_fmt_desc->comp[0].depth;
> > +if (mov->is_animated_avif) {
> > +// For animated AVIF, major brand is "avis". Add "avif" as a
> > +// compatible brand.
> > +ffio_wfourcc(pb, "avif");
> > +ffio_wfourcc(pb, "msf1");
> > +ffio_wfourcc(pb, "iso8");
> > +}
> > +ffio_wfourcc(pb, "mif1");
> > +ffio_wfourcc(pb, "miaf");
> > +if (depth == 8 || depth == 10) {
> > +// MA1B and MA1A brands are based on AV1 profile. Short hand 
> > for
> > +// computing that is based on chroma subsampling type. 420 
> > chroma
> > +// subsampling is MA1B.  444 chroma subsampling is MA1A.
> > +if (pix_fmt_desc->log2_chroma_w == 0 && 
> > pix_fmt_desc->log2_chroma_h == 0) {
>
> !... is the preferred style.

Done.

>
> > @@ -6773,12 +6983,13 @@ static int mov_init(AVFormatContext *s)
> >  pix_fmt == AV_PIX_FMT_MONOWHITE ||
> >  pix_fmt == AV_PIX_FMT_MONOBLACK;
> >  }
> > -if (track->par->codec_id == AV_CODEC_ID_VP9 ||
> > -track->par->codec_id == AV_CODEC_ID_AV1) {
> > -if (track->mode != MODE_MP4) {
> > -av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", 
> > avcodec_get_name(track->par->codec_id));
> > -return AVERROR(EINVAL);
> > -}
> > +if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != 
> > MODE_MP4) {
> > +av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", 
> > avcodec_get_name(track->par->codec_id));
> > +   return AVERROR(EINVAL);
>
> This is indented with tabs.

Oops, fixed.

-- 
Vignesh
___
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/movenc: Add support for AVIF muxing

2022-04-13 Thread Vignesh Venkatasubramanian
Add an AVIF muxer by re-using the existing the mov/mp4 muxer.

AVIF Specification: https://aomediacodec.github.io/av1-avif

Sample usage for still image:
ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif

Sample usage for animated AVIF image:
ffmpeg -i video.mp4 animated.avif

We can re-use any of the AV1 encoding options that will make
sense for image encoding (like bitrate, tiles, encoding speed,
etc).

The files generated by this muxer has been verified to be valid
AVIF files by the following:
1) Displays on Chrome (both still and animated images).
2) Displays on Firefox (only still images, firefox does not support
   animated AVIF yet).
3) Verified to be valid by Compliance Warden:
   https://github.com/gpac/ComplianceWarden

Fixes the encoder/muxer part of Trac Ticket #7621

Signed-off-by: Vignesh Venkatasubramanian 
---
 configure|   1 +
 libavformat/allformats.c |   1 +
 libavformat/movenc.c | 337 ---
 libavformat/movenc.h |   5 +
 4 files changed, 319 insertions(+), 25 deletions(-)

diff --git a/configure b/configure
index 358a614854..ef9d6cdc92 100755
--- a/configure
+++ b/configure
@@ -3398,6 +3398,7 @@ asf_stream_muxer_select="asf_muxer"
 av1_demuxer_select="av1_frame_merge_bsf av1_parser"
 avi_demuxer_select="riffdec exif"
 avi_muxer_select="riffenc"
+avif_muxer_select="mov_muxer"
 caf_demuxer_select="iso_media"
 caf_muxer_select="iso_media"
 dash_muxer_select="mp4_muxer"
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 7c1d0ac38f..320ddf9898 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
 extern const AVInputFormat  ff_av1_demuxer;
 extern const AVInputFormat  ff_avi_demuxer;
 extern const AVOutputFormat ff_avi_muxer;
+extern const AVOutputFormat ff_avif_muxer;
 extern const AVInputFormat  ff_avisynth_demuxer;
 extern const AVOutputFormat ff_avm2_muxer;
 extern const AVInputFormat  ff_avr_demuxer;
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 4202d0b79a..302ee1fda5 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1334,7 +1334,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack 
*track)
 
 avio_wb32(pb, 0);
 ffio_wfourcc(pb, "av1C");
-ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
+ff_isom_write_av1c(pb, track->vos_data, track->vos_len, track->mode != 
MODE_AVIF);
 return update_size(pb, pos);
 }
 
@@ -2035,12 +2035,13 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
 }
 }
 
-/* We should only ever be called by MOV or MP4. */
-av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
+/* We should only ever be called for MOV, MP4 and AVIF. */
+av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
+   track->mode == MODE_AVIF);
 
 avio_wb32(pb, 0); /* size */
 ffio_wfourcc(pb, "colr");
-if (track->mode == MODE_MP4)
+if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
 ffio_wfourcc(pb, "nclx");
 else
 ffio_wfourcc(pb, "nclc");
@@ -2050,7 +2051,7 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
 avio_wb16(pb, track->par->color_primaries);
 avio_wb16(pb, track->par->color_trc);
 avio_wb16(pb, track->par->color_space);
-if (track->mode == MODE_MP4) {
+if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
 int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
 avio_w8(pb, full_range << 7);
 }
@@ -2116,7 +2117,7 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
   || (track->par->width == 1440 && track->par->height == 1080)
   || (track->par->width == 1920 && track->par->height == 1080);
 
-if (track->mode == MODE_MOV &&
+if ((track->mode == MODE_AVIF || track->mode == MODE_MOV) &&
 (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
 av_strlcpy(compressor_name, encoder->value, 32);
 } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
@@ -2137,6 +2138,25 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
 }
 }
 
+static int mov_write_ccst_tag(AVIOContext *pb)
+{
+int64_t pos = avio_tell(pb);
+// Write sane defaults:
+// all_ref_pics_intra = 0 : all samples can use any type of reference.
+// intra_pred_used = 1 : intra prediction may or may not be used.
+// max_ref_per_pic = 15 : reserved value to indicate that any number of
+//reference im

  1   2   >