ref: 86b0042f44fb7e6f316468c452354127f15e9316
parent: f93305aa07859dbcac921c670dda28b046ad87e0
author: Marco <[email protected]>
date: Fri Oct 28 12:26:30 EDT 2016
vp9-svc: Add decoder control to decode up to x spatial layers. Change-Id: I85536473b8722424785c84c5b5520960b4e5744a
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -553,6 +553,9 @@
ctx->decrypt_cb, ctx->decrypt_state);
if (res != VPX_CODEC_OK) return res;
+ if (ctx->svc_decoding && ctx->svc_spatial_layer < frame_count - 1)
+ frame_count = ctx->svc_spatial_layer + 1;
+
if (ctx->frame_parallel_decode) {
// Decode in frame parallel mode. When decoding in this mode, the frame
// passed to the decoder must be either a normal frame or a superframe with
@@ -1001,6 +1004,16 @@
return VPX_CODEC_OK;
}
+static vpx_codec_err_t ctrl_set_spatial_layer_svc(vpx_codec_alg_priv_t *ctx,
+ va_list args) {
+ ctx->svc_decoding = 1;
+ ctx->svc_spatial_layer = va_arg(args, int);
+ if (ctx->svc_spatial_layer < 0)
+ return VPX_CODEC_INVALID_PARAM;
+ else
+ return VPX_CODEC_OK;
+}
+
static vpx_codec_ctrl_fn_map_t decoder_ctrl_maps[] = {
{ VP8_COPY_REFERENCE, ctrl_copy_reference },
@@ -1011,6 +1024,7 @@
{ VPXD_SET_DECRYPTOR, ctrl_set_decryptor },
{ VP9_SET_BYTE_ALIGNMENT, ctrl_set_byte_alignment },
{ VP9_SET_SKIP_LOOP_FILTER, ctrl_set_skip_loop_filter },
+ { VP9_DECODE_SVC_SPATIAL_LAYER, ctrl_set_spatial_layer_svc },
// Getters
{ VP8D_GET_LAST_REF_UPDATES, ctrl_get_last_ref_updates },
--- a/vp9/vp9_dx_iface.h
+++ b/vp9/vp9_dx_iface.h
@@ -60,6 +60,10 @@
void *ext_priv; // Private data associated with the external frame buffers.
vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb;
vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb;
+
+ // Allow for decoding up to a given spatial layer for SVC stream.
+ int svc_decoding;
+ int svc_spatial_layer;
};
#endif // VP9_VP9_DX_IFACE_H_
--- a/vpx/vp8dx.h
+++ b/vpx/vp8dx.h
@@ -111,6 +111,11 @@
*/
VP9_SET_SKIP_LOOP_FILTER,
+ /** control function to decode SVC stream up to the x spatial layers,
+ * where x is passed in through the control, and is 0 for base layer.
+ */
+ VP9_DECODE_SVC_SPATIAL_LAYER,
+
VP8_DECODER_CTRL_ID_MAX
};
@@ -162,6 +167,8 @@
#define VPX_CTRL_VP9D_GET_FRAME_SIZE
VPX_CTRL_USE_TYPE(VP9_INVERT_TILE_DECODE_ORDER, int)
#define VPX_CTRL_VP9_INVERT_TILE_DECODE_ORDER
+#define VPX_CTRL_VP9_DECODE_SVC_SPATIAL_LAYER
+VPX_CTRL_USE_TYPE(VP9_DECODE_SVC_SPATIAL_LAYER, int)
/*!\endcond */
/*! @} - end defgroup vp8_decoder */
--- a/vpxdec.c
+++ b/vpxdec.c
@@ -92,31 +92,19 @@
static const arg_def_t outbitdeptharg =
ARG_DEF(NULL, "output-bit-depth", 1, "Output bit-depth for decoded frames");
#endif
+static const arg_def_t svcdecodingarg = ARG_DEF(
+ NULL, "svc-decode-layer", 1, "Decode SVC stream up to given spatial layer");
-static const arg_def_t *all_args[] = { &codecarg,
- &use_yv12,
- &use_i420,
- &flipuvarg,
- &rawvideo,
- &noblitarg,
- &progressarg,
- &limitarg,
- &skiparg,
- &postprocarg,
- &summaryarg,
- &outputfile,
- &threadsarg,
- &frameparallelarg,
- &verbosearg,
- &scalearg,
- &fb_arg,
- &md5arg,
- &error_concealment,
- &continuearg,
+static const arg_def_t *all_args[] = {
+ &codecarg, &use_yv12, &use_i420, &flipuvarg, &rawvideo,
+ &noblitarg, &progressarg, &limitarg, &skiparg, &postprocarg,
+ &summaryarg, &outputfile, &threadsarg, &frameparallelarg, &verbosearg,
+ &scalearg, &fb_arg, &md5arg, &error_concealment, &continuearg,
#if CONFIG_VP9_HIGHBITDEPTH
- &outbitdeptharg,
+ &outbitdeptharg,
#endif
- NULL };
+ &svcdecodingarg, NULL
+};
#if CONFIG_VP8_DECODER
static const arg_def_t addnoise_level =
@@ -519,6 +507,8 @@
#if CONFIG_VP9_HIGHBITDEPTH
unsigned int output_bit_depth = 0;
#endif
+ int svc_decoding = 0;
+ int svc_spatial_layer = 0;
#if CONFIG_VP8_DECODER
vp8_postproc_cfg_t vp8_pp_cfg = { 0, 0, 0 };
#endif
@@ -610,6 +600,10 @@
output_bit_depth = arg_parse_uint(&arg);
}
#endif
+ else if (arg_match(&arg, &svcdecodingarg, argi)) {
+ svc_decoding = 1;
+ svc_spatial_layer = arg_parse_uint(&arg);
+ }
#if CONFIG_VP8_DECODER
else if (arg_match(&arg, &addnoise_level, argi)) {
postproc = 1;
@@ -726,7 +720,14 @@
vpx_codec_error(&decoder));
goto fail2;
}
-
+ if (svc_decoding) {
+ if (vpx_codec_control(&decoder, VP9_DECODE_SVC_SPATIAL_LAYER,
+ svc_spatial_layer)) {
+ fprintf(stderr, "Failed to set spatial layer for svc decode: %s\n",
+ vpx_codec_error(&decoder));
+ goto fail;
+ }
+ }
if (!quiet) fprintf(stderr, "%s\n", decoder.name);
#if CONFIG_VP8_DECODER