1 /*
2 * gstvp8parser.c - VP8 parser
3 *
4 * Copyright (C) 2013-2014 Intel Corporation
5 * Author: Halley Zhao <halley.zhao@intel.com>
6 * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24 /**
25 * SECTION:gstvp8parser
26 * @title: GstVp8Parser
27 * @short_description: Convenience library for parsing vp8 video bitstream.
28 *
29 * For more details about the structures, you can refer to the
30 * specifications: VP8-rfc6386.pdf
31 */
32
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36 #include <string.h>
37 #include <gst/base/gstbytereader.h>
38 #include "gstvp8parser.h"
39 #include "gstvp8rangedecoder.h"
40 #include "vp8utils.h"
41
42 #ifndef GST_DISABLE_GST_DEBUG
43 #define GST_CAT_DEFAULT gst_vp8_debug_category_get()
44 static GstDebugCategory *
gst_vp8_debug_category_get(void)45 gst_vp8_debug_category_get (void)
46 {
47 static gsize cat_gonce = 0;
48
49 if (g_once_init_enter (&cat_gonce)) {
50 GstDebugCategory *cat = NULL;
51
52 GST_DEBUG_CATEGORY_INIT (cat, "codecparsers_vp8", 0, "vp8 parser library");
53
54 g_once_init_leave (&cat_gonce, (gsize) cat);
55 }
56
57 return (GstDebugCategory *) cat_gonce;
58 }
59 #endif /* GST_DISABLE_GST_DEBUG */
60
61 static GstVp8MvProbs vp8_mv_update_probs;
62 static GstVp8TokenProbs vp8_token_update_probs;
63
64 static void
ensure_prob_tables(void)65 ensure_prob_tables (void)
66 {
67 static gsize is_initialized;
68
69 if (g_once_init_enter (&is_initialized)) {
70 gst_vp8_mv_update_probs_init (&vp8_mv_update_probs);
71 gst_vp8_token_update_probs_init (&vp8_token_update_probs);
72 g_once_init_leave (&is_initialized, TRUE);
73 }
74 }
75
76 #define READ_BOOL(rd, val, field_name) \
77 val = vp8_read_bool ((rd))
78 #define READ_UINT(rd, val, nbits, field_name) \
79 val = vp8_read_uint ((rd), (nbits))
80 #define READ_SINT(rd, val, nbits, field_name) \
81 val = vp8_read_sint ((rd), (nbits))
82
83 static inline gboolean
vp8_read_bool(GstVp8RangeDecoder * rd)84 vp8_read_bool (GstVp8RangeDecoder * rd)
85 {
86 return (gboolean) gst_vp8_range_decoder_read_literal (rd, 1);
87 }
88
89 static inline guint
vp8_read_uint(GstVp8RangeDecoder * rd,guint nbits)90 vp8_read_uint (GstVp8RangeDecoder * rd, guint nbits)
91 {
92 return (guint) gst_vp8_range_decoder_read_literal (rd, nbits);
93 }
94
95 static inline gint
vp8_read_sint(GstVp8RangeDecoder * rd,guint nbits)96 vp8_read_sint (GstVp8RangeDecoder * rd, guint nbits)
97 {
98 gint v;
99
100 v = gst_vp8_range_decoder_read_literal (rd, nbits);
101 if (gst_vp8_range_decoder_read_literal (rd, 1))
102 v = -v;
103 return v;
104 }
105
106 /* Parse update_segmentation() */
107 static gboolean
parse_update_segmentation(GstVp8RangeDecoder * rd,GstVp8Segmentation * seg)108 parse_update_segmentation (GstVp8RangeDecoder * rd, GstVp8Segmentation * seg)
109 {
110 gboolean update;
111 gint i;
112
113 seg->update_mb_segmentation_map = FALSE;
114 seg->update_segment_feature_data = FALSE;
115
116 READ_BOOL (rd, seg->segmentation_enabled, "segmentation_enabled");
117 if (!seg->segmentation_enabled)
118 return TRUE;
119
120 READ_BOOL (rd, seg->update_mb_segmentation_map, "update_mb_segmentation_map");
121 READ_BOOL (rd, seg->update_segment_feature_data,
122 "update_segment_feature_data");
123
124 if (seg->update_segment_feature_data) {
125 READ_UINT (rd, seg->segment_feature_mode, 1, "segment_feature_mode");
126
127 /* quantizer_update_value defaults to zero if update flag is zero
128 (Section 9.3, 4.b) */
129 for (i = 0; i < 4; i++) {
130 READ_BOOL (rd, update, "quantizer_update");
131 if (update) {
132 READ_SINT (rd, seg->quantizer_update_value[i], 7,
133 "quantizer_update_value");
134 } else
135 seg->quantizer_update_value[i] = 0;
136 }
137
138 /* lf_update_value defaults to zero if update flag is zero
139 (Section 9.3, 4.b) */
140 for (i = 0; i < 4; i++) {
141 READ_BOOL (rd, update, "loop_filter_update");
142 if (update) {
143 READ_SINT (rd, seg->lf_update_value[i], 6, "lf_update_value");
144 } else
145 seg->lf_update_value[i] = 0;
146 }
147 }
148
149 /* segment_prob defaults to 255 if update flag is zero
150 (Section 9.3, 5) */
151 if (seg->update_mb_segmentation_map) {
152 for (i = 0; i < 3; i++) {
153 READ_BOOL (rd, update, "segment_prob_update");
154 if (update) {
155 READ_UINT (rd, seg->segment_prob[i], 8, "segment_prob");
156 } else
157 seg->segment_prob[i] = 255;
158 }
159 }
160 return TRUE;
161 }
162
163 /* Parse mb_lf_adjustments() to update loop filter delta adjustments */
164 static gboolean
parse_mb_lf_adjustments(GstVp8RangeDecoder * rd,GstVp8MbLfAdjustments * adj)165 parse_mb_lf_adjustments (GstVp8RangeDecoder * rd, GstVp8MbLfAdjustments * adj)
166 {
167 gboolean update;
168 gint i;
169
170 adj->mode_ref_lf_delta_update = FALSE;
171
172 READ_BOOL (rd, adj->loop_filter_adj_enable, "loop_filter_adj_enable");
173 if (!adj->loop_filter_adj_enable)
174 return TRUE;
175
176 READ_BOOL (rd, adj->mode_ref_lf_delta_update, "mode_ref_lf_delta_update");
177 if (!adj->mode_ref_lf_delta_update)
178 return TRUE;
179
180 for (i = 0; i < 4; i++) {
181 READ_BOOL (rd, update, "ref_frame_delta_update_flag");
182 if (update) {
183 READ_SINT (rd, adj->ref_frame_delta[i], 6, "ref_frame_delta_magniture");
184 }
185 }
186
187 for (i = 0; i < 4; i++) {
188 READ_BOOL (rd, update, "mb_mode_delta_update_flag");
189 if (update) {
190 READ_SINT (rd, adj->mb_mode_delta[i], 6, "mb_mode_delta_magnitude");
191 }
192 }
193 return TRUE;
194 }
195
196 /* Parse quant_indices() */
197 static gboolean
parse_quant_indices(GstVp8RangeDecoder * rd,GstVp8QuantIndices * qip)198 parse_quant_indices (GstVp8RangeDecoder * rd, GstVp8QuantIndices * qip)
199 {
200 gboolean update;
201
202 READ_UINT (rd, qip->y_ac_qi, 7, "y_ac_qi");
203
204 READ_BOOL (rd, update, "y_dc_delta_present");
205 if (update) {
206 READ_SINT (rd, qip->y_dc_delta, 4, "y_dc_delta_magnitude");
207 } else
208 qip->y_dc_delta = 0;
209
210 READ_BOOL (rd, update, "y2_dc_delta_present");
211 if (update) {
212 READ_SINT (rd, qip->y2_dc_delta, 4, "y2_dc_delta_magnitude");
213 } else
214 qip->y2_dc_delta = 0;
215
216 READ_BOOL (rd, update, "y2_ac_delta_present");
217 if (update) {
218 READ_SINT (rd, qip->y2_ac_delta, 4, "y2_ac_delta_magnitude");
219 } else
220 qip->y2_ac_delta = 0;
221
222 READ_BOOL (rd, update, "uv_dc_delta_present");
223 if (update) {
224 READ_SINT (rd, qip->uv_dc_delta, 4, "uv_dc_delta_magnitude");
225 } else
226 qip->uv_dc_delta = 0;
227
228 READ_BOOL (rd, update, "uv_ac_delta_present");
229 if (update) {
230 READ_SINT (rd, qip->uv_ac_delta, 4, "uv_ac_delta_magnitude");
231 } else
232 qip->uv_ac_delta = 0;
233
234 return TRUE;
235 }
236
237 /* Parse token_prob_update() to update persistent token probabilities */
238 static gboolean
parse_token_prob_update(GstVp8RangeDecoder * rd,GstVp8TokenProbs * probs)239 parse_token_prob_update (GstVp8RangeDecoder * rd, GstVp8TokenProbs * probs)
240 {
241 gint i, j, k, l;
242 guint8 prob;
243
244 for (i = 0; i < 4; i++) {
245 for (j = 0; j < 8; j++) {
246 for (k = 0; k < 3; k++) {
247 for (l = 0; l < 11; l++) {
248 if (gst_vp8_range_decoder_read (rd,
249 vp8_token_update_probs.prob[i][j][k][l])) {
250 READ_UINT (rd, prob, 8, "token_prob_update");
251 probs->prob[i][j][k][l] = prob;
252 }
253 }
254 }
255 }
256 }
257 return TRUE;
258 }
259
260 /* Parse prob_update() to update probabilities used for MV decoding */
261 static gboolean
parse_mv_prob_update(GstVp8RangeDecoder * rd,GstVp8MvProbs * probs)262 parse_mv_prob_update (GstVp8RangeDecoder * rd, GstVp8MvProbs * probs)
263 {
264 gint i, j;
265 guint8 prob;
266
267 for (i = 0; i < 2; i++) {
268 for (j = 0; j < 19; j++) {
269 if (gst_vp8_range_decoder_read (rd, vp8_mv_update_probs.prob[i][j])) {
270 READ_UINT (rd, prob, 7, "mv_prob_update");
271 probs->prob[i][j] = prob ? (prob << 1) : 1;
272 }
273 }
274 }
275 return TRUE;
276 }
277
278 /* Calculate partition sizes */
279 static gboolean
calc_partition_sizes(GstVp8FrameHdr * frame_hdr,const guint8 * data,guint size)280 calc_partition_sizes (GstVp8FrameHdr * frame_hdr, const guint8 * data,
281 guint size)
282 {
283 const guint num_partitions = 1 << frame_hdr->log2_nbr_of_dct_partitions;
284 guint i, ofs, part_size, part_size_ofs = frame_hdr->first_part_size;
285
286 ofs = part_size_ofs + 3 * (num_partitions - 1);
287 if (ofs > size) {
288 GST_ERROR ("not enough bytes left to parse partition sizes");
289 return FALSE;
290 }
291
292 /* The size of the last partition is not specified (9.5) */
293 for (i = 0; i < num_partitions - 1; i++) {
294 part_size = (guint32) data[part_size_ofs + 0] |
295 ((guint32) data[part_size_ofs + 1] << 8) |
296 ((guint32) data[part_size_ofs + 2] << 16);
297 part_size_ofs += 3;
298
299 frame_hdr->partition_size[i] = part_size;
300 ofs += part_size;
301 }
302
303 if (ofs > size) {
304 GST_ERROR ("not enough bytes left to determine the last partition size");
305 return FALSE;
306 }
307 frame_hdr->partition_size[i] = size - ofs;
308
309 while (++i < G_N_ELEMENTS (frame_hdr->partition_size))
310 frame_hdr->partition_size[i] = 0;
311 return TRUE;
312 }
313
314 /* Parse uncompressed data chunk (19.1) */
315 static GstVp8ParserResult
parse_uncompressed_data_chunk(GstVp8Parser * parser,GstByteReader * br,GstVp8FrameHdr * frame_hdr)316 parse_uncompressed_data_chunk (GstVp8Parser * parser, GstByteReader * br,
317 GstVp8FrameHdr * frame_hdr)
318 {
319 guint32 frame_tag, start_code;
320 guint16 size_code;
321
322 GST_DEBUG ("parsing \"Uncompressed Data Chunk\"");
323
324 if (!gst_byte_reader_get_uint24_le (br, &frame_tag))
325 goto error;
326
327 frame_hdr->key_frame = !(frame_tag & 0x01);
328 frame_hdr->version = (frame_tag >> 1) & 0x07;
329 frame_hdr->show_frame = (frame_tag >> 4) & 0x01;
330 frame_hdr->first_part_size = (frame_tag >> 5) & 0x7ffff;
331
332 if (frame_hdr->key_frame) {
333 if (!gst_byte_reader_get_uint24_be (br, &start_code))
334 goto error;
335 if (start_code != 0x9d012a)
336 GST_WARNING ("vp8 parser: invalid start code in frame header");
337
338 if (!gst_byte_reader_get_uint16_le (br, &size_code))
339 goto error;
340 frame_hdr->width = size_code & 0x3fff;
341 frame_hdr->horiz_scale_code = size_code >> 14;
342
343 if (!gst_byte_reader_get_uint16_le (br, &size_code)) {
344 goto error;
345 }
346 frame_hdr->height = size_code & 0x3fff;
347 frame_hdr->vert_scale_code = (size_code >> 14);
348
349 /* Reset parser state on key frames */
350 gst_vp8_parser_init (parser);
351 } else {
352 frame_hdr->width = 0;
353 frame_hdr->height = 0;
354 frame_hdr->horiz_scale_code = 0;
355 frame_hdr->vert_scale_code = 0;
356 }
357
358 /* Calculated values */
359 frame_hdr->data_chunk_size = gst_byte_reader_get_pos (br);
360 return GST_VP8_PARSER_OK;
361
362 error:
363 GST_WARNING ("error parsing \"Uncompressed Data Chunk\"");
364 return GST_VP8_PARSER_ERROR;
365 }
366
367 /* Parse Frame Header (19.2) */
368 static GstVp8ParserResult
parse_frame_header(GstVp8Parser * parser,GstVp8RangeDecoder * rd,GstVp8FrameHdr * frame_hdr)369 parse_frame_header (GstVp8Parser * parser, GstVp8RangeDecoder * rd,
370 GstVp8FrameHdr * frame_hdr)
371 {
372 gboolean update;
373 guint i;
374
375 GST_DEBUG ("parsing \"Frame Header\"");
376
377 if (frame_hdr->key_frame) {
378 READ_UINT (rd, frame_hdr->color_space, 1, "color_space");
379 READ_UINT (rd, frame_hdr->clamping_type, 1, "clamping_type");
380 }
381
382 if (!parse_update_segmentation (rd, &parser->segmentation))
383 goto error;
384
385 READ_UINT (rd, frame_hdr->filter_type, 1, "filter_type");
386 READ_UINT (rd, frame_hdr->loop_filter_level, 6, "loop_filter_level");
387 READ_UINT (rd, frame_hdr->sharpness_level, 3, "sharpness_level");
388
389 if (!parse_mb_lf_adjustments (rd, &parser->mb_lf_adjust))
390 goto error;
391
392 READ_UINT (rd, frame_hdr->log2_nbr_of_dct_partitions, 2,
393 "log2_nbr_of_dct_partitions");
394
395 if (!parse_quant_indices (rd, &frame_hdr->quant_indices))
396 goto error;
397
398 frame_hdr->copy_buffer_to_golden = 0;
399 frame_hdr->copy_buffer_to_alternate = 0;
400 if (frame_hdr->key_frame) {
401 READ_BOOL (rd, frame_hdr->refresh_entropy_probs, "refresh_entropy_probs");
402
403 frame_hdr->refresh_last = TRUE;
404 frame_hdr->refresh_golden_frame = TRUE;
405 frame_hdr->refresh_alternate_frame = TRUE;
406
407 gst_vp8_mode_probs_init_defaults (&frame_hdr->mode_probs, TRUE);
408 } else {
409 READ_BOOL (rd, frame_hdr->refresh_golden_frame, "refresh_golden_frame");
410 READ_BOOL (rd, frame_hdr->refresh_alternate_frame,
411 "refresh_alternate_frame");
412
413 if (!frame_hdr->refresh_golden_frame) {
414 READ_UINT (rd, frame_hdr->copy_buffer_to_golden, 2,
415 "copy_buffer_to_golden");
416 }
417
418 if (!frame_hdr->refresh_alternate_frame) {
419 READ_UINT (rd, frame_hdr->copy_buffer_to_alternate, 2,
420 "copy_buffer_to_alternate");
421 }
422
423 READ_UINT (rd, frame_hdr->sign_bias_golden, 1, "sign_bias_golden");
424 READ_UINT (rd, frame_hdr->sign_bias_alternate, 1, "sign_bias_alternate");
425 READ_BOOL (rd, frame_hdr->refresh_entropy_probs, "refresh_entropy_probs");
426 READ_BOOL (rd, frame_hdr->refresh_last, "refresh_last");
427
428 memcpy (&frame_hdr->mode_probs, &parser->mode_probs,
429 sizeof (parser->mode_probs));
430 }
431 memcpy (&frame_hdr->token_probs, &parser->token_probs,
432 sizeof (parser->token_probs));
433 memcpy (&frame_hdr->mv_probs, &parser->mv_probs, sizeof (parser->mv_probs));
434
435 if (!parse_token_prob_update (rd, &frame_hdr->token_probs))
436 goto error;
437
438 READ_BOOL (rd, frame_hdr->mb_no_skip_coeff, "mb_no_skip_coeff");
439 if (frame_hdr->mb_no_skip_coeff) {
440 READ_UINT (rd, frame_hdr->prob_skip_false, 8, "prob_skip_false");
441 }
442
443 if (!frame_hdr->key_frame) {
444 READ_UINT (rd, frame_hdr->prob_intra, 8, "prob_intra");
445 READ_UINT (rd, frame_hdr->prob_last, 8, "prob_last");
446 READ_UINT (rd, frame_hdr->prob_gf, 8, "prob_gf");
447
448 READ_BOOL (rd, update, "intra_16x16_prob_update_flag");
449 if (update) {
450 for (i = 0; i < 4; i++) {
451 READ_UINT (rd, frame_hdr->mode_probs.y_prob[i], 8, "intra_16x16_prob");
452 }
453 }
454
455 READ_BOOL (rd, update, "intra_chroma_prob_update_flag");
456 if (update) {
457 for (i = 0; i < 3; i++) {
458 READ_UINT (rd, frame_hdr->mode_probs.uv_prob[i], 8,
459 "intra_chroma_prob");
460 }
461 }
462
463 if (!parse_mv_prob_update (rd, &frame_hdr->mv_probs))
464 goto error;
465 }
466
467 /* Refresh entropy probabilities */
468 if (frame_hdr->refresh_entropy_probs) {
469 memcpy (&parser->token_probs, &frame_hdr->token_probs,
470 sizeof (frame_hdr->token_probs));
471 memcpy (&parser->mv_probs, &frame_hdr->mv_probs,
472 sizeof (frame_hdr->mv_probs));
473 if (!frame_hdr->key_frame)
474 memcpy (&parser->mode_probs, &frame_hdr->mode_probs,
475 sizeof (frame_hdr->mode_probs));
476 }
477
478 /* Calculated values */
479 frame_hdr->header_size = gst_vp8_range_decoder_get_pos (rd);
480 return GST_VP8_PARSER_OK;
481
482 error:
483 GST_WARNING ("error parsing \"Frame Header\"");
484 return GST_VP8_PARSER_ERROR;
485 }
486
487 /**** API ****/
488 /**
489 * gst_vp8_parser_init:
490 * @parser: The #GstVp8Parser to initialize
491 *
492 * Initializes the supplied @parser structure with its default values.
493 *
494 * Since: 1.4
495 */
496 void
gst_vp8_parser_init(GstVp8Parser * parser)497 gst_vp8_parser_init (GstVp8Parser * parser)
498 {
499 g_return_if_fail (parser != NULL);
500
501 memset (&parser->segmentation, 0, sizeof (parser->segmentation));
502 memset (&parser->mb_lf_adjust, 0, sizeof (parser->mb_lf_adjust));
503 gst_vp8_token_probs_init_defaults (&parser->token_probs);
504 gst_vp8_mv_probs_init_defaults (&parser->mv_probs);
505 gst_vp8_mode_probs_init_defaults (&parser->mode_probs, FALSE);
506 }
507
508 /**
509 * gst_vp8_parser_parse_frame_header:
510 * @parser: The #GstVp8Parser
511 * @frame_hdr: The #GstVp8FrameHdr to fill
512 * @data: The data to parse
513 * @size: The size of the @data to parse
514 *
515 * Parses the VP8 bitstream contained in @data, and fills in @frame_hdr
516 * with the information. The supplied @data shall point to a complete
517 * frame since there is no sync code specified for VP8 bitstreams. Thus,
518 * the @size argument shall represent the whole frame size.
519 *
520 * Returns: a #GstVp8ParserResult
521 *
522 * Since: 1.4
523 */
524 GstVp8ParserResult
gst_vp8_parser_parse_frame_header(GstVp8Parser * parser,GstVp8FrameHdr * frame_hdr,const guint8 * data,gsize size)525 gst_vp8_parser_parse_frame_header (GstVp8Parser * parser,
526 GstVp8FrameHdr * frame_hdr, const guint8 * data, gsize size)
527 {
528 GstByteReader br;
529 GstVp8RangeDecoder rd;
530 GstVp8RangeDecoderState rd_state;
531 GstVp8ParserResult result;
532
533 ensure_prob_tables ();
534
535 g_return_val_if_fail (frame_hdr != NULL, GST_VP8_PARSER_ERROR);
536 g_return_val_if_fail (parser != NULL, GST_VP8_PARSER_ERROR);
537
538 memset (frame_hdr, 0, sizeof (GstVp8FrameHdr));
539
540 /* Uncompressed Data Chunk */
541 gst_byte_reader_init (&br, data, size);
542
543 result = parse_uncompressed_data_chunk (parser, &br, frame_hdr);
544 if (result != GST_VP8_PARSER_OK)
545 return result;
546
547 /* Frame Header */
548 if (frame_hdr->data_chunk_size + frame_hdr->first_part_size > size)
549 return GST_VP8_PARSER_BROKEN_DATA;
550
551 data += frame_hdr->data_chunk_size;
552 size -= frame_hdr->data_chunk_size;
553 if (!gst_vp8_range_decoder_init (&rd, data, size))
554 return GST_VP8_PARSER_BROKEN_DATA;
555
556 result = parse_frame_header (parser, &rd, frame_hdr);
557 if (result != GST_VP8_PARSER_OK)
558 return result;
559
560 /* Calculate partition sizes */
561 if (!calc_partition_sizes (frame_hdr, data, size))
562 return GST_VP8_PARSER_BROKEN_DATA;
563
564 /* Sync range decoder state */
565 gst_vp8_range_decoder_get_state (&rd, &rd_state);
566 frame_hdr->rd_range = rd_state.range;
567 frame_hdr->rd_value = rd_state.value;
568 frame_hdr->rd_count = rd_state.count;
569 return GST_VP8_PARSER_OK;
570 }
571