From: John Koleszar Date: Tue, 20 Mar 2012 23:38:25 +0000 (-0700) Subject: WIP: add support for using the modemv from the original stream directly X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6463c7cf72112962fcfc3dc81783852020a83895;p=libvpx WIP: add support for using the modemv from the original stream directly Change-Id: I4e849a67eaeb654cd1f5c2ac907145cac040a532 --- diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index 276859d31..f97336711 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -70,6 +70,7 @@ struct vpx_codec_alg_priv vpx_image_t img; int img_setup; int img_avail; + vpx_fixed_buf_t mode_info; }; static unsigned long vp8_priv_sz(const vpx_codec_dec_cfg_t *si, vpx_codec_flags_t flags) @@ -743,6 +744,43 @@ static vpx_codec_err_t vp8_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, } +static vpx_codec_err_t get_mode_info(vpx_codec_alg_priv_t *ctx, + int ctrl_id, + va_list args) +{ + vpx_fixed_buf_t **data = va_arg(args, vpx_fixed_buf_t **); + VP8D_COMP *pbi = (VP8D_COMP *)ctx->pbi; + size_t mi_sz = sizeof(MODE_INFO)*pbi->common.mb_rows * pbi->common.mb_cols; + char *buf; + size_t buf_stride; + int i; + MODE_INFO *mi; + + if(data) + { + if(ctx->mode_info.sz != mi_sz) + { + free(ctx->mode_info.buf); + ctx->mode_info.buf = malloc(mi_sz); + ctx->mode_info.sz = mi_sz; + } + + mi = pbi->common.mi; + buf = ctx->mode_info.buf; + buf_stride = pbi->common.mb_cols * sizeof(MODE_INFO); + for(i=0; icommon.mb_rows; i++) + { + memcpy(buf, mi, buf_stride); + buf += buf_stride; + mi += pbi->common.mode_info_stride; + } + *data = &ctx->mode_info; + return VPX_CODEC_OK; + } + else + return VPX_CODEC_INVALID_PARAM; +} + vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = { {VP8_SET_REFERENCE, vp8_set_reference}, @@ -755,6 +793,7 @@ vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = {VP8D_GET_LAST_REF_UPDATES, vp8_get_last_ref_updates}, {VP8D_GET_FRAME_CORRUPTED, vp8_get_frame_corrupted}, {VP8D_GET_LAST_REF_USED, vp8_get_last_ref_frame}, + {VP8D_GET_MODE_INFO, get_mode_info}, { -1, NULL}, }; diff --git a/vpx/vp8dx.h b/vpx/vp8dx.h index 86610358c..42310abf3 100644 --- a/vpx/vp8dx.h +++ b/vpx/vp8dx.h @@ -60,6 +60,8 @@ enum vp8_dec_control_id */ VP8D_GET_LAST_REF_USED, + VP8D_GET_MODE_INFO, + VP8_DECODER_CTRL_ID_MAX } ; @@ -75,6 +77,7 @@ enum vp8_dec_control_id VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_UPDATES, int *) VPX_CTRL_USE_TYPE(VP8D_GET_FRAME_CORRUPTED, int *) VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_USED, int *) +VPX_CTRL_USE_TYPE(VP8D_GET_MODE_INFO, vpx_fixed_buf_t **) /*! @} - end defgroup vp8_decoder */ diff --git a/vpx/vpx_codec.h b/vpx/vpx_codec.h index d92e165ff..4692edc9b 100644 --- a/vpx/vpx_codec.h +++ b/vpx/vpx_codec.h @@ -134,6 +134,17 @@ extern "C" { vpx_codec_err_t; + /*!\brief Generic fixed size buffer structure + * + * This structure is able to hold a reference to any fixed size buffer. + */ + typedef struct vpx_fixed_buf + { + void *buf; /**< Pointer to the data */ + size_t sz; /**< Length of the buffer, in chars */ + } vpx_fixed_buf_t; /**< alias for struct vpx_fixed_buf */ + + /*! \brief Codec capabilities bitfield * * Each codec advertises the capabilities it supports as part of its diff --git a/vpx/vpx_encoder.h b/vpx/vpx_encoder.h index c5429c9bc..093749c39 100644 --- a/vpx/vpx_encoder.h +++ b/vpx/vpx_encoder.h @@ -77,17 +77,6 @@ extern "C" { partition at a time. */ - /*!\brief Generic fixed size buffer structure - * - * This structure is able to hold a reference to any fixed size buffer. - */ - typedef struct vpx_fixed_buf - { - void *buf; /**< Pointer to the data */ - size_t sz; /**< Length of the buffer, in chars */ - } vpx_fixed_buf_t; /**< alias for struct vpx_fixed_buf */ - - /*!\brief Time Stamp Type * * An integer, which when multiplied by the stream's time base, provides diff --git a/vpxenc.c b/vpxenc.c index d8c4fd71a..8f125d7c3 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -2612,12 +2612,14 @@ float usec_to_fps(uint64_t usec, unsigned int frames) static void set_modeinfo(struct stream_state *stream, - struct webm_ctx *webm) + struct input_state *input) { + struct webm_ctx *webm = &input->webm; unsigned char *ptr; struct link_record link; int again; int refs=0; + int mi_set = 0; vpx_codec_control(&stream->encoder, VP8E_SET_MODEINFO, NULL); ptr = webm->buf + webm->buf_sz; @@ -2638,9 +2640,32 @@ static void set_modeinfo(struct stream_state *stream, vpx_codec_control(&stream->encoder, VP8E_SET_MODEINFO, &modeinfo); vpx_codec_control(&stream->encoder, VP8E_UPD_REFERENCE, link.refs_updated); ctx_exit_on_error(&stream->encoder, "Failed to set refs"); + mi_set = 1; break; } + if((link.w|link.sz)&0xF) + break; + if(link.w > 16383 || link.h > 16383) + break; } while(again); + + if(!mi_set + && stream->config.cfg.g_w == input->w + && stream->config.cfg.g_h == input->h) + { + vpx_fixed_buf_t *modeinfo; + int refs_updated; + + vpx_codec_control(&webm->decoder, VP8D_GET_MODE_INFO, &modeinfo); + ctx_exit_on_error(&webm->decoder, "Failed to get mode info"); + vpx_codec_control(&stream->encoder, VP8E_SET_MODEINFO, modeinfo); + ctx_exit_on_error(&webm->decoder, "Failed to set mode info"); + + vpx_codec_control(&webm->decoder, VP8D_GET_LAST_REF_UPDATES, &refs_updated); + ctx_exit_on_error(&webm->decoder, "Failed to get ref updates"); + vpx_codec_control(&stream->encoder, VP8E_UPD_REFERENCE, refs_updated); + ctx_exit_on_error(&stream->encoder, "Failed to set ref updates"); + } } int main(int argc, const char **argv_) @@ -2801,7 +2826,7 @@ int main(int argc, const char **argv_) /* Update mode/mv info if available */ if(input.file_type == FILE_TYPE_WEBM && global.read_modemv) - FOREACH_STREAM(set_modeinfo(stream, &input.webm)); + FOREACH_STREAM(set_modeinfo(stream, &input)); vpx_usec_timer_start(&timer); FOREACH_STREAM(encode_frame(stream, &global,