Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * RV30/40 parser | |
3 | * Copyright (c) 2011 Konstantin Shishkov | |
4 | * | |
5 | * This file is part of FFmpeg. | |
6 | * | |
7 | * FFmpeg is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU Lesser General Public | |
9 | * License as published by the Free Software Foundation; either | |
10 | * version 2.1 of the License, or (at your option) any later version. | |
11 | * | |
12 | * FFmpeg is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * Lesser General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public | |
18 | * License along with FFmpeg; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | */ | |
21 | ||
22 | /** | |
23 | * @file | |
24 | * RV30/40 parser | |
25 | */ | |
26 | ||
27 | #include "parser.h" | |
28 | #include "libavutil/intreadwrite.h" | |
29 | ||
30 | typedef struct { | |
31 | ParseContext pc; | |
32 | int64_t key_dts; | |
33 | int key_pts; | |
34 | } RV34ParseContext; | |
35 | ||
36 | static const int rv_to_av_frame_type[4] = { | |
37 | AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, | |
38 | }; | |
39 | ||
40 | static int rv34_parse(AVCodecParserContext *s, | |
41 | AVCodecContext *avctx, | |
42 | const uint8_t **poutbuf, int *poutbuf_size, | |
43 | const uint8_t *buf, int buf_size) | |
44 | { | |
45 | RV34ParseContext *pc = s->priv_data; | |
46 | int type, pts, hdr; | |
47 | ||
48 | if (buf_size < 13 + *buf * 8) { | |
49 | *poutbuf = buf; | |
50 | *poutbuf_size = buf_size; | |
51 | return buf_size; | |
52 | } | |
53 | ||
54 | hdr = AV_RB32(buf + 9 + *buf * 8); | |
55 | if (avctx->codec_id == AV_CODEC_ID_RV30) { | |
56 | type = (hdr >> 27) & 3; | |
57 | pts = (hdr >> 7) & 0x1FFF; | |
58 | } else { | |
59 | type = (hdr >> 29) & 3; | |
60 | pts = (hdr >> 6) & 0x1FFF; | |
61 | } | |
62 | ||
63 | if (type != 3 && s->pts != AV_NOPTS_VALUE) { | |
64 | pc->key_dts = s->pts; | |
65 | pc->key_pts = pts; | |
66 | } else { | |
67 | if (type != 3) | |
68 | s->pts = pc->key_dts + ((pts - pc->key_pts) & 0x1FFF); | |
69 | else | |
70 | s->pts = pc->key_dts - ((pc->key_pts - pts) & 0x1FFF); | |
71 | } | |
72 | s->pict_type = rv_to_av_frame_type[type]; | |
73 | ||
74 | *poutbuf = buf; | |
75 | *poutbuf_size = buf_size; | |
76 | return buf_size; | |
77 | } | |
78 | ||
79 | #if CONFIG_RV30_PARSER | |
80 | AVCodecParser ff_rv30_parser = { | |
81 | .codec_ids = { AV_CODEC_ID_RV30 }, | |
82 | .priv_data_size = sizeof(RV34ParseContext), | |
83 | .parser_parse = rv34_parse, | |
84 | }; | |
85 | #endif | |
86 | ||
87 | #if CONFIG_RV40_PARSER | |
88 | AVCodecParser ff_rv40_parser = { | |
89 | .codec_ids = { AV_CODEC_ID_RV40 }, | |
90 | .priv_data_size = sizeof(RV34ParseContext), | |
91 | .parser_parse = rv34_parse, | |
92 | }; | |
93 | #endif |