OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 | 11 |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 #include <string.h> | 13 #include <string.h> |
14 #include "vpx/vpx_decoder.h" | 14 #include "vpx/vpx_decoder.h" |
15 #include "vpx/vp8dx.h" | 15 #include "vpx/vp8dx.h" |
16 #include "vpx/internal/vpx_codec_internal.h" | 16 #include "vpx/internal/vpx_codec_internal.h" |
17 #include "vpx_version.h" | 17 #include "vpx_version.h" |
18 #include "decoder/vp9_onyxd.h" | 18 #include "vp9/decoder/vp9_onyxd.h" |
19 #include "decoder/vp9_onyxd_int.h" | 19 #include "vp9/decoder/vp9_onyxd_int.h" |
| 20 #include "vp9/decoder/vp9_read_bit_buffer.h" |
20 #include "vp9/vp9_iface_common.h" | 21 #include "vp9/vp9_iface_common.h" |
21 | 22 |
22 #define VP9_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) | 23 #define VP9_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) |
23 typedef vpx_codec_stream_info_t vp9_stream_info_t; | 24 typedef vpx_codec_stream_info_t vp9_stream_info_t; |
24 | 25 |
25 /* Structures for handling memory allocations */ | 26 /* Structures for handling memory allocations */ |
26 typedef enum { | 27 typedef enum { |
27 VP9_SEG_ALG_PRIV = 256, | 28 VP9_SEG_ALG_PRIV = 256, |
28 VP9_SEG_MAX | 29 VP9_SEG_MAX |
29 } mem_seg_id_t; | 30 } mem_seg_id_t; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 if (ctx->mmaps[i].dtor) | 136 if (ctx->mmaps[i].dtor) |
136 ctx->mmaps[i].dtor(&ctx->mmaps[i]); | 137 ctx->mmaps[i].dtor(&ctx->mmaps[i]); |
137 } | 138 } |
138 | 139 |
139 return VPX_CODEC_OK; | 140 return VPX_CODEC_OK; |
140 } | 141 } |
141 | 142 |
142 static vpx_codec_err_t vp9_peek_si(const uint8_t *data, | 143 static vpx_codec_err_t vp9_peek_si(const uint8_t *data, |
143 unsigned int data_sz, | 144 unsigned int data_sz, |
144 vpx_codec_stream_info_t *si) { | 145 vpx_codec_stream_info_t *si) { |
145 vpx_codec_err_t res = VPX_CODEC_OK; | 146 if (data_sz <= 8) return VPX_CODEC_UNSUP_BITSTREAM; |
| 147 if (data + data_sz <= data) return VPX_CODEC_INVALID_PARAM; |
146 | 148 |
147 if (data_sz <= 8) return VPX_CODEC_UNSUP_BITSTREAM; | 149 si->is_kf = 0; |
| 150 si->w = si->h = 0; |
148 | 151 |
149 if (data + data_sz <= data) { | 152 { |
150 res = VPX_CODEC_INVALID_PARAM; | 153 struct vp9_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL }; |
151 } else { | 154 const int frame_marker = vp9_rb_read_literal(&rb, 2); |
152 const int frame_marker = (data[0] >> 6) & 0x3; | 155 const int version = vp9_rb_read_bit(&rb) | (vp9_rb_read_bit(&rb) << 1); |
153 const int version = (data[0] >> 4) & 0x3; | |
154 if (frame_marker != 0x2) return VPX_CODEC_UNSUP_BITSTREAM; | 156 if (frame_marker != 0x2) return VPX_CODEC_UNSUP_BITSTREAM; |
| 157 #if CONFIG_NON420 |
| 158 if (version > 1) return VPX_CODEC_UNSUP_BITSTREAM; |
| 159 #else |
155 if (version != 0) return VPX_CODEC_UNSUP_BITSTREAM; | 160 if (version != 0) return VPX_CODEC_UNSUP_BITSTREAM; |
| 161 #endif |
156 | 162 |
157 si->is_kf = !((data[0] >> 2) & 0x1); | 163 if (vp9_rb_read_bit(&rb)) { // show an existing frame |
| 164 return VPX_CODEC_OK; |
| 165 } |
| 166 |
| 167 si->is_kf = !vp9_rb_read_bit(&rb); |
158 if (si->is_kf) { | 168 if (si->is_kf) { |
159 const uint8_t *c = data + 1; | 169 const int sRGB = 7; |
| 170 int colorspace; |
160 | 171 |
161 if (c[0] != SYNC_CODE_0 || c[1] != SYNC_CODE_1 || c[2] != SYNC_CODE_2) | 172 rb.bit_offset += 1; // show frame |
| 173 rb.bit_offset += 1; // error resilient |
| 174 |
| 175 if (vp9_rb_read_literal(&rb, 8) != SYNC_CODE_0 || |
| 176 vp9_rb_read_literal(&rb, 8) != SYNC_CODE_1 || |
| 177 vp9_rb_read_literal(&rb, 8) != SYNC_CODE_2) { |
162 return VPX_CODEC_UNSUP_BITSTREAM; | 178 return VPX_CODEC_UNSUP_BITSTREAM; |
| 179 } |
163 | 180 |
164 c += 3; | 181 colorspace = vp9_rb_read_literal(&rb, 3); |
165 si->w = (((c[0] & 0xf) << 12) | (c[1] << 4) | ((c[2] >> 4) & 0xf)) + 1; | 182 if (colorspace != sRGB) { |
166 si->h = (((c[2] & 0xf) << 12) | (c[3] << 4) | ((c[4] >> 4) & 0xf)) + 1; | 183 rb.bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range |
| 184 if (version == 1) { |
| 185 rb.bit_offset += 2; // subsampling x/y |
| 186 rb.bit_offset += 1; // has extra plane |
| 187 } |
| 188 } else { |
| 189 if (version == 1) { |
| 190 rb.bit_offset += 1; // has extra plane |
| 191 } else { |
| 192 // RGB is only available in version 1 |
| 193 return VPX_CODEC_UNSUP_BITSTREAM; |
| 194 } |
| 195 } |
| 196 |
| 197 // TODO(jzern): these are available on non-keyframes in intra only mode. |
| 198 si->w = vp9_rb_read_literal(&rb, 16) + 1; |
| 199 si->h = vp9_rb_read_literal(&rb, 16) + 1; |
167 } | 200 } |
168 } | 201 } |
169 | 202 |
170 return res; | 203 return VPX_CODEC_OK; |
171 } | 204 } |
172 | 205 |
173 static vpx_codec_err_t vp9_get_si(vpx_codec_alg_priv_t *ctx, | 206 static vpx_codec_err_t vp9_get_si(vpx_codec_alg_priv_t *ctx, |
174 vpx_codec_stream_info_t *si) { | 207 vpx_codec_stream_info_t *si) { |
175 | 208 |
176 unsigned int sz; | 209 unsigned int sz; |
177 | 210 |
178 if (si->sz >= sizeof(vp9_stream_info_t)) | 211 if (si->sz >= sizeof(vp9_stream_info_t)) |
179 sz = sizeof(vp9_stream_info_t); | 212 sz = sizeof(vp9_stream_info_t); |
180 else | 213 else |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 const uint8_t *data, | 394 const uint8_t *data, |
362 unsigned int data_sz, | 395 unsigned int data_sz, |
363 void *user_priv, | 396 void *user_priv, |
364 long deadline) { | 397 long deadline) { |
365 const uint8_t *data_start = data; | 398 const uint8_t *data_start = data; |
366 const uint8_t *data_end = data + data_sz; | 399 const uint8_t *data_end = data + data_sz; |
367 vpx_codec_err_t res = 0; | 400 vpx_codec_err_t res = 0; |
368 uint32_t sizes[8]; | 401 uint32_t sizes[8]; |
369 int frames_this_pts, frame_count = 0; | 402 int frames_this_pts, frame_count = 0; |
370 | 403 |
| 404 if (data == NULL || data_sz == 0) return VPX_CODEC_INVALID_PARAM; |
| 405 |
371 parse_superframe_index(data, data_sz, sizes, &frames_this_pts); | 406 parse_superframe_index(data, data_sz, sizes, &frames_this_pts); |
372 | 407 |
373 do { | 408 do { |
374 // Skip over the superframe index, if present | 409 // Skip over the superframe index, if present |
375 if (data_sz && (*data_start & 0xe0) == 0xc0) { | 410 if (data_sz && (*data_start & 0xe0) == 0xc0) { |
376 const uint8_t marker = *data_start; | 411 const uint8_t marker = *data_start; |
377 const uint32_t frames = (marker & 0x7) + 1; | 412 const uint32_t frames = (marker & 0x7) + 1; |
378 const uint32_t mag = ((marker >> 3) & 0x3) + 1; | 413 const uint32_t mag = ((marker >> 3) & 0x3) + 1; |
379 const uint32_t index_sz = 2 + mag * frames; | 414 const uint32_t index_sz = 2 + mag * frames; |
380 | 415 |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 { | 708 { |
674 /* encoder functions */ | 709 /* encoder functions */ |
675 NOT_IMPLEMENTED, | 710 NOT_IMPLEMENTED, |
676 NOT_IMPLEMENTED, | 711 NOT_IMPLEMENTED, |
677 NOT_IMPLEMENTED, | 712 NOT_IMPLEMENTED, |
678 NOT_IMPLEMENTED, | 713 NOT_IMPLEMENTED, |
679 NOT_IMPLEMENTED, | 714 NOT_IMPLEMENTED, |
680 NOT_IMPLEMENTED | 715 NOT_IMPLEMENTED |
681 } | 716 } |
682 }; | 717 }; |
OLD | NEW |