On 12/9/2020 6:36 PM, Mark Thompson wrote:
On 15/11/2020 21:55, James Almer wrote:
Signed-off-by: James Almer <jamr...@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-requ...@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".