| 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 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 | 113 |
| 114 static void update_switchable_interp_probs(VP9_COMMON *cm, vp9_writer *w) { | 114 static void update_switchable_interp_probs(VP9_COMMON *cm, vp9_writer *w) { |
| 115 int j; | 115 int j; |
| 116 for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) | 116 for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) |
| 117 prob_diff_update(vp9_switchable_interp_tree, | 117 prob_diff_update(vp9_switchable_interp_tree, |
| 118 cm->fc.switchable_interp_prob[j], | 118 cm->fc.switchable_interp_prob[j], |
| 119 cm->counts.switchable_interp[j], SWITCHABLE_FILTERS, w); | 119 cm->counts.switchable_interp[j], SWITCHABLE_FILTERS, w); |
| 120 } | 120 } |
| 121 | 121 |
| 122 static void pack_mb_tokens(vp9_writer *w, | 122 static void pack_mb_tokens(vp9_writer *w, |
| 123 TOKENEXTRA **tp, const TOKENEXTRA *const stop) { | 123 TOKENEXTRA **tp, const TOKENEXTRA *const stop, |
| 124 vpx_bit_depth_t bit_depth) { |
| 124 TOKENEXTRA *p = *tp; | 125 TOKENEXTRA *p = *tp; |
| 125 | 126 |
| 126 while (p < stop && p->token != EOSB_TOKEN) { | 127 while (p < stop && p->token != EOSB_TOKEN) { |
| 127 const int t = p->token; | 128 const int t = p->token; |
| 128 const struct vp9_token *const a = &vp9_coef_encodings[t]; | 129 const struct vp9_token *const a = &vp9_coef_encodings[t]; |
| 129 const vp9_extra_bit *const b = &vp9_extra_bits[t]; | |
| 130 int i = 0; | 130 int i = 0; |
| 131 int v = a->value; | 131 int v = a->value; |
| 132 int n = a->len; | 132 int n = a->len; |
| 133 #if CONFIG_VP9_HIGHBITDEPTH |
| 134 const vp9_extra_bit *b; |
| 135 if (bit_depth == VPX_BITS_12) |
| 136 b = &vp9_extra_bits_high12[t]; |
| 137 else if (bit_depth == VPX_BITS_10) |
| 138 b = &vp9_extra_bits_high10[t]; |
| 139 else |
| 140 b = &vp9_extra_bits[t]; |
| 141 #else |
| 142 const vp9_extra_bit *const b = &vp9_extra_bits[t]; |
| 143 (void) bit_depth; |
| 144 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 133 | 145 |
| 134 /* skip one or two nodes */ | 146 /* skip one or two nodes */ |
| 135 if (p->skip_eob_node) { | 147 if (p->skip_eob_node) { |
| 136 n -= p->skip_eob_node; | 148 n -= p->skip_eob_node; |
| 137 i = 2 * p->skip_eob_node; | 149 i = 2 * p->skip_eob_node; |
| 138 } | 150 } |
| 139 | 151 |
| 140 // TODO(jbb): expanding this can lead to big gains. It allows | 152 // TODO(jbb): expanding this can lead to big gains. It allows |
| 141 // much better branch prediction and would enable us to avoid numerous | 153 // much better branch prediction and would enable us to avoid numerous |
| 142 // lookups and compares. | 154 // lookups and compares. |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 mi_row, num_8x8_blocks_high_lookup[m->mbmi.sb_type], | 392 mi_row, num_8x8_blocks_high_lookup[m->mbmi.sb_type], |
| 381 mi_col, num_8x8_blocks_wide_lookup[m->mbmi.sb_type], | 393 mi_col, num_8x8_blocks_wide_lookup[m->mbmi.sb_type], |
| 382 cm->mi_rows, cm->mi_cols); | 394 cm->mi_rows, cm->mi_cols); |
| 383 if (frame_is_intra_only(cm)) { | 395 if (frame_is_intra_only(cm)) { |
| 384 write_mb_modes_kf(cm, xd, xd->mi, w); | 396 write_mb_modes_kf(cm, xd, xd->mi, w); |
| 385 } else { | 397 } else { |
| 386 pack_inter_mode_mvs(cpi, m, w); | 398 pack_inter_mode_mvs(cpi, m, w); |
| 387 } | 399 } |
| 388 | 400 |
| 389 assert(*tok < tok_end); | 401 assert(*tok < tok_end); |
| 390 pack_mb_tokens(w, tok, tok_end); | 402 pack_mb_tokens(w, tok, tok_end, cm->bit_depth); |
| 391 } | 403 } |
| 392 | 404 |
| 393 static void write_partition(const VP9_COMMON *const cm, | 405 static void write_partition(const VP9_COMMON *const cm, |
| 394 const MACROBLOCKD *const xd, | 406 const MACROBLOCKD *const xd, |
| 395 int hbs, int mi_row, int mi_col, | 407 int hbs, int mi_row, int mi_col, |
| 396 PARTITION_TYPE p, BLOCK_SIZE bsize, vp9_writer *w) { | 408 PARTITION_TYPE p, BLOCK_SIZE bsize, vp9_writer *w) { |
| 397 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize); | 409 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize); |
| 398 const vp9_prob *const probs = get_partition_probs(cm, ctx); | 410 const vp9_prob *const probs = get_partition_probs(cm, ctx); |
| 399 const int has_rows = (mi_row + hbs) < cm->mi_rows; | 411 const int has_rows = (mi_row + hbs) < cm->mi_rows; |
| 400 const int has_cols = (mi_col + hbs) < cm->mi_cols; | 412 const int has_cols = (mi_col + hbs) < cm->mi_cols; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 412 } | 424 } |
| 413 } | 425 } |
| 414 | 426 |
| 415 static void write_modes_sb(VP9_COMP *cpi, | 427 static void write_modes_sb(VP9_COMP *cpi, |
| 416 const TileInfo *const tile, vp9_writer *w, | 428 const TileInfo *const tile, vp9_writer *w, |
| 417 TOKENEXTRA **tok, const TOKENEXTRA *const tok_end, | 429 TOKENEXTRA **tok, const TOKENEXTRA *const tok_end, |
| 418 int mi_row, int mi_col, BLOCK_SIZE bsize) { | 430 int mi_row, int mi_col, BLOCK_SIZE bsize) { |
| 419 const VP9_COMMON *const cm = &cpi->common; | 431 const VP9_COMMON *const cm = &cpi->common; |
| 420 MACROBLOCKD *const xd = &cpi->mb.e_mbd; | 432 MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
| 421 | 433 |
| 422 const int bsl = b_width_log2(bsize); | 434 const int bsl = b_width_log2_lookup[bsize]; |
| 423 const int bs = (1 << bsl) / 4; | 435 const int bs = (1 << bsl) / 4; |
| 424 PARTITION_TYPE partition; | 436 PARTITION_TYPE partition; |
| 425 BLOCK_SIZE subsize; | 437 BLOCK_SIZE subsize; |
| 426 const MODE_INFO *m = NULL; | 438 const MODE_INFO *m = NULL; |
| 427 | 439 |
| 428 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) | 440 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
| 429 return; | 441 return; |
| 430 | 442 |
| 431 m = cm->mi[mi_row * cm->mi_stride + mi_col].src_mi; | 443 m = cm->mi[mi_row * cm->mi_stride + mi_col].src_mi; |
| 432 | 444 |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 | 928 |
| 917 static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) { | 929 static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) { |
| 918 VP9_COMMON *const cm = &cpi->common; | 930 VP9_COMMON *const cm = &cpi->common; |
| 919 vp9_writer residual_bc; | 931 vp9_writer residual_bc; |
| 920 | 932 |
| 921 int tile_row, tile_col; | 933 int tile_row, tile_col; |
| 922 TOKENEXTRA *tok[4][1 << 6], *tok_end; | 934 TOKENEXTRA *tok[4][1 << 6], *tok_end; |
| 923 size_t total_size = 0; | 935 size_t total_size = 0; |
| 924 const int tile_cols = 1 << cm->log2_tile_cols; | 936 const int tile_cols = 1 << cm->log2_tile_cols; |
| 925 const int tile_rows = 1 << cm->log2_tile_rows; | 937 const int tile_rows = 1 << cm->log2_tile_rows; |
| 938 TileInfo tile[4][1 << 6]; |
| 939 TOKENEXTRA *pre_tok = cpi->tok; |
| 940 int tile_tok = 0; |
| 926 | 941 |
| 927 vpx_memset(cm->above_seg_context, 0, sizeof(*cm->above_seg_context) * | 942 vpx_memset(cm->above_seg_context, 0, sizeof(*cm->above_seg_context) * |
| 928 mi_cols_aligned_to_sb(cm->mi_cols)); | 943 mi_cols_aligned_to_sb(cm->mi_cols)); |
| 929 | 944 |
| 930 tok[0][0] = cpi->tok; | 945 for (tile_row = 0; tile_row < tile_rows; ++tile_row) { |
| 931 for (tile_row = 0; tile_row < tile_rows; tile_row++) { | 946 for (tile_col = 0; tile_col < tile_cols; ++tile_col) { |
| 932 if (tile_row) | 947 vp9_tile_init(&tile[tile_row][tile_col], cm, tile_row, tile_col); |
| 933 tok[tile_row][0] = tok[tile_row - 1][tile_cols - 1] + | |
| 934 cpi->tok_count[tile_row - 1][tile_cols - 1]; | |
| 935 | 948 |
| 936 for (tile_col = 1; tile_col < tile_cols; tile_col++) | 949 tok[tile_row][tile_col] = pre_tok + tile_tok; |
| 937 tok[tile_row][tile_col] = tok[tile_row][tile_col - 1] + | 950 pre_tok = tok[tile_row][tile_col]; |
| 938 cpi->tok_count[tile_row][tile_col - 1]; | 951 tile_tok = allocated_tokens(tile[tile_row][tile_col]); |
| 952 } |
| 939 } | 953 } |
| 940 | 954 |
| 941 for (tile_row = 0; tile_row < tile_rows; tile_row++) { | 955 for (tile_row = 0; tile_row < tile_rows; tile_row++) { |
| 942 for (tile_col = 0; tile_col < tile_cols; tile_col++) { | 956 for (tile_col = 0; tile_col < tile_cols; tile_col++) { |
| 943 TileInfo tile; | 957 const TileInfo * const ptile = &tile[tile_row][tile_col]; |
| 944 | 958 |
| 945 vp9_tile_init(&tile, cm, tile_row, tile_col); | |
| 946 tok_end = tok[tile_row][tile_col] + cpi->tok_count[tile_row][tile_col]; | 959 tok_end = tok[tile_row][tile_col] + cpi->tok_count[tile_row][tile_col]; |
| 947 | 960 |
| 948 if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1) | 961 if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1) |
| 949 vp9_start_encode(&residual_bc, data_ptr + total_size + 4); | 962 vp9_start_encode(&residual_bc, data_ptr + total_size + 4); |
| 950 else | 963 else |
| 951 vp9_start_encode(&residual_bc, data_ptr + total_size); | 964 vp9_start_encode(&residual_bc, data_ptr + total_size); |
| 952 | 965 |
| 953 write_modes(cpi, &tile, &residual_bc, &tok[tile_row][tile_col], tok_end); | 966 write_modes(cpi, ptile, &residual_bc, &tok[tile_row][tile_col], tok_end); |
| 954 assert(tok[tile_row][tile_col] == tok_end); | 967 assert(tok[tile_row][tile_col] == tok_end); |
| 955 vp9_stop_encode(&residual_bc); | 968 vp9_stop_encode(&residual_bc); |
| 956 if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1) { | 969 if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1) { |
| 957 // size of this tile | 970 // size of this tile |
| 958 mem_put_be32(data_ptr + total_size, residual_bc.pos); | 971 mem_put_be32(data_ptr + total_size, residual_bc.pos); |
| 959 total_size += 4; | 972 total_size += 4; |
| 960 } | 973 } |
| 961 | 974 |
| 962 total_size += residual_bc.pos; | 975 total_size += residual_bc.pos; |
| 963 } | 976 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 994 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { | 1007 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { |
| 995 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, ref_frame); | 1008 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, ref_frame); |
| 996 found = cm->width == cfg->y_crop_width && | 1009 found = cm->width == cfg->y_crop_width && |
| 997 cm->height == cfg->y_crop_height; | 1010 cm->height == cfg->y_crop_height; |
| 998 | 1011 |
| 999 // Set "found" to 0 for temporal svc and for spatial svc key frame | 1012 // Set "found" to 0 for temporal svc and for spatial svc key frame |
| 1000 if (cpi->use_svc && | 1013 if (cpi->use_svc && |
| 1001 ((cpi->svc.number_temporal_layers > 1 && | 1014 ((cpi->svc.number_temporal_layers > 1 && |
| 1002 cpi->oxcf.rc_mode == VPX_CBR) || | 1015 cpi->oxcf.rc_mode == VPX_CBR) || |
| 1003 (cpi->svc.number_spatial_layers > 1 && | 1016 (cpi->svc.number_spatial_layers > 1 && |
| 1004 cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame))) { | 1017 cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame) || |
| 1018 (is_two_pass_svc(cpi) && |
| 1019 cpi->svc.encode_empty_frame_state == ENCODING && |
| 1020 cpi->svc.layer_context[0].frames_from_key_frame < |
| 1021 cpi->svc.number_temporal_layers + 1))) { |
| 1005 found = 0; | 1022 found = 0; |
| 1006 } | 1023 } |
| 1007 vp9_wb_write_bit(wb, found); | 1024 vp9_wb_write_bit(wb, found); |
| 1008 if (found) { | 1025 if (found) { |
| 1009 break; | 1026 break; |
| 1010 } | 1027 } |
| 1011 } | 1028 } |
| 1012 | 1029 |
| 1013 if (!found) { | 1030 if (!found) { |
| 1014 vp9_wb_write_literal(wb, cm->width - 1, 16); | 1031 vp9_wb_write_literal(wb, cm->width - 1, 16); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 write_frame_size(cm, wb); | 1103 write_frame_size(cm, wb); |
| 1087 } else { | 1104 } else { |
| 1088 // In spatial svc if it's not error_resilient_mode then we need to code all | 1105 // In spatial svc if it's not error_resilient_mode then we need to code all |
| 1089 // visible frames as invisible. But we need to keep the show_frame flag so | 1106 // visible frames as invisible. But we need to keep the show_frame flag so |
| 1090 // that the publisher could know whether it is supposed to be visible. | 1107 // that the publisher could know whether it is supposed to be visible. |
| 1091 // So we will code the show_frame flag as it is. Then code the intra_only | 1108 // So we will code the show_frame flag as it is. Then code the intra_only |
| 1092 // bit here. This will make the bitstream incompatible. In the player we | 1109 // bit here. This will make the bitstream incompatible. In the player we |
| 1093 // will change to show_frame flag to 0, then add an one byte frame with | 1110 // will change to show_frame flag to 0, then add an one byte frame with |
| 1094 // show_existing_frame flag which tells the decoder which frame we want to | 1111 // show_existing_frame flag which tells the decoder which frame we want to |
| 1095 // show. | 1112 // show. |
| 1096 if (!cm->show_frame || | 1113 if (!cm->show_frame) |
| 1097 (is_two_pass_svc(cpi) && cm->error_resilient_mode == 0)) | |
| 1098 vp9_wb_write_bit(wb, cm->intra_only); | 1114 vp9_wb_write_bit(wb, cm->intra_only); |
| 1099 | 1115 |
| 1100 if (!cm->error_resilient_mode) | 1116 if (!cm->error_resilient_mode) |
| 1101 vp9_wb_write_literal(wb, cm->reset_frame_context, 2); | 1117 vp9_wb_write_literal(wb, cm->reset_frame_context, 2); |
| 1102 | 1118 |
| 1103 if (cm->intra_only) { | 1119 if (cm->intra_only) { |
| 1104 write_sync_code(wb); | 1120 write_sync_code(wb); |
| 1105 | 1121 |
| 1106 // Note for profile 0, 420 8bpp is assumed. | 1122 // Note for profile 0, 420 8bpp is assumed. |
| 1107 if (cm->profile > PROFILE_0) { | 1123 if (cm->profile > PROFILE_0) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1236 | 1252 |
| 1237 first_part_size = write_compressed_header(cpi, data); | 1253 first_part_size = write_compressed_header(cpi, data); |
| 1238 data += first_part_size; | 1254 data += first_part_size; |
| 1239 // TODO(jbb): Figure out what to do if first_part_size > 16 bits. | 1255 // TODO(jbb): Figure out what to do if first_part_size > 16 bits. |
| 1240 vp9_wb_write_literal(&saved_wb, (int)first_part_size, 16); | 1256 vp9_wb_write_literal(&saved_wb, (int)first_part_size, 16); |
| 1241 | 1257 |
| 1242 data += encode_tiles(cpi, data); | 1258 data += encode_tiles(cpi, data); |
| 1243 | 1259 |
| 1244 *size = data - dest; | 1260 *size = data - dest; |
| 1245 } | 1261 } |
| OLD | NEW |