blob: 765d39055032bdb46ad3a73692d741843fe629c2
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 RV34ParseContext { |
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 |
94 |