Mercurial > libavcodec.hg
annotate libvpxdec.c @ 12494:94eaea836bf4 libavcodec
Check avctx width/height more thoroughly (e.g. all values 0 except width would
have been accepted before).
Also do not fail if they are invalid but instead override them to 0.
This allows decoding e.g. MPEG video when only the container values are corrupted.
For encoding a value of 0,0 of course makes no sense, but was allowed
through before and will be caught by an extra check in the encode function.
author | reimar |
---|---|
date | Wed, 15 Sep 2010 04:46:55 +0000 |
parents | ffb3668ff7af |
children |
rev | line source |
---|---|
11756 | 1 /* |
2 * Copyright (c) 2010, Google, Inc. | |
3 * | |
4 * This file is part of FFmpeg. | |
5 * | |
6 * FFmpeg is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2.1 of the License, or (at your option) any later version. | |
10 * | |
11 * FFmpeg is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with FFmpeg; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 */ | |
20 | |
21 /** | |
22 * @file | |
23 * VP8 decoder support via libvpx | |
24 */ | |
25 | |
26 #define VPX_CODEC_DISABLE_COMPAT 1 | |
11758
6c1e78b8aba5
Headers for libvpx are installed into vpx subdirectory.
cehoyos
parents:
11756
diff
changeset
|
27 #include <vpx/vpx_decoder.h> |
6c1e78b8aba5
Headers for libvpx are installed into vpx subdirectory.
cehoyos
parents:
11756
diff
changeset
|
28 #include <vpx/vp8dx.h> |
11756 | 29 |
12375
98004cbdda4e
libvpxdec: Fix "error: implicit declaration of function ¡Æav_check_image_size¡Ç".
alexc
parents:
12372
diff
changeset
|
30 #include "libavcore/imgutils.h" |
11756 | 31 #include "avcodec.h" |
32 | |
33 typedef struct VP8DecoderContext { | |
34 struct vpx_codec_ctx decoder; | |
35 } VP8Context; | |
36 | |
37 static av_cold int vp8_init(AVCodecContext *avctx) | |
38 { | |
39 VP8Context *ctx = avctx->priv_data; | |
40 const struct vpx_codec_iface *iface = &vpx_codec_vp8_dx_algo; | |
41 struct vpx_codec_dec_cfg deccfg = { | |
42 /* token partitions+1 would be a decent choice */ | |
43 .threads = FFMIN(avctx->thread_count, 16) | |
44 }; | |
45 | |
46 av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str()); | |
47 av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config()); | |
48 | |
49 if (vpx_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != VPX_CODEC_OK) { | |
50 const char *error = vpx_codec_error(&ctx->decoder); | |
51 av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n", | |
52 error); | |
53 return AVERROR(EINVAL); | |
54 } | |
55 | |
56 avctx->pix_fmt = PIX_FMT_YUV420P; | |
57 return 0; | |
58 } | |
59 | |
60 static int vp8_decode(AVCodecContext *avctx, | |
61 void *data, int *data_size, AVPacket *avpkt) | |
62 { | |
63 VP8Context *ctx = avctx->priv_data; | |
64 AVFrame *picture = data; | |
65 const void *iter = NULL; | |
66 struct vpx_image *img; | |
67 | |
68 if (vpx_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL, 0) != | |
69 VPX_CODEC_OK) { | |
70 const char *error = vpx_codec_error(&ctx->decoder); | |
71 const char *detail = vpx_codec_error_detail(&ctx->decoder); | |
72 | |
73 av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error); | |
74 if (detail) | |
75 av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n", | |
76 detail); | |
77 return AVERROR_INVALIDDATA; | |
78 } | |
79 | |
80 if ((img = vpx_codec_get_frame(&ctx->decoder, &iter))) { | |
81 if (img->fmt != VPX_IMG_FMT_I420) { | |
82 av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d)\n", | |
83 img->fmt); | |
84 return AVERROR_INVALIDDATA; | |
85 } | |
86 | |
87 if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) { | |
88 av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n", | |
89 avctx->width, avctx->height, img->d_w, img->d_h); | |
12462
ffb3668ff7af
Use new imgutils.h API names, fix deprecation warnings.
stefano
parents:
12375
diff
changeset
|
90 if (av_image_check_size(img->d_w, img->d_h, 0, avctx)) |
11756 | 91 return AVERROR_INVALIDDATA; |
92 avcodec_set_dimensions(avctx, img->d_w, img->d_h); | |
93 } | |
94 picture->data[0] = img->planes[0]; | |
95 picture->data[1] = img->planes[1]; | |
96 picture->data[2] = img->planes[2]; | |
97 picture->data[3] = NULL; | |
98 picture->linesize[0] = img->stride[0]; | |
99 picture->linesize[1] = img->stride[1]; | |
100 picture->linesize[2] = img->stride[2]; | |
101 picture->linesize[3] = 0; | |
102 *data_size = sizeof(AVPicture); | |
103 } | |
104 return avpkt->size; | |
105 } | |
106 | |
107 static av_cold int vp8_free(AVCodecContext *avctx) | |
108 { | |
109 VP8Context *ctx = avctx->priv_data; | |
110 vpx_codec_destroy(&ctx->decoder); | |
111 return 0; | |
112 } | |
113 | |
114 AVCodec libvpx_decoder = { | |
115 "libvpx", | |
116 AVMEDIA_TYPE_VIDEO, | |
117 CODEC_ID_VP8, | |
118 sizeof(VP8Context), | |
119 vp8_init, | |
120 NULL, /* encode */ | |
121 vp8_free, | |
122 vp8_decode, | |
123 0, /* capabilities */ | |
124 .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"), | |
125 }; |