blob: 609f5077d1a1b2add1dd3e13f0508615428dafa0
1 | /* |
2 | * This file is part of FFmpeg. |
3 | * |
4 | * FFmpeg is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2.1 of the License, or (at your option) any later version. |
8 | * |
9 | * FFmpeg is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with FFmpeg; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | #include "libavutil/intreadwrite.h" |
20 | |
21 | #include "avcodec.h" |
22 | |
23 | static int parse(AVCodecParserContext *s, |
24 | AVCodecContext *avctx, |
25 | const uint8_t **poutbuf, int *poutbuf_size, |
26 | const uint8_t *buf, int buf_size) |
27 | { |
28 | unsigned int frame_type; |
29 | unsigned int profile; |
30 | |
31 | if (buf_size < 3) |
32 | return buf_size; |
33 | |
34 | frame_type = buf[0] & 1; |
35 | profile = (buf[0] >> 1) & 7; |
36 | if (profile > 3) { |
37 | av_log(avctx, AV_LOG_ERROR, "Invalid profile %u.\n", profile); |
38 | return buf_size; |
39 | } |
40 | |
41 | avctx->profile = profile; |
42 | s->key_frame = frame_type == 0; |
43 | s->pict_type = frame_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; |
44 | s->format = AV_PIX_FMT_YUV420P; |
45 | s->field_order = AV_FIELD_PROGRESSIVE; |
46 | s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; |
47 | |
48 | if (frame_type == 0) { |
49 | unsigned int sync_code; |
50 | unsigned int width, height; |
51 | |
52 | if (buf_size < 10) |
53 | return buf_size; |
54 | |
55 | sync_code = AV_RL24(buf + 3); |
56 | if (sync_code != 0x2a019d) { |
57 | av_log(avctx, AV_LOG_ERROR, "Invalid sync code %06x.\n", sync_code); |
58 | return buf_size; |
59 | } |
60 | |
61 | width = AV_RL16(buf + 6) & 0x3fff; |
62 | height = AV_RL16(buf + 8) & 0x3fff; |
63 | |
64 | s->width = width; |
65 | s->height = height; |
66 | s->coded_width = FFALIGN(width, 16); |
67 | s->coded_height = FFALIGN(height, 16); |
68 | } |
69 | |
70 | *poutbuf = buf; |
71 | *poutbuf_size = buf_size; |
72 | return buf_size; |
73 | } |
74 | |
75 | AVCodecParser ff_vp8_parser = { |
76 | .codec_ids = { AV_CODEC_ID_VP8 }, |
77 | .parser_parse = parse, |
78 | }; |
79 |