FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vp9_parser.c
Go to the documentation of this file.
1 /*
2  * VP9 compatible video decoder
3  *
4  * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
5  * Copyright (C) 2013 Clément Bœsch <u pkh me>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "libavutil/intreadwrite.h"
25 #include "libavcodec/get_bits.h"
26 #include "parser.h"
27 
28 typedef struct VP9ParseContext {
29  int n_frames; // 1-8
30  int size[8];
32  int64_t pts;
34 
36 {
37  VP9ParseContext *s = ctx->priv_data;
38  GetBitContext gb;
39  int res, profile, keyframe, invisible;
40 
41  if ((res = init_get_bits8(&gb, buf, size)) < 0)
42  return res;
43  get_bits(&gb, 2); // frame marker
44  profile = get_bits1(&gb);
45  profile |= get_bits1(&gb) << 1;
46  if (profile == 3) profile += get_bits1(&gb);
47 
48  if (get_bits1(&gb)) {
49  keyframe = 0;
50  invisible = 0;
51  } else {
52  keyframe = !get_bits1(&gb);
53  invisible = !get_bits1(&gb);
54  }
55 
56  if (!keyframe) {
58  ctx->key_frame = 0;
59  } else {
61  ctx->key_frame = 1;
62  }
63 
64  if (!invisible) {
65  if (ctx->pts == AV_NOPTS_VALUE)
66  ctx->pts = s->pts;
67  s->pts = AV_NOPTS_VALUE;
68  } else if (ctx->pts != AV_NOPTS_VALUE) {
69  s->pts = ctx->pts;
70  ctx->pts = AV_NOPTS_VALUE;
71  }
72 
73  return 0;
74 }
75 
77  AVCodecContext *avctx,
78  const uint8_t **out_data, int *out_size,
79  const uint8_t *data, int size)
80 {
81  VP9ParseContext *s = ctx->priv_data;
82  int full_size = size;
83  int marker;
84 
85  if (size <= 0) {
86  *out_size = 0;
87  *out_data = data;
88 
89  return 0;
90  }
91 
92  if (s->n_frames > 0) {
93  int i;
94  int size_sum = 0;
95 
96  for (i = 0; i < s->n_frames ;i++)
97  size_sum += s->size[i];
98  size_sum += s->marker_size;
99 
100  if (size_sum != size) {
101  av_log(avctx, AV_LOG_ERROR, "Inconsistent input frame sizes %d %d\n",
102  size_sum, size);
103  s->n_frames = 0;
104  }
105  }
106 
107  if (s->n_frames > 0) {
108  *out_data = data;
109  *out_size = s->size[--s->n_frames];
110  parse_frame(ctx, *out_data, *out_size);
111 
112  return s->n_frames > 0 ? *out_size : size /* i.e. include idx tail */;
113  }
114 
115  marker = data[size - 1];
116  if ((marker & 0xe0) == 0xc0) {
117  int nbytes = 1 + ((marker >> 3) & 0x3);
118  int n_frames = 1 + (marker & 0x7), idx_sz = 2 + n_frames * nbytes;
119 
120  if (size >= idx_sz && data[size - idx_sz] == marker) {
121  const uint8_t *idx = data + size + 1 - idx_sz;
122  int first = 1;
123 
124  switch (nbytes) {
125 #define case_n(a, rd) \
126  case a: \
127  while (n_frames--) { \
128  unsigned sz = rd; \
129  idx += a; \
130  if (sz == 0 || sz > size) { \
131  s->n_frames = 0; \
132  *out_size = size; \
133  *out_data = data; \
134  av_log(avctx, AV_LOG_ERROR, \
135  "Invalid superframe packet size: %u frame size: %d\n", \
136  sz, size); \
137  return full_size; \
138  } \
139  if (first) { \
140  first = 0; \
141  *out_data = data; \
142  *out_size = sz; \
143  s->n_frames = n_frames; \
144  } else { \
145  s->size[n_frames] = sz; \
146  } \
147  data += sz; \
148  size -= sz; \
149  } \
150  s->marker_size = size; \
151  parse_frame(ctx, *out_data, *out_size); \
152  return s->n_frames > 0 ? *out_size : full_size
153 
154  case_n(1, *idx);
155  case_n(2, AV_RL16(idx));
156  case_n(3, AV_RL24(idx));
157  case_n(4, AV_RL32(idx));
158  }
159  }
160  }
161 
162  *out_data = data;
163  *out_size = size;
164  parse_frame(ctx, data, size);
165 
166  return size;
167 }
168 
170  .codec_ids = { AV_CODEC_ID_VP9 },
171  .priv_data_size = sizeof(VP9ParseContext),
172  .parser_parse = parse,
173 };
AVCodecParser ff_vp9_parser
Definition: vp9_parser.c:169
const char * s
Definition: avisynth_c.h:768
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:261
int codec_ids[5]
Definition: avcodec.h:5335
int out_size
Definition: movenc.c:55
static int parse(AVCodecParserContext *ctx, AVCodecContext *avctx, const uint8_t **out_data, int *out_size, const uint8_t *data, int size)
Definition: vp9_parser.c:76
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:87
uint8_t
bitstream reader API header.
ptrdiff_t size
Definition: opengl_enc.c:101
#define av_log(a,...)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_RL24
Definition: bytestream.h:87
AVFormatContext * ctx
Definition: movenc.c:48
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:456
main external API structure.
Definition: avcodec.h:1761
#define case_n(a, rd)
void * buf
Definition: avisynth_c.h:690
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:313
mfxU16 profile
Definition: qsvenc.c:44
static int parse_frame(AVCodecParserContext *ctx, const uint8_t *buf, int size)
Definition: vp9_parser.c:35
if(ret< 0)
Definition: vf_mcdeint.c:279
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87
int key_frame
Set by parser to 1 for key frames and 0 for non-key frames.
Definition: avcodec.h:5216
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
Predicted.
Definition: avutil.h:275