Re: [FFmpeg-devel] [PATCH 03/13] avcodec/decode: support applying LCEVC enhacements
On 8/31/2024 5:31 PM, James Almer wrote: > Signed-off-by: James Almer > --- > libavcodec/avcodec.c | 2 ++ > libavcodec/avcodec.h | 5 + > libavcodec/decode.c| 42 +- > libavcodec/internal.h | 2 ++ > libavcodec/lcevcdec.c | 2 ++ > libavcodec/options_table.h | 1 + > libavcodec/pthread_frame.c | 7 +++ > 7 files changed, 60 insertions(+), 1 deletion(-) No real opinion on the other patches, but this one feels really gross. I feel liek we should not be adding new codec-specific things in AVCodecInternal or in generic threding, decode, etc. It really feels quite wrong. I probably missed discussion on this in previous revisions of this patch set, but I wanted to get my thoughts in writing. - Derek ___ 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 07/13] avcodec/hevcdec: export LCEVC metadata as frame side data
On 8/31/2024 5:31 PM, James Almer wrote: > Signed-off-by: James Almer > --- > configure | 1 + > libavcodec/hevc/hevcdec.c | 3 +++ > libavcodec/hevc/refs.c| 15 ++- > 3 files changed, 18 insertions(+), 1 deletion(-) Maybe I've misunderstood, but doesn't requiring every possible base layer codec to explicitly support exporting LCEVC kind of defeat the point of a 'generic' enhancement layer codec like LCEVC? - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2] lavu/stereo3d: change the horizontal FOV field to a rational
On 6/24/2024 1:13 AM, James Almer wrote: > If Derek is also ok with this then LGTM. I do not object. - Derek ___ 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] lavu/stereo3d: change baseline and horizontal FOV to rationals
On 6/23/2024 12:05 PM, Derek Buitenhuis wrote: > If I sound grumpy, it's because I am... the set sat commentless. The tone was unnecessary, sorry about that. - Derek ___ 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] lavu/stereo3d: change baseline and horizontal FOV to rationals
On 6/22/2024 9:11 PM, Lynne via ffmpeg-devel wrote: > The API was committed 2 days ago, so changing these fields now > is within the realms of acceptable. > --- You also had weeks to comment on 3 revisions of the set, and it would have been nice to hear about this then instead of changing it after I've already pushed and integrated it in my own downstream work. If I sound grumpy, it's because I am... the set sat commentless. > diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h > index 00a5c3900e..097f6c9455 100644 > --- a/libavutil/stereo3d.h > +++ b/libavutil/stereo3d.h > @@ -213,9 +213,9 @@ typedef struct AVStereo3D { > > /** > * The distance between the centres of the lenses of the camera system, > - * in micrometers. Zero if unset. > + * in meters. Zero if unset. > */ > -uint32_t baseline; > +AVRational baseline; Can't be AVRational for the reason James mentioned, uint32_t can't be put in an int, and can't be negative. Also, in terms of units, using meters here is silly, it's the distance between two lenses, meters is an crazy unit to measure that in, not idiomatic at all, and I would argue violates the principal of least surprise (both in terms of units, and being a distance as a rational). > /** > - * Horizontal field of view in thousanths of a degree. Zero if unset. > + * Horizontal field of view, in degrees. Zero if unset. > */ > -uint32_t horizontal_field_of_view; > +AVRational horizontal_field_of_view; > } AVStereo3D; This one is more reasonable. I am not happy about the post-push change, but if the community wants this one, I am not going to block it. > +horizontal_field_of_view=0/0 If it is changed, this should be initialized to 0/1, as that is what James last set did for the rest of all side data. - Derek ___ 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/dump: Print all possible Stereo3D info
On 6/18/2024 7:34 PM, James Almer wrote: > nit: These three could be combined into a single av_log call. v2 sent. - Derek ___ 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 v2] avformat/dump: Print all possible Stereo3D info
Signed-off-by: Derek Buitenhuis --- libavformat/dump.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libavformat/dump.c b/libavformat/dump.c index 059fb84522..61a2c6a29f 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -259,7 +259,16 @@ static void dump_stereo3d(void *ctx, const AVPacketSideData *sd, int log_level) stereo = (const AVStereo3D *)sd->data; -av_log(ctx, log_level, "%s", av_stereo3d_type_name(stereo->type)); +av_log(ctx, log_level, "%s, view: %s, primary eye: %s", + av_stereo3d_type_name(stereo->type), av_stereo3d_view_name(stereo->view), + av_stereo3d_primary_eye_name(stereo->primary_eye)); +if (stereo->baseline) +av_log(ctx, log_level, ", baseline: %"PRIu32"", stereo->baseline); +if (stereo->horizontal_disparity_adjustment.num && stereo->horizontal_disparity_adjustment.den) +av_log(ctx, log_level, ", horizontal_disparity_adjustment: %d/%d", + stereo->horizontal_disparity_adjustment.num, stereo->horizontal_disparity_adjustment.den); +if (stereo->horizontal_field_of_view) +av_log(ctx, log_level, ", horizontal_field_of_view: %"PRIu32"", stereo->horizontal_field_of_view); if (stereo->flags & AV_STEREO3D_FLAG_INVERT) av_log(ctx, log_level, " (inverted)"); -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avformat/dump: Print all possible Stereo3D info
Signed-off-by: Derek Buitenhuis --- As requested by James. --- libavformat/dump.c | 9 + 1 file changed, 9 insertions(+) diff --git a/libavformat/dump.c b/libavformat/dump.c index 059fb84522..8e8b9e1959 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -260,6 +260,15 @@ static void dump_stereo3d(void *ctx, const AVPacketSideData *sd, int log_level) stereo = (const AVStereo3D *)sd->data; av_log(ctx, log_level, "%s", av_stereo3d_type_name(stereo->type)); +av_log(ctx, log_level, ", view: %s", av_stereo3d_view_name(stereo->view)); +av_log(ctx, log_level, ", primary eye: %s", av_stereo3d_primary_eye_name(stereo->primary_eye)); +if (stereo->baseline) +av_log(ctx, log_level, ", baseline: %"PRIu32"", stereo->baseline); +if (stereo->horizontal_disparity_adjustment.num && stereo->horizontal_disparity_adjustment.den) +av_log(ctx, log_level, ", horizontal_disparity_adjustment: %d/%d", + stereo->horizontal_disparity_adjustment.num, stereo->horizontal_disparity_adjustment.den); +if (stereo->horizontal_field_of_view) +av_log(ctx, log_level, ", horizontal_field_of_view: %"PRIu32"", stereo->horizontal_field_of_view); if (stereo->flags & AV_STEREO3D_FLAG_INVERT) av_log(ctx, log_level, " (inverted)"); -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v3 0/5] Vision Pro Spatial Data
On 6/17/2024 8:20 PM, Derek Buitenhuis wrote: > 12 files changed, 490 insertions(+), 1 deletion(-) Will push later today if there are no objections. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v3 4/5] avformat/mov: Add support for exporting Video Extension Usage info
On 6/17/2024 9:33 PM, James Almer wrote: > Personally I'd say yes, but other similar lavu APIs (Mastering, Ambient > Viewing) don't seem to bother with it, so maybe just leave it as 0 > unless someone else has a strong opinion about it. I'll leave it for consistency then. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v3 4/5] avformat/mov: Add support for exporting Video Extension Usage info
On 6/17/2024 9:07 PM, James Almer wrote: > nit: { 0, 1 }. If we set it to 0, 1 here, should it be set to that in the alloc function too? It'll be 0, 0 at alloc time due to use of av_mallocz. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v3 2/5] avutil/stereo3d: Fill out stereo info provided by Vision Pro files
On 6/17/2024 9:03 PM, James Almer wrote: > Missing APIChanges entry (no need to resend, you can just amend before > pushing). Done locally for this and previous commit. - Derek ___ 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 v3 5/5] avformat/mov: Add support for reading and exporting horizontal field of view
These boxes are created by the Apple Vision Pro and the iPhone 15+ when capture for the Vision Pro is enabled. Based off of the swift API: * https://developer.apple.com/documentation/coremedia/kcmformatdescriptionextension_horizontalfieldofview Signed-off-by: Derek Buitenhuis --- libavformat/mov.c | 29 + 1 file changed, 29 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 5724b4ef93..367af8478b 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6759,6 +6759,34 @@ static int mov_read_vexu(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +if (atom.size != 4) { + av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size); + return AVERROR_INVALIDDATA; +} + + +if (!sc->stereo3d) { +sc->stereo3d = av_stereo3d_alloc(); +if (!sc->stereo3d) +return AVERROR(ENOMEM); +} + +sc->stereo3d->horizontal_field_of_view = avio_rb32(pb); + +return 0; +} + static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len) { int ret = 0; @@ -8878,6 +8906,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */ { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */ { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */ +{ MKTAG('h','f','o','v'), mov_read_hfov }, { MKTAG('d','O','p','s'), mov_read_dops }, { MKTAG('d','m','l','p'), mov_read_dmlp }, { MKTAG('S','m','D','m'), mov_read_smdm }, -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 4/5] avformat/mov: Add support for exporting Video Extension Usage info
This box is provided by files created by the Apple Vision Pro, as well as the iPhone 15+ when capture for Vision Pro is enabled. The boxes are a mix of things documented by Apple in some PDFs, their API docs, and reverse engineering. Ideally we will have a real spec one day. Links: * https://developer.apple.com/av-foundation/Stereo-Video-ISOBMFF-Extensions.pdf * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_horizontaldisparityadjustment * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_stereocamerabaseline * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_heroeye Signed-off-by: Derek Buitenhuis --- libavformat/mov.c | 283 ++ 1 file changed, 283 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 9016cd5ad0..5724b4ef93 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6477,6 +6477,288 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; +int size; +uint32_t tag; +enum AVSphericalProjection projection; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +if (atom.size != 16) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size); +return AVERROR_INVALIDDATA; +} + +size = avio_rb32(pb); +if (size != 16) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size); +return AVERROR_INVALIDDATA; +} + +tag = avio_rl32(pb); +if (tag != MKTAG('p','r','j','i')) { +av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag); +return AVERROR_INVALIDDATA; +} + +avio_skip(pb, 1); // version +avio_skip(pb, 3); // flags + +tag = avio_rl32(pb); +switch (tag) { +case MKTAG('r','e','c','t'): +projection = AV_SPHERICAL_RECTILINEAR; +break; +case MKTAG('e','q','u','i'): +projection = AV_SPHERICAL_EQUIRECTANGULAR; +break; +case MKTAG('h','e','q','u'): +projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR; +break; +case MKTAG('f','i','s','h'): +projection = AV_SPHERICAL_FISHEYE; +break; +default: +av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag); +return AVERROR_INVALIDDATA; +} + +sc->spherical = av_spherical_alloc(&sc->spherical_size); +if (!sc->spherical) +return AVERROR(ENOMEM); + +sc->spherical->projection = projection; + +return 0; +} + +static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; +int size, flags = 0; +int64_t remaining; +uint32_t tag, baseline = 0; +enum AVStereo3DView view = AV_STEREO3D_VIEW_PACKED; +enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE; +AVRational horizontal_disparity_adjustment = { 0, 0 }; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +remaining = atom.size; +while (remaining > 0) { +size = avio_rb32(pb); +if (size < 8 || size > remaining ) { +av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n"); +return AVERROR_INVALIDDATA; +} + +tag = avio_rl32(pb); +switch (tag) { +case MKTAG('s','t','r','i'): { +int has_right, has_left; +uint8_t tmp; +if (size != 13) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size); +return AVERROR_INVALIDDATA; +} +avio_skip(pb, 1); // version +avio_skip(pb, 3); // flags + +tmp = avio_r8(pb); + +// eye_views_reversed +if (tmp & 8) { +flags |= AV_STEREO3D_FLAG_INVERT; +} +// has_additional_views +if (tmp & 4) { +// skip... +} + +has_right = tmp & 2; // has_right_eye_view +has_left = tmp & 1; // has_left_eye_view + +if (has_left && has_right) +view = AV_STEREO3D_VIEW_PACKED; +else if (has_left) +view = AV_STEREO3D_VIEW_
[FFmpeg-devel] [PATCH v3 3/5] fftools/ffprobe: Print more Stereo 3D info from side data
Signed-off-by: Derek Buitenhuis --- fftools/ffprobe.c| 8 tests/ref/fate/matroska-spherical-mono | 2 ++ tests/ref/fate/matroska-spherical-mono-remux | 4 tests/ref/fate/matroska-stereo_mode | 8 tests/ref/fate/matroska-vp8-alpha-remux | 2 ++ tests/ref/fate/mov-spherical-mono| 2 ++ 6 files changed, 26 insertions(+) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 2d38e5dfdc..a814cb5ade 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -2544,6 +2544,14 @@ static void print_pkt_side_data(WriterContext *w, const AVStereo3D *stereo = (AVStereo3D *)sd->data; print_str("type", av_stereo3d_type_name(stereo->type)); print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT)); +print_str("view", av_stereo3d_view_name(stereo->view)); +print_str("primary_eye", av_stereo3d_primary_eye_name(stereo->primary_eye)); +if (stereo->baseline) +print_int("baseline", stereo->baseline); +if (stereo->horizontal_disparity_adjustment.num && stereo->horizontal_disparity_adjustment.den) +print_q("horizontal_disparity_adjustment", stereo->horizontal_disparity_adjustment, '/'); +if (stereo->horizontal_field_of_view) +print_int("horizontal_field_of_view", stereo->horizontal_field_of_view); } else if (sd->type == AV_PKT_DATA_SPHERICAL) { const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; print_str("projection", av_spherical_projection_name(spherical->projection)); diff --git a/tests/ref/fate/matroska-spherical-mono b/tests/ref/fate/matroska-spherical-mono index bd57d94514..08b94e455b 100644 --- a/tests/ref/fate/matroska-spherical-mono +++ b/tests/ref/fate/matroska-spherical-mono @@ -3,6 +3,8 @@ side_data_type=Stereo 3D type=2D inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping diff --git a/tests/ref/fate/matroska-spherical-mono-remux b/tests/ref/fate/matroska-spherical-mono-remux index 6fcda14822..0ca77c8074 100644 --- a/tests/ref/fate/matroska-spherical-mono-remux +++ b/tests/ref/fate/matroska-spherical-mono-remux @@ -27,6 +27,8 @@ DISPOSITION:forced=1 side_data_type=Stereo 3D type=2D inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping @@ -51,6 +53,8 @@ DISPOSITION:forced=0 side_data_type=Stereo 3D type=2D inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping diff --git a/tests/ref/fate/matroska-stereo_mode b/tests/ref/fate/matroska-stereo_mode index 739b789fea..13bce13cb8 100644 --- a/tests/ref/fate/matroska-stereo_mode +++ b/tests/ref/fate/matroska-stereo_mode @@ -132,6 +132,8 @@ TAG:DURATION=00:00:10.0 side_data_type=Stereo 3D type=side by side inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [/STREAM] [STREAM] @@ -147,6 +149,8 @@ TAG:DURATION=00:00:10.0 side_data_type=Stereo 3D type=top and bottom inverted=1 +view=packed +primary_eye=none [/SIDE_DATA] [/STREAM] [STREAM] @@ -160,6 +164,8 @@ TAG:DURATION=00:00:10.0 side_data_type=Stereo 3D type=interleaved lines inverted=1 +view=packed +primary_eye=none [/SIDE_DATA] [/STREAM] [STREAM] @@ -174,6 +180,8 @@ TAG:DURATION=00:00:10.0 side_data_type=Stereo 3D type=interleaved columns inverted=1 +view=packed +primary_eye=none [/SIDE_DATA] [/STREAM] [STREAM] diff --git a/tests/ref/fate/matroska-vp8-alpha-remux b/tests/ref/fate/matroska-vp8-alpha-remux index f6c24dead6..e54304cafd 100644 --- a/tests/ref/fate/matroska-vp8-alpha-remux +++ b/tests/ref/fate/matroska-vp8-alpha-remux @@ -35,5 +35,7 @@ DISPOSITION:still_image=0 side_data_type=Stereo 3D type=2D inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [/STREAM] diff --git a/tests/ref/fate/mov-spherical-mono b/tests/ref/fate/mov-spherical-mono index bd57d94514..08b94e455b 100644 --- a/tests/ref/fate/mov-spherical-mono +++ b/tests/ref/fate/mov-spherical-mono @@ -3,6 +3,8 @@ side_data_type=Stereo 3D type=2D inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 2/5] avutil/stereo3d: Fill out stereo info provided by Vision Pro files
Based on what is in the files themselves, and what the API provides to users. URLs: * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_heroeye * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_stereocamerabaseline * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_horizontaldisparityadjustment * https://developer.apple.com/documentation/coremedia/kcmformatdescriptionextension_horizontalfieldofview Signed-off-by: Derek Buitenhuis --- libavutil/stereo3d.c | 52 + libavutil/stereo3d.h | 78 libavutil/version.h | 2 +- 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/libavutil/stereo3d.c b/libavutil/stereo3d.c index 9c29ab01b5..a40a9439bb 100644 --- a/libavutil/stereo3d.c +++ b/libavutil/stereo3d.c @@ -55,6 +55,18 @@ static const char * const stereo3d_type_names[] = { [AV_STEREO3D_COLUMNS] = "interleaved columns", }; +static const char * const stereo3d_view_names[] = { +[AV_STEREO3D_VIEW_PACKED] = "packed", +[AV_STEREO3D_VIEW_LEFT] = "left", +[AV_STEREO3D_VIEW_RIGHT] = "right", +}; + +static const char * const stereo3d_primary_eye_names[] = { +[AV_PRIMARY_EYE_NONE] = "none", +[AV_PRIMARY_EYE_LEFT] = "left", +[AV_PRIMARY_EYE_RIGHT] = "right", +}; + const char *av_stereo3d_type_name(unsigned int type) { if (type >= FF_ARRAY_ELEMS(stereo3d_type_names)) @@ -74,3 +86,43 @@ int av_stereo3d_from_name(const char *name) return -1; } + +const char *av_stereo3d_view_name(unsigned int view) +{ +if (view >= FF_ARRAY_ELEMS(stereo3d_view_names)) +return "unknown"; + +return stereo3d_view_names[view]; +} + +int av_stereo3d_view_from_name(const char *name) +{ +int i; + +for (i = 0; i < FF_ARRAY_ELEMS(stereo3d_view_names); i++) { +if (av_strstart(name, stereo3d_view_names[i], NULL)) +return i; +} + +return -1; +} + +const char *av_stereo3d_primary_eye_name(unsigned int eye) +{ +if (eye >= FF_ARRAY_ELEMS(stereo3d_primary_eye_names)) +return "unknown"; + +return stereo3d_primary_eye_names[eye]; +} + +int av_stereo3d_primary_eye_from_name(const char *name) +{ +int i; + +for (i = 0; i < FF_ARRAY_ELEMS(stereo3d_primary_eye_names); i++) { +if (av_strstart(name, stereo3d_primary_eye_names[i], NULL)) +return i; +} + +return -1; +} diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h index 3aab959b79..00a5c3900e 100644 --- a/libavutil/stereo3d.h +++ b/libavutil/stereo3d.h @@ -158,6 +158,26 @@ enum AVStereo3DView { AV_STEREO3D_VIEW_RIGHT, }; +/** + * List of possible primary eyes. + */ +enum AVStereo3DPrimaryEye { +/** + * Neither eye. + */ +AV_PRIMARY_EYE_NONE, + +/** + * Left eye. + */ +AV_PRIMARY_EYE_LEFT, + +/** + * Right eye + */ +AV_PRIMARY_EYE_RIGHT, +}; + /** * Inverted views, Right/Bottom represents the left view. */ @@ -185,6 +205,28 @@ typedef struct AVStereo3D { * Determines which views are packed. */ enum AVStereo3DView view; + +/** + * Which eye is the primary eye when rendering in 2D. + */ +enum AVStereo3DPrimaryEye primary_eye; + +/** + * The distance between the centres of the lenses of the camera system, + * in micrometers. Zero if unset. + */ +uint32_t baseline; + +/** + * Relative shift of the left and right images, which changes the zero parallax plane. + * Range is -1.0 to 1.0. Zero if unset. + */ +AVRational horizontal_disparity_adjustment; + +/** + * Horizontal field of view in thousanths of a degree. Zero if unset. + */ +uint32_t horizontal_field_of_view; } AVStereo3D; /** @@ -222,6 +264,42 @@ const char *av_stereo3d_type_name(unsigned int type); */ int av_stereo3d_from_name(const char *name); +/** + * Provide a human-readable name of a given stereo3d view. + * + * @param type The input stereo3d view value. + * + * @return The name of the stereo3d view value, or "unknown". + */ +const char *av_stereo3d_view_name(unsigned int view); + +/** + * Get the AVStereo3DView form a human-readable name. + * + * @param name The input string. + * + * @return The AVStereo3DView value, or -1 if not found. + */ +int av_stereo3d_view_from_name(const char *name); + +/** + * Provide a human-readable name of a given stereo3d primary eye. + * + * @param type The input stereo3d primary eye value. + * + * @return The name of the stereo3d primary eye value, or "unknown". + */ +const char *av_stereo3d_primary_eye_name(unsigned int eye); + +/** + * Get the AVStereo3DPrimaryEye form a human-readable name. + * + * @param name The input string. + * + * @return The AVStereo3DPrimaryEye value,
[FFmpeg-devel] [PATCH v3 1/5] avutil/spherical: Add more spherical types
These originate from the Apple Vision Pro, and are documented here: https://developer.apple.com/documentation/coremedia/cmprojectiontype Signed-off-by: Derek Buitenhuis --- libavutil/spherical.c | 5 + libavutil/spherical.h | 16 libavutil/version.h | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libavutil/spherical.c b/libavutil/spherical.c index 800d3459a5..64ade1d0ec 100644 --- a/libavutil/spherical.c +++ b/libavutil/spherical.c @@ -29,6 +29,8 @@ AVSphericalMapping *av_spherical_alloc(size_t *size) if (!spherical) return NULL; +spherical->projection = AV_SPHERICAL_RECTILINEAR; + if (size) *size = sizeof(*spherical); @@ -57,6 +59,9 @@ static const char *const spherical_projection_names[] = { [AV_SPHERICAL_EQUIRECTANGULAR] = "equirectangular", [AV_SPHERICAL_CUBEMAP] = "cubemap", [AV_SPHERICAL_EQUIRECTANGULAR_TILE] = "tiled equirectangular", +[AV_SPHERICAL_HALF_EQUIRECTANGULAR] = "half equirectangular", +[AV_SPHERICAL_RECTILINEAR] = "rectilinear", +[AV_SPHERICAL_FISHEYE] = "fisheye", }; const char *av_spherical_projection_name(enum AVSphericalProjection projection) diff --git a/libavutil/spherical.h b/libavutil/spherical.h index 828ac836da..2e90f7752d 100644 --- a/libavutil/spherical.h +++ b/libavutil/spherical.h @@ -66,6 +66,22 @@ enum AVSphericalProjection { * the position of the current video in a larger surface. */ AV_SPHERICAL_EQUIRECTANGULAR_TILE, + +/** + * Video frame displays as a 180 degree equirectangular projection. + */ +AV_SPHERICAL_HALF_EQUIRECTANGULAR, + +/** + * Video frame displays on a flat, rectangular 2D surface. + */ +AV_SPHERICAL_RECTILINEAR, + +/** + * Fisheye projection (Apple). + * See: https://developer.apple.com/documentation/coremedia/cmprojectiontype/fisheye + */ +AV_SPHERICAL_FISHEYE, }; /** diff --git a/libavutil/version.h b/libavutil/version.h index 2756f2aa03..7df546ee22 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 59 -#define LIBAVUTIL_VERSION_MINOR 22 +#define LIBAVUTIL_VERSION_MINOR 23 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 0/5] Vision Pro Spatial Data
Changes since v2: * horizontal display adjustment is now a rational Derek Buitenhuis (5): avutil/spherical: Add more spherical types avutil/stereo3d: Fill out stereo info provided by Vision Pro files fftools/ffprobe: Print more Stereo 3D info from side data avformat/mov: Add support for exporting Video Extension Usage info avformat/mov: Add support for reading and exporting horizontal field of view fftools/ffprobe.c| 8 + libavformat/mov.c| 312 +++ libavutil/spherical.c| 5 + libavutil/spherical.h| 16 + libavutil/stereo3d.c | 52 libavutil/stereo3d.h | 78 + libavutil/version.h | 2 +- tests/ref/fate/matroska-spherical-mono | 2 + tests/ref/fate/matroska-spherical-mono-remux | 4 + tests/ref/fate/matroska-stereo_mode | 8 + tests/ref/fate/matroska-vp8-alpha-remux | 2 + tests/ref/fate/mov-spherical-mono| 2 + 12 files changed, 490 insertions(+), 1 deletion(-) -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 2/5] avutil/stereo3d: Fill out stereo info provided by Vision Pro files
On 6/17/2024 7:09 PM, James Almer wrote: > No, it's av_d2q(), av_q2d(), and av_rescale() as needed. Same as we do > for Mastering Display and Ambient Viewing Environment Metadata. > The reason to use AVRational is that in this specific spec the values > have a denominator of 1, but in others it doesn't need to, allowing > for more precise values (Matroska would store it as a double, in fact). This is unfortunate. Possibly we should add some util func for this case, as it's a case I know I've personally hit more than once (with bugs caused by lossy roundtrip) in my own code - I ended up manually using num/den in the end. > So we shouldn't define our API for one specific implementation but > rather in a generic way that should accommodate to any potential > implementation. I think we already did the former with a Google > implementation (x.y fixed point values), and i want to avoid doing it again. Will send a v3 set using AVRational, then. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 2/5] avutil/stereo3d: Fill out stereo info provided by Vision Pro files
On 6/17/2024 5:53 PM, James Almer wrote: > Maybe this should be an AVRational then. While that is probably 'more correct', it does mean that in 100% places this could be used, it'll have to be converted back to the -1 to 1 range. Is there a simple way to do that with an AVRational that doesn't involve a round trip to a double or float (i.e. lossy)? - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 4/5] avformat/mov: Add support for exporting Video Extension Usage info
On 6/17/2024 2:41 PM, Derek Buitenhuis wrote: > Signed-off-by: Derek Buitenhuis > --- > libavformat/mov.c | 279 ++ > 1 file changed, 279 insertions(+) Replaced by v3. - Derek ___ 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 v3 4/5] avformat/mov: Add support for exporting Video Extension Usage info
This box is provided by files created by the Apple Vision Pro, as well as the iPhone 15+ when capture for Vision Pro is enabled. The boxes are a mix of things documented by Apple in some PDFs, their API docs, and reverse engineering. Ideally we will have a real spec one day. Links: * https://developer.apple.com/av-foundation/Stereo-Video-ISOBMFF-Extensions.pdf * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_horizontaldisparityadjustment * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_stereocamerabaseline * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_heroeye Signed-off-by: Derek Buitenhuis --- Only difference from v2 is s/RECTANGULAR/RECTILINEAR/. --- libavformat/mov.c | 279 ++ 1 file changed, 279 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 9016cd5ad0..0f8d7e83b2 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6477,6 +6477,284 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; +int size; +uint32_t tag; +enum AVSphericalProjection projection; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +if (atom.size != 16) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size); +return AVERROR_INVALIDDATA; +} + +size = avio_rb32(pb); +if (size != 16) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size); +return AVERROR_INVALIDDATA; +} + +tag = avio_rl32(pb); +if (tag != MKTAG('p','r','j','i')) { +av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag); +return AVERROR_INVALIDDATA; +} + +avio_skip(pb, 1); // version +avio_skip(pb, 3); // flags + +tag = avio_rl32(pb); +switch (tag) { +case MKTAG('r','e','c','t'): +projection = AV_SPHERICAL_RECTILINEAR; +break; +case MKTAG('e','q','u','i'): +projection = AV_SPHERICAL_EQUIRECTANGULAR; +break; +case MKTAG('h','e','q','u'): +projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR; +break; +case MKTAG('f','i','s','h'): +projection = AV_SPHERICAL_FISHEYE; +break; +default: +av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag); +return AVERROR_INVALIDDATA; +} + +sc->spherical = av_spherical_alloc(&sc->spherical_size); +if (!sc->spherical) +return AVERROR(ENOMEM); + +sc->spherical->projection = projection; + +return 0; +} + +static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; +int size, flags = 0; +int64_t remaining; +uint32_t tag, baseline = 0; +enum AVStereo3DView view = AV_STEREO3D_VIEW_PACKED; +enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE; +int32_t horizontal_disparity_adjustment = 0; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +remaining = atom.size; +while (remaining > 0) { +size = avio_rb32(pb); +if (size < 8 || size > remaining ) { +av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n"); +return AVERROR_INVALIDDATA; +} + +tag = avio_rl32(pb); +switch (tag) { +case MKTAG('s','t','r','i'): { +int has_right, has_left; +uint8_t tmp; +if (size != 13) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size); +return AVERROR_INVALIDDATA; +} +avio_skip(pb, 1); // version +avio_skip(pb, 3); // flags + +tmp = avio_r8(pb); + +// eye_views_reversed +if (tmp & 8) { +flags |= AV_STEREO3D_FLAG_INVERT; +} +// has_additional_views +if (tmp & 4) { +// skip... +} + +has_right = tmp & 2; // has_right_eye_view +has_left = tmp & 1; // has_left_eye_view + +if (has_left && has_right) +view = AV_STEREO3D_VIEW_PACKED; +else if (has
[FFmpeg-devel] [PATCH v2 5/5] avformat/mov: Add support for reading and exporting horizontal field of view
These boxes are created by the Apple Vision Pro and the iPhone 15+ when capture for the Vision Pro is enabled. Based off of the swift API: * https://developer.apple.com/documentation/coremedia/kcmformatdescriptionextension_horizontalfieldofview Signed-off-by: Derek Buitenhuis --- libavformat/mov.c | 29 + 1 file changed, 29 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index a7ca0b5a3c..391b11a4e1 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6755,6 +6755,34 @@ static int mov_read_vexu(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +if (atom.size != 4) { + av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size); + return AVERROR_INVALIDDATA; +} + + +if (!sc->stereo3d) { +sc->stereo3d = av_stereo3d_alloc(); +if (!sc->stereo3d) +return AVERROR(ENOMEM); +} + +sc->stereo3d->horizontal_field_of_view = avio_rb32(pb); + +return 0; +} + static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len) { int ret = 0; @@ -8874,6 +8902,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */ { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */ { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */ +{ MKTAG('h','f','o','v'), mov_read_hfov }, { MKTAG('d','O','p','s'), mov_read_dops }, { MKTAG('d','m','l','p'), mov_read_dmlp }, { MKTAG('S','m','D','m'), mov_read_smdm }, -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 4/5] avformat/mov: Add support for exporting Video Extension Usage info
This box is provided by files created by the Apple Vision Pro, as well as the iPhone 15+ when capture for Vision Pro is enabled. The boxes are a mix of things documented by Apple in some PDFs, their API docs, and reverse engineering. Ideally we will have a real spec one day. Links: * https://developer.apple.com/av-foundation/Stereo-Video-ISOBMFF-Extensions.pdf * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_horizontaldisparityadjustment * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_stereocamerabaseline * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_heroeye Signed-off-by: Derek Buitenhuis --- libavformat/mov.c | 279 ++ 1 file changed, 279 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 9016cd5ad0..a7ca0b5a3c 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6477,6 +6477,284 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; +int size; +uint32_t tag; +enum AVSphericalProjection projection; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +if (atom.size != 16) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size); +return AVERROR_INVALIDDATA; +} + +size = avio_rb32(pb); +if (size != 16) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size); +return AVERROR_INVALIDDATA; +} + +tag = avio_rl32(pb); +if (tag != MKTAG('p','r','j','i')) { +av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag); +return AVERROR_INVALIDDATA; +} + +avio_skip(pb, 1); // version +avio_skip(pb, 3); // flags + +tag = avio_rl32(pb); +switch (tag) { +case MKTAG('r','e','c','t'): +projection = AV_SPHERICAL_RECTANGULAR; +break; +case MKTAG('e','q','u','i'): +projection = AV_SPHERICAL_EQUIRECTANGULAR; +break; +case MKTAG('h','e','q','u'): +projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR; +break; +case MKTAG('f','i','s','h'): +projection = AV_SPHERICAL_FISHEYE; +break; +default: +av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag); +return AVERROR_INVALIDDATA; +} + +sc->spherical = av_spherical_alloc(&sc->spherical_size); +if (!sc->spherical) +return AVERROR(ENOMEM); + +sc->spherical->projection = projection; + +return 0; +} + +static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; +int size, flags = 0; +int64_t remaining; +uint32_t tag, baseline = 0; +enum AVStereo3DView view = AV_STEREO3D_VIEW_PACKED; +enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE; +int32_t horizontal_disparity_adjustment = 0; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +remaining = atom.size; +while (remaining > 0) { +size = avio_rb32(pb); +if (size < 8 || size > remaining ) { +av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n"); +return AVERROR_INVALIDDATA; +} + +tag = avio_rl32(pb); +switch (tag) { +case MKTAG('s','t','r','i'): { +int has_right, has_left; +uint8_t tmp; +if (size != 13) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size); +return AVERROR_INVALIDDATA; +} +avio_skip(pb, 1); // version +avio_skip(pb, 3); // flags + +tmp = avio_r8(pb); + +// eye_views_reversed +if (tmp & 8) { +flags |= AV_STEREO3D_FLAG_INVERT; +} +// has_additional_views +if (tmp & 4) { +// skip... +} + +has_right = tmp & 2; // has_right_eye_view +has_left = tmp & 1; // has_left_eye_view + +if (has_left && has_right) +view = AV_STEREO3D_VIEW_PACKED; +else if (has_left) +view = AV_STEREO3D_VIEW_LEFT; +
[FFmpeg-devel] [PATCH v2 3/5] fftools/ffprobe: Print more Stereo 3D info from side data
Signed-off-by: Derek Buitenhuis --- fftools/ffprobe.c| 8 tests/ref/fate/matroska-spherical-mono | 2 ++ tests/ref/fate/matroska-spherical-mono-remux | 4 tests/ref/fate/matroska-stereo_mode | 8 tests/ref/fate/matroska-vp8-alpha-remux | 2 ++ tests/ref/fate/mov-spherical-mono| 2 ++ 6 files changed, 26 insertions(+) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 2d38e5dfdc..082cec8a64 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -2544,6 +2544,14 @@ static void print_pkt_side_data(WriterContext *w, const AVStereo3D *stereo = (AVStereo3D *)sd->data; print_str("type", av_stereo3d_type_name(stereo->type)); print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT)); +print_str("view", av_stereo3d_view_name(stereo->view)); +print_str("primary_eye", av_stereo3d_primary_eye_name(stereo->primary_eye)); +if (stereo->baseline) +print_int("baseline", stereo->baseline); +if (stereo->horizontal_disparity_adjustment) +print_int("horizontal_disparity_adjustment", stereo->horizontal_disparity_adjustment); +if (stereo->horizontal_field_of_view) +print_int("horizontal_field_of_view", stereo->horizontal_field_of_view); } else if (sd->type == AV_PKT_DATA_SPHERICAL) { const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; print_str("projection", av_spherical_projection_name(spherical->projection)); diff --git a/tests/ref/fate/matroska-spherical-mono b/tests/ref/fate/matroska-spherical-mono index bd57d94514..08b94e455b 100644 --- a/tests/ref/fate/matroska-spherical-mono +++ b/tests/ref/fate/matroska-spherical-mono @@ -3,6 +3,8 @@ side_data_type=Stereo 3D type=2D inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping diff --git a/tests/ref/fate/matroska-spherical-mono-remux b/tests/ref/fate/matroska-spherical-mono-remux index 6fcda14822..0ca77c8074 100644 --- a/tests/ref/fate/matroska-spherical-mono-remux +++ b/tests/ref/fate/matroska-spherical-mono-remux @@ -27,6 +27,8 @@ DISPOSITION:forced=1 side_data_type=Stereo 3D type=2D inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping @@ -51,6 +53,8 @@ DISPOSITION:forced=0 side_data_type=Stereo 3D type=2D inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping diff --git a/tests/ref/fate/matroska-stereo_mode b/tests/ref/fate/matroska-stereo_mode index 739b789fea..13bce13cb8 100644 --- a/tests/ref/fate/matroska-stereo_mode +++ b/tests/ref/fate/matroska-stereo_mode @@ -132,6 +132,8 @@ TAG:DURATION=00:00:10.0 side_data_type=Stereo 3D type=side by side inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [/STREAM] [STREAM] @@ -147,6 +149,8 @@ TAG:DURATION=00:00:10.0 side_data_type=Stereo 3D type=top and bottom inverted=1 +view=packed +primary_eye=none [/SIDE_DATA] [/STREAM] [STREAM] @@ -160,6 +164,8 @@ TAG:DURATION=00:00:10.0 side_data_type=Stereo 3D type=interleaved lines inverted=1 +view=packed +primary_eye=none [/SIDE_DATA] [/STREAM] [STREAM] @@ -174,6 +180,8 @@ TAG:DURATION=00:00:10.0 side_data_type=Stereo 3D type=interleaved columns inverted=1 +view=packed +primary_eye=none [/SIDE_DATA] [/STREAM] [STREAM] diff --git a/tests/ref/fate/matroska-vp8-alpha-remux b/tests/ref/fate/matroska-vp8-alpha-remux index f6c24dead6..e54304cafd 100644 --- a/tests/ref/fate/matroska-vp8-alpha-remux +++ b/tests/ref/fate/matroska-vp8-alpha-remux @@ -35,5 +35,7 @@ DISPOSITION:still_image=0 side_data_type=Stereo 3D type=2D inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [/STREAM] diff --git a/tests/ref/fate/mov-spherical-mono b/tests/ref/fate/mov-spherical-mono index bd57d94514..08b94e455b 100644 --- a/tests/ref/fate/mov-spherical-mono +++ b/tests/ref/fate/mov-spherical-mono @@ -3,6 +3,8 @@ side_data_type=Stereo 3D type=2D inverted=0 +view=packed +primary_eye=none [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 2/5] avutil/stereo3d: Fill out stereo info provided by Vision Pro files
Based on what is in the files themselves, and what the API provides to users. URLs: * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_heroeye * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_stereocamerabaseline * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_horizontaldisparityadjustment * https://developer.apple.com/documentation/coremedia/kcmformatdescriptionextension_horizontalfieldofview Signed-off-by: Derek Buitenhuis --- libavutil/stereo3d.c | 52 + libavutil/stereo3d.h | 78 libavutil/version.h | 2 +- 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/libavutil/stereo3d.c b/libavutil/stereo3d.c index 9c29ab01b5..a40a9439bb 100644 --- a/libavutil/stereo3d.c +++ b/libavutil/stereo3d.c @@ -55,6 +55,18 @@ static const char * const stereo3d_type_names[] = { [AV_STEREO3D_COLUMNS] = "interleaved columns", }; +static const char * const stereo3d_view_names[] = { +[AV_STEREO3D_VIEW_PACKED] = "packed", +[AV_STEREO3D_VIEW_LEFT] = "left", +[AV_STEREO3D_VIEW_RIGHT] = "right", +}; + +static const char * const stereo3d_primary_eye_names[] = { +[AV_PRIMARY_EYE_NONE] = "none", +[AV_PRIMARY_EYE_LEFT] = "left", +[AV_PRIMARY_EYE_RIGHT] = "right", +}; + const char *av_stereo3d_type_name(unsigned int type) { if (type >= FF_ARRAY_ELEMS(stereo3d_type_names)) @@ -74,3 +86,43 @@ int av_stereo3d_from_name(const char *name) return -1; } + +const char *av_stereo3d_view_name(unsigned int view) +{ +if (view >= FF_ARRAY_ELEMS(stereo3d_view_names)) +return "unknown"; + +return stereo3d_view_names[view]; +} + +int av_stereo3d_view_from_name(const char *name) +{ +int i; + +for (i = 0; i < FF_ARRAY_ELEMS(stereo3d_view_names); i++) { +if (av_strstart(name, stereo3d_view_names[i], NULL)) +return i; +} + +return -1; +} + +const char *av_stereo3d_primary_eye_name(unsigned int eye) +{ +if (eye >= FF_ARRAY_ELEMS(stereo3d_primary_eye_names)) +return "unknown"; + +return stereo3d_primary_eye_names[eye]; +} + +int av_stereo3d_primary_eye_from_name(const char *name) +{ +int i; + +for (i = 0; i < FF_ARRAY_ELEMS(stereo3d_primary_eye_names); i++) { +if (av_strstart(name, stereo3d_primary_eye_names[i], NULL)) +return i; +} + +return -1; +} diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h index 3aab959b79..d35e46e670 100644 --- a/libavutil/stereo3d.h +++ b/libavutil/stereo3d.h @@ -158,6 +158,26 @@ enum AVStereo3DView { AV_STEREO3D_VIEW_RIGHT, }; +/** + * List of possible primary eyes. + */ +enum AVStereo3DPrimaryEye { +/** + * Neither eye. + */ +AV_PRIMARY_EYE_NONE, + +/** + * Left eye. + */ +AV_PRIMARY_EYE_LEFT, + +/** + * Right eye + */ +AV_PRIMARY_EYE_RIGHT, +}; + /** * Inverted views, Right/Bottom represents the left view. */ @@ -185,6 +205,28 @@ typedef struct AVStereo3D { * Determines which views are packed. */ enum AVStereo3DView view; + +/** + * Which eye is the primary eye when rendering in 2D. + */ +enum AVStereo3DPrimaryEye primary_eye; + +/** + * The distance between the centres of the lenses of the camera system, + * in micrometers. Zero if unset. + */ +uint32_t baseline; + +/** + * Relative shift of the left and right images, which changes the zero parallax plane. + * Range -1 to 1, mapped to -1.0 to 1.0. Zero if unset. + */ +int32_t horizontal_disparity_adjustment; + +/** + * Horizontal field of view in thousanths of a degree. Zero if unset. + */ +uint32_t horizontal_field_of_view; } AVStereo3D; /** @@ -222,6 +264,42 @@ const char *av_stereo3d_type_name(unsigned int type); */ int av_stereo3d_from_name(const char *name); +/** + * Provide a human-readable name of a given stereo3d view. + * + * @param type The input stereo3d view value. + * + * @return The name of the stereo3d view value, or "unknown". + */ +const char *av_stereo3d_view_name(unsigned int view); + +/** + * Get the AVStereo3DView form a human-readable name. + * + * @param name The input string. + * + * @return The AVStereo3DView value, or -1 if not found. + */ +int av_stereo3d_view_from_name(const char *name); + +/** + * Provide a human-readable name of a given stereo3d primary eye. + * + * @param type The input stereo3d primary eye value. + * + * @return The name of the stereo3d primary eye value, or "unknown". + */ +const char *av_stereo3d_primary_eye_name(unsigned int eye); + +/** + * Get the AVStereo3DPrimaryEye form a human-readable name. + * + * @param name The input string. + *
[FFmpeg-devel] [PATCH v2 1/5] avutil/spherical: Add more spherical types
These originate from the Apple Vision Pro, and are documented here: https://developer.apple.com/documentation/coremedia/cmprojectiontype Signed-off-by: Derek Buitenhuis --- libavutil/spherical.c | 5 + libavutil/spherical.h | 16 libavutil/version.h | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libavutil/spherical.c b/libavutil/spherical.c index 800d3459a5..64ade1d0ec 100644 --- a/libavutil/spherical.c +++ b/libavutil/spherical.c @@ -29,6 +29,8 @@ AVSphericalMapping *av_spherical_alloc(size_t *size) if (!spherical) return NULL; +spherical->projection = AV_SPHERICAL_RECTILINEAR; + if (size) *size = sizeof(*spherical); @@ -57,6 +59,9 @@ static const char *const spherical_projection_names[] = { [AV_SPHERICAL_EQUIRECTANGULAR] = "equirectangular", [AV_SPHERICAL_CUBEMAP] = "cubemap", [AV_SPHERICAL_EQUIRECTANGULAR_TILE] = "tiled equirectangular", +[AV_SPHERICAL_HALF_EQUIRECTANGULAR] = "half equirectangular", +[AV_SPHERICAL_RECTILINEAR] = "rectilinear", +[AV_SPHERICAL_FISHEYE] = "fisheye", }; const char *av_spherical_projection_name(enum AVSphericalProjection projection) diff --git a/libavutil/spherical.h b/libavutil/spherical.h index 828ac836da..2e90f7752d 100644 --- a/libavutil/spherical.h +++ b/libavutil/spherical.h @@ -66,6 +66,22 @@ enum AVSphericalProjection { * the position of the current video in a larger surface. */ AV_SPHERICAL_EQUIRECTANGULAR_TILE, + +/** + * Video frame displays as a 180 degree equirectangular projection. + */ +AV_SPHERICAL_HALF_EQUIRECTANGULAR, + +/** + * Video frame displays on a flat, rectangular 2D surface. + */ +AV_SPHERICAL_RECTILINEAR, + +/** + * Fisheye projection (Apple). + * See: https://developer.apple.com/documentation/coremedia/cmprojectiontype/fisheye + */ +AV_SPHERICAL_FISHEYE, }; /** diff --git a/libavutil/version.h b/libavutil/version.h index 2756f2aa03..7df546ee22 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 59 -#define LIBAVUTIL_VERSION_MINOR 22 +#define LIBAVUTIL_VERSION_MINOR 23 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 0/5] Vision Pro Spatial Data
* All comments applied from previous review. * Renamed rectangular to more industry standard rectilinear. Derek Buitenhuis (5): avutil/spherical: Add more spherical types avutil/stereo3d: Fill out stereo info provided by Vision Pro files fftools/ffprobe: Print more Stereo 3D info from side data avformat/mov: Add support for exporting Video Extension Usage info avformat/mov: Add support for reading and exporting horizontal field of view fftools/ffprobe.c| 8 + libavformat/mov.c| 308 +++ libavutil/spherical.c| 5 + libavutil/spherical.h| 16 + libavutil/stereo3d.c | 52 libavutil/stereo3d.h | 78 + libavutil/version.h | 2 +- tests/ref/fate/matroska-spherical-mono | 2 + tests/ref/fate/matroska-spherical-mono-remux | 4 + tests/ref/fate/matroska-stereo_mode | 8 + tests/ref/fate/matroska-vp8-alpha-remux | 2 + tests/ref/fate/mov-spherical-mono| 2 + 12 files changed, 486 insertions(+), 1 deletion(-) -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/5] avutil/spherical: Add more spherical types
On 6/14/2024 2:03 PM, Derek Buitenhuis wrote: > I think setting it to 0 (AV_STEREO3D_2D) is correct rather than this (and is > already > done), and I don't think we need to reorder. > > I had discussed this with Vittorio and it was decided that it was good to > disambiguate > between 2D (not stereoscopic) and coded rectangular. Please disregard this, my brain got two enums mixed up. You're right, and I have made this change locally. - Derek ___ 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] fftools/ffprobe: Print more Stereo 3D info from side data
On 6/11/2024 7:43 PM, Derek Buitenhuis wrote: > Perhaps if type!=2D? Changed locally to this and updated the test. - Derek ___ 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/5] avutil/spherical: Add more spherical types
On 6/11/2024 7:44 PM, James Almer wrote: > This should ideally be the enum with value 0, but until next major when > such a change can happen, it would be IMO a good idea if you set > spherical->projection to AV_SPHERICAL_RECTANGULAR in av_spherical_alloc(). I think setting it to 0 (AV_STEREO3D_2D) is correct rather than this (and is already done), and I don't think we need to reorder. I had discussed this with Vittorio and it was decided that it was good to disambiguate between 2D (not stereoscopic) and coded rectangular. - Derek ___ 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] fftools/ffprobe: Print more Stereo 3D info from side data
On 6/11/2024 7:09 PM, Michael Niedermayer wrote: > side_data_type=Stereo 3D > type=2D > inverted=0 > +view=packed > +primary_eye=none Hmm. This does make me think we need a better way to print 'view' and 'inverted' in FFprobe. Perhaps if type!=2D? - Derek ___ 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 4/5] avformat/mov: Add support for exporting Video Extension Usage info
On 6/10/2024 8:38 PM, James Almer wrote: >> +remaining = atom.size; >> +while (remaining > 0) { > > Maybe this loop should call mov_read_default, with proj and eyes added > to mov_default_parse_table[]. Although i don't know if eyes may show up > as child for other parent boxes or not. > At least with proj, i see it can be a child for sv3d, where only prhd is > expected as a child box in turn. But it shouldn't a problem to add a > mov_read_proj that handles both prhd and prji for this purpose. Well, the proj box that that's in sv3d and this proj box are unrelated - they both exist because Apple and Google don't play nice with eachother, and both defined their own incompatible projection boxes, which exist in entirely different parts of the file, so it seemed kind of wrong to handle it that way... The other reason I left it this way is because it left it easier for us to implement the 'must' box if we wanted to, which needs to keep track of what boxes have been seen inside the 'vexu' box, and its inner boxes. To my knowledge eyes (and indeed all the other boxes inside the 'vexu' box besides the 'proj' box) only appear in the 'vexu' box. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 5/5] avformat/mov: Add support for reading and exporting horizontal field of view
These boxes are created by the Apple Vision Pro and the iPhone 15+ when capture for the Vision Pro is enabled. Based off of the swift API: * https://developer.apple.com/documentation/coremedia/kcmformatdescriptionextension_horizontalfieldofview Signed-off-by: Derek Buitenhuis --- libavformat/mov.c | 29 + 1 file changed, 29 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index b164bb0adb..a118ade089 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6755,6 +6755,34 @@ static int mov_read_vexu(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +if (atom.size != 4) { + av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size); + return AVERROR_INVALIDDATA; +} + + +if (!sc->stereo3d) { +sc->stereo3d = av_stereo3d_alloc(); +if (!sc->stereo3d) +return AVERROR(ENOMEM); +} + +sc->stereo3d->horizontal_field_of_view = avio_rb32(pb); + +return 0; +} + static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len) { int ret = 0; @@ -8874,6 +8902,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */ { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */ { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */ +{ MKTAG('h','f','o','v'), mov_read_hfov }, { MKTAG('d','O','p','s'), mov_read_dops }, { MKTAG('d','m','l','p'), mov_read_dmlp }, { MKTAG('S','m','D','m'), mov_read_smdm }, -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/5] avformat/mov: Add support for exporting Video Extension Usage info
This box is provided by files created by the Apple Vision Pro, as well as the iPhone 15+ when capture for Vision Pro is enabled. The boxes are a mix of things documented by Apple in some PDFs, their API docs, and reverse engineering. Ideally we will have a real spec one day. Links: * https://developer.apple.com/av-foundation/Stereo-Video-ISOBMFF-Extensions.pdf * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_horizontaldisparityadjustment * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_stereocamerabaseline * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_heroeye Signed-off-by: Derek Buitenhuis --- libavformat/mov.c | 279 ++ 1 file changed, 279 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 160e9626d7..b164bb0adb 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6477,6 +6477,284 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; +int size; +uint32_t tag; +enum AVSphericalProjection projection; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +if (atom.size != 16) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size); +return AVERROR_INVALIDDATA; +} + +size = avio_rb32(pb); +if (size != 16) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size); +return AVERROR_INVALIDDATA; +} + +tag = avio_rl32(pb); +if (tag != MKTAG('p','r','j','i')) { +av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag); +return AVERROR_INVALIDDATA; +} + +avio_skip(pb, 1); // version +avio_skip(pb, 3); // flags + +tag = avio_rl32(pb); +switch (tag) { +case MKTAG('r','e','c','t'): +projection = AV_SPHERICAL_RECTANGULAR; +break; +case MKTAG('e','q','u','i'): +projection = AV_SPHERICAL_EQUIRECTANGULAR; +break; +case MKTAG('h','e','q','u'): +projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR; +break; +case MKTAG('f','i','s','h'): +projection = AV_SPHERICAL_FISHEYE; +break; +default: +av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag); +return AVERROR_INVALIDDATA; +} + +sc->spherical = av_spherical_alloc(&sc->spherical_size); +if (!sc->spherical) +return AVERROR(ENOMEM); + +sc->spherical->projection = projection; + +return 0; +} + +static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVStream *st; +MOVStreamContext *sc; +int size, flags = 0; +int64_t remaining; +uint32_t tag, baseline = 0; +enum AVStereo3DView view = AV_STEREO3D_VIEW_PACKED; +enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE; +int32_t horizontal_disparity_adjustment = 0; + +if (c->fc->nb_streams < 1) +return 0; + +st = c->fc->streams[c->fc->nb_streams - 1]; +sc = st->priv_data; + +remaining = atom.size; +while (remaining > 0) { +size = avio_rb32(pb); +if (size < 8 || size > remaining ) { +av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n"); +return AVERROR_INVALIDDATA; +} + +tag = avio_rl32(pb); +switch (tag) { +case MKTAG('s','t','r','i'): { +int has_right, has_left; +uint8_t tmp; +if (size != 13) { +av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size); +return AVERROR_INVALIDDATA; +} +avio_skip(pb, 1); // version +avio_skip(pb, 3); // flags + +tmp = avio_r8(pb); + +// eye_views_reversed +if (tmp & 8) { +flags |= AV_STEREO3D_FLAG_INVERT; +} +// has_additional_views +if (tmp & 4) { +// skip... +} + +has_right = tmp & 2; // has_right_eye_view +has_left = tmp & 1; // has_left_eye_view + +if (has_left && has_right) +view = AV_STEREO3D_VIEW_PACKED; +else if (has_left) +view = AV_STEREO3D_VIEW_LEFT; +
[FFmpeg-devel] [PATCH 3/5] fftools/ffprobe: Print more Stereo 3D info from side data
Signed-off-by: Derek Buitenhuis --- fftools/ffprobe.c | 8 1 file changed, 8 insertions(+) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 2d38e5dfdc..082cec8a64 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -2544,6 +2544,14 @@ static void print_pkt_side_data(WriterContext *w, const AVStereo3D *stereo = (AVStereo3D *)sd->data; print_str("type", av_stereo3d_type_name(stereo->type)); print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT)); +print_str("view", av_stereo3d_view_name(stereo->view)); +print_str("primary_eye", av_stereo3d_primary_eye_name(stereo->primary_eye)); +if (stereo->baseline) +print_int("baseline", stereo->baseline); +if (stereo->horizontal_disparity_adjustment) +print_int("horizontal_disparity_adjustment", stereo->horizontal_disparity_adjustment); +if (stereo->horizontal_field_of_view) +print_int("horizontal_field_of_view", stereo->horizontal_field_of_view); } else if (sd->type == AV_PKT_DATA_SPHERICAL) { const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; print_str("projection", av_spherical_projection_name(spherical->projection)); -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/5] avutil/stereo3d: Fill out stereo info provided by Vision Pro files
Based on what is in the files themselves, and what the API provides to users. URLs: * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_heroeye * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_stereocamerabaseline * https://developer.apple.com/documentation/videotoolbox/kvtcompressionpropertykey_horizontaldisparityadjustment * https://developer.apple.com/documentation/coremedia/kcmformatdescriptionextension_horizontalfieldofview Signed-off-by: Derek Buitenhuis --- libavutil/stereo3d.c | 52 libavutil/stereo3d.h | 80 libavutil/version.h | 2 +- 3 files changed, 133 insertions(+), 1 deletion(-) diff --git a/libavutil/stereo3d.c b/libavutil/stereo3d.c index 9c29ab01b5..a40a9439bb 100644 --- a/libavutil/stereo3d.c +++ b/libavutil/stereo3d.c @@ -55,6 +55,18 @@ static const char * const stereo3d_type_names[] = { [AV_STEREO3D_COLUMNS] = "interleaved columns", }; +static const char * const stereo3d_view_names[] = { +[AV_STEREO3D_VIEW_PACKED] = "packed", +[AV_STEREO3D_VIEW_LEFT] = "left", +[AV_STEREO3D_VIEW_RIGHT] = "right", +}; + +static const char * const stereo3d_primary_eye_names[] = { +[AV_PRIMARY_EYE_NONE] = "none", +[AV_PRIMARY_EYE_LEFT] = "left", +[AV_PRIMARY_EYE_RIGHT] = "right", +}; + const char *av_stereo3d_type_name(unsigned int type) { if (type >= FF_ARRAY_ELEMS(stereo3d_type_names)) @@ -74,3 +86,43 @@ int av_stereo3d_from_name(const char *name) return -1; } + +const char *av_stereo3d_view_name(unsigned int view) +{ +if (view >= FF_ARRAY_ELEMS(stereo3d_view_names)) +return "unknown"; + +return stereo3d_view_names[view]; +} + +int av_stereo3d_view_from_name(const char *name) +{ +int i; + +for (i = 0; i < FF_ARRAY_ELEMS(stereo3d_view_names); i++) { +if (av_strstart(name, stereo3d_view_names[i], NULL)) +return i; +} + +return -1; +} + +const char *av_stereo3d_primary_eye_name(unsigned int eye) +{ +if (eye >= FF_ARRAY_ELEMS(stereo3d_primary_eye_names)) +return "unknown"; + +return stereo3d_primary_eye_names[eye]; +} + +int av_stereo3d_primary_eye_from_name(const char *name) +{ +int i; + +for (i = 0; i < FF_ARRAY_ELEMS(stereo3d_primary_eye_names); i++) { +if (av_strstart(name, stereo3d_primary_eye_names[i], NULL)) +return i; +} + +return -1; +} diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h index 3aab959b79..6efbb09b32 100644 --- a/libavutil/stereo3d.h +++ b/libavutil/stereo3d.h @@ -158,6 +158,26 @@ enum AVStereo3DView { AV_STEREO3D_VIEW_RIGHT, }; +/** + * List of possible primary eyes. + */ +enum AVStereo3DPrimaryEye { +/** + * Neither eye. + */ +AV_PRIMARY_EYE_NONE, + +/** + * Left eye. + */ +AV_PRIMARY_EYE_LEFT, + +/** + * Right eye + */ +AV_PRIMARY_EYE_RIGHT, +}; + /** * Inverted views, Right/Bottom represents the left view. */ @@ -185,6 +205,28 @@ typedef struct AVStereo3D { * Determines which views are packed. */ enum AVStereo3DView view; + +/** + * Which eye is the primary eye when rendering in 2D. + */ +enum AVStereo3DPrimaryEye primary_eye; + +/** + * The distance between the centres of the lenses of the camera system, + * in micrometers. Zero if unset. + */ +uint32_t baseline; + +/** + * Relative shift of the left and right images, which changes the zero parallax plane. + * Range -1 to 1, mapped to -1.0 to 1.0. Zero if unset. + */ +int32_t horizontal_disparity_adjustment; + +/** + * Horizontal field of view in thousanths of a degree. Zero if unset. + */ +uint32_t horizontal_field_of_view; } AVStereo3D; /** @@ -222,6 +264,44 @@ const char *av_stereo3d_type_name(unsigned int type); */ int av_stereo3d_from_name(const char *name); +/** + * Provide a human-readable name of a given stereo3d view. + * + * @param type The input stereo3d view value. + * + * @return The name of the stereo3d view value, or "unknown". + */ +const char *av_stereo3d_view_name(unsigned int view); + +/** + * Get the AVStereo3DView form a human-readable name. + * + * @param name The input string. + * + * @return The AVStereo3DView value, or -1 if not found. + */ +int av_stereo3d_view_from_name(const char *name); + +/** + * Provide a human-readable name of a given stereo3d primary eye. + * + * @param type The input stereo3d primary eye value. + * + * @return The name of the stereo3d primary eye value, or "unknown". + */ +const char *av_stereo3d_primary_eye_name(unsigned int eye); + +/** + * Get the AVStereo3DPrimaryEye form a human-readable name. + * + * @param name The input string. + *
[FFmpeg-devel] [PATCH 1/5] avutil/spherical: Add more spherical types
These originate from the Apple Vision Pro, and are documented here: https://developer.apple.com/documentation/coremedia/cmprojectiontype Signed-off-by: Derek Buitenhuis --- libavutil/spherical.c | 3 +++ libavutil/spherical.h | 16 2 files changed, 19 insertions(+) diff --git a/libavutil/spherical.c b/libavutil/spherical.c index 800d3459a5..d78f98f945 100644 --- a/libavutil/spherical.c +++ b/libavutil/spherical.c @@ -57,6 +57,9 @@ static const char *const spherical_projection_names[] = { [AV_SPHERICAL_EQUIRECTANGULAR] = "equirectangular", [AV_SPHERICAL_CUBEMAP] = "cubemap", [AV_SPHERICAL_EQUIRECTANGULAR_TILE] = "tiled equirectangular", +[AV_SPHERICAL_HALF_EQUIRECTANGULAR] = "half equirectangular", +[AV_SPHERICAL_RECTANGULAR] = "rectangular", +[AV_SPHERICAL_FISHEYE] = "fisheye", }; const char *av_spherical_projection_name(enum AVSphericalProjection projection) diff --git a/libavutil/spherical.h b/libavutil/spherical.h index 828ac836da..118fbcc3d1 100644 --- a/libavutil/spherical.h +++ b/libavutil/spherical.h @@ -66,6 +66,22 @@ enum AVSphericalProjection { * the position of the current video in a larger surface. */ AV_SPHERICAL_EQUIRECTANGULAR_TILE, + +/** + * Video frame displays as a 180 degree equirectangular projection. + */ +AV_SPHERICAL_HALF_EQUIRECTANGULAR, + +/** + * Video contentframe displays on a flat, rectangular 2D surface. + */ +AV_SPHERICAL_RECTANGULAR, + +/** + * Fisheye projection (Apple). + * See: https://developer.apple.com/documentation/coremedia/cmprojectiontype/fisheye + */ +AV_SPHERICAL_FISHEYE, }; /** -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 0/5] Apple Spatial Metadata
So I am a bit hesitant to send this, because while some of the boxes are documented officially by Apple, some of what are created by the Vision Pro / iPhones are not, because the official PDF is outdated. It's a call we have to make whether or not we want to push this, or hold out faith Apple will eventually update their document. I reverse engienered the rest of the boxes based on the what the AVFoundation APIs expose for spatial files. See each commit message. Example file: https://www.dropbox.com/scl/fi/g4b0q6c0e0xb9kwxcsvaa/IMG_1722.MOV?rlkey=az1qik442xut3jwq73jvcau9n&dl=0 Example stream from Apple: https://developer.apple.com/streaming/examples/ I can provide more if needed. Anyone with an iPhone 15+ or Vision Pro can make some files, too, of course. Some other notes: * I did not implement the 'must' box, as described in [1], since its only purpose seems to be to fail input files. I can add this as information-only if people want. I have not found any samples with this box, including files made by Apple. * Right now I am checking if the side data values are zero, as this is the best I could come up with, but comments welcome. * I like the idea that the 'dadj' box sits inside a 'cmfy' box, it seems very wholesome. [1] https://developer.apple.com/av-foundation/HEVC-Stereo-Video-Profile.pdf Derek Buitenhuis (5): avutil/spherical: Add more spherical types avutil/stereo3d: Fill out stereo info provided by Vision Pro files fftools/ffprobe: Print more Stereo 3D info from side data avformat/mov: Add support for exporting Video Extension Usage info avformat/mov: Add support for reading and exporting horizontal field of view fftools/ffprobe.c | 8 ++ libavformat/mov.c | 308 ++ libavutil/spherical.c | 3 + libavutil/spherical.h | 16 +++ libavutil/stereo3d.c | 52 +++ libavutil/stereo3d.h | 80 +++ libavutil/version.h | 2 +- 7 files changed, 468 insertions(+), 1 deletion(-) -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [RFC] STF 2025
On 5/17/2024 7:50 PM, Michael Niedermayer wrote: > The people on the booth are predominantly male. Similarly ffmpeg-devel > is predominantly male. More gender diversity would be good. That I can agree with. - Derek ___ 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] [RFC] STF 2025
On 5/17/2024 2:49 PM, Michael Niedermayer wrote: > Also we need more cute girls on these events, everything i hear > its 100% male geeks/hackers. This is gross and sexist. - Derek ___ 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] fftools/ffprobe: Avoid overflow when calculating DAR
Both the codecpar's width and height, and the SAR num and den are ints, which can overflow. Cast to int64_t, which is what av_reduce takes. Without this, occasionally, display_aspect_ratio can be negative in ffprobe's -show_stream output. Signed-off-by: Derek Buitenhuis --- fftools/ffprobe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 0d4cd0b048..5b40dad527 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -3324,8 +3324,8 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id if (sar.num) { print_q("sample_aspect_ratio", sar, ':'); av_reduce(&dar.num, &dar.den, - par->width * sar.num, - par->height * sar.den, + (int64_t) par->width * sar.num, + (int64_t) par->height * sar.den, 1024*1024); print_q("display_aspect_ratio", dar, ':'); } else { -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v3 0/2] HTTP Retry-After Support
On 4/25/2024 9:22 PM, Martin Storsjö wrote: > Thanks, these patches LGTM. Pushed, thanks. - Derek ___ 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] [EXTERNAL] Request for Official GitHub Mirror of rtmpdump for Enhanced Security
Hi, Replies inline. On 4/26/2024 12:10 AM, Javier Matos Denizac via ffmpeg-devel wrote: > Actually, I noticed that you publish release tarballs -> > http://rtmpdump.mplayerhq.hu/download/, but I don’t see a release tarball for > 2.4. Would y’all be willing to publish a release for 2.4 and maybe mint and > publish a release tarball for 2.6? As far as I can tell, the rtmpdump author has, move away from tarballs and only uses git tags, now, as per https://rtmpdump.mplayerhq.hu/, which itself seems outdated. You may have better luck contacting its main contributor (Howard Chu), on rtmpdump's own mailing list (https://lists.mplayerhq.hu/mailman/listinfo/rtmpdump) or directly. FFmpeg only provides infrastructure for it, to my knowledge. > As for why SHA-512, we use SHA-512 checksums to verify the integrity of the > file and as an identifier for our asset caching mechanism. That way we can > identify if we have already downloaded the tarball and avoid downloading it > again. It was unclear you were talking about tarballs as you only referred to GitHub and the FFmpeg-run git server... That said, I am unsure why git is not considered secure / verifiable enough, compared to a tarball. I would actually argue the opposite is true for autogenerated tarballs like GitHub provides. - Derek ___ 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 v3 2/2] avformat/http: Add support for Retry-After header
429 and 503 codes can, and often do (e.g. all Google Cloud Storage URLs can), return a Retry-After header with the error, indicating how long to wait, asd either a date, or in seconds, before retrying again. If it is not respected by, for example, using our default backoff stratetgy instead, chances of success are very unlikely. Some references: * https://datatracker.ietf.org/doc/html/rfc6585 * https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.3 This adds an AVOption to respect that header. Signed-off-by: Derek Buitenhuis --- doc/protocols.texi| 5 + libavformat/http.c| 24 libavformat/version.h | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/doc/protocols.texi b/doc/protocols.texi index 571d78ec43..ed70af4b33 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -569,6 +569,11 @@ Set the maximum number of times to retry a connection. Default unset. @item reconnect_delay_total_max Set the maximum total delay in seconds after which to give up reconnecting. +@item respect_retry_after +If enabled, and a Retry-After header is encountered, its requested reconnection +delay will be honored, rather than using exponential backoff. Useful for 429 and +503 errors. Default enabled. + @item listen If set to 1 enables experimental HTTP server. This can be used to send data when used as an output option, or read data from a client with HTTP POST when used as diff --git a/libavformat/http.c b/libavformat/http.c index d324674e97..1a67068a44 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -31,6 +31,7 @@ #include "libavutil/avstring.h" #include "libavutil/bprint.h" #include "libavutil/getenv_utf8.h" +#include "libavutil/macros.h" #include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/time.h" @@ -138,6 +139,8 @@ typedef struct HTTPContext { char *new_location; AVDictionary *redirect_cache; uint64_t filesize_from_content_range; +int respect_retry_after; +unsigned int retry_after; int reconnect_max_retries; int reconnect_delay_total_max; } HTTPContext; @@ -180,6 +183,7 @@ static const AVOption options[] = { { "reconnect_delay_max", "max reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_max), AV_OPT_TYPE_INT, { .i64 = 120 }, 0, UINT_MAX/1000/1000, D }, { "reconnect_max_retries", "the max number of times to retry a connection", OFFSET(reconnect_max_retries), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, D }, { "reconnect_delay_total_max", "max total reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_total_max), AV_OPT_TYPE_INT, { .i64 = 256 }, 0, UINT_MAX/1000/1000, D }, +{ "respect_retry_after", "respect the Retry-After header when retrying connections", OFFSET(respect_retry_after), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, D }, { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E }, { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E}, @@ -393,6 +397,14 @@ redo: reconnect_delay_total > s->reconnect_delay_total_max) goto fail; +/* Both fields here are in seconds. */ +if (s->respect_retry_after && s->retry_after > 0) { +reconnect_delay = s->retry_after; +if (reconnect_delay > s->reconnect_delay_max) +goto fail; +s->retry_after = 0; +} + av_log(h, AV_LOG_WARNING, "Will reconnect at %"PRIu64" in %d second(s).\n", off, reconnect_delay); ret = ff_network_sleep_interruptible(1000U * 1000 * reconnect_delay, &h->interrupt_callback); if (ret != AVERROR(ETIMEDOUT)) @@ -1241,6 +1253,18 @@ static int process_line(URLContext *h, char *line, int line_count, int *parsed_h parse_expires(s, p); } else if (!av_strcasecmp(tag, "Cache-Control")) { parse_cache_control(s, p); +} else if (!av_strcasecmp(tag, "Retry-After")) { +/* The header can be either an integer that represents seconds, or a date. */ +struct tm tm; +int date_ret = parse_http_date(p, &tm); +if (!date_ret) { +time_t retry = av_timegm(&tm); +int64_t now= av_gettime() / 100; +int64_t diff = ((int64_t) retry) - now; +s->retry_after = (unsigned int) FFMAX(0, diff); +} else { +
[FFmpeg-devel] [PATCH v3 1/2] avformat/http: Rename parse_set_cookie_expiry_time to parse_http_date
That is what it actually does, and it will be needed for more than the Expiry header soon. Signed-off-by: Derek Buitenhuis --- libavformat/http.c | 38 +++--- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index eecc4fd357..d324674e97 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -56,7 +56,7 @@ #define MAX_CACHED_REDIRECTS 32 #define HTTP_SINGLE 1 #define HTTP_MUTLI2 -#define MAX_EXPIRY19 +#define MAX_DATE_LEN 19 #define WHITESPACES " \n\t\r" typedef enum { LOWER_PROTO, @@ -913,29 +913,29 @@ static int parse_icy(HTTPContext *s, const char *tag, const char *p) return 0; } -static int parse_set_cookie_expiry_time(const char *exp_str, struct tm *buf) +static int parse_http_date(const char *date_str, struct tm *buf) { -char exp_buf[MAX_EXPIRY]; -int i, j, exp_buf_len = MAX_EXPIRY-1; -char *expiry; +char date_buf[MAX_DATE_LEN]; +int i, j, date_buf_len = MAX_DATE_LEN-1; +char *date; // strip off any punctuation or whitespace -for (i = 0, j = 0; exp_str[i] != '\0' && j < exp_buf_len; i++) { -if ((exp_str[i] >= '0' && exp_str[i] <= '9') || -(exp_str[i] >= 'A' && exp_str[i] <= 'Z') || -(exp_str[i] >= 'a' && exp_str[i] <= 'z')) { -exp_buf[j] = exp_str[i]; +for (i = 0, j = 0; date_str[i] != '\0' && j < date_buf_len; i++) { +if ((date_str[i] >= '0' && date_str[i] <= '9') || +(date_str[i] >= 'A' && date_str[i] <= 'Z') || +(date_str[i] >= 'a' && date_str[i] <= 'z')) { +date_buf[j] = date_str[i]; j++; } } -exp_buf[j] = '\0'; -expiry = exp_buf; +date_buf[j] = '\0'; +date = date_buf; // move the string beyond the day of week -while ((*expiry < '0' || *expiry > '9') && *expiry != '\0') -expiry++; +while ((*date < '0' || *date > '9') && *date != '\0') +date++; -return av_small_strptime(expiry, "%d%b%Y%H%M%S", buf) ? 0 : AVERROR(EINVAL); +return av_small_strptime(date, "%d%b%Y%H%M%S", buf) ? 0 : AVERROR(EINVAL); } static int parse_set_cookie(const char *set_cookie, AVDictionary **dict) @@ -995,7 +995,7 @@ static int parse_cookie(HTTPContext *s, const char *p, AVDictionary **cookies) // ensure the cookie is not expired or older than an existing value if ((e = av_dict_get(new_params, "expires", NULL, 0)) && e->value) { struct tm new_tm = {0}; -if (!parse_set_cookie_expiry_time(e->value, &new_tm)) { +if (!parse_http_date(e->value, &new_tm)) { AVDictionaryEntry *e2; // if the cookie has already expired ignore it @@ -1012,7 +1012,7 @@ static int parse_cookie(HTTPContext *s, const char *p, AVDictionary **cookies) e2 = av_dict_get(old_params, "expires", NULL, 0); if (e2 && e2->value) { struct tm old_tm = {0}; -if (!parse_set_cookie_expiry_time(e->value, &old_tm)) { +if (!parse_http_date(e->value, &old_tm)) { if (av_timegm(&new_tm) < av_timegm(&old_tm)) { av_dict_free(&new_params); av_dict_free(&old_params); @@ -1064,7 +1064,7 @@ static void parse_expires(HTTPContext *s, const char *p) { struct tm tm; -if (!parse_set_cookie_expiry_time(p, &tm)) { +if (!parse_http_date(p, &tm)) { s->expires = av_timegm(&tm); } } @@ -1295,7 +1295,7 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, // if the cookie has expired, don't add it if ((e = av_dict_get(cookie_params, "expires", NULL, 0)) && e->value) { struct tm tm_buf = {0}; -if (!parse_set_cookie_expiry_time(e->value, &tm_buf)) { +if (!parse_http_date(e->value, &tm_buf)) { if (av_timegm(&tm_buf) < av_gettime() / 100) goto skip_cookie; } -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 0/2] HTTP Retry-After Support
Changes since last set: * Updated commit message with RFC references. * Properly support Retry-After as both a date and integer number of seconds. I have tested this against both an HTTP-Date and seconds, and confirmed it to work. Derek Buitenhuis (2): avformat/http: Rename parse_set_cookie_expiry_time to parse_http_date avformat/http: Add support for Retry-After header doc/protocols.texi| 5 libavformat/http.c| 62 ++- libavformat/version.h | 2 +- 3 files changed, 49 insertions(+), 20 deletions(-) -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 0/9] HTTP rate limiting and retry improvements
On 4/24/2024 8:43 PM, Derek Buitenhuis wrote: > Applied all your comments. > > Will wait a day and then push if no others appear. Pushed all except Retry-After support, which I need to change. While adding RFC references I noticed it can be in seconds, *or* a date... fun. Sending an updated patch for that in a bit in a new thread. - Derek ___ 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] Request for Official GitHub Mirror of rtmpdump for Enhanced Security
On 4/23/2024 10:46 PM, Michael Niedermayer wrote: > Can you elaborate what the problem is ? > I would have thought https://git.ffmpeg.org/rtmpdump.git > is secure I have to assume he means SHA-256, and not SHA-512. git apparently supports using SHA-256 instead of SHA-1 hashes, but support does not seem to be very mainstream. I am not even sure GitHub supports it (https://github.com/orgs/community/discussions/12490 seems to indicate not yet). So either this is vcpkg trying to be vey aggressive in requiring git features, or there is some clarification neeed. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 0/9] HTTP rate limiting and retry improvements
On 4/24/2024 12:13 PM, Martin Storsjö wrote: > I had a look over this patchset, and I had a handful of minor comments, > but overall, the patchset seems fine to me. Thanks! Applied all your comments. Will wait a day and then push if no others appear. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 6/9] avformat/http: Add options to set the max number of connection retries
On 4/24/2024 12:08 PM, Martin Storsjö wrote: > Minor inconsistency; the corresponding variable in the other function was > called conn_attempts, as a plural. Renamed to the plural version. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 2/9] avformat/http: Use AVERROR_HTTP_TOO_MANY_REQUESTS
On 4/24/2024 11:58 AM, Martin Storsjö wrote: > This function seems to handle both the literal status codes, like 429, and > also AVERROR style error codes, as when called from handle_http_errors, so > perhaps it would be good for consistency to add the AVERROR here too. Good catch. Added. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 2/9] avformat/http: Use AVERROR_HTTP_TOO_MANY_REQUESTS
On 4/24/2024 11:53 AM, Martin Storsjö wrote: > Typo in the commit message Fixed locally. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 4/9] avformat/http: Add support for Retry-After header
On 4/24/2024 12:06 PM, Martin Storsjö wrote: > Is this feature standardized in a RFC, or is it some other spec somewhere? > I think it would be nice with a link to a spec in the commit message here. It is in the RFC for 429 I noted in the commit I added that: RFC6585. It is also probably in the 503 and 301 RFCs. See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After I will add those. >> +if (s->respect_retry_after && s->retry_after > 0) { >> +reconnect_delay = s->retry_after; > > It'd be nice with a comment to clarify the units of both values here, > which apparently both happen to be integer seconds? Yes, seconds. I have added: /* Both the Retry-After header and the option are in seconds. */ >> +} else if (!av_strcasecmp(tag, "Retry-After")) { >> +s->retry_after = strtoul(p, NULL, 10); > > Can you add a comment here, to clarify what unit the value is expressed > in? Added: /* Specifies how long to wait before retrying in second. */ - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 1/9] avutil/error: Add HTTP 429 Too Many Requests AVERROR code
On 4/22/2024 3:25 PM, Derek Buitenhuis wrote: > +{ ERROR_TAG(HTTP_TOO_MANY_REQUESTS), "Server returned 404 Too Many > Requests" }, Derp. Change locally to "Server returned 429 Too Many Requests". - Derek ___ 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 8/6] doc/protocols: Fill in missing HTTP options
On 4/16/2024 6:13 PM, Stefano Sabatini wrote: >> +@item metadata >> +An exported dictionary containing Icecast metadata from the bitstream, if >> present. >> +Only useful with the C API. > > Probably best to use impersonal verbal mode: > Set an exported ... This is not quite right. This is not a user-settable option, but exported data from http.c to be read by the user. >> +@item location >> +An exported dictionary containing the content location. Only useful with >> the C >> +API. > > Ditto Same comment as above. >> +@item reconnect_max_retries >> +Sets the maximum number of times to retry a connection. Default unset. > > Set the ... Done. >> +@item resource >> +The resource requested by a client, when the experimental HTTP server is in >> use. > > Set the ... It is an export, as noted in a few of the above options, and not user-settable. > also this might be more explicit (what is a resource in this context?) Resource is a standard HTTP term: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web >> +@item short_seek_size >> +The threshold, in bytes, for when a readahead should be prefered over a >> seek and >> +new HTTP request. This is useful, for example, to make sure the same >> connection >> +is used for reading large video packets with small audio packets in between. > > Set the ... > for consistency reasons Done. v2 patch set sent: https://ffmpeg.org//pipermail/ffmpeg-devel/2024-April/326065.html - Derek ___ 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 v2 7/9] avformat/http: Add option to limit total reconnect delay
The existing option only allows users to set the max delay for a single attempt, rather than the total allowed delay, which is both pretty unintitive, and only applicable when exponential backoff is used. The default for this option is set to 256, which is just above the effective total delay accomplished by the the existing reconnect_delay_max default of 120. Signed-off-by: Derek Buitenhuis --- libavformat/http.c| 12 ++-- libavformat/version.h | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 06bd3e340e..930c115ec3 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -141,6 +141,7 @@ typedef struct HTTPContext { int respect_retry_after; unsigned int retry_after; int reconnect_max_retries; +int reconnect_delay_total_max; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -180,6 +181,7 @@ static const AVOption options[] = { { "reconnect_streamed", "auto reconnect streamed / non seekable streams", OFFSET(reconnect_streamed), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, { "reconnect_delay_max", "max reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_max), AV_OPT_TYPE_INT, { .i64 = 120 }, 0, UINT_MAX/1000/1000, D }, { "reconnect_max_retries", "the max number of times to retry a connection", OFFSET(reconnect_max_retries), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, D }, +{ "reconnect_delay_total_max", "max total reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_total_max), AV_OPT_TYPE_INT, { .i64 = 256 }, 0, UINT_MAX/1000/1000, D }, { "respect_retry_after", "respect the Retry-After header when retrying connections", OFFSET(respect_retry_after), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, D }, { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E }, { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, @@ -363,6 +365,7 @@ static int http_open_cnx(URLContext *h, AVDictionary **options) HTTPContext *s = h->priv_data; int ret, conn_attempts = 1, auth_attempts = 0, redirects = 0; int reconnect_delay = 0; +int reconnect_delay_total = 0; uint64_t off; char *cached; @@ -389,7 +392,8 @@ redo: if (ret < 0) { if (!http_should_reconnect(s, ret) || reconnect_delay > s->reconnect_delay_max || -(s->reconnect_max_retries >= 0 && conn_attempts > s->reconnect_max_retries)) +(s->reconnect_max_retries >= 0 && conn_attempts > s->reconnect_max_retries) || +reconnect_delay_total > s->reconnect_delay_total_max) goto fail; if (s->respect_retry_after && s->retry_after > 0) { @@ -403,6 +407,7 @@ redo: ret = ff_network_sleep_interruptible(1000U * 1000 * reconnect_delay, &h->interrupt_callback); if (ret != AVERROR(ETIMEDOUT)) goto fail; +reconnect_delay_total += reconnect_delay; reconnect_delay = 1 + 2 * reconnect_delay; conn_attempts++; @@ -1710,6 +1715,7 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) int err, read_ret; int64_t seek_ret; int reconnect_delay = 0; +int reconnect_delay_total = 0; int conn_attempt = 1; if (!s->hd) @@ -1739,13 +1745,15 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) !(s->reconnect_at_eof && read_ret == AVERROR_EOF)) break; -if (reconnect_delay > s->reconnect_delay_max || (s->reconnect_max_retries >= 0 && conn_attempt > s->reconnect_max_retries)) +if (reconnect_delay > s->reconnect_delay_max || (s->reconnect_max_retries >= 0 && conn_attempt > s->reconnect_max_retries) || +reconnect_delay_total > s->reconnect_delay_total_max) return AVERROR(EIO); av_log(h, AV_LOG_WARNING, "Will reconnect at %"PRIu64" in %d second(s), error=%s.\n", s->off, reconnect_delay, av_err2str(read_ret)); err = ff_network_sleep_interruptible(1000U*1000*reconnect_delay, &h->interrupt_callback); if (err != AVERROR(ETIMEDOUT)) return err; +reconnect_delay_total += reconnect_delay; reconnect_delay = 1 + 2*reconnect_delay; conn_attempt++; seek_ret = http_seek_internal(h, target, SEEK_SET, 1); diff --git a/libavformat/version.h b/libavformat/version.h index 41dbd4ad01..5310326bda 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMA
[FFmpeg-devel] [PATCH v2 6/9] avformat/http: Add options to set the max number of connection retries
Not every use case benefits from setting retries in terms of the backoff. Signed-off-by: Derek Buitenhuis --- libavformat/http.c| 12 +--- libavformat/version.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 6927fea2fb..06bd3e340e 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -140,6 +140,7 @@ typedef struct HTTPContext { uint64_t filesize_from_content_range; int respect_retry_after; unsigned int retry_after; +int reconnect_max_retries; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -178,6 +179,7 @@ static const AVOption options[] = { { "reconnect_on_http_error", "list of http status codes to reconnect on", OFFSET(reconnect_on_http_error), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D }, { "reconnect_streamed", "auto reconnect streamed / non seekable streams", OFFSET(reconnect_streamed), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, { "reconnect_delay_max", "max reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_max), AV_OPT_TYPE_INT, { .i64 = 120 }, 0, UINT_MAX/1000/1000, D }, +{ "reconnect_max_retries", "the max number of times to retry a connection", OFFSET(reconnect_max_retries), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, D }, { "respect_retry_after", "respect the Retry-After header when retrying connections", OFFSET(respect_retry_after), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, D }, { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E }, { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, @@ -359,7 +361,7 @@ static int http_open_cnx(URLContext *h, AVDictionary **options) { HTTPAuthType cur_auth_type, cur_proxy_auth_type; HTTPContext *s = h->priv_data; -int ret, auth_attempts = 0, redirects = 0; +int ret, conn_attempts = 1, auth_attempts = 0, redirects = 0; int reconnect_delay = 0; uint64_t off; char *cached; @@ -386,7 +388,8 @@ redo: ret = http_open_cnx_internal(h, options); if (ret < 0) { if (!http_should_reconnect(s, ret) || -reconnect_delay > s->reconnect_delay_max) +reconnect_delay > s->reconnect_delay_max || +(s->reconnect_max_retries >= 0 && conn_attempts > s->reconnect_max_retries)) goto fail; if (s->respect_retry_after && s->retry_after > 0) { @@ -401,6 +404,7 @@ redo: if (ret != AVERROR(ETIMEDOUT)) goto fail; reconnect_delay = 1 + 2 * reconnect_delay; +conn_attempts++; /* restore the offset (http_connect resets it) */ s->off = off; @@ -1706,6 +1710,7 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) int err, read_ret; int64_t seek_ret; int reconnect_delay = 0; +int conn_attempt = 1; if (!s->hd) return AVERROR_EOF; @@ -1734,7 +1739,7 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) !(s->reconnect_at_eof && read_ret == AVERROR_EOF)) break; -if (reconnect_delay > s->reconnect_delay_max) +if (reconnect_delay > s->reconnect_delay_max || (s->reconnect_max_retries >= 0 && conn_attempt > s->reconnect_max_retries)) return AVERROR(EIO); av_log(h, AV_LOG_WARNING, "Will reconnect at %"PRIu64" in %d second(s), error=%s.\n", s->off, reconnect_delay, av_err2str(read_ret)); @@ -1742,6 +1747,7 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) if (err != AVERROR(ETIMEDOUT)) return err; reconnect_delay = 1 + 2*reconnect_delay; +conn_attempt++; seek_ret = http_seek_internal(h, target, SEEK_SET, 1); if (seek_ret >= 0 && seek_ret != target) { av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRIu64".\n", target); diff --git a/libavformat/version.h b/libavformat/version.h index ee91990360..41dbd4ad01 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 3 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MICRO 102 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 5/9] avformat/http: Rename attempts to auth_attempts
This accurately reflects what it does, as per e75bbcf493aeb549d04c56f49406aeee3950d93b. Signed-off-by: Derek Buitenhuis --- libavformat/http.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 5ed481b63a..6927fea2fb 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -359,7 +359,7 @@ static int http_open_cnx(URLContext *h, AVDictionary **options) { HTTPAuthType cur_auth_type, cur_proxy_auth_type; HTTPContext *s = h->priv_data; -int ret, attempts = 0, redirects = 0; +int ret, auth_attempts = 0, redirects = 0; int reconnect_delay = 0; uint64_t off; char *cached; @@ -409,10 +409,10 @@ redo: goto redo; } -attempts++; +auth_attempts++; if (s->http_code == 401) { if ((cur_auth_type == HTTP_AUTH_NONE || s->auth_state.stale) && -s->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) { +s->auth_state.auth_type != HTTP_AUTH_NONE && auth_attempts < 4) { ffurl_closep(&s->hd); goto redo; } else @@ -420,7 +420,7 @@ redo: } if (s->http_code == 407) { if ((cur_proxy_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) && -s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) { +s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && auth_attempts < 4) { ffurl_closep(&s->hd); goto redo; } else @@ -449,7 +449,7 @@ redo: /* Restart the authentication process with the new target, which * might use a different auth mechanism. */ memset(&s->auth_state, 0, sizeof(s->auth_state)); -attempts = 0; +auth_attempts = 0; goto redo; } return 0; @@ -2082,7 +2082,7 @@ static int http_proxy_open(URLContext *h, const char *uri, int flags) char hostname[1024], hoststr[1024]; char auth[1024], pathbuf[1024], *path; char lower_url[100]; -int port, ret = 0, attempts = 0; +int port, ret = 0, auth_attempts = 0; HTTPAuthType cur_auth_type; char *authstr; @@ -2142,10 +2142,10 @@ redo: if (ret < 0) goto fail; -attempts++; +auth_attempts++; if (s->http_code == 407 && (cur_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) && -s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2) { +s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && auth_attempts < 2) { ffurl_closep(&s->hd); goto redo; } -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 9/9] doc/protocols: Fill in missing HTTP options
Signed-off-by: Derek Buitenhuis --- doc/protocols.texi | 35 ++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/doc/protocols.texi b/doc/protocols.texi index 5ce1ddc8f4..ed70af4b33 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -492,6 +492,10 @@ contains the last non-empty metadata packet sent by the server. It should be polled in regular intervals by applications interested in mid-stream metadata updates. +@item metadata +Set an exported dictionary containing Icecast metadata from the bitstream, if present. +Only useful with the C API. + @item auth_type Set HTTP authentication type. No option for Digest, since this method requires @@ -519,6 +523,10 @@ Send an Expect: 100-continue header for POST. If set to 1 it will send, if set to 0 it won't, if set to -1 it will try to send if it is applicable. Default value is -1. +@item location +An exported dictionary containing the content location. Only useful with the C +API. + @item offset Set initial byte offset. @@ -535,6 +543,9 @@ be given a Bad Request response. When unset the HTTP method is not checked for now. This will be replaced by autodetection in the future. +@item reconnect +Reconnect automatically when disconnected before EOF is hit. + @item reconnect_at_eof If set then eof is treated like an error and causes reconnection, this is useful for live / endless streams. @@ -550,7 +561,18 @@ include specific status codes (e.g. '503') or the strings '4xx' / '5xx'. If set then even streamed/non seekable streams will be reconnected on errors. @item reconnect_delay_max -Sets the maximum delay in seconds after which to give up reconnecting +Set the maximum delay in seconds after which to give up reconnecting. + +@item reconnect_max_retries +Set the maximum number of times to retry a connection. Default unset. + +@item reconnect_delay_total_max +Set the maximum total delay in seconds after which to give up reconnecting. + +@item respect_retry_after +If enabled, and a Retry-After header is encountered, its requested reconnection +delay will be honored, rather than using exponential backoff. Useful for 429 and +503 errors. Default enabled. @item listen If set to 1 enables experimental HTTP server. This can be used to send data when @@ -578,6 +600,17 @@ ffmpeg -i somefile.ogg -chunked_post 0 -c copy -f ogg http://@var{server}:@var{p wget --post-file=somefile.ogg http://@var{server}:@var{port} @end example +@item resource +The resource requested by a client, when the experimental HTTP server is in use. + +@item reply_code +The HTTP code returned to the client, when the experimental HTTP server is in use. + +@item short_seek_size +Set the threshold, in bytes, for when a readahead should be prefered over a seek and +new HTTP request. This is useful, for example, to make sure the same connection +is used for reading large video packets with small audio packets in between. + @end table @subsection HTTP Cookies -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 8/9] doc/protocols: Re-order HTTP options to match http.c order
This makes the list easier to maintain. Signed-off-by: Derek Buitenhuis --- doc/protocols.texi | 112 ++--- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/doc/protocols.texi b/doc/protocols.texi index f54600b846..5ce1ddc8f4 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -442,9 +442,6 @@ value is -1. @item chunked_post If set to 1 use chunked Transfer-Encoding for posts, default is 1. -@item content_type -Set a specific content type for the POST messages or for listen mode. - @item http_proxy set HTTP proxy to tunnel through e.g. http://example.com:1234 @@ -452,35 +449,21 @@ set HTTP proxy to tunnel through e.g. http://example.com:1234 Set custom HTTP headers, can override built in default headers. The value must be a string encoding the headers. -@item multiple_requests -Use persistent connections if set to 1, default is 0. - -@item post_data -Set custom HTTP post data. - -@item referer -Set the Referer header. Include 'Referer: URL' header in HTTP request. +@item content_type +Set a specific content type for the POST messages or for listen mode. @item user_agent Override the User-Agent header. If not specified the protocol will use a string describing the libavformat build. ("Lavf/") -@item reconnect_at_eof -If set then eof is treated like an error and causes reconnection, this is useful -for live / endless streams. - -@item reconnect_streamed -If set then even streamed/non seekable streams will be reconnected on errors. - -@item reconnect_on_network_error -Reconnect automatically in case of TCP/TLS errors during connect. +@item referer +Set the Referer header. Include 'Referer: URL' header in HTTP request. -@item reconnect_on_http_error -A comma separated list of HTTP status codes to reconnect on. The list can -include specific status codes (e.g. '503') or the strings '4xx' / '5xx'. +@item multiple_requests +Use persistent connections if set to 1, default is 0. -@item reconnect_delay_max -Sets the maximum delay in seconds after which to give up reconnecting +@item post_data +Set custom HTTP post data. @item mime_type Export the MIME type. @@ -488,6 +471,11 @@ Export the MIME type. @item http_version Exports the HTTP response version number. Usually "1.0" or "1.1". +@item cookies +Set the cookies to be sent in future requests. The format of each cookie is the +same as the value of a Set-Cookie HTTP response field. Multiple cookies can be +delimited by a newline character. + @item icy If set to 1 request ICY (SHOUTcast) metadata from the server. If the server supports this, the metadata has to be retrieved by the application by reading @@ -504,10 +492,32 @@ contains the last non-empty metadata packet sent by the server. It should be polled in regular intervals by applications interested in mid-stream metadata updates. -@item cookies -Set the cookies to be sent in future requests. The format of each cookie is the -same as the value of a Set-Cookie HTTP response field. Multiple cookies can be -delimited by a newline character. +@item auth_type + +Set HTTP authentication type. No option for Digest, since this method requires +getting nonce parameters from the server first and can't be used straight away like +Basic. + +@table @option +@item none +Choose the HTTP authentication type automatically. This is the default. +@item basic + +Choose the HTTP basic authentication. + +Basic authentication sends a Base64-encoded string that contains a user name and password +for the client. Base64 is not a form of encryption and should be considered the same as +sending the user name and password in clear text (Base64 is a reversible encoding). +If a resource needs to be protected, strongly consider using an authentication scheme +other than basic authentication. HTTPS/TLS should be used with basic authentication. +Without these additional security enhancements, basic authentication should not be used +to protect sensitive or valuable information. +@end table + +@item send_expect_100 +Send an Expect: 100-continue header for POST. If set to 1 it will send, if set +to 0 it won't, if set to -1 it will try to send if it is applicable. Default +value is -1. @item offset Set initial byte offset. @@ -525,6 +535,23 @@ be given a Bad Request response. When unset the HTTP method is not checked for now. This will be replaced by autodetection in the future. +@item reconnect_at_eof +If set then eof is treated like an error and causes reconnection, this is useful +for live / endless streams. + +@item reconnect_on_network_error +Reconnect automatically in case of TCP/TLS errors during connect. + +@item reconnect_on_http_error +A comma separated list of HTTP status codes to reconnect on. The list can +include specific status codes (e.g. '503') or the strings '4xx' / '5xx'. + +@item reconn
[FFmpeg-devel] [PATCH v2 4/9] avformat/http: Add support for Retry-After header
429 and 503 codes can, and often do (e.g. all Google Cloud Storage URLs can), return a Retry-After header with the error, indicating how long to wait, in seconds, before retrying again. If it is not respected by, for example, using our default backoff stratetgy instead, chances of success are very unlikely. This adds an AVOption to respect that header. Signed-off-by: Derek Buitenhuis --- libavformat/http.c| 12 libavformat/version.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libavformat/http.c b/libavformat/http.c index e7603037f4..5ed481b63a 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -138,6 +138,8 @@ typedef struct HTTPContext { char *new_location; AVDictionary *redirect_cache; uint64_t filesize_from_content_range; +int respect_retry_after; +unsigned int retry_after; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -176,6 +178,7 @@ static const AVOption options[] = { { "reconnect_on_http_error", "list of http status codes to reconnect on", OFFSET(reconnect_on_http_error), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D }, { "reconnect_streamed", "auto reconnect streamed / non seekable streams", OFFSET(reconnect_streamed), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, { "reconnect_delay_max", "max reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_max), AV_OPT_TYPE_INT, { .i64 = 120 }, 0, UINT_MAX/1000/1000, D }, +{ "respect_retry_after", "respect the Retry-After header when retrying connections", OFFSET(respect_retry_after), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, D }, { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E }, { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E}, @@ -386,6 +389,13 @@ redo: reconnect_delay > s->reconnect_delay_max) goto fail; +if (s->respect_retry_after && s->retry_after > 0) { +reconnect_delay = s->retry_after; +if (reconnect_delay > s->reconnect_delay_max) +goto fail; +s->retry_after = 0; +} + av_log(h, AV_LOG_WARNING, "Will reconnect at %"PRIu64" in %d second(s).\n", off, reconnect_delay); ret = ff_network_sleep_interruptible(1000U * 1000 * reconnect_delay, &h->interrupt_callback); if (ret != AVERROR(ETIMEDOUT)) @@ -1231,6 +1241,8 @@ static int process_line(URLContext *h, char *line, int line_count, int *parsed_h parse_expires(s, p); } else if (!av_strcasecmp(tag, "Cache-Control")) { parse_cache_control(s, p); +} else if (!av_strcasecmp(tag, "Retry-After")) { +s->retry_after = strtoul(p, NULL, 10); } } return 1; diff --git a/libavformat/version.h b/libavformat/version.h index 7ff1483912..ee91990360 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 3 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 3/9] avformat/http: Don't bail on parsing headers on "bad" HTTP codes
Many "bad" HTTP codes like 429 and 503 may include important info in their headers. Also, in general, there is no purpose in bailing here. Signed-off-by: Derek Buitenhuis --- libavformat/http.c | 25 - 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index bbace2694f..e7603037f4 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -1086,7 +1086,7 @@ static void parse_cache_control(HTTPContext *s, const char *p) } } -static int process_line(URLContext *h, char *line, int line_count) +static int process_line(URLContext *h, char *line, int line_count, int *parsed_http_code) { HTTPContext *s = h->priv_data; const char *auto_method = h->flags & AVIO_FLAG_READ ? "POST" : "GET"; @@ -1166,6 +1166,8 @@ static int process_line(URLContext *h, char *line, int line_count) av_log(h, AV_LOG_TRACE, "http_code=%d\n", s->http_code); +*parsed_http_code = 1; + if ((ret = check_http_code(h, s->http_code, end)) < 0) return ret; } @@ -1338,7 +1340,7 @@ static int http_read_header(URLContext *h) { HTTPContext *s = h->priv_data; char line[MAX_URL_SIZE]; -int err = 0; +int err = 0, http_err = 0; av_freep(&s->new_location); s->expires = 0; @@ -1346,18 +1348,31 @@ static int http_read_header(URLContext *h) s->filesize_from_content_range = UINT64_MAX; for (;;) { +int parsed_http_code = 0; + if ((err = http_get_line(s, line, sizeof(line))) < 0) return err; av_log(h, AV_LOG_TRACE, "header='%s'\n", line); -err = process_line(h, line, s->line_count); -if (err < 0) -return err; +err = process_line(h, line, s->line_count, &parsed_http_code); +if (err < 0) { +if (parsed_http_code) { +http_err = err; +} else { +/* Prefer to return HTTP code error if we've already seen one. */ +if (http_err) +return http_err; +else +return err; +} +} if (err == 0) break; s->line_count++; } +if (http_err) +return http_err; // filesize from Content-Range can always be used, even if using chunked Transfer-Encoding if (s->filesize_from_content_range != UINT64_MAX) -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 2/9] avformat/http: Use AVERROR_HTTP_TOO_MANY_REQUESTS
Added in thep previous commit. Signed-off-by: Derek Buitenhuis --- libavformat/http.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index ed20359552..bbace2694f 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -286,6 +286,7 @@ static int http_should_reconnect(HTTPContext *s, int err) case AVERROR_HTTP_UNAUTHORIZED: case AVERROR_HTTP_FORBIDDEN: case AVERROR_HTTP_NOT_FOUND: +case AVERROR_HTTP_TOO_MANY_REQUESTS: case AVERROR_HTTP_OTHER_4XX: status_group = "4xx"; break; @@ -522,6 +523,7 @@ int ff_http_averror(int status_code, int default_averror) case 401: return AVERROR_HTTP_UNAUTHORIZED; case 403: return AVERROR_HTTP_FORBIDDEN; case 404: return AVERROR_HTTP_NOT_FOUND; +case 429: return AVERROR_HTTP_TOO_MANY_REQUESTS; default: break; } if (status_code >= 400 && status_code <= 499) @@ -558,6 +560,10 @@ static int http_write_reply(URLContext* h, int status_code) reply_code = 404; reply_text = "Not Found"; break; +case 429: +reply_code = 429; +reply_text = "Too Many Requests"; +break; case 200: reply_code = 200; reply_text = "OK"; -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 1/9] avutil/error: Add HTTP 429 Too Many Requests AVERROR code
This is a common error code from e.g. CDNs or cloud storage, and it is useful to be able to handle it differently to a generic 4XX code. Its source is RFC6585. Signed-off-by: Derek Buitenhuis --- libavutil/error.c | 1 + libavutil/error.h | 1 + libavutil/version.h | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libavutil/error.c b/libavutil/error.c index 938a8bc000..7a9d760e76 100644 --- a/libavutil/error.c +++ b/libavutil/error.c @@ -61,6 +61,7 @@ static const struct error_entry error_entries[] = { { ERROR_TAG(HTTP_UNAUTHORIZED), "Server returned 401 Unauthorized (authorization failed)" }, { ERROR_TAG(HTTP_FORBIDDEN), "Server returned 403 Forbidden (access denied)" }, { ERROR_TAG(HTTP_NOT_FOUND), "Server returned 404 Not Found" }, +{ ERROR_TAG(HTTP_TOO_MANY_REQUESTS), "Server returned 404 Too Many Requests" }, { ERROR_TAG(HTTP_OTHER_4XX), "Server returned 4XX Client Error, but not one of 40{0,1,3,4}" }, { ERROR_TAG(HTTP_SERVER_ERROR), "Server returned 5XX Server Error reply" }, #if !HAVE_STRERROR_R diff --git a/libavutil/error.h b/libavutil/error.h index 0d3269aa6d..1efa86c4c1 100644 --- a/libavutil/error.h +++ b/libavutil/error.h @@ -79,6 +79,7 @@ #define AVERROR_HTTP_UNAUTHORIZED FFERRTAG(0xF8,'4','0','1') #define AVERROR_HTTP_FORBIDDEN FFERRTAG(0xF8,'4','0','3') #define AVERROR_HTTP_NOT_FOUND FFERRTAG(0xF8,'4','0','4') +#define AVERROR_HTTP_TOO_MANY_REQUESTS FFERRTAG(0xF8,'4','2','9') #define AVERROR_HTTP_OTHER_4XX FFERRTAG(0xF8,'4','X','X') #define AVERROR_HTTP_SERVER_ERROR FFERRTAG(0xF8,'5','X','X') diff --git a/libavutil/version.h b/libavutil/version.h index 1f2bddc022..5de2d92146 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 59 #define LIBAVUTIL_VERSION_MINOR 15 -#define LIBAVUTIL_VERSION_MICRO 100 +#define LIBAVUTIL_VERSION_MICRO 101 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 0/9] HTTP rate limiting and retry improvements
This patch set adds support for properly handling HTTP 429 codes, and their rate limiting, which is widely used and is standardized. Changes since first set: * Added AVERROR_HTTP_TOO_MANY_REQUESTS top error_entries in error.c, per Andreas' review. * Made respect_retry_after unsigned and use strtoull, per James' review. * Added docs, as per Stefano's reviews./ * Added a new option to limit the total reconnect delay. * Unfortunate, but HTTP connection management is messy business. Original set link: https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325706.html Derek Buitenhuis (9): avutil/error: Add HTTP 429 Too Many Requests AVERROR code avformat/http: Use AVERROR_HTTP_TOO_MANY_REQUESTS avformat/http: Don't bail on parsing headers on "bad" HTTP codes avformat/http: Add support for Retry-After header avformat/http: Rename attempts to auth_attempts avformat/http: Add options to set the max number of connection retries avformat/http: Add option to limit total reconnect delay doc/protocols: Re-order HTTP options to match http.c order doc/protocols: Fill in missing HTTP options doc/protocols.texi| 139 ++ libavformat/http.c| 77 ++- libavformat/version.h | 2 +- libavutil/error.c | 1 + libavutil/error.h | 1 + libavutil/version.h | 2 +- 6 files changed, 152 insertions(+), 70 deletions(-) -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] Mailinglist conduct
On 4/17/2024 8:33 PM, James Almer wrote: >>> This was an unnecessary personal attack, please don't do that again. Repeat >>> offense may result in temporary bans on the mailinglist and/or IRC. Please >>> keep it civil. >> >> That does not make it untrue, however. > > It's ok to have opinions. But there are better way to express them. It is not an opinion if it is true. >> I would have preferred a ban. > > Let's drop it here, please. I will say what I said earlier in private. [16:15] i am tired of the whole thing where the person pointing out the insanity is punished because they were mean [16:15] and the people doing long term damage keep on scott free [16:17] focusing on Mean Words [16:17] instead of deeper issues I agree I was out of line, but for the above reason (among others), the CC is a lame duck, lacking the ability to enact actual meaningful change. The modus operandi here is to drive anyone sane into eventually getting angry and saying regretful things. Gaslighting, sort of. More like [1]. Coupled with the complacent attitude of Please Just Stop So I Can Code from a chunk of the rest of the community, I find myself screaming into the void. I am tired of screaming into the void. I have taken this opportunity to unsubscribe for a while, as a self imposed temp ban for my own benefit. I did that last time I felt like [1] here, and it was beneficial. - Derek [1] https://www.youtube.com/watch?v=HOK6mE7sdvs ___ 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] Mailinglist conduct
On 4/17/2024 8:00 PM, Ronald S. Bultje wrote: > This was an unnecessary personal attack, please don't do that again. Repeat > offense may result in temporary bans on the mailinglist and/or IRC. Please > keep it civil. That does not make it untrue, however. I would have preferred a ban. - Derek ___ 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] FFmpeg table at NAB
On 4/17/2024 2:54 PM, James Almer wrote: > But why were there GPAC people at the FFmpeg booth? > And i don't think a single person should represent the project in these > conferences to begin with. All this should go through the GA, including > who funds it and how. That is a good question, and one that I asked weeks ago (as per link). - Derek ___ 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] FFmpeg table at NAB
On 4/17/2024 12:21 AM, Devin Heitmueller wrote: > Hello all, [...] Yeah, this is exactly what I was screaming into the void about for literal months, no literally 0 response. Look for the thread: [FFmpeg-devel] FFmpeg at NAB 2024 It spans months. My last mail is particularily relevant to your experience: https://ffmpeg.org//pipermail/ffmpeg-devel/2024-March/324816.html I assume Thilo was hung over, and thus not on the booth. It is a disgrace. - Derek ___ 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 4/6 v2] avformat/http: Add support for Retry-After header
On 4/15/2024 6:33 PM, Stefano Sabatini wrote: > missing doc/protocols.texi update Sent patch 7 and 8 to address this. - Derek ___ 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 8/6] doc/protocols: Fill in missing HTTP options
Signed-off-by: Derek Buitenhuis --- doc/protocols.texi | 30 ++ 1 file changed, 30 insertions(+) diff --git a/doc/protocols.texi b/doc/protocols.texi index 5ce1ddc8f4..60c6d831dd 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -492,6 +492,10 @@ contains the last non-empty metadata packet sent by the server. It should be polled in regular intervals by applications interested in mid-stream metadata updates. +@item metadata +An exported dictionary containing Icecast metadata from the bitstream, if present. +Only useful with the C API. + @item auth_type Set HTTP authentication type. No option for Digest, since this method requires @@ -519,6 +523,10 @@ Send an Expect: 100-continue header for POST. If set to 1 it will send, if set to 0 it won't, if set to -1 it will try to send if it is applicable. Default value is -1. +@item location +An exported dictionary containing the content location. Only useful with the C +API. + @item offset Set initial byte offset. @@ -535,6 +543,9 @@ be given a Bad Request response. When unset the HTTP method is not checked for now. This will be replaced by autodetection in the future. +@item reconnect +Reconnect automatically when disconnected before EOF is hit. + @item reconnect_at_eof If set then eof is treated like an error and causes reconnection, this is useful for live / endless streams. @@ -552,6 +563,14 @@ If set then even streamed/non seekable streams will be reconnected on errors. @item reconnect_delay_max Sets the maximum delay in seconds after which to give up reconnecting +@item reconnect_max_retries +Sets the maximum number of times to retry a connection. Default unset. + +@item respect_retry_after +If enabled, and a Retry-After header is encountered, its requested reconnection +delay will be honored, rather than using exponential backoff. Useful for 429 and +503 errors. Default enabled. + @item listen If set to 1 enables experimental HTTP server. This can be used to send data when used as an output option, or read data from a client with HTTP POST when used as @@ -578,6 +597,17 @@ ffmpeg -i somefile.ogg -chunked_post 0 -c copy -f ogg http://@var{server}:@var{p wget --post-file=somefile.ogg http://@var{server}:@var{port} @end example +@item resource +The resource requested by a client, when the experimental HTTP server is in use. + +@item reply_code +The HTTP code returned to the client, when the experimental HTTP server is in use. + +@item short_seek_size +The threshold, in bytes, for when a readahead should be prefered over a seek and +new HTTP request. This is useful, for example, to make sure the same connection +is used for reading large video packets with small audio packets in between. + @end table @subsection HTTP Cookies -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 7/6] doc/protocols: Re-order HTTP options to match http.c order
This makes the list easier to maintain. Signed-off-by: Derek Buitenhuis --- doc/protocols.texi | 112 ++--- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/doc/protocols.texi b/doc/protocols.texi index f54600b846..5ce1ddc8f4 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -442,9 +442,6 @@ value is -1. @item chunked_post If set to 1 use chunked Transfer-Encoding for posts, default is 1. -@item content_type -Set a specific content type for the POST messages or for listen mode. - @item http_proxy set HTTP proxy to tunnel through e.g. http://example.com:1234 @@ -452,35 +449,21 @@ set HTTP proxy to tunnel through e.g. http://example.com:1234 Set custom HTTP headers, can override built in default headers. The value must be a string encoding the headers. -@item multiple_requests -Use persistent connections if set to 1, default is 0. - -@item post_data -Set custom HTTP post data. - -@item referer -Set the Referer header. Include 'Referer: URL' header in HTTP request. +@item content_type +Set a specific content type for the POST messages or for listen mode. @item user_agent Override the User-Agent header. If not specified the protocol will use a string describing the libavformat build. ("Lavf/") -@item reconnect_at_eof -If set then eof is treated like an error and causes reconnection, this is useful -for live / endless streams. - -@item reconnect_streamed -If set then even streamed/non seekable streams will be reconnected on errors. - -@item reconnect_on_network_error -Reconnect automatically in case of TCP/TLS errors during connect. +@item referer +Set the Referer header. Include 'Referer: URL' header in HTTP request. -@item reconnect_on_http_error -A comma separated list of HTTP status codes to reconnect on. The list can -include specific status codes (e.g. '503') or the strings '4xx' / '5xx'. +@item multiple_requests +Use persistent connections if set to 1, default is 0. -@item reconnect_delay_max -Sets the maximum delay in seconds after which to give up reconnecting +@item post_data +Set custom HTTP post data. @item mime_type Export the MIME type. @@ -488,6 +471,11 @@ Export the MIME type. @item http_version Exports the HTTP response version number. Usually "1.0" or "1.1". +@item cookies +Set the cookies to be sent in future requests. The format of each cookie is the +same as the value of a Set-Cookie HTTP response field. Multiple cookies can be +delimited by a newline character. + @item icy If set to 1 request ICY (SHOUTcast) metadata from the server. If the server supports this, the metadata has to be retrieved by the application by reading @@ -504,10 +492,32 @@ contains the last non-empty metadata packet sent by the server. It should be polled in regular intervals by applications interested in mid-stream metadata updates. -@item cookies -Set the cookies to be sent in future requests. The format of each cookie is the -same as the value of a Set-Cookie HTTP response field. Multiple cookies can be -delimited by a newline character. +@item auth_type + +Set HTTP authentication type. No option for Digest, since this method requires +getting nonce parameters from the server first and can't be used straight away like +Basic. + +@table @option +@item none +Choose the HTTP authentication type automatically. This is the default. +@item basic + +Choose the HTTP basic authentication. + +Basic authentication sends a Base64-encoded string that contains a user name and password +for the client. Base64 is not a form of encryption and should be considered the same as +sending the user name and password in clear text (Base64 is a reversible encoding). +If a resource needs to be protected, strongly consider using an authentication scheme +other than basic authentication. HTTPS/TLS should be used with basic authentication. +Without these additional security enhancements, basic authentication should not be used +to protect sensitive or valuable information. +@end table + +@item send_expect_100 +Send an Expect: 100-continue header for POST. If set to 1 it will send, if set +to 0 it won't, if set to -1 it will try to send if it is applicable. Default +value is -1. @item offset Set initial byte offset. @@ -525,6 +535,23 @@ be given a Bad Request response. When unset the HTTP method is not checked for now. This will be replaced by autodetection in the future. +@item reconnect_at_eof +If set then eof is treated like an error and causes reconnection, this is useful +for live / endless streams. + +@item reconnect_on_network_error +Reconnect automatically in case of TCP/TLS errors during connect. + +@item reconnect_on_http_error +A comma separated list of HTTP status codes to reconnect on. The list can +include specific status codes (e.g. '503') or the strings '4xx' / '5xx'. + +@item reconn
Re: [FFmpeg-devel] [PATCH 0/3] avcodec/h264dec: Fix dropped frames when draining
On 4/9/2024 4:15 PM, Derek Buitenhuis wrote: > To me, it LGTM, but I would like someone more experience in H.264 internals > to OK it, too - possibly Michael? If there are no objections raised, I will merge this tomorrow. - Derek ___ 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 4/6] avformat/http: Add support for Retry-After header
On 4/15/2024 5:35 PM, James Almer wrote: > Why strtoull for an int? If the value can't be negative, then make it > unsigned and use strtoul instead. Done, v2 sent. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/6 v2] avformat/http: Add support for Retry-After header
429 and 503 codes can, and often do (e.g. all Google Cloud Storage URLs can), return a Retry-After header with the error, indicating how long to wait, in seconds, before retrying again. If it is not respected by, for example, using our default backoff stratetgy instead, chances of success are very unlikely. This adds an AVOption to respect that header. Signed-off-by: Derek Buitenhuis --- libavformat/http.c| 12 libavformat/version.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libavformat/http.c b/libavformat/http.c index e7603037f4..5ed481b63a 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -138,6 +138,8 @@ typedef struct HTTPContext { char *new_location; AVDictionary *redirect_cache; uint64_t filesize_from_content_range; +int respect_retry_after; +unsigned int retry_after; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -176,6 +178,7 @@ static const AVOption options[] = { { "reconnect_on_http_error", "list of http status codes to reconnect on", OFFSET(reconnect_on_http_error), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D }, { "reconnect_streamed", "auto reconnect streamed / non seekable streams", OFFSET(reconnect_streamed), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, { "reconnect_delay_max", "max reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_max), AV_OPT_TYPE_INT, { .i64 = 120 }, 0, UINT_MAX/1000/1000, D }, +{ "respect_retry_after", "respect the Retry-After header when retrying connections", OFFSET(respect_retry_after), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, D }, { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E }, { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E}, @@ -386,6 +389,13 @@ redo: reconnect_delay > s->reconnect_delay_max) goto fail; +if (s->respect_retry_after && s->retry_after > 0) { +reconnect_delay = s->retry_after; +if (reconnect_delay > s->reconnect_delay_max) +goto fail; +s->retry_after = 0; +} + av_log(h, AV_LOG_WARNING, "Will reconnect at %"PRIu64" in %d second(s).\n", off, reconnect_delay); ret = ff_network_sleep_interruptible(1000U * 1000 * reconnect_delay, &h->interrupt_callback); if (ret != AVERROR(ETIMEDOUT)) @@ -1231,6 +1241,8 @@ static int process_line(URLContext *h, char *line, int line_count, int *parsed_h parse_expires(s, p); } else if (!av_strcasecmp(tag, "Cache-Control")) { parse_cache_control(s, p); +} else if (!av_strcasecmp(tag, "Retry-After")) { +s->retry_after = strtoul(p, NULL, 10); } } return 1; diff --git a/libavformat/version.h b/libavformat/version.h index 7ff1483912..ee91990360 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 3 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/6] avutil/error: Add HTTP 429 Too Many Requests AVERROR code
On 4/15/2024 5:43 PM, Derek Buitenhuis wrote: > --- > libavutil/error.c | 1 + > libavutil/error.h | 1 + > libavutil/version.h | 2 +- > 3 files changed, 3 insertions(+), 1 deletion(-) This is a v2 I forgot to tag as v2. Woops. - Derek ___ 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/6] avutil/error: Add HTTP 429 Too Many Requests AVERROR code
On 4/15/2024 5:31 PM, Andreas Rheinhardt wrote: > Wouldn't you need to add a new entry to error_entries in error.c for this? You are right, I missed that since grep failed me, as error.c uses macros, and thus does not contain any AVERROR_HTTP_* directly. I have sent a v2 for this patch. - Derek ___ 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/6] avutil/error: Add HTTP 429 Too Many Requests AVERROR code
This is a common error code from e.g. CDNs or cloud storage, and it is useful to be able to handle it differently to a generic 4XX code. Its source is RFC6585. Signed-off-by: Derek Buitenhuis --- libavutil/error.c | 1 + libavutil/error.h | 1 + libavutil/version.h | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libavutil/error.c b/libavutil/error.c index 938a8bc000..7a9d760e76 100644 --- a/libavutil/error.c +++ b/libavutil/error.c @@ -61,6 +61,7 @@ static const struct error_entry error_entries[] = { { ERROR_TAG(HTTP_UNAUTHORIZED), "Server returned 401 Unauthorized (authorization failed)" }, { ERROR_TAG(HTTP_FORBIDDEN), "Server returned 403 Forbidden (access denied)" }, { ERROR_TAG(HTTP_NOT_FOUND), "Server returned 404 Not Found" }, +{ ERROR_TAG(HTTP_TOO_MANY_REQUESTS), "Server returned 404 Too Many Requests" }, { ERROR_TAG(HTTP_OTHER_4XX), "Server returned 4XX Client Error, but not one of 40{0,1,3,4}" }, { ERROR_TAG(HTTP_SERVER_ERROR), "Server returned 5XX Server Error reply" }, #if !HAVE_STRERROR_R diff --git a/libavutil/error.h b/libavutil/error.h index 0d3269aa6d..1efa86c4c1 100644 --- a/libavutil/error.h +++ b/libavutil/error.h @@ -79,6 +79,7 @@ #define AVERROR_HTTP_UNAUTHORIZED FFERRTAG(0xF8,'4','0','1') #define AVERROR_HTTP_FORBIDDEN FFERRTAG(0xF8,'4','0','3') #define AVERROR_HTTP_NOT_FOUND FFERRTAG(0xF8,'4','0','4') +#define AVERROR_HTTP_TOO_MANY_REQUESTS FFERRTAG(0xF8,'4','2','9') #define AVERROR_HTTP_OTHER_4XX FFERRTAG(0xF8,'4','X','X') #define AVERROR_HTTP_SERVER_ERROR FFERRTAG(0xF8,'5','X','X') diff --git a/libavutil/version.h b/libavutil/version.h index 1f2bddc022..5de2d92146 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 59 #define LIBAVUTIL_VERSION_MINOR 15 -#define LIBAVUTIL_VERSION_MICRO 100 +#define LIBAVUTIL_VERSION_MICRO 101 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 6/6] avformat/http: Add options to set the max number of connection retries
Not every use case benefits from setting retries in terms of the backoff. Signed-off-by: Derek Buitenhuis --- libavformat/http.c| 12 +--- libavformat/version.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index ce1af5f976..009536901a 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -140,6 +140,7 @@ typedef struct HTTPContext { uint64_t filesize_from_content_range; int respect_retry_after; int retry_after; +int reconnect_max_retries; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -178,6 +179,7 @@ static const AVOption options[] = { { "reconnect_on_http_error", "list of http status codes to reconnect on", OFFSET(reconnect_on_http_error), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D }, { "reconnect_streamed", "auto reconnect streamed / non seekable streams", OFFSET(reconnect_streamed), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, { "reconnect_delay_max", "max reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_max), AV_OPT_TYPE_INT, { .i64 = 120 }, 0, UINT_MAX/1000/1000, D }, +{ "reconnect_max_retries", "the max number of times to retry a connection", OFFSET(reconnect_max_retries), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, D }, { "respect_retry_after", "respect the Retry-After header when retrying connections", OFFSET(respect_retry_after), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, D }, { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E }, { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, @@ -359,7 +361,7 @@ static int http_open_cnx(URLContext *h, AVDictionary **options) { HTTPAuthType cur_auth_type, cur_proxy_auth_type; HTTPContext *s = h->priv_data; -int ret, auth_attempts = 0, redirects = 0; +int ret, conn_attempts = 1, auth_attempts = 0, redirects = 0; int reconnect_delay = 0; uint64_t off; char *cached; @@ -386,7 +388,8 @@ redo: ret = http_open_cnx_internal(h, options); if (ret < 0) { if (!http_should_reconnect(s, ret) || -reconnect_delay > s->reconnect_delay_max) +reconnect_delay > s->reconnect_delay_max || +(s->reconnect_max_retries >= 0 && conn_attempts > s->reconnect_max_retries)) goto fail; if (s->respect_retry_after && s->retry_after > 0) { @@ -401,6 +404,7 @@ redo: if (ret != AVERROR(ETIMEDOUT)) goto fail; reconnect_delay = 1 + 2 * reconnect_delay; +conn_attempts++; /* restore the offset (http_connect resets it) */ s->off = off; @@ -1706,6 +1710,7 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) int err, read_ret; int64_t seek_ret; int reconnect_delay = 0; +int conn_attempt = 1; if (!s->hd) return AVERROR_EOF; @@ -1734,7 +1739,7 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) !(s->reconnect_at_eof && read_ret == AVERROR_EOF)) break; -if (reconnect_delay > s->reconnect_delay_max) +if (reconnect_delay > s->reconnect_delay_max || (s->reconnect_max_retries >= 0 && conn_attempt > s->reconnect_max_retries)) return AVERROR(EIO); av_log(h, AV_LOG_WARNING, "Will reconnect at %"PRIu64" in %d second(s), error=%s.\n", s->off, reconnect_delay, av_err2str(read_ret)); @@ -1742,6 +1747,7 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) if (err != AVERROR(ETIMEDOUT)) return err; reconnect_delay = 1 + 2*reconnect_delay; +conn_attempt++; seek_ret = http_seek_internal(h, target, SEEK_SET, 1); if (seek_ret >= 0 && seek_ret != target) { av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRIu64".\n", target); diff --git a/libavformat/version.h b/libavformat/version.h index ee91990360..41dbd4ad01 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 3 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MICRO 102 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 5/6] avformat/http: Rename attempts to auth_attempts
This accurately reflects what it does, as per e75bbcf493aeb549d04c56f49406aeee3950d93b. Signed-off-by: Derek Buitenhuis --- libavformat/http.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 8f092f108d..ce1af5f976 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -359,7 +359,7 @@ static int http_open_cnx(URLContext *h, AVDictionary **options) { HTTPAuthType cur_auth_type, cur_proxy_auth_type; HTTPContext *s = h->priv_data; -int ret, attempts = 0, redirects = 0; +int ret, auth_attempts = 0, redirects = 0; int reconnect_delay = 0; uint64_t off; char *cached; @@ -409,10 +409,10 @@ redo: goto redo; } -attempts++; +auth_attempts++; if (s->http_code == 401) { if ((cur_auth_type == HTTP_AUTH_NONE || s->auth_state.stale) && -s->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) { +s->auth_state.auth_type != HTTP_AUTH_NONE && auth_attempts < 4) { ffurl_closep(&s->hd); goto redo; } else @@ -420,7 +420,7 @@ redo: } if (s->http_code == 407) { if ((cur_proxy_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) && -s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) { +s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && auth_attempts < 4) { ffurl_closep(&s->hd); goto redo; } else @@ -449,7 +449,7 @@ redo: /* Restart the authentication process with the new target, which * might use a different auth mechanism. */ memset(&s->auth_state, 0, sizeof(s->auth_state)); -attempts = 0; +auth_attempts = 0; goto redo; } return 0; @@ -2082,7 +2082,7 @@ static int http_proxy_open(URLContext *h, const char *uri, int flags) char hostname[1024], hoststr[1024]; char auth[1024], pathbuf[1024], *path; char lower_url[100]; -int port, ret = 0, attempts = 0; +int port, ret = 0, auth_attempts = 0; HTTPAuthType cur_auth_type; char *authstr; @@ -2142,10 +2142,10 @@ redo: if (ret < 0) goto fail; -attempts++; +auth_attempts++; if (s->http_code == 407 && (cur_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) && -s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2) { +s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && auth_attempts < 2) { ffurl_closep(&s->hd); goto redo; } -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/6] avformat/http: Add support for Retry-After header
429 and 503 codes can, and often do (e.g. all Google Cloud Storage URLs can), return a Retry-After header with the error, indicating how long to wait, in seconds, before retrying again. If it is not respected by, for example, using our default backoff stratetgy instead, chances of success are very unlikely. This adds an AVOption to respect that header. Signed-off-by: Derek Buitenhuis --- libavformat/http.c| 12 libavformat/version.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libavformat/http.c b/libavformat/http.c index e7603037f4..8f092f108d 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -138,6 +138,8 @@ typedef struct HTTPContext { char *new_location; AVDictionary *redirect_cache; uint64_t filesize_from_content_range; +int respect_retry_after; +int retry_after; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -176,6 +178,7 @@ static const AVOption options[] = { { "reconnect_on_http_error", "list of http status codes to reconnect on", OFFSET(reconnect_on_http_error), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D }, { "reconnect_streamed", "auto reconnect streamed / non seekable streams", OFFSET(reconnect_streamed), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, { "reconnect_delay_max", "max reconnect delay in seconds after which to give up", OFFSET(reconnect_delay_max), AV_OPT_TYPE_INT, { .i64 = 120 }, 0, UINT_MAX/1000/1000, D }, +{ "respect_retry_after", "respect the Retry-After header when retrying connections", OFFSET(respect_retry_after), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, D }, { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E }, { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E}, @@ -386,6 +389,13 @@ redo: reconnect_delay > s->reconnect_delay_max) goto fail; +if (s->respect_retry_after && s->retry_after > 0) { +reconnect_delay = s->retry_after; +if (reconnect_delay > s->reconnect_delay_max) +goto fail; +s->retry_after = 0; +} + av_log(h, AV_LOG_WARNING, "Will reconnect at %"PRIu64" in %d second(s).\n", off, reconnect_delay); ret = ff_network_sleep_interruptible(1000U * 1000 * reconnect_delay, &h->interrupt_callback); if (ret != AVERROR(ETIMEDOUT)) @@ -1231,6 +1241,8 @@ static int process_line(URLContext *h, char *line, int line_count, int *parsed_h parse_expires(s, p); } else if (!av_strcasecmp(tag, "Cache-Control")) { parse_cache_control(s, p); +} else if (!av_strcasecmp(tag, "Retry-After")) { +s->retry_after = strtoull(p, NULL, 10); } } return 1; diff --git a/libavformat/version.h b/libavformat/version.h index 7ff1483912..ee91990360 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 3 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/6] avformat/http: Don't bail on parsing headers on "bad" HTTP codes
Many "bad" HTTP codes like 429 and 503 may include important info in their headers. Also, in general, there is no purpose in bailing here. Signed-off-by: Derek Buitenhuis --- libavformat/http.c | 25 - 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index bbace2694f..e7603037f4 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -1086,7 +1086,7 @@ static void parse_cache_control(HTTPContext *s, const char *p) } } -static int process_line(URLContext *h, char *line, int line_count) +static int process_line(URLContext *h, char *line, int line_count, int *parsed_http_code) { HTTPContext *s = h->priv_data; const char *auto_method = h->flags & AVIO_FLAG_READ ? "POST" : "GET"; @@ -1166,6 +1166,8 @@ static int process_line(URLContext *h, char *line, int line_count) av_log(h, AV_LOG_TRACE, "http_code=%d\n", s->http_code); +*parsed_http_code = 1; + if ((ret = check_http_code(h, s->http_code, end)) < 0) return ret; } @@ -1338,7 +1340,7 @@ static int http_read_header(URLContext *h) { HTTPContext *s = h->priv_data; char line[MAX_URL_SIZE]; -int err = 0; +int err = 0, http_err = 0; av_freep(&s->new_location); s->expires = 0; @@ -1346,18 +1348,31 @@ static int http_read_header(URLContext *h) s->filesize_from_content_range = UINT64_MAX; for (;;) { +int parsed_http_code = 0; + if ((err = http_get_line(s, line, sizeof(line))) < 0) return err; av_log(h, AV_LOG_TRACE, "header='%s'\n", line); -err = process_line(h, line, s->line_count); -if (err < 0) -return err; +err = process_line(h, line, s->line_count, &parsed_http_code); +if (err < 0) { +if (parsed_http_code) { +http_err = err; +} else { +/* Prefer to return HTTP code error if we've already seen one. */ +if (http_err) +return http_err; +else +return err; +} +} if (err == 0) break; s->line_count++; } +if (http_err) +return http_err; // filesize from Content-Range can always be used, even if using chunked Transfer-Encoding if (s->filesize_from_content_range != UINT64_MAX) -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/6] avformat/http: Use AVERROR_HTTP_TOO_MANY_REQUESTS
Added in thep previous commit. Signed-off-by: Derek Buitenhuis --- libavformat/http.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index ed20359552..bbace2694f 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -286,6 +286,7 @@ static int http_should_reconnect(HTTPContext *s, int err) case AVERROR_HTTP_UNAUTHORIZED: case AVERROR_HTTP_FORBIDDEN: case AVERROR_HTTP_NOT_FOUND: +case AVERROR_HTTP_TOO_MANY_REQUESTS: case AVERROR_HTTP_OTHER_4XX: status_group = "4xx"; break; @@ -522,6 +523,7 @@ int ff_http_averror(int status_code, int default_averror) case 401: return AVERROR_HTTP_UNAUTHORIZED; case 403: return AVERROR_HTTP_FORBIDDEN; case 404: return AVERROR_HTTP_NOT_FOUND; +case 429: return AVERROR_HTTP_TOO_MANY_REQUESTS; default: break; } if (status_code >= 400 && status_code <= 499) @@ -558,6 +560,10 @@ static int http_write_reply(URLContext* h, int status_code) reply_code = 404; reply_text = "Not Found"; break; +case 429: +reply_code = 429; +reply_text = "Too Many Requests"; +break; case 200: reply_code = 200; reply_text = "OK"; -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/6] avutil/error: Add HTTP 429 Too Many Requests AVERROR code
This is a common error code from e.g. CDNs or cloud storage, and it is useful to be able to handle it differently to a generic 4XX code. Its source is RFC6585. Signed-off-by: Derek Buitenhuis --- libavutil/error.h | 1 + libavutil/version.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libavutil/error.h b/libavutil/error.h index 0d3269aa6d..1efa86c4c1 100644 --- a/libavutil/error.h +++ b/libavutil/error.h @@ -79,6 +79,7 @@ #define AVERROR_HTTP_UNAUTHORIZED FFERRTAG(0xF8,'4','0','1') #define AVERROR_HTTP_FORBIDDEN FFERRTAG(0xF8,'4','0','3') #define AVERROR_HTTP_NOT_FOUND FFERRTAG(0xF8,'4','0','4') +#define AVERROR_HTTP_TOO_MANY_REQUESTS FFERRTAG(0xF8,'4','2','9') #define AVERROR_HTTP_OTHER_4XX FFERRTAG(0xF8,'4','X','X') #define AVERROR_HTTP_SERVER_ERROR FFERRTAG(0xF8,'5','X','X') diff --git a/libavutil/version.h b/libavutil/version.h index 1f2bddc022..5de2d92146 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 59 #define LIBAVUTIL_VERSION_MINOR 15 -#define LIBAVUTIL_VERSION_MICRO 100 +#define LIBAVUTIL_VERSION_MICRO 101 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 0/6] HTTP rate limiting and retry improvements
This patch set adds support for properly handling HTTP 429 codes, and their rate limiting, which is widely used and is standardized. Derek Buitenhuis (6): avutil/error: Add HTTP 429 Too Many Requests AVERROR code avformat/http: Use AVERROR_HTTP_TOO_MANY_REQUESTS avformat/http: Don't bail on parsing headers on "bad" HTTP codes avformat/http: Add support for Retry-After header avformat/http: Rename attempts to auth_attempts avformat/http: Add options to set the max number of connection retries libavformat/http.c| 69 +-- libavformat/version.h | 2 +- libavutil/error.h | 1 + libavutil/version.h | 2 +- 4 files changed, 57 insertions(+), 17 deletions(-) -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 0/3] avcodec/h264dec: Fix dropped frames when draining
On 4/3/2024 10:45 PM, arch1t3cht wrote: > Can I bump this? It's my first time sending a patch here so let me know > if I did something wrong. To me, it LGTM, but I would like someone more experience in H.264 internals to OK it, too - possibly Michael? - Derek ___ 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] FFmpeg at NAB 2024
On 11/1/2023 9:25 PM, Derek Buitenhuis wrote: > This is certainly interesting considering we just had a giant thread about > not using > or using SPI, with multiple people accused of having corporate interests. Adding to the list of wtf NAB things: https://twitter.com/JanetGrecoBP/status/1773342135514779700 I will be with #GPAC on the #FFMPEG stand #W4232 during #NABShow, from 13-17th April in Las Vegas. If you're interested in cutting-edge #openSource #ultramedia video streaming & next-gen multimedia transcoding, packaging & delivery software, do stop by or DM to meet! @wearegpac (Janet does PR/markey and stuff for Motion Spell, GPAC's commercial arm.) I am sure this email will continue the long trend of emails in this thread being routed to Thilo's /dev/null. - Derek ___ 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/decode: remove HDR10+ from the global side data array
On 3/5/2024 2:46 PM, James Almer wrote: > It's a per packet/frame side data type. > > Signed-off-by: James Almer > --- > libavcodec/decode.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) LGTM - Derek ___ 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 07/29] lavc: add a decoder option for configuring side data preference
On 3/4/2024 1:06 PM, Anton Khirnov wrote: > +/** > + * Decoding only. May be set by the caller before avcodec_open2() to an > + * av_malloc()'ed array (or via AVOptions). Owned and freed by the > decoder > + * afterwards. > + * > + * By default, when some side data type is present both in global > + * user-supplied coded_side_data and inside the coded bitstream, avcodec > + * will propagate the latter to the decoded frame. > + * > + * This array contains a list of AVPacketSideDataType for which this > + * preference should be switched, i.e. avcodec will prefer global side > data > + * over those in stored in the bytestream. It may also contain a single > -1, > + * in which case the preference is switched for all side data types. > + */ > +int*side_data_prefer_global; My only comment is that it would be nice to include some text about what the practical application of this option is, rather than just technical details. Something like: This can be useful, when, for example, input contains data in both the container and bitstream. - Derek ___ 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] FFmpeg 7.0 blocking issues
On 2/9/2024 3:32 AM, Michael Niedermayer wrote: > please make sure its marked on the bug tracker so it shows up here: > > https://trac.ffmpeg.org/query?status=new&status=open&status=reopened&blocking=~7.0 > > thx Done: https://trac.ffmpeg.org/ticket/10857 - Derek ___ 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] Call for SOWs [due Feb 10 at 23:59 UTC]
Hello, On 2/8/2024 6:02 AM, Pierre-Anthony Lemieux wrote: > The suggested approach is that interested individuals email me, no > later than Feb 10 at 23:59 UTC, a completed SOW using the template at > [2]. I feel obliged to point out that the GA vote Michael called n this ends on 11 Feb,after the due date listed here. Turns out dropping this on the list under 2 weeks before the due date was a poor choice. - Derek ___ 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] FFmpeg 7.0 blocking issues
Hi, On 1/23/2024 7:22 PM, Michael Niedermayer wrote: > What is blocking? (IMHO) > * regressions (unless its non possible to fix before release) > * crashes > * security issues > * data loss > * privacy issues > * anything the commuity agrees should be in the release We discussed it at FOSDEM, but I forgot to mark it as blocking at the time: Curently master is broken when files have both stream and frame level metadata of the same type. We all agreed on the fix, so nothing controversial, though - should be in meeting notes. - Derek ___ 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] Sovereign Tech Fund
On 1/31/2024 9:44 PM, Derek Buitenhuis wrote: > On 1/30/2024 1:48 AM, Michael Niedermayer wrote: >> https://trac.ffmpeg.org/wiki/SponsoringPrograms/STF/2024 > > Not to derail this fine thread, but what forks does the Merge Forks > project refer to? I do not believe this has been answered. - Derek ___ 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] Sovereign Tech Fund
On 1/30/2024 1:48 AM, Michael Niedermayer wrote: > https://trac.ffmpeg.org/wiki/SponsoringPrograms/STF/2024 Not to derail this fine thread, but what forks does the Merge Forks project refer to? - Derek ___ 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] Meeting at FOSDEM
On 1/28/2024 10:31 PM, Jean-Baptiste Kempf wrote: > It would be a great idea to meet for a FFmpeg discussion, since quite a few > of us will be there. > So please bring your technical topics with you 🙂 I would like to propose discussion a solution to the current frame/stream side data issue when both are present. - Derek ___ 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] Sovereign Tech Fund
On 1/29/2024 8:19 PM, Anton Khirnov wrote: > I, for one, see a much bigger problem in the fact that it only starts > being discussed on the ML this late, after so much underground dealings > that bypassed the community entirely. +1 - Derek ___ 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] Sovereign Tech Fund
On 1/29/2024 8:09 PM, Vittorio Giovara wrote: > This is not something that should be discussed on a public ML and the lack > of visibility and clarity on how SPI/STM got involved this time around is > at least disingenuous IMO. I am more curious how Thilo managed to insert himself as the sole representative of the community without anyone else knowing this stuff existed at all. Between this, the unaswered NAB questions, the second vote ridiculousness, the accidental email to the ML from Thilo where he admits he has purposely not replied, etc., I intend to raise this for discussion at the FOSDEM meeting. It is so sketchy. - Derek ___ 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] Sovereign Tech Fund
>> On 1/28/2024 3:25 AM, Michael Niedermayer wrote: >> As others have said, the whole model of using discrete projects here seems >> opposed to >> the actual intent of the STF - maintained and stable OSS long term. > > The whole suggestion here is based on what STF and SPI said. There was a > conference > between SPI and STF where they worked the details out. > Also all the things SPI told us had STF in CC. What SPI convinced STF is best is not necessarily the same. Also notably missing here is the community (as in, more than just Thilo) having any access to review, comment, or help direct this. > I think you should try to bring the work you want funded into the framework > that they told us to use. Instead of complaining Vibes of "shut up and stop dissenting". Nice. I will not be sending any more replies. >> Furthermore, we *already* have a bunch of money sitting in SPI funds that >> *is* suitable >> for use on discete projects, but it never gets used. It is a poor way to >> encourage useful >> work, IMO. > > Theres a very big difference. we have around 100k USD in SPI > > STF has a lower limit of 150.000 € so we actually need to ask them for > at least 150k to be qualified IIUC > And honestly if you reject that, i just dont understand you. > "Estimated costs: The cost of the work described in the application must > exceed €150,000 (current minimum)." > > AT no point could we have done anything with SPI money in a similar > magnitude. In fact trying to use SPI money for any work failed because of it > not being enough. I have yet to see an actual project of "this magnitude" materialize as a proposal. - Derek ___ 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] Sovereign Tech Fund
On 1/29/2024 3:02 PM, Kieran Kunhya wrote: > In this project, acceptance of a patch is based on the technical contents > of a patch, not a few vague paragraphs in a SoW. These decisions are made > by the Technical Committee and the General Assembly. > > Tying the project contractually is unacceptable. Who even has the legal authority to force an open source project to push code? We will reject bad code, and the person or entity who agreed to such a contract will be the one with an issue. - Derek ___ 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".