From patchwork Fri Nov 11 07:57:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jun Zhao X-Patchwork-Id: 1384 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.90.1 with SMTP id o1csp1270856vsb; Thu, 10 Nov 2016 23:57:29 -0800 (PST) X-Received: by 10.194.95.65 with SMTP id di1mr7922659wjb.184.1478851049164; Thu, 10 Nov 2016 23:57:29 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id v4si8984585wjk.289.2016.11.10.23.57.28; Thu, 10 Nov 2016 23:57:29 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 844C1689DFC; Fri, 11 Nov 2016 09:57:22 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf0-f173.google.com (mail-pf0-f173.google.com [209.85.192.173]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 47734689CCC for ; Fri, 11 Nov 2016 09:57:15 +0200 (EET) Received: by mail-pf0-f173.google.com with SMTP id d2so8032507pfd.0 for ; Thu, 10 Nov 2016 23:57:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=to:from:subject:message-id:date:user-agent:mime-version; bh=AHQdA4SOAAoXuzYrWSuv/x1u61+7slRxYF1VqzdMgtk=; b=C5C6nY2BP4NISpvoNqmyzPIKq39cNhIWiq+1JSfx9IGzED4Qjul+2JoPUacfhHkPLX jC8tKFX+tBU118AgD8nMVZkIsCVIT4J9EZeCPJwIrlEm1QI2ikbACbvdiLVIdqEedcsg UaxCBnWZj9+/XQ07rsnYjLVTaasOCOd1gy6HZaDskKfUw9W6WQnuePeSkdOy8yhuej3f DPvXSDcNYNNhCr8X5XQARQ2KPP5kY3ZuX3ZNL/6s0djVHeP6mBMDZKjFkSi7XIvH9WZg 1uJhY56ifdWBchWoc+vaGF/lF8Loo6aYWdGC+drxitLja7KK8WbHnR5VPbYZ3lUwY3Mn x4tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version; bh=AHQdA4SOAAoXuzYrWSuv/x1u61+7slRxYF1VqzdMgtk=; b=Z16wl8Z7iV3+/qrwwn0qQNERxCpB7Uq3lthiNYJFIjUXRjpl2bQ3mD9QI/puGeiuC9 3Gnjvi5rUp6qc4RUbQV+oRZ98qcba/s9hMDsMEt9AUu88zD/NfmCsvf8sIIIl5SL8fLQ 7a7T3pgThgJUyn2zIDC7MQCmUhVUlUF1e/stnRz54CqIjCmOWgnyHFmBFk01V72joPw9 218T8CLVg1eEhdIwpFyFVb1WdEx4Qpsvu29OXNDSYs7UcepZs5Bg61Mpd58Wwx7yk57U slV70IUsE7hbIFxm0FfVz0QNyhW1kxc3eKwj6uLtlKMMCK+S8Vp0NdCVugQyT09PzWGH uYdA== X-Gm-Message-State: ABUngvdDeFBlwIApNnvkxFELxQhZ3AvGSKUC+KLdieAS7uMhd2KrQpOgzq8YxcSB9DGvdw== X-Received: by 10.98.67.138 with SMTP id l10mr4476025pfi.101.1478851037303; Thu, 10 Nov 2016 23:57:17 -0800 (PST) Received: from [10.239.204.196] ([192.55.54.43]) by smtp.gmail.com with ESMTPSA id t20sm12583853pfk.48.2016.11.10.23.57.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 10 Nov 2016 23:57:16 -0800 (PST) To: FFmpeg development discussions and patches , jun.zhao@intel.com, Mark Thompson , mypopydev@gmail.com, Yi Wang From: Jun Zhao Message-ID: Date: Fri, 11 Nov 2016 15:57:13 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 Content-Disposition: attachment; filename="0001-lavc-vaapi-Add-VP8-decode-hwaccel.patch" X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: [FFmpeg-devel] [PATCH] lavc/vaapi: Add VP8 decode hwaccel X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From 4635e7e4a0ea24f77e71ffc9a9074e75c61bfe44 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Fri, 11 Nov 2016 15:51:01 +0800 Subject: [PATCH] lavc/vaapi: Add VP8 decode hwaccel Add VP8 decode hwaccel based on the libav: commit a9fb134730da1f9642eb5a2baa50943b8a4aa245 lavc/vaapi: Add VP8 decode hwaccel commit 75d642a944d5579e4ef20ff3701422a64692afcf vaapi_vp8: Explicitly include libva vp8 decode header Reviewed-by: Jun Zhao Signed-off-by: Wang, Yi A ase enter the commit message for your changes. Lines starting --- configure | 3 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/vaapi.c | 15 ++++- libavcodec/vaapi.h | 9 +++ libavcodec/vaapi_internal.h | 3 + libavcodec/vp8.c | 149 ++++++++++++++++++++++++++++++-------------- libavcodec/vp8.h | 29 ++++++++- 8 files changed, 159 insertions(+), 51 deletions(-) diff --git a/configure b/configure index 87b06f1..7b6a1c4 100755 --- a/configure +++ b/configure @@ -2668,6 +2668,8 @@ vp8_cuvid_hwaccel_deps="cuda cuvid" vp9_cuvid_hwaccel_deps="cuda cuvid" vp8_mediacodec_decoder_deps="mediacodec" vp8_mediacodec_hwaccel_deps="mediacodec" +vp8_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferVP8" +vp8_vaapi_hwaccel_select="vp8_decoder" vp9_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_VP9" vp9_d3d11va_hwaccel_select="vp9_decoder" vp9_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_VP9" @@ -5588,6 +5590,7 @@ check_type "va/va.h va/va_vpp.h" "VAProcPipelineParameterBuffer" check_type "va/va.h va/va_enc_h264.h" "VAEncPictureParameterBufferH264" check_type "va/va.h va/va_enc_hevc.h" "VAEncPictureParameterBufferHEVC" check_type "va/va.h va/va_enc_jpeg.h" "VAEncPictureParameterBufferJPEG" +check_type "va/va.h va/va_dec_vp8.h" "VAPictureParameterBufferVP8" check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 5fdc97f..502872c 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -804,6 +804,7 @@ OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o OBJS-$(CONFIG_VP9_D3D11VA_HWACCEL) += dxva2_vp9.o OBJS-$(CONFIG_VP9_DXVA2_HWACCEL) += dxva2_vp9.o OBJS-$(CONFIG_VP9_VAAPI_HWACCEL) += vaapi_vp9.o +OBJS-$(CONFIG_VP8_VAAPI_HWACCEL) += vaapi_vp8.o # libavformat dependencies OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index ada9481..64a7ccd 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -125,6 +125,7 @@ void avcodec_register_all(void) REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2); REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi); REGISTER_HWACCEL(WMV3_VDPAU, wmv3_vdpau); + REGISTER_HWACCEL(VP8_VAAPI, vp8_vaapi); /* video codecs */ REGISTER_ENCODER(A64MULTI, a64multi); diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c index 36db640..e440e8f 100644 --- a/libavcodec/vaapi.c +++ b/libavcodec/vaapi.c @@ -59,6 +59,7 @@ int ff_vaapi_context_init(AVCodecContext *avctx) vactx->pic_param_buf_id = VA_INVALID_ID; vactx->iq_matrix_buf_id = VA_INVALID_ID; vactx->bitplane_buf_id = VA_INVALID_ID; + vactx->prob_buf_id = VA_INVALID_ID; return 0; } @@ -70,7 +71,7 @@ int ff_vaapi_context_fini(AVCodecContext *avctx) int ff_vaapi_render_picture(FFVAContext *vactx, VASurfaceID surface) { - VABufferID va_buffers[3]; + VABufferID va_buffers[4]; unsigned int n_va_buffers = 0; if (vactx->pic_param_buf_id == VA_INVALID_ID) @@ -89,6 +90,11 @@ int ff_vaapi_render_picture(FFVAContext *vactx, VASurfaceID surface) va_buffers[n_va_buffers++] = vactx->bitplane_buf_id; } + if (vactx->prob_buf_id != VA_INVALID_ID) { + vaUnmapBuffer(vactx->display, vactx->prob_buf_id); + va_buffers[n_va_buffers++] = vactx->prob_buf_id; + } + if (vaBeginPicture(vactx->display, vactx->context_id, surface) != VA_STATUS_SUCCESS) return -1; @@ -175,6 +181,11 @@ uint8_t *ff_vaapi_alloc_bitplane(FFVAContext *vactx, uint32_t size) return alloc_buffer(vactx, VABitPlaneBufferType, size, &vactx->bitplane_buf_id); } +uint8_t *ff_vaapi_alloc_prob_buffer(FFVAContext *vactx, uint32_t size) +{ + return alloc_buffer(vactx, VAProbabilityBufferType, size, &vactx->prob_buf_id); +} + VASliceParameterBufferBase *ff_vaapi_alloc_slice(FFVAContext *vactx, const uint8_t *buffer, uint32_t size) { uint8_t *slice_params; @@ -209,10 +220,10 @@ VASliceParameterBufferBase *ff_vaapi_alloc_slice(FFVAContext *vactx, const uint8 void ff_vaapi_common_end_frame(AVCodecContext *avctx) { FFVAContext * const vactx = ff_vaapi_get_context(avctx); - destroy_buffers(vactx->display, &vactx->pic_param_buf_id, 1); destroy_buffers(vactx->display, &vactx->iq_matrix_buf_id, 1); destroy_buffers(vactx->display, &vactx->bitplane_buf_id, 1); + destroy_buffers(vactx->display, &vactx->prob_buf_id, 1); destroy_buffers(vactx->display, vactx->slice_buf_ids, vactx->n_slice_buf_ids); av_freep(&vactx->slice_buf_ids); av_freep(&vactx->slice_params); diff --git a/libavcodec/vaapi.h b/libavcodec/vaapi.h index 7a29f6f..4c86538 100644 --- a/libavcodec/vaapi.h +++ b/libavcodec/vaapi.h @@ -103,6 +103,15 @@ struct vaapi_context { uint32_t bitplane_buf_id; /** + * VAProbabilityBuffer ID (for VP-8 decoding) + * + * - encoding: unused + * - decoding: Set by libavcodec + */ + attribute_deprecated + uint32_t prob_buf_id; + + /** * Slice parameter/data buffer IDs * * - encoding: unused diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h index 306ae13..76cc6b0 100644 --- a/libavcodec/vaapi_internal.h +++ b/libavcodec/vaapi_internal.h @@ -42,6 +42,7 @@ typedef struct { VABufferID pic_param_buf_id; ///< Picture parameter buffer VABufferID iq_matrix_buf_id; ///< Inverse quantiser matrix buffer VABufferID bitplane_buf_id; ///< Bitplane buffer (for VC-1 decoding) + VABufferID prob_buf_id; ///< Prob buffer (for VP-8 decoding) VABufferID *slice_buf_ids; ///< Slice parameter/data buffers unsigned int n_slice_buf_ids; ///< Number of effective slice buffers unsigned int slice_buf_ids_alloc; ///< Number of allocated slice buffers @@ -83,6 +84,8 @@ void *ff_vaapi_alloc_iq_matrix(FFVAContext *vactx, unsigned int size); /** Allocate a new bit-plane buffer */ uint8_t *ff_vaapi_alloc_bitplane(FFVAContext *vactx, uint32_t size); +/** Allocate a new prob buffer */ +uint8_t *ff_vaapi_alloc_prob_buffer(FFVAContext *vactx, uint32_t size); /** * Allocate a new slice descriptor for the input slice. * diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index c1c3eb7..fe53806 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -140,7 +140,7 @@ static VP8Frame *vp8_find_free_buffer(VP8Context *s) av_log(s->avctx, AV_LOG_FATAL, "Ran out of free frames!\n"); abort(); } - if (frame->tf.f->data[0]) + if (frame->tf.f->buf[0]) vp8_release_frame(s, frame); return frame; @@ -218,8 +218,9 @@ static void parse_segment_info(VP8Context *s) int i; s->segmentation.update_map = vp8_rac_get(c); + s->segmentation.update_feature_data = vp8_rac_get(c); - if (vp8_rac_get(c)) { // update segment feature data + if (s->segmentation.update_feature_data) { // update segment feature data s->segmentation.absolute_vals = vp8_rac_get(c); for (i = 0; i < 4; i++) @@ -273,11 +274,14 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) int size = AV_RL24(sizes + 3 * i); if (buf_size - size < 0) return -1; + s->coeff_partition_size[i] = size; ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); buf += size; buf_size -= size; } + + s->coeff_partition_size[i] = buf_size; ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); return 0; @@ -333,6 +337,12 @@ static void vp8_get_quants(VP8Context *s) s->qmat[i].luma_dc_qmul[1] = FFMAX(s->qmat[i].luma_dc_qmul[1], 8); s->qmat[i].chroma_qmul[0] = FFMIN(s->qmat[i].chroma_qmul[0], 132); } + s->quant.yac_qi = yac_qi; + s->quant.ydc_delta = ydc_delta; + s->quant.y2dc_delta = y2dc_delta; + s->quant.y2ac_delta = y2ac_delta; + s->quant.uvdc_delta = uvdc_delta; + s->quant.uvac_delta = uvac_delta; } /** @@ -656,6 +666,7 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si buf += 3; buf_size -= 3; + s->header_partition_size = header_size; if (s->profile > 3) av_log(s->avctx, AV_LOG_WARNING, "Unknown profile %d\n", s->profile); @@ -719,9 +730,11 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si s->filter.level = vp8_rac_get_uint(c, 6); s->filter.sharpness = vp8_rac_get_uint(c, 3); - if ((s->lf_delta.enabled = vp8_rac_get(c))) - if (vp8_rac_get(c)) + if ((s->lf_delta.enabled = vp8_rac_get(c))) { + s->lf_delta.update = vp8_rac_get(c); + if (s->lf_delta.update) update_lf_deltas(s); + } if (setup_partitions(s, buf, buf_size)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid partitions\n"); @@ -761,6 +774,12 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP8_MVC_SIZE); } + s->c.code_word = vp56_rac_renorm(&s->c); + s->coder_state_at_header_end.input = s->c.buffer - (-s->c.bits / 8); + s->coder_state_at_header_end.range = s->c.high; + s->coder_state_at_header_end.value = s->c.code_word >> 16; + s->coder_state_at_header_end.bit_count = -s->c.bits % 8; + return 0; } @@ -2538,6 +2557,22 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (ret < 0) goto err; + if (!is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) { + enum AVPixelFormat pix_fmts[] = { +#if CONFIG_VP8_VAAPI_HWACCEL + AV_PIX_FMT_VAAPI, +#endif + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NONE, + }; + + s->pix_fmt = ff_get_format(s->avctx, pix_fmts); + if (s->pix_fmt < 0) { + ret = AVERROR(EINVAL); + goto err; + } + avctx->pix_fmt = s->pix_fmt; + } prev_frame = s->framep[VP56_FRAME_CURRENT]; @@ -2557,7 +2592,7 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, // release no longer referenced frames for (i = 0; i < 5; i++) - if (s->frames[i].tf.f->data[0] && + if (s->frames[i].tf.f->buf[0] && &s->frames[i] != prev_frame && &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] && &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] && @@ -2613,52 +2648,65 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (avctx->codec->update_thread_context) ff_thread_finish_setup(avctx); - s->linesize = curframe->tf.f->linesize[0]; - s->uvlinesize = curframe->tf.f->linesize[1]; - - memset(s->top_nnz, 0, s->mb_width * sizeof(*s->top_nnz)); - /* Zero macroblock structures for top/top-left prediction - * from outside the frame. */ - if (!s->mb_layout) - memset(s->macroblocks + s->mb_height * 2 - 1, 0, - (s->mb_width + 1) * sizeof(*s->macroblocks)); - if (!s->mb_layout && s->keyframe) - memset(s->intra4x4_pred_mode_top, DC_PRED, s->mb_width * 4); + if (avctx->hwaccel) { + ret = avctx->hwaccel->start_frame(avctx, avpkt->data, avpkt->size); + if (ret < 0) + goto err; + ret = avctx->hwaccel->decode_slice(avctx, avpkt->data, avpkt->size); + if (ret < 0) + goto err; + ret = avctx->hwaccel->end_frame(avctx); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "end_frame error"); + goto err; + } + } else { + s->linesize = curframe->tf.f->linesize[0]; + s->uvlinesize = curframe->tf.f->linesize[1]; - memset(s->ref_count, 0, sizeof(s->ref_count)); + memset(s->top_nnz, 0, s->mb_width * sizeof(*s->top_nnz)); + /* Zero macroblock structures for top/top-left prediction + * from outside the frame. */ + if (!s->mb_layout) + memset(s->macroblocks + s->mb_height * 2 - 1, 0, + (s->mb_width + 1) * sizeof(*s->macroblocks)); + if (!s->mb_layout && s->keyframe) + memset(s->intra4x4_pred_mode_top, DC_PRED, s->mb_width * 4); + + memset(s->ref_count, 0, sizeof(s->ref_count)); + + if (s->mb_layout == 1) { + // Make sure the previous frame has read its segmentation map, + // if we re-use the same map. + if (prev_frame && s->segmentation.enabled && + !s->segmentation.update_map) + ff_thread_await_progress(&prev_frame->tf, 1, 0); + if (is_vp7) + vp7_decode_mv_mb_modes(avctx, curframe, prev_frame); + else + vp8_decode_mv_mb_modes(avctx, curframe, prev_frame); + } - if (s->mb_layout == 1) { - // Make sure the previous frame has read its segmentation map, - // if we re-use the same map. - if (prev_frame && s->segmentation.enabled && - !s->segmentation.update_map) - ff_thread_await_progress(&prev_frame->tf, 1, 0); - if (is_vp7) - vp7_decode_mv_mb_modes(avctx, curframe, prev_frame); + if (avctx->active_thread_type == FF_THREAD_FRAME) + num_jobs = 1; else - vp8_decode_mv_mb_modes(avctx, curframe, prev_frame); - } - - if (avctx->active_thread_type == FF_THREAD_FRAME) - num_jobs = 1; - else - num_jobs = FFMIN(s->num_coeff_partitions, avctx->thread_count); - s->num_jobs = num_jobs; - s->curframe = curframe; - s->prev_frame = prev_frame; - s->mv_min.y = -MARGIN; - s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN; - for (i = 0; i < MAX_THREADS; i++) { - s->thread_data[i].thread_mb_pos = 0; - s->thread_data[i].wait_mb_pos = INT_MAX; - } - if (is_vp7) - avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL, + num_jobs = FFMIN(s->num_coeff_partitions, avctx->thread_count); + s->num_jobs = num_jobs; + s->curframe = curframe; + s->prev_frame = prev_frame; + s->mv_min.y = -MARGIN; + s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN; + for (i = 0; i < MAX_THREADS; i++) { + s->thread_data[i].thread_mb_pos = 0; + s->thread_data[i].wait_mb_pos = INT_MAX; + } + if (is_vp7) + avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL, num_jobs); - else - avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL, + else + avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL, num_jobs); - + } ff_thread_report_progress(&curframe->tf, INT_MAX, 0); memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4); @@ -2727,6 +2775,7 @@ int vp78_decode_init(AVCodecContext *avctx, int is_vp7) int ret; s->avctx = avctx; + s->pix_fmt = AV_PIX_FMT_NONE; s->vp7 = avctx->codec->id == AV_CODEC_ID_VP7; avctx->pix_fmt = AV_PIX_FMT_YUV420P; avctx->internal->allocate_progress = 1; @@ -2800,14 +2849,18 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, s->mb_width = s_src->mb_width; s->mb_height = s_src->mb_height; } - s->prob[0] = s_src->prob[!s_src->update_probabilities]; s->segmentation = s_src->segmentation; s->lf_delta = s_src->lf_delta; + s->pix_fmt = s_src->pix_fmt; + s->mbskip_enabled = s_src->mbskip_enabled; + s->filter = s_src->filter; memcpy(s->sign_bias, s_src->sign_bias, sizeof(s->sign_bias)); + s->num_coeff_partitions = s_src->num_coeff_partitions; + s->header_partition_size = s_src->header_partition_size; for (i = 0; i < FF_ARRAY_ELEMS(s_src->frames); i++) { - if (s_src->frames[i].tf.f->data[0]) { + if (s_src->frames[i].tf.f->buf[0]) { int ret = vp8_ref_frame(s, &s->frames[i], &s_src->frames[i]); if (ret < 0) return ret; diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h index 374e138..af7285f 100644 --- a/libavcodec/vp8.h +++ b/libavcodec/vp8.h @@ -136,6 +136,8 @@ typedef struct VP8intmv { typedef struct VP8Context { VP8ThreadData *thread_data; AVCodecContext *avctx; + enum AVPixelFormat pix_fmt; + VP8Frame *framep[4]; VP8Frame *next_framep[4]; VP8Frame *curframe; @@ -165,6 +167,7 @@ typedef struct VP8Context { uint8_t enabled; uint8_t absolute_vals; uint8_t update_map; + uint8_t update_feature_data; int8_t base_quant[4]; int8_t filter_level[4]; ///< base loop filter level } segmentation; @@ -192,9 +195,19 @@ typedef struct VP8Context { int16_t chroma_qmul[2]; } qmat[4]; + // Raw quantisation values, which may be needed by hwaccel decode. struct { - uint8_t enabled; ///< whether each mb can have a different strength based on mode/ref + int yac_qi; + int ydc_delta; + int y2dc_delta; + int y2ac_delta; + int uvdc_delta; + int uvac_delta; + } quant; + struct { + uint8_t enabled; ///< whether each mb can have a different strength based on mode/ref + uint8_t update; /** * filter strength adjustment for the following macroblock modes: * [0-3] - i16x16 (always zero) @@ -221,6 +234,19 @@ typedef struct VP8Context { VP56RangeCoder c; ///< header context, includes mb modes and motion vectors + /* This contains the entropy coder state at the end of the header + * block, in the form specified by the standard. For use by + * hwaccels, so that a hardware decoder has the information to + * start decoding at the macroblock layer. + */ + struct { + const uint8_t *input; + uint32_t range; + uint32_t value; + int bit_count; + } coder_state_at_header_end; + + int header_partition_size; /** * These are all of the updatable probabilities for binary decisions. * They are only implicitly reset on keyframes, making it quite likely @@ -258,6 +284,7 @@ typedef struct VP8Context { */ int num_coeff_partitions; VP56RangeCoder coeff_partition[8]; + int coeff_partition_size[8]; VideoDSPContext vdsp; VP8DSPContext vp8dsp; H264PredContext hpc;