| 177 | } |
| 178 | |
| 179 | static enum AVPixelFormat get_pixel_format(VP8Context *s) |
| 180 | { |
| 181 | enum AVPixelFormat pix_fmts[] = { |
| 182 | #if CONFIG_VP8_VAAPI_HWACCEL |
| 183 | AV_PIX_FMT_VAAPI, |
| 184 | #endif |
| 185 | #if CONFIG_VP8_NVDEC_HWACCEL |
| 186 | AV_PIX_FMT_CUDA, |
| 187 | #endif |
| 188 | AV_PIX_FMT_YUV420P, |
| 189 | AV_PIX_FMT_NONE, |
| 190 | }; |
| 191 | |
| 192 | return ff_get_format(s->avctx, pix_fmts); |
| 193 | } |
| 194 | |
| 195 | static av_always_inline |
| 196 | int update_dimensions(VP8Context *s, int width, int height, int is_vp7) |
| 197 | { |
| 198 | AVCodecContext *avctx = s->avctx; |
| 199 | int i, ret, dim_reset = 0; |
| 200 | |
| 201 | if (width != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base || |
| 202 | height != s->avctx->height) { |
| 203 | vp8_decode_flush_impl(s->avctx, 1); |
| 204 | |
| 205 | ret = ff_set_dimensions(s->avctx, width, height); |
| 206 | if (ret < 0) |
| 207 | return ret; |
| 208 | |
| 209 | dim_reset = (s->macroblocks_base != NULL); |
| 210 | } |
| 211 | |
| 212 | if ((s->pix_fmt == AV_PIX_FMT_NONE || dim_reset) && |
| 213 | !s->actually_webp && !is_vp7) { |
| 214 | s->pix_fmt = get_pixel_format(s); |
| 215 | if (s->pix_fmt < 0) |
| 216 | return AVERROR(EINVAL); |
| 217 | avctx->pix_fmt = s->pix_fmt; |
| 218 | } |
| 219 | |
| 220 | s->mb_width = (s->avctx->coded_width + 15) / 16; |
| 221 | s->mb_height = (s->avctx->coded_height + 15) / 16; |
| 222 | |
| 223 | s->mb_layout = is_vp7 || avctx->active_thread_type == FF_THREAD_SLICE && |
| 224 | avctx->thread_count > 1; |
| 225 | if (!s->mb_layout) { // Frame threading and one thread |
| 226 | s->macroblocks_base = av_mallocz((s->mb_width + s->mb_height * 2 + 1) * |
| 227 | sizeof(*s->macroblocks)); |
| 228 | s->intra4x4_pred_mode_top = av_mallocz(s->mb_width * 4); |
| 229 | } else // Sliced threading |
| 230 | s->macroblocks_base = av_mallocz((s->mb_width + 2) * (s->mb_height + 2) * |
| 231 | sizeof(*s->macroblocks)); |
| 232 | s->top_nnz = av_mallocz(s->mb_width * sizeof(*s->top_nnz)); |
| 233 | s->top_border = av_mallocz((s->mb_width + 1) * sizeof(*s->top_border)); |
| 234 | s->thread_data = av_mallocz(MAX_THREADS * sizeof(VP8ThreadData)); |
| 235 | |
| 236 | if (!s->macroblocks_base || !s->top_nnz || !s->top_border || |
no test coverage detected