Message ID | 20201115215541.4526-4-jamrial@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/4,v2] avcodec/cbs: add an AVClass to CodedBitstreamType for option handling | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
andriy/PPC64_make | success | Make finished |
andriy/PPC64_make_fate | success | Make fate finished |
On 11/15/2020 6:55 PM, James Almer wrote: > Signed-off-by: James Almer <jamrial@gmail.com> > --- > doc/decoders.texi | 13 +++++++++++++ > libavcodec/av1dec.c | 30 ++++++++++++++++++++++++++++++ > libavcodec/av1dec.h | 4 ++++ > 3 files changed, 47 insertions(+) > > diff --git a/doc/decoders.texi b/doc/decoders.texi > index bfab562fb2..27c6ba4a5d 100644 > --- a/doc/decoders.texi > +++ b/doc/decoders.texi > @@ -25,6 +25,19 @@ enabled decoders. > A description of some of the currently available video decoders > follows. > > +@section av1 > + > +AOMedia Video 1 (AV1) decoder. > + > +@subsection Options > + > +@table @option > + > +@item operating_point > +Select an operating point of a scalable AV1 bitstream (0 - 31). Default is 0. > + > +@end table > + > @section rawvideo > > Raw video decoder. > diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c > index c1967f03bd..b7ee307159 100644 > --- a/libavcodec/av1dec.c > +++ b/libavcodec/av1dec.c > @@ -19,6 +19,7 @@ > */ > > #include "libavutil/pixdesc.h" > +#include "libavutil/opt.h" > #include "avcodec.h" > #include "av1dec.h" > #include "bytestream.h" > @@ -615,6 +616,8 @@ static av_cold int av1_decode_init(AVCodecContext *avctx) > if (ret < 0) > return ret; > > + av_opt_set_int(s->cbc->priv_data, "operating_point", s->operating_point, 0); > + > if (avctx->extradata && avctx->extradata_size) { > ret = ff_cbs_read(s->cbc, &s->current_obu, avctx->extradata, > avctx->extradata_size); > @@ -704,6 +707,11 @@ static int set_output_frame(AVCodecContext *avctx, AVFrame *frame, > const AVFrame *srcframe = s->cur_frame.tf.f; > int ret; > > + // TODO: all layers > + if (s->operating_point_idc && > + av_log2(s->operating_point_idc >> 8) > s->cur_frame.spatial_id) > + return 0; > + > ret = av_frame_ref(frame, srcframe); > if (ret < 0) > return ret; > @@ -809,6 +817,8 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame, > goto end; > } > > + s->operating_point_idc = s->raw_seq->operating_point_idc[s->operating_point]; > + > if (s->pix_fmt == AV_PIX_FMT_NONE) { > ret = get_pixel_format(avctx); > if (ret < 0) { > @@ -888,6 +898,9 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame, > s->cur_frame.spatial_id = header->spatial_id; > s->cur_frame.temporal_id = header->temporal_id; > > + s->cur_frame.spatial_id = header->spatial_id; > + s->cur_frame.temporal_id = header->temporal_id; Removed this locally for obvious reasons, seeing the lines immediately above them... > + > if (avctx->hwaccel) { > ret = avctx->hwaccel->start_frame(avctx, unit->data, > unit->data_size); > @@ -979,12 +992,28 @@ static void av1_decode_flush(AVCodecContext *avctx) > av1_frame_unref(avctx, &s->ref[i]); > > av1_frame_unref(avctx, &s->cur_frame); > + s->operating_point_idc = 0; > s->raw_frame_header = NULL; > s->raw_seq = NULL; > > ff_cbs_flush(s->cbc); > } > > +#define OFFSET(x) offsetof(AV1DecContext, x) > +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM > +static const AVOption av1_options[] = { > + { "operating_point", "Select an operating point of the scalable bitstream", > + OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, AV1_MAX_OPERATING_POINTS - 1, VD }, > + { NULL } > +}; > + > +static const AVClass av1_class = { > + .class_name = "AV1 decoder", > + .item_name = av_default_item_name, > + .option = av1_options, > + .version = LIBAVUTIL_VERSION_INT, > +}; > + > AVCodec ff_av1_decoder = { > .name = "av1", > .long_name = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"), > @@ -1000,6 +1029,7 @@ AVCodec ff_av1_decoder = { > FF_CODEC_CAP_SETS_PKT_DTS, > .flush = av1_decode_flush, > .profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), > + .priv_class = &av1_class, > .hw_configs = (const AVCodecHWConfigInternal * []) { > #if CONFIG_AV1_DXVA2_HWACCEL > HWACCEL_DXVA2(av1), > diff --git a/libavcodec/av1dec.h b/libavcodec/av1dec.h > index 4b218f64bb..70414c9ca3 100644 > --- a/libavcodec/av1dec.h > +++ b/libavcodec/av1dec.h > @@ -74,9 +74,13 @@ typedef struct AV1DecContext { > uint16_t tg_start; > uint16_t tg_end; > > + int operating_point_idc; > + > AV1Frame ref[AV1_NUM_REF_FRAMES]; > AV1Frame cur_frame; > > + // AVOptions > + int operating_point; > } AV1DecContext; > > #endif /* AVCODEC_AV1DEC_H */ >
On 15/11/2020 21:55, James Almer wrote: > Signed-off-by: James Almer <jamrial@gmail.com> > --- > doc/decoders.texi | 13 +++++++++++++ > libavcodec/av1dec.c | 30 ++++++++++++++++++++++++++++++ > libavcodec/av1dec.h | 4 ++++ > 3 files changed, 47 insertions(+) > > diff --git a/doc/decoders.texi b/doc/decoders.texi > index bfab562fb2..27c6ba4a5d 100644 > --- a/doc/decoders.texi > +++ b/doc/decoders.texi > @@ -25,6 +25,19 @@ enabled decoders. > A description of some of the currently available video decoders > follows. > > +@section av1 > + > +AOMedia Video 1 (AV1) decoder. > + > +@subsection Options > + > +@table @option > + > +@item operating_point > +Select an operating point of a scalable AV1 bitstream (0 - 31). Default is 0. > + > +@end table > + > @section rawvideo > > Raw video decoder. > diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c > index c1967f03bd..b7ee307159 100644 > --- a/libavcodec/av1dec.c > +++ b/libavcodec/av1dec.c > @@ -19,6 +19,7 @@ > */ > > #include "libavutil/pixdesc.h" > +#include "libavutil/opt.h" > #include "avcodec.h" > #include "av1dec.h" > #include "bytestream.h" > @@ -615,6 +616,8 @@ static av_cold int av1_decode_init(AVCodecContext *avctx) > if (ret < 0) > return ret; > > + av_opt_set_int(s->cbc->priv_data, "operating_point", s->operating_point, 0); > + > if (avctx->extradata && avctx->extradata_size) { > ret = ff_cbs_read(s->cbc, &s->current_obu, avctx->extradata, > avctx->extradata_size); > @@ -704,6 +707,11 @@ static int set_output_frame(AVCodecContext *avctx, AVFrame *frame, > const AVFrame *srcframe = s->cur_frame.tf.f; > int ret; > > + // TODO: all layers > + if (s->operating_point_idc && > + av_log2(s->operating_point_idc >> 8) > s->cur_frame.spatial_id) > + return 0; I'm confused by what this is doing. Shouldn't it be checking that the spatial_id is in the mask, rather than a numerical comparison? Also, what about temporal_id? > + > ret = av_frame_ref(frame, srcframe); > if (ret < 0) > return ret; > @@ -809,6 +817,8 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame, > goto end; > } > > + s->operating_point_idc = s->raw_seq->operating_point_idc[s->operating_point]; > + > if (s->pix_fmt == AV_PIX_FMT_NONE) { > ret = get_pixel_format(avctx); > if (ret < 0) { > @@ -888,6 +898,9 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame, > s->cur_frame.spatial_id = header->spatial_id; > s->cur_frame.temporal_id = header->temporal_id; > > + s->cur_frame.spatial_id = header->spatial_id; > + s->cur_frame.temporal_id = header->temporal_id; > + > if (avctx->hwaccel) { > ret = avctx->hwaccel->start_frame(avctx, unit->data, > unit->data_size); > @@ -979,12 +992,28 @@ static void av1_decode_flush(AVCodecContext *avctx) > av1_frame_unref(avctx, &s->ref[i]); > > av1_frame_unref(avctx, &s->cur_frame); > + s->operating_point_idc = 0; > s->raw_frame_header = NULL; > s->raw_seq = NULL; > > ff_cbs_flush(s->cbc); > } > > +#define OFFSET(x) offsetof(AV1DecContext, x) > +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM > +static const AVOption av1_options[] = { > + { "operating_point", "Select an operating point of the scalable bitstream", > + OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, AV1_MAX_OPERATING_POINTS - 1, VD }, > + { NULL } > +}; > + > +static const AVClass av1_class = { > + .class_name = "AV1 decoder", > + .item_name = av_default_item_name, > + .option = av1_options, > + .version = LIBAVUTIL_VERSION_INT, > +}; > + > AVCodec ff_av1_decoder = { > .name = "av1", > .long_name = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"), > @@ -1000,6 +1029,7 @@ AVCodec ff_av1_decoder = { > FF_CODEC_CAP_SETS_PKT_DTS, > .flush = av1_decode_flush, > .profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), > + .priv_class = &av1_class, > .hw_configs = (const AVCodecHWConfigInternal * []) { > #if CONFIG_AV1_DXVA2_HWACCEL > HWACCEL_DXVA2(av1), > diff --git a/libavcodec/av1dec.h b/libavcodec/av1dec.h > index 4b218f64bb..70414c9ca3 100644 > --- a/libavcodec/av1dec.h > +++ b/libavcodec/av1dec.h > @@ -74,9 +74,13 @@ typedef struct AV1DecContext { > uint16_t tg_start; > uint16_t tg_end; > > + int operating_point_idc; > + > AV1Frame ref[AV1_NUM_REF_FRAMES]; > AV1Frame cur_frame; > > + // AVOptions > + int operating_point; > } AV1DecContext; > > #endif /* AVCODEC_AV1DEC_H */ > - Mark
On 12/9/2020 6:36 PM, Mark Thompson wrote: > On 15/11/2020 21:55, James Almer wrote: >> Signed-off-by: James Almer <jamrial@gmail.com> >> --- >> doc/decoders.texi | 13 +++++++++++++ >> libavcodec/av1dec.c | 30 ++++++++++++++++++++++++++++++ >> libavcodec/av1dec.h | 4 ++++ >> 3 files changed, 47 insertions(+) >> >> diff --git a/doc/decoders.texi b/doc/decoders.texi >> index bfab562fb2..27c6ba4a5d 100644 >> --- a/doc/decoders.texi >> +++ b/doc/decoders.texi >> @@ -25,6 +25,19 @@ enabled decoders. >> A description of some of the currently available video decoders >> follows. >> +@section av1 >> + >> +AOMedia Video 1 (AV1) decoder. >> + >> +@subsection Options >> + >> +@table @option >> + >> +@item operating_point >> +Select an operating point of a scalable AV1 bitstream (0 - 31). >> Default is 0. >> + >> +@end table >> + >> @section rawvideo >> Raw video decoder. >> diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c >> index c1967f03bd..b7ee307159 100644 >> --- a/libavcodec/av1dec.c >> +++ b/libavcodec/av1dec.c >> @@ -19,6 +19,7 @@ >> */ >> #include "libavutil/pixdesc.h" >> +#include "libavutil/opt.h" >> #include "avcodec.h" >> #include "av1dec.h" >> #include "bytestream.h" >> @@ -615,6 +616,8 @@ static av_cold int av1_decode_init(AVCodecContext >> *avctx) >> if (ret < 0) >> return ret; >> + av_opt_set_int(s->cbc->priv_data, "operating_point", >> s->operating_point, 0); >> + >> if (avctx->extradata && avctx->extradata_size) { >> ret = ff_cbs_read(s->cbc, &s->current_obu, avctx->extradata, >> avctx->extradata_size); >> @@ -704,6 +707,11 @@ static int set_output_frame(AVCodecContext >> *avctx, AVFrame *frame, >> const AVFrame *srcframe = s->cur_frame.tf.f; >> int ret; >> + // TODO: all layers >> + if (s->operating_point_idc && >> + av_log2(s->operating_point_idc >> 8) > s->cur_frame.spatial_id) >> + return 0; > > I'm confused by what this is doing. Shouldn't it be checking that the > spatial_id is in the mask, rather than a numerical comparison? It's what dav1d does. Checking that the current frame's spatial layer is the highest, which is also the highest quality one, and skipping the rest. Ensuring it's in the mask is done by CBS. > > Also, what about temporal_id? That's also handled by CBS, in the drop_obu() change from patch 3. > >> + >> ret = av_frame_ref(frame, srcframe); >> if (ret < 0) >> return ret; >> @@ -809,6 +817,8 @@ static int av1_decode_frame(AVCodecContext *avctx, >> void *frame, >> goto end; >> } >> + s->operating_point_idc = >> s->raw_seq->operating_point_idc[s->operating_point]; >> + >> if (s->pix_fmt == AV_PIX_FMT_NONE) { >> ret = get_pixel_format(avctx); >> if (ret < 0) { >> @@ -888,6 +898,9 @@ static int av1_decode_frame(AVCodecContext *avctx, >> void *frame, >> s->cur_frame.spatial_id = header->spatial_id; >> s->cur_frame.temporal_id = header->temporal_id; >> + s->cur_frame.spatial_id = header->spatial_id; >> + s->cur_frame.temporal_id = header->temporal_id; >> + >> if (avctx->hwaccel) { >> ret = avctx->hwaccel->start_frame(avctx, unit->data, >> unit->data_size); >> @@ -979,12 +992,28 @@ static void av1_decode_flush(AVCodecContext *avctx) >> av1_frame_unref(avctx, &s->ref[i]); >> av1_frame_unref(avctx, &s->cur_frame); >> + s->operating_point_idc = 0; >> s->raw_frame_header = NULL; >> s->raw_seq = NULL; >> ff_cbs_flush(s->cbc); >> } >> +#define OFFSET(x) offsetof(AV1DecContext, x) >> +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM >> +static const AVOption av1_options[] = { >> + { "operating_point", "Select an operating point of the scalable >> bitstream", >> + OFFSET(operating_point), AV_OPT_TYPE_INT, { >> .i64 = 0 }, 0, AV1_MAX_OPERATING_POINTS - 1, VD }, >> + { NULL } >> +}; >> + >> +static const AVClass av1_class = { >> + .class_name = "AV1 decoder", >> + .item_name = av_default_item_name, >> + .option = av1_options, >> + .version = LIBAVUTIL_VERSION_INT, >> +}; >> + >> AVCodec ff_av1_decoder = { >> .name = "av1", >> .long_name = NULL_IF_CONFIG_SMALL("Alliance for Open >> Media AV1"), >> @@ -1000,6 +1029,7 @@ AVCodec ff_av1_decoder = { >> FF_CODEC_CAP_SETS_PKT_DTS, >> .flush = av1_decode_flush, >> .profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), >> + .priv_class = &av1_class, >> .hw_configs = (const AVCodecHWConfigInternal * []) { >> #if CONFIG_AV1_DXVA2_HWACCEL >> HWACCEL_DXVA2(av1), >> diff --git a/libavcodec/av1dec.h b/libavcodec/av1dec.h >> index 4b218f64bb..70414c9ca3 100644 >> --- a/libavcodec/av1dec.h >> +++ b/libavcodec/av1dec.h >> @@ -74,9 +74,13 @@ typedef struct AV1DecContext { >> uint16_t tg_start; >> uint16_t tg_end; >> + int operating_point_idc; >> + >> AV1Frame ref[AV1_NUM_REF_FRAMES]; >> AV1Frame cur_frame; >> + // AVOptions >> + int operating_point; >> } AV1DecContext; >> #endif /* AVCODEC_AV1DEC_H */ >> > > - Mark > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff --git a/doc/decoders.texi b/doc/decoders.texi index bfab562fb2..27c6ba4a5d 100644 --- a/doc/decoders.texi +++ b/doc/decoders.texi @@ -25,6 +25,19 @@ enabled decoders. A description of some of the currently available video decoders follows. +@section av1 + +AOMedia Video 1 (AV1) decoder. + +@subsection Options + +@table @option + +@item operating_point +Select an operating point of a scalable AV1 bitstream (0 - 31). Default is 0. + +@end table + @section rawvideo Raw video decoder. diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c index c1967f03bd..b7ee307159 100644 --- a/libavcodec/av1dec.c +++ b/libavcodec/av1dec.c @@ -19,6 +19,7 @@ */ #include "libavutil/pixdesc.h" +#include "libavutil/opt.h" #include "avcodec.h" #include "av1dec.h" #include "bytestream.h" @@ -615,6 +616,8 @@ static av_cold int av1_decode_init(AVCodecContext *avctx) if (ret < 0) return ret; + av_opt_set_int(s->cbc->priv_data, "operating_point", s->operating_point, 0); + if (avctx->extradata && avctx->extradata_size) { ret = ff_cbs_read(s->cbc, &s->current_obu, avctx->extradata, avctx->extradata_size); @@ -704,6 +707,11 @@ static int set_output_frame(AVCodecContext *avctx, AVFrame *frame, const AVFrame *srcframe = s->cur_frame.tf.f; int ret; + // TODO: all layers + if (s->operating_point_idc && + av_log2(s->operating_point_idc >> 8) > s->cur_frame.spatial_id) + return 0; + ret = av_frame_ref(frame, srcframe); if (ret < 0) return ret; @@ -809,6 +817,8 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame, goto end; } + s->operating_point_idc = s->raw_seq->operating_point_idc[s->operating_point]; + if (s->pix_fmt == AV_PIX_FMT_NONE) { ret = get_pixel_format(avctx); if (ret < 0) { @@ -888,6 +898,9 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame, s->cur_frame.spatial_id = header->spatial_id; s->cur_frame.temporal_id = header->temporal_id; + s->cur_frame.spatial_id = header->spatial_id; + s->cur_frame.temporal_id = header->temporal_id; + if (avctx->hwaccel) { ret = avctx->hwaccel->start_frame(avctx, unit->data, unit->data_size); @@ -979,12 +992,28 @@ static void av1_decode_flush(AVCodecContext *avctx) av1_frame_unref(avctx, &s->ref[i]); av1_frame_unref(avctx, &s->cur_frame); + s->operating_point_idc = 0; s->raw_frame_header = NULL; s->raw_seq = NULL; ff_cbs_flush(s->cbc); } +#define OFFSET(x) offsetof(AV1DecContext, x) +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM +static const AVOption av1_options[] = { + { "operating_point", "Select an operating point of the scalable bitstream", + OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, AV1_MAX_OPERATING_POINTS - 1, VD }, + { NULL } +}; + +static const AVClass av1_class = { + .class_name = "AV1 decoder", + .item_name = av_default_item_name, + .option = av1_options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_av1_decoder = { .name = "av1", .long_name = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"), @@ -1000,6 +1029,7 @@ AVCodec ff_av1_decoder = { FF_CODEC_CAP_SETS_PKT_DTS, .flush = av1_decode_flush, .profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), + .priv_class = &av1_class, .hw_configs = (const AVCodecHWConfigInternal * []) { #if CONFIG_AV1_DXVA2_HWACCEL HWACCEL_DXVA2(av1), diff --git a/libavcodec/av1dec.h b/libavcodec/av1dec.h index 4b218f64bb..70414c9ca3 100644 --- a/libavcodec/av1dec.h +++ b/libavcodec/av1dec.h @@ -74,9 +74,13 @@ typedef struct AV1DecContext { uint16_t tg_start; uint16_t tg_end; + int operating_point_idc; + AV1Frame ref[AV1_NUM_REF_FRAMES]; AV1Frame cur_frame; + // AVOptions + int operating_point; } AV1DecContext; #endif /* AVCODEC_AV1DEC_H */
Signed-off-by: James Almer <jamrial@gmail.com> --- doc/decoders.texi | 13 +++++++++++++ libavcodec/av1dec.c | 30 ++++++++++++++++++++++++++++++ libavcodec/av1dec.h | 4 ++++ 3 files changed, 47 insertions(+)