From 86b0042f44fb7e6f316468c452354127f15e9316 Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 28 Oct 2016 16:26:30 -0700 Subject: [PATCH] vp9-svc: Add decoder control to decode up to x spatial layers. Change-Id: I85536473b8722424785c84c5b5520960b4e5744a --- vp9/vp9_dx_iface.c | 14 ++++++++++++++ vp9/vp9_dx_iface.h | 4 ++++ vpx/vp8dx.h | 7 +++++++ vpxdec.c | 47 +++++++++++++++++++++++----------------------- 4 files changed, 49 insertions(+), 23 deletions(-) diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c index 4a1ebbc8c..0a3e84a0d 100644 --- a/vp9/vp9_dx_iface.c +++ b/vp9/vp9_dx_iface.c @@ -553,6 +553,9 @@ static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, 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 @@ static vpx_codec_err_t ctrl_set_skip_loop_filter(vpx_codec_alg_priv_t *ctx, 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 @@ static vpx_codec_ctrl_fn_map_t decoder_ctrl_maps[] = { { 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 }, diff --git a/vp9/vp9_dx_iface.h b/vp9/vp9_dx_iface.h index cc3d51842..c1559599b 100644 --- a/vp9/vp9_dx_iface.h +++ b/vp9/vp9_dx_iface.h @@ -60,6 +60,10 @@ struct vpx_codec_alg_priv { 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_ diff --git a/vpx/vp8dx.h b/vpx/vp8dx.h index 88204acd3..0d7759eb2 100644 --- a/vpx/vp8dx.h +++ b/vpx/vp8dx.h @@ -111,6 +111,11 @@ enum vp8_dec_control_id { */ 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 @@ VPX_CTRL_USE_TYPE(VP9D_GET_FRAME_SIZE, int *) #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 */ diff --git a/vpxdec.c b/vpxdec.c index f1b09e657..2cdb69d5a 100644 --- a/vpxdec.c +++ b/vpxdec.c @@ -92,31 +92,19 @@ static const arg_def_t md5arg = 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 @@ static int main_loop(int argc, const char **argv_) { #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 @@ static int main_loop(int argc, const char **argv_) { 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 @@ static int main_loop(int argc, const char **argv_) { 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