2 * Copyright (C) 2008 Michael Niedermayer
4 * This file is part of FFmpeg.
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.
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.
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
21 #include "libavutil/intreadwrite.h"
24 typedef struct VP9ParseContext
{
29 static void parse_frame(AVCodecParserContext
*ctx
, const uint8_t *buf
, int size
)
32 ctx
->pict_type
= AV_PICTURE_TYPE_P
;
35 ctx
->pict_type
= AV_PICTURE_TYPE_I
;
40 static int parse(AVCodecParserContext
*ctx
,
41 AVCodecContext
*avctx
,
42 const uint8_t **out_data
, int *out_size
,
43 const uint8_t *data
, int size
)
45 VP9ParseContext
*s
= ctx
->priv_data
;
55 if (s
->n_frames
> 0) {
57 *out_size
= s
->size
[--s
->n_frames
];
58 parse_frame(ctx
, *out_data
, *out_size
);
60 return s
->n_frames
> 0 ? *out_size
: size
/* i.e. include idx tail */;
63 marker
= data
[size
- 1];
64 if ((marker
& 0xe0) == 0xc0) {
65 int nbytes
= 1 + ((marker
>> 3) & 0x3);
66 int n_frames
= 1 + (marker
& 0x7), idx_sz
= 2 + n_frames
* nbytes
;
68 if (size
>= idx_sz
&& data
[size
- idx_sz
] == marker
) {
69 const uint8_t *idx
= data
+ size
+ 1 - idx_sz
;
73 #define case_n(a, rd) \
75 while (n_frames--) { \
82 av_log(avctx, AV_LOG_ERROR, \
83 "Superframe packet size too big: %u > %d\n", \
91 s->n_frames = n_frames; \
93 s->size[n_frames] = sz; \
98 parse_frame(ctx, *out_data, *out_size); \
102 case_n(2, AV_RL16(idx
));
103 case_n(3, AV_RL24(idx
));
104 case_n(4, AV_RL32(idx
));
111 parse_frame(ctx
, data
, size
);
116 AVCodecParser ff_vp9_parser
= {
117 .codec_ids
= { AV_CODEC_ID_VP9
},
118 .priv_data_size
= sizeof(VP9ParseContext
),
119 .parser_parse
= parse
,