Index: media/filters/vp9_uncompressed_header_parser.cc |
diff --git a/media/filters/vp9_uncompressed_header_parser.cc b/media/filters/vp9_uncompressed_header_parser.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7ec6e2f277c2fddb86fea6f67eeb83f3d870c9a9 |
--- /dev/null |
+++ b/media/filters/vp9_uncompressed_header_parser.cc |
@@ -0,0 +1,1084 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "media/filters/vp9_uncompressed_header_parser.h" |
+ |
+#include "base/logging.h" |
+ |
+namespace media { |
+ |
+namespace { |
+ |
+// 10.5 Default probability tables |
+Vp9FrameContext kVp9DefaultFrameContext = { |
+ .tx_probs_8x8 = {{100}, {66}}, |
+ .tx_probs_16x16 = {{20, 152}, {15, 101}}, |
+ .tx_probs_32x32 = {{3, 136, 37}, {5, 52, 13}}, |
+ .coef_probs = |
+ {// 4x4 |
+ {{{{{195, 29, 183}, {84, 49, 136}, {8, 42, 71}}, |
+ {{31, 107, 169}, |
+ {35, 99, 159}, |
+ {17, 82, 140}, |
+ {8, 66, 114}, |
+ {2, 44, 76}, |
+ {1, 19, 32}}, |
+ {{40, 132, 201}, |
+ {29, 114, 187}, |
+ {13, 91, 157}, |
+ {7, 75, 127}, |
+ {3, 58, 95}, |
+ {1, 28, 47}}, |
+ {{69, 142, 221}, |
+ {42, 122, 201}, |
+ {15, 91, 159}, |
+ {6, 67, 121}, |
+ {1, 42, 77}, |
+ {1, 17, 31}}, |
+ {{102, 148, 228}, |
+ {67, 117, 204}, |
+ {17, 82, 154}, |
+ {6, 59, 114}, |
+ {2, 39, 75}, |
+ {1, 15, 29}}, |
+ {{156, 57, 233}, |
+ {119, 57, 212}, |
+ {58, 48, 163}, |
+ {29, 40, 124}, |
+ {12, 30, 81}, |
+ {3, 12, 31}}}, |
+ {{{191, 107, 226}, {124, 117, 204}, {25, 99, 155}}, |
+ {{29, 148, 210}, |
+ {37, 126, 194}, |
+ {8, 93, 157}, |
+ {2, 68, 118}, |
+ {1, 39, 69}, |
+ {1, 17, 33}}, |
+ {{41, 151, 213}, |
+ {27, 123, 193}, |
+ {3, 82, 144}, |
+ {1, 58, 105}, |
+ {1, 32, 60}, |
+ {1, 13, 26}}, |
+ {{59, 159, 220}, |
+ {23, 126, 198}, |
+ {4, 88, 151}, |
+ {1, 66, 114}, |
+ {1, 38, 71}, |
+ {1, 18, 34}}, |
+ {{114, 136, 232}, |
+ {51, 114, 207}, |
+ {11, 83, 155}, |
+ {3, 56, 105}, |
+ {1, 33, 65}, |
+ {1, 17, 34}}, |
+ {{149, 65, 234}, |
+ {121, 57, 215}, |
+ {61, 49, 166}, |
+ {28, 36, 114}, |
+ {12, 25, 76}, |
+ {3, 16, 42}}}}, |
+ {{{{214, 49, 220}, {132, 63, 188}, {42, 65, 137}}, |
+ {{85, 137, 221}, |
+ {104, 131, 216}, |
+ {49, 111, 192}, |
+ {21, 87, 155}, |
+ {2, 49, 87}, |
+ {1, 16, 28}}, |
+ {{89, 163, 230}, |
+ {90, 137, 220}, |
+ {29, 100, 183}, |
+ {10, 70, 135}, |
+ {2, 42, 81}, |
+ {1, 17, 33}}, |
+ {{108, 167, 237}, |
+ {55, 133, 222}, |
+ {15, 97, 179}, |
+ {4, 72, 135}, |
+ {1, 45, 85}, |
+ {1, 19, 38}}, |
+ {{124, 146, 240}, |
+ {66, 124, 224}, |
+ {17, 88, 175}, |
+ {4, 58, 122}, |
+ {1, 36, 75}, |
+ {1, 18, 37}}, |
+ {{141, 79, 241}, |
+ {126, 70, 227}, |
+ {66, 58, 182}, |
+ {30, 44, 136}, |
+ {12, 34, 96}, |
+ {2, 20, 47}}}, |
+ {{{229, 99, 249}, {143, 111, 235}, {46, 109, 192}}, |
+ {{82, 158, 236}, |
+ {94, 146, 224}, |
+ {25, 117, 191}, |
+ {9, 87, 149}, |
+ {3, 56, 99}, |
+ {1, 33, 57}}, |
+ {{83, 167, 237}, |
+ {68, 145, 222}, |
+ {10, 103, 177}, |
+ {2, 72, 131}, |
+ {1, 41, 79}, |
+ {1, 20, 39}}, |
+ {{99, 167, 239}, |
+ {47, 141, 224}, |
+ {10, 104, 178}, |
+ {2, 73, 133}, |
+ {1, 44, 85}, |
+ {1, 22, 47}}, |
+ {{127, 145, 243}, |
+ {71, 129, 228}, |
+ {17, 93, 177}, |
+ {3, 61, 124}, |
+ {1, 41, 84}, |
+ {1, 21, 52}}, |
+ {{157, 78, 244}, |
+ {140, 72, 231}, |
+ {69, 58, 184}, |
+ {31, 44, 137}, |
+ {14, 38, 105}, |
+ {8, 23, 61}}}}}, |
+ // 8x8 |
+ {{{{{125, 34, 187}, {52, 41, 133}, {6, 31, 56}}, |
+ {{37, 109, 153}, |
+ {51, 102, 147}, |
+ {23, 87, 128}, |
+ {8, 67, 101}, |
+ {1, 41, 63}, |
+ {1, 19, 29}}, |
+ {{31, 154, 185}, |
+ {17, 127, 175}, |
+ {6, 96, 145}, |
+ {2, 73, 114}, |
+ {1, 51, 82}, |
+ {1, 28, 45}}, |
+ {{23, 163, 200}, |
+ {10, 131, 185}, |
+ {2, 93, 148}, |
+ {1, 67, 111}, |
+ {1, 41, 69}, |
+ {1, 14, 24}}, |
+ {{29, 176, 217}, |
+ {12, 145, 201}, |
+ {3, 101, 156}, |
+ {1, 69, 111}, |
+ {1, 39, 63}, |
+ {1, 14, 23}}, |
+ {{57, 192, 233}, |
+ {25, 154, 215}, |
+ {6, 109, 167}, |
+ {3, 78, 118}, |
+ {1, 48, 69}, |
+ {1, 21, 29}}}, |
+ {{{202, 105, 245}, {108, 106, 216}, {18, 90, 144}}, |
+ {{33, 172, 219}, |
+ {64, 149, 206}, |
+ {14, 117, 177}, |
+ {5, 90, 141}, |
+ {2, 61, 95}, |
+ {1, 37, 57}}, |
+ {{33, 179, 220}, |
+ {11, 140, 198}, |
+ {1, 89, 148}, |
+ {1, 60, 104}, |
+ {1, 33, 57}, |
+ {1, 12, 21}}, |
+ {{30, 181, 221}, |
+ {8, 141, 198}, |
+ {1, 87, 145}, |
+ {1, 58, 100}, |
+ {1, 31, 55}, |
+ {1, 12, 20}}, |
+ {{32, 186, 224}, |
+ {7, 142, 198}, |
+ {1, 86, 143}, |
+ {1, 58, 100}, |
+ {1, 31, 55}, |
+ {1, 12, 22}}, |
+ {{57, 192, 227}, |
+ {20, 143, 204}, |
+ {3, 96, 154}, |
+ {1, 68, 112}, |
+ {1, 42, 69}, |
+ {1, 19, 32}}}}, |
+ {{{{212, 35, 215}, {113, 47, 169}, {29, 48, 105}}, |
+ {{74, 129, 203}, |
+ {106, 120, 203}, |
+ {49, 107, 178}, |
+ {19, 84, 144}, |
+ {4, 50, 84}, |
+ {1, 15, 25}}, |
+ {{71, 172, 217}, |
+ {44, 141, 209}, |
+ {15, 102, 173}, |
+ {6, 76, 133}, |
+ {2, 51, 89}, |
+ {1, 24, 42}}, |
+ {{64, 185, 231}, |
+ {31, 148, 216}, |
+ {8, 103, 175}, |
+ {3, 74, 131}, |
+ {1, 46, 81}, |
+ {1, 18, 30}}, |
+ {{65, 196, 235}, |
+ {25, 157, 221}, |
+ {5, 105, 174}, |
+ {1, 67, 120}, |
+ {1, 38, 69}, |
+ {1, 15, 30}}, |
+ {{65, 204, 238}, |
+ {30, 156, 224}, |
+ {7, 107, 177}, |
+ {2, 70, 124}, |
+ {1, 42, 73}, |
+ {1, 18, 34}}}, |
+ {{{225, 86, 251}, {144, 104, 235}, {42, 99, 181}}, |
+ {{85, 175, 239}, |
+ {112, 165, 229}, |
+ {29, 136, 200}, |
+ {12, 103, 162}, |
+ {6, 77, 123}, |
+ {2, 53, 84}}, |
+ {{75, 183, 239}, |
+ {30, 155, 221}, |
+ {3, 106, 171}, |
+ {1, 74, 128}, |
+ {1, 44, 76}, |
+ {1, 17, 28}}, |
+ {{73, 185, 240}, |
+ {27, 159, 222}, |
+ {2, 107, 172}, |
+ {1, 75, 127}, |
+ {1, 42, 73}, |
+ {1, 17, 29}}, |
+ {{62, 190, 238}, |
+ {21, 159, 222}, |
+ {2, 107, 172}, |
+ {1, 72, 122}, |
+ {1, 40, 71}, |
+ {1, 18, 32}}, |
+ {{61, 199, 240}, |
+ {27, 161, 226}, |
+ {4, 113, 180}, |
+ {1, 76, 129}, |
+ {1, 46, 80}, |
+ {1, 23, 41}}}}}, |
+ // 16x16 |
+ {{{{{7, 27, 153}, {5, 30, 95}, {1, 16, 30}}, |
+ {{50, 75, 127}, |
+ {57, 75, 124}, |
+ {27, 67, 108}, |
+ {10, 54, 86}, |
+ {1, 33, 52}, |
+ {1, 12, 18}}, |
+ {{43, 125, 151}, |
+ {26, 108, 148}, |
+ {7, 83, 122}, |
+ {2, 59, 89}, |
+ {1, 38, 60}, |
+ {1, 17, 27}}, |
+ {{23, 144, 163}, |
+ {13, 112, 154}, |
+ {2, 75, 117}, |
+ {1, 50, 81}, |
+ {1, 31, 51}, |
+ {1, 14, 23}}, |
+ {{18, 162, 185}, |
+ {6, 123, 171}, |
+ {1, 78, 125}, |
+ {1, 51, 86}, |
+ {1, 31, 54}, |
+ {1, 14, 23}}, |
+ {{15, 199, 227}, |
+ {3, 150, 204}, |
+ {1, 91, 146}, |
+ {1, 55, 95}, |
+ {1, 30, 53}, |
+ {1, 11, 20}}}, |
+ {{{19, 55, 240}, {19, 59, 196}, {3, 52, 105}}, |
+ {{41, 166, 207}, |
+ {104, 153, 199}, |
+ {31, 123, 181}, |
+ {14, 101, 152}, |
+ {5, 72, 106}, |
+ {1, 36, 52}}, |
+ {{35, 176, 211}, |
+ {12, 131, 190}, |
+ {2, 88, 144}, |
+ {1, 60, 101}, |
+ {1, 36, 60}, |
+ {1, 16, 28}}, |
+ {{28, 183, 213}, |
+ {8, 134, 191}, |
+ {1, 86, 142}, |
+ {1, 56, 96}, |
+ {1, 30, 53}, |
+ {1, 12, 20}}, |
+ {{20, 190, 215}, |
+ {4, 135, 192}, |
+ {1, 84, 139}, |
+ {1, 53, 91}, |
+ {1, 28, 49}, |
+ {1, 11, 20}}, |
+ {{13, 196, 216}, |
+ {2, 137, 192}, |
+ {1, 86, 143}, |
+ {1, 57, 99}, |
+ {1, 32, 56}, |
+ {1, 13, 24}}}}, |
+ {{{{211, 29, 217}, {96, 47, 156}, {22, 43, 87}}, |
+ {{78, 120, 193}, |
+ {111, 116, 186}, |
+ {46, 102, 164}, |
+ {15, 80, 128}, |
+ {2, 49, 76}, |
+ {1, 18, 28}}, |
+ {{71, 161, 203}, |
+ {42, 132, 192}, |
+ {10, 98, 150}, |
+ {3, 69, 109}, |
+ {1, 44, 70}, |
+ {1, 18, 29}}, |
+ {{57, 186, 211}, |
+ {30, 140, 196}, |
+ {4, 93, 146}, |
+ {1, 62, 102}, |
+ {1, 38, 65}, |
+ {1, 16, 27}}, |
+ {{47, 199, 217}, |
+ {14, 145, 196}, |
+ {1, 88, 142}, |
+ {1, 57, 98}, |
+ {1, 36, 62}, |
+ {1, 15, 26}}, |
+ {{26, 219, 229}, |
+ {5, 155, 207}, |
+ {1, 94, 151}, |
+ {1, 60, 104}, |
+ {1, 36, 62}, |
+ {1, 16, 28}}}, |
+ {{{233, 29, 248}, {146, 47, 220}, {43, 52, 140}}, |
+ {{100, 163, 232}, |
+ {179, 161, 222}, |
+ {63, 142, 204}, |
+ {37, 113, 174}, |
+ {26, 89, 137}, |
+ {18, 68, 97}}, |
+ {{85, 181, 230}, |
+ {32, 146, 209}, |
+ {7, 100, 164}, |
+ {3, 71, 121}, |
+ {1, 45, 77}, |
+ {1, 18, 30}}, |
+ {{65, 187, 230}, |
+ {20, 148, 207}, |
+ {2, 97, 159}, |
+ {1, 68, 116}, |
+ {1, 40, 70}, |
+ {1, 14, 29}}, |
+ {{40, 194, 227}, |
+ {8, 147, 204}, |
+ {1, 94, 155}, |
+ {1, 65, 112}, |
+ {1, 39, 66}, |
+ {1, 14, 26}}, |
+ {{16, 208, 228}, |
+ {3, 151, 207}, |
+ {1, 98, 160}, |
+ {1, 67, 117}, |
+ {1, 41, 74}, |
+ {1, 17, 31}}}}}, |
+ // 32x32 |
+ {{{{{17, 38, 140}, {7, 34, 80}, {1, 17, 29}}, |
+ {{37, 75, 128}, |
+ {41, 76, 128}, |
+ {26, 66, 116}, |
+ {12, 52, 94}, |
+ {2, 32, 55}, |
+ {1, 10, 16}}, |
+ {{50, 127, 154}, |
+ {37, 109, 152}, |
+ {16, 82, 121}, |
+ {5, 59, 85}, |
+ {1, 35, 54}, |
+ {1, 13, 20}}, |
+ {{40, 142, 167}, |
+ {17, 110, 157}, |
+ {2, 71, 112}, |
+ {1, 44, 72}, |
+ {1, 27, 45}, |
+ {1, 11, 17}}, |
+ {{30, 175, 188}, |
+ {9, 124, 169}, |
+ {1, 74, 116}, |
+ {1, 48, 78}, |
+ {1, 30, 49}, |
+ {1, 11, 18}}, |
+ {{10, 222, 223}, |
+ {2, 150, 194}, |
+ {1, 83, 128}, |
+ {1, 48, 79}, |
+ {1, 27, 45}, |
+ {1, 11, 17}}}, |
+ {{{36, 41, 235}, {29, 36, 193}, {10, 27, 111}}, |
+ {{85, 165, 222}, |
+ {177, 162, 215}, |
+ {110, 135, 195}, |
+ {57, 113, 168}, |
+ {23, 83, 120}, |
+ {10, 49, 61}}, |
+ {{85, 190, 223}, |
+ {36, 139, 200}, |
+ {5, 90, 146}, |
+ {1, 60, 103}, |
+ {1, 38, 65}, |
+ {1, 18, 30}}, |
+ {{72, 202, 223}, |
+ {23, 141, 199}, |
+ {2, 86, 140}, |
+ {1, 56, 97}, |
+ {1, 36, 61}, |
+ {1, 16, 27}}, |
+ {{55, 218, 225}, |
+ {13, 145, 200}, |
+ {1, 86, 141}, |
+ {1, 57, 99}, |
+ {1, 35, 61}, |
+ {1, 13, 22}}, |
+ {{15, 235, 212}, |
+ {1, 132, 184}, |
+ {1, 84, 139}, |
+ {1, 57, 97}, |
+ {1, 34, 56}, |
+ {1, 14, 23}}}}, |
+ {{{{181, 21, 201}, {61, 37, 123}, {10, 38, 71}}, |
+ {{47, 106, 172}, |
+ {95, 104, 173}, |
+ {42, 93, 159}, |
+ {18, 77, 131}, |
+ {4, 50, 81}, |
+ {1, 17, 23}}, |
+ {{62, 147, 199}, |
+ {44, 130, 189}, |
+ {28, 102, 154}, |
+ {18, 75, 115}, |
+ {2, 44, 65}, |
+ {1, 12, 19}}, |
+ {{55, 153, 210}, |
+ {24, 130, 194}, |
+ {3, 93, 146}, |
+ {1, 61, 97}, |
+ {1, 31, 50}, |
+ {1, 10, 16}}, |
+ {{49, 186, 223}, |
+ {17, 148, 204}, |
+ {1, 96, 142}, |
+ {1, 53, 83}, |
+ {1, 26, 44}, |
+ {1, 11, 17}}, |
+ {{13, 217, 212}, |
+ {2, 136, 180}, |
+ {1, 78, 124}, |
+ {1, 50, 83}, |
+ {1, 29, 49}, |
+ {1, 14, 23}}}, |
+ {{{197, 13, 247}, {82, 17, 222}, {25, 17, 162}}, |
+ {{126, 186, 247}, |
+ {234, 191, 243}, |
+ {176, 177, 234}, |
+ {104, 158, 220}, |
+ {66, 128, 186}, |
+ {55, 90, 137}}, |
+ {{111, 197, 242}, |
+ {46, 158, 219}, |
+ {9, 104, 171}, |
+ {2, 65, 125}, |
+ {1, 44, 80}, |
+ {1, 17, 91}}, |
+ {{104, 208, 245}, |
+ {39, 168, 224}, |
+ {3, 109, 162}, |
+ {1, 79, 124}, |
+ {1, 50, 102}, |
+ {1, 43, 102}}, |
+ {{84, 220, 246}, |
+ {31, 177, 231}, |
+ {2, 115, 180}, |
+ {1, 79, 134}, |
+ {1, 55, 77}, |
+ {1, 60, 79}}, |
+ {{43, 243, 240}, |
+ {8, 180, 217}, |
+ {1, 115, 166}, |
+ {1, 84, 121}, |
+ {1, 51, 67}, |
+ {1, 16, 6}}}}}}, |
+ .skip_prob = {192, 128, 64}, |
+ .inter_mode_probs = {{2, 173, 34}, |
+ {7, 145, 85}, |
+ {7, 166, 63}, |
+ {7, 94, 66}, |
+ {8, 64, 46}, |
+ {17, 81, 31}, |
+ {25, 29, 30}}, |
+ .interp_filter_probs = {{235, 162}, {36, 255}, {34, 3}, {149, 144}}, |
+ .is_inter_prob = {9, 102, 187, 225}, |
+ .comp_mode_prob = {239, 183, 119, 96, 41}, |
+ .single_ref_prob = {{33, 16}, {77, 74}, {142, 142}, {172, 170}, {238, 247}}, |
+ .comp_ref_prob = {50, 126, 123, 221, 226}, |
+ .y_mode_probs = {{65, 32, 18, 144, 162, 194, 41, 51, 98}, |
+ {132, 68, 18, 165, 217, 196, 45, 40, 78}, |
+ {173, 80, 19, 176, 240, 193, 64, 35, 46}, |
+ {221, 135, 38, 194, 248, 121, 96, 85, 29}}, |
+ .uv_mode_probs = {{120, 7, 76, 176, 208, 126, 28, 54, 103}, |
+ {48, 12, 154, 155, 139, 90, 34, 117, 119}, |
+ {67, 6, 25, 204, 243, 158, 13, 21, 96}, |
+ {97, 5, 44, 131, 176, 139, 48, 68, 97}, |
+ {83, 5, 42, 156, 111, 152, 26, 49, 152}, |
+ {80, 5, 58, 178, 74, 83, 33, 62, 145}, |
+ {86, 5, 32, 154, 192, 168, 14, 22, 163}, |
+ {85, 5, 32, 156, 216, 148, 19, 29, 73}, |
+ {77, 7, 64, 116, 132, 122, 37, 126, 120}, |
+ {101, 21, 107, 181, 192, 103, 19, 67, 125}}, |
+ .partition_probs = {{199, 122, 141}, |
+ {147, 63, 159}, |
+ {148, 133, 118}, |
+ {121, 104, 114}, |
+ {174, 73, 87}, |
+ {92, 41, 83}, |
+ {82, 99, 50}, |
+ {53, 39, 39}, |
+ {177, 58, 59}, |
+ {68, 26, 63}, |
+ {52, 79, 25}, |
+ {17, 14, 12}, |
+ {222, 34, 30}, |
+ {72, 16, 44}, |
+ {58, 32, 12}, |
+ {10, 7, 6}}, |
+ .mv_joint_probs = {32, 64, 96}, |
+ .mv_sign_prob = {128, 128}, |
+ .mv_class_probs = {{224, 144, 192, 168, 192, 176, 192, 198, 198, 245}, |
+ {216, 128, 176, 160, 176, 176, 192, 198, 198, 208}}, |
+ .mv_class0_bit_prob = {216, 208}, |
+ .mv_bits_prob = {{136, 140, 148, 160, 176, 192, 224, 234, 234, 240}, |
+ {136, 140, 148, 160, 176, 192, 224, 234, 234, 240}}, |
+ .mv_class0_fr_probs = {{{128, 128, 64}, {96, 112, 64}}, |
+ {{128, 128, 64}, {96, 112, 64}}}, |
+ .mv_fr_probs = {{64, 96, 64}, {64, 96, 64}}, |
+ .mv_class0_hp_prob = {160, 160}, |
+ .mv_hp_prob = {128, 128}, |
+}; |
+ |
+// Helper function for Vp9Parser::ReadTileInfo. Defined as |
+// calc_min_log2_tile_cols in spec 6.2.14 Tile size calculation. |
+int GetMinLog2TileCols(int sb64_cols) { |
+ const int kMaxTileWidthB64 = 64; |
+ int min_log2 = 0; |
+ while ((kMaxTileWidthB64 << min_log2) < sb64_cols) |
+ min_log2++; |
+ return min_log2; |
+} |
+ |
+// Helper function for Vp9Parser::ReadTileInfo. Defined as |
+// calc_max_log2_tile_cols in spec 6.2.14 Tile size calculation. |
+int GetMaxLog2TileCols(int sb64_cols) { |
+ const int kMinTileWidthB64 = 4; |
+ int max_log2 = 1; |
+ while ((sb64_cols >> max_log2) >= kMinTileWidthB64) |
+ max_log2++; |
+ return max_log2 - 1; |
+} |
+ |
+} // namespace |
+ |
+Vp9UncompressedHeaderParser::Vp9UncompressedHeaderParser( |
+ Vp9Parser::Context* context) |
+ : context_(context) {} |
+ |
+uint8_t Vp9UncompressedHeaderParser::ReadProfile() { |
+ uint8_t profile = 0; |
+ |
+ // LSB first. |
+ if (reader_.ReadBool()) |
+ profile |= 1; |
+ if (reader_.ReadBool()) |
+ profile |= 2; |
+ if (profile > 2 && reader_.ReadBool()) |
+ profile += 1; |
+ return profile; |
+} |
+ |
+// 6.2.1 Frame sync syntax |
+bool Vp9UncompressedHeaderParser::VerifySyncCode() { |
+ const int kSyncCode = 0x498342; |
+ if (reader_.ReadLiteral(8 * 3) != kSyncCode) { |
+ DVLOG(1) << "Invalid frame sync code"; |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+// 6.2.2 Color config syntax |
+bool Vp9UncompressedHeaderParser::ReadColorConfig(Vp9FrameHeader* fhdr) { |
+ if (fhdr->profile == 2 || fhdr->profile == 3) { |
+ fhdr->bit_depth = reader_.ReadBool() ? 12 : 10; |
+ } else { |
+ fhdr->bit_depth = 8; |
+ } |
+ |
+ fhdr->color_space = static_cast<Vp9ColorSpace>(reader_.ReadLiteral(3)); |
+ if (fhdr->color_space != Vp9ColorSpace::SRGB) { |
+ fhdr->color_range = reader_.ReadBool(); |
+ if (fhdr->profile == 1 || fhdr->profile == 3) { |
+ fhdr->subsampling_x = reader_.ReadBool() ? 1 : 0; |
+ fhdr->subsampling_y = reader_.ReadBool() ? 1 : 0; |
+ if (fhdr->subsampling_x == 1 && fhdr->subsampling_y == 1) { |
+ DVLOG(1) << "4:2:0 color not supported in profile 1 or 3"; |
+ return false; |
+ } |
+ bool reserved = reader_.ReadBool(); |
+ if (reserved) { |
+ DVLOG(1) << "reserved bit set"; |
+ return false; |
+ } |
+ } else { |
+ fhdr->subsampling_x = fhdr->subsampling_y = 1; |
+ } |
+ } else { |
+ fhdr->color_range = true; |
+ if (fhdr->profile == 1 || fhdr->profile == 3) { |
+ fhdr->subsampling_x = fhdr->subsampling_y = 0; |
+ |
+ bool reserved = reader_.ReadBool(); |
+ if (reserved) { |
+ DVLOG(1) << "reserved bit set"; |
+ return false; |
+ } |
+ } else { |
+ DVLOG(1) << "4:4:4 color not supported in profile 0 or 2"; |
+ return false; |
+ } |
+ } |
+ |
+ return true; |
+} |
+ |
+// 6.2.3 Frame size syntax |
+void Vp9UncompressedHeaderParser::ReadFrameSize(Vp9FrameHeader* fhdr) { |
+ fhdr->frame_width = reader_.ReadLiteral(16) + 1; |
+ fhdr->frame_height = reader_.ReadLiteral(16) + 1; |
+} |
+ |
+// 6.2.4 Render size syntax |
+void Vp9UncompressedHeaderParser::ReadRenderSize(Vp9FrameHeader* fhdr) { |
+ if (reader_.ReadBool()) { |
+ fhdr->render_width = reader_.ReadLiteral(16) + 1; |
+ fhdr->render_height = reader_.ReadLiteral(16) + 1; |
+ } else { |
+ fhdr->render_width = fhdr->frame_width; |
+ fhdr->render_height = fhdr->frame_height; |
+ } |
+} |
+ |
+// 6.2.5 Frame size with refs syntax |
+bool Vp9UncompressedHeaderParser::ReadFrameSizeFromRefs(Vp9FrameHeader* fhdr) { |
+ bool found_ref = false; |
+ for (const auto& idx : fhdr->ref_frame_idx) { |
+ found_ref = reader_.ReadBool(); |
+ if (found_ref) { |
+ const Vp9Parser::ReferenceSlot& ref = context_->ref_slots[idx]; |
+ DCHECK(ref.initialized); |
+ fhdr->frame_width = ref.frame_width; |
+ fhdr->frame_height = ref.frame_height; |
+ |
+ const unsigned kMaxDimension = 1u << 16; |
+ DCHECK_LE(fhdr->frame_width, kMaxDimension); |
+ DCHECK_LE(fhdr->frame_height, kMaxDimension); |
+ break; |
+ } |
+ } |
+ |
+ if (!found_ref) |
+ ReadFrameSize(fhdr); |
+ |
+ // 7.2.5 Frame size with refs semantics |
+ bool has_valid_ref_frame = false; |
+ for (const auto& idx : fhdr->ref_frame_idx) { |
+ const Vp9Parser::ReferenceSlot& ref = context_->ref_slots[idx]; |
+ if (2 * fhdr->frame_width >= ref.frame_width && |
+ 2 * fhdr->frame_height >= ref.frame_height && |
+ fhdr->frame_width <= 16 * ref.frame_width && |
+ fhdr->frame_height <= 16 * ref.frame_height) { |
+ has_valid_ref_frame = true; |
+ break; |
+ } |
+ } |
+ if (!has_valid_ref_frame) { |
+ DVLOG(1) << "There should be at least one reference frame meeting " |
+ << "size conditions."; |
+ return false; |
+ } |
+ |
+ ReadRenderSize(fhdr); |
+ return true; |
+} |
+ |
+// 6.2.7 Interpolation filter syntax |
+Vp9InterpolationFilter Vp9UncompressedHeaderParser::ReadInterpolationFilter() { |
+ if (reader_.ReadBool()) |
+ return Vp9InterpolationFilter::SWITCHABLE; |
+ |
+ // The mapping table for next two bits. |
+ const Vp9InterpolationFilter table[] = { |
+ Vp9InterpolationFilter::EIGHTTAP_SMOOTH, Vp9InterpolationFilter::EIGHTTAP, |
+ Vp9InterpolationFilter::EIGHTTAP_SHARP, Vp9InterpolationFilter::BILINEAR, |
+ }; |
+ return table[reader_.ReadLiteral(2)]; |
+} |
+ |
+void Vp9UncompressedHeaderParser::SetupPastIndependence(Vp9FrameHeader* fhdr) { |
+ memset(&context_->segmentation, 0, sizeof(context_->segmentation)); |
+ ResetLoopfilter(); |
+ fhdr->frame_context = kVp9DefaultFrameContext; |
+ DCHECK(Vp9FrameContextManager::IsValidFrameContext(fhdr->frame_context)); |
+} |
+ |
+// 6.2.8 Loop filter params syntax |
+void Vp9UncompressedHeaderParser::ReadLoopFilterParams() { |
+ Vp9LoopFilterParams& loop_filter = context_->loop_filter; |
+ |
+ loop_filter.level = reader_.ReadLiteral(6); |
+ loop_filter.sharpness = reader_.ReadLiteral(3); |
+ loop_filter.delta_update = false; |
+ |
+ loop_filter.delta_enabled = reader_.ReadBool(); |
+ if (loop_filter.delta_enabled) { |
+ loop_filter.delta_update = reader_.ReadBool(); |
+ if (loop_filter.delta_update) { |
+ for (size_t i = 0; i < Vp9FrameType::VP9_FRAME_MAX; i++) { |
+ loop_filter.update_ref_deltas[i] = reader_.ReadBool(); |
+ if (loop_filter.update_ref_deltas[i]) |
+ loop_filter.ref_deltas[i] = reader_.ReadSignedLiteral(6); |
+ } |
+ |
+ for (size_t i = 0; i < Vp9LoopFilterParams::kNumModeDeltas; i++) { |
+ loop_filter.update_mode_deltas[i] = reader_.ReadBool(); |
+ if (loop_filter.update_mode_deltas[i]) |
+ loop_filter.mode_deltas[i] = reader_.ReadLiteral(6); |
+ } |
+ } |
+ } |
+} |
+ |
+// 6.2.9 Quantization params syntax |
+void Vp9UncompressedHeaderParser::ReadQuantizationParams( |
+ Vp9QuantizationParams* quants) { |
+ quants->base_q_idx = reader_.ReadLiteral(8); |
+ |
+ quants->delta_q_y_dc = ReadDeltaQ(); |
+ quants->delta_q_uv_dc = ReadDeltaQ(); |
+ quants->delta_q_uv_ac = ReadDeltaQ(); |
+} |
+ |
+// 6.2.10 Delta quantizer syntax |
+int8_t Vp9UncompressedHeaderParser::ReadDeltaQ() { |
+ if (reader_.ReadBool()) |
+ return reader_.ReadSignedLiteral(4); |
+ return 0; |
+} |
+ |
+// 6.2.11 Segmentation params syntax |
+bool Vp9UncompressedHeaderParser::ReadSegmentationParams() { |
+ Vp9SegmentationParams& segmentation = context_->segmentation; |
+ segmentation.update_map = false; |
+ segmentation.update_data = false; |
+ |
+ segmentation.enabled = reader_.ReadBool(); |
+ if (!segmentation.enabled) |
+ return true; |
+ |
+ segmentation.update_map = reader_.ReadBool(); |
+ if (segmentation.update_map) { |
+ for (auto& tree_prob : segmentation.tree_probs) { |
+ tree_prob = ReadProb(); |
+ } |
+ |
+ segmentation.temporal_update = reader_.ReadBool(); |
+ for (auto& pred_prob : segmentation.pred_probs) { |
+ pred_prob = segmentation.temporal_update ? ReadProb() : kVp9MaxProb; |
+ } |
+ } |
+ |
+ segmentation.update_data = reader_.ReadBool(); |
+ if (segmentation.update_data) { |
+ segmentation.abs_or_delta_update = reader_.ReadBool(); |
+ |
+ const int kFeatureDataBits[] = {8, 6, 2, 0}; |
+ const bool kFeatureDataSigned[] = {true, true, false, false}; |
+ |
+ for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; i++) { |
+ for (size_t j = 0; j < Vp9SegmentationParams::SEG_LVL_MAX; j++) { |
+ int16_t data = 0; |
+ segmentation.feature_enabled[i][j] = reader_.ReadBool(); |
+ if (segmentation.feature_enabled[i][j]) { |
+ data = reader_.ReadLiteral(kFeatureDataBits[j]); |
+ if (kFeatureDataSigned[j]) |
+ if (reader_.ReadBool()) { |
+ // 7.2.9 |
+ if (segmentation.abs_or_delta_update) { |
+ DVLOG(1) << "feature_sign should be 0" |
+ << " if abs_or_delta_update is 1"; |
+ return false; |
+ } |
+ data = -data; |
+ } |
+ } |
+ segmentation.feature_data[i][j] = data; |
+ } |
+ } |
+ } |
+ return true; |
+} |
+ |
+// 6.2.12 Probability syntax |
+uint8_t Vp9UncompressedHeaderParser::ReadProb() { |
+ return reader_.ReadBool() ? reader_.ReadLiteral(8) : kVp9MaxProb; |
+} |
+ |
+// 6.2.13 Tile info syntax |
+bool Vp9UncompressedHeaderParser::ReadTileInfo(Vp9FrameHeader* fhdr) { |
+ int sb64_cols = (fhdr->frame_width + 63) / 64; |
+ |
+ int min_log2_tile_cols = GetMinLog2TileCols(sb64_cols); |
+ int max_log2_tile_cols = GetMaxLog2TileCols(sb64_cols); |
+ |
+ int max_ones = max_log2_tile_cols - min_log2_tile_cols; |
+ fhdr->tile_cols_log2 = min_log2_tile_cols; |
+ while (max_ones-- && reader_.ReadBool()) |
+ fhdr->tile_cols_log2++; |
+ |
+ fhdr->tile_rows_log2 = reader_.ReadBool() ? 1 : 0; |
+ if (fhdr->tile_rows_log2 > 0 && reader_.ReadBool()) |
+ fhdr->tile_rows_log2++; |
+ |
+ // 7.2.11 Tile info semantics |
+ if (fhdr->tile_cols_log2 > 6) { |
+ VLOG(1) << "tile_cols_log2 should be <= 6"; |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+void Vp9UncompressedHeaderParser::ResetLoopfilter() { |
+ Vp9LoopFilterParams& loop_filter = context_->loop_filter; |
+ |
+ loop_filter.delta_enabled = true; |
+ loop_filter.delta_update = true; |
+ |
+ loop_filter.ref_deltas[VP9_FRAME_INTRA] = 1; |
+ loop_filter.ref_deltas[VP9_FRAME_LAST] = 0; |
+ loop_filter.ref_deltas[VP9_FRAME_GOLDEN] = -1; |
+ loop_filter.ref_deltas[VP9_FRAME_ALTREF] = -1; |
+ |
+ memset(loop_filter.mode_deltas, 0, sizeof(loop_filter.mode_deltas)); |
+} |
+ |
+// 6.2 Uncompressed header syntax |
+bool Vp9UncompressedHeaderParser::Parse(const uint8_t* stream, |
+ off_t frame_size, |
+ Vp9FrameHeader* fhdr) { |
+ DVLOG(2) << "UncompressedHeaderParser::Parse"; |
+ reader_.Initialize(stream, frame_size); |
+ |
+ fhdr->data = stream; |
+ fhdr->frame_size = frame_size; |
+ |
+ // frame marker |
+ if (reader_.ReadLiteral(2) != 0x2) { |
+ DVLOG(1) << "frame marker shall be equal to 2"; |
+ return false; |
+ } |
+ |
+ fhdr->profile = ReadProfile(); |
+ if (fhdr->profile >= kVp9MaxProfile) { |
+ DVLOG(1) << "Unsupported bitstream profile"; |
+ return false; |
+ } |
+ |
+ fhdr->show_existing_frame = reader_.ReadBool(); |
+ if (fhdr->show_existing_frame) { |
+ fhdr->frame_to_show_map_idx = reader_.ReadLiteral(3); |
+ fhdr->show_frame = true; |
+ |
+ if (!reader_.ConsumeTrailingBits()) { |
+ DVLOG(1) << "trailing bits are not zero"; |
+ return false; |
+ } |
+ if (!reader_.IsValid()) { |
+ DVLOG(1) << "parser reads beyond the end of buffer"; |
+ return false; |
+ } |
+ fhdr->uncompressed_header_size = reader_.GetBytesRead(); |
+ fhdr->header_size_in_bytes = 0; |
+ return true; |
+ } |
+ |
+ fhdr->frame_type = static_cast<Vp9FrameHeader::FrameType>(reader_.ReadBool()); |
+ fhdr->show_frame = reader_.ReadBool(); |
+ fhdr->error_resilient_mode = reader_.ReadBool(); |
+ |
+ if (fhdr->IsKeyframe()) { |
+ if (!VerifySyncCode()) |
+ return false; |
+ |
+ if (!ReadColorConfig(fhdr)) |
+ return false; |
+ |
+ ReadFrameSize(fhdr); |
+ ReadRenderSize(fhdr); |
+ fhdr->refresh_frame_flags = 0xff; |
+ } else { |
+ if (!fhdr->show_frame) |
+ fhdr->intra_only = reader_.ReadBool(); |
+ |
+ if (!fhdr->error_resilient_mode) |
+ fhdr->reset_frame_context = reader_.ReadLiteral(2); |
+ |
+ if (fhdr->intra_only) { |
+ if (!VerifySyncCode()) |
+ return false; |
+ |
+ if (fhdr->profile > 0) { |
+ if (!ReadColorConfig(fhdr)) |
+ return false; |
+ } else { |
+ fhdr->bit_depth = 8; |
+ fhdr->color_space = Vp9ColorSpace::BT_601; |
+ fhdr->subsampling_x = fhdr->subsampling_y = 1; |
+ } |
+ |
+ fhdr->refresh_frame_flags = reader_.ReadLiteral(8); |
+ |
+ ReadFrameSize(fhdr); |
+ ReadRenderSize(fhdr); |
+ } else { |
+ fhdr->refresh_frame_flags = reader_.ReadLiteral(8); |
+ |
+ static_assert(arraysize(fhdr->ref_frame_sign_bias) >= |
+ Vp9FrameType::VP9_FRAME_LAST + kVp9NumRefsPerFrame, |
+ "ref_frame_sign_bias is not big enough"); |
+ for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { |
+ fhdr->ref_frame_idx[i] = reader_.ReadLiteral(kVp9NumRefFramesLog2); |
+ fhdr->ref_frame_sign_bias[Vp9FrameType::VP9_FRAME_LAST + i] = |
+ reader_.ReadBool(); |
+ |
+ // 8.2 Frame order constraints |
+ // ref_frame_idx[i] refers to an earlier decoded frame. |
+ const Vp9Parser::ReferenceSlot& ref = |
+ context_->ref_slots[fhdr->ref_frame_idx[i]]; |
+ if (!ref.initialized) { |
+ DVLOG(1) << "ref_frame_idx[" << i |
+ << "]=" << static_cast<int>(fhdr->ref_frame_idx[i]) |
+ << " refers to unused frame"; |
+ return false; |
+ } |
+ |
+ // 7.2 Uncompressed header semantics |
+ // the selected reference frames match the current frame in bit depth, |
+ // profile, chroma subsampling, and color space. |
+ // TODO(kcwu): how about color_range? |
+ if (ref.profile != fhdr->profile) { |
+ DVLOG(1) << "profile of referenced frame mismatch"; |
+ return false; |
+ } |
+ if (i == 0) { |
+ // Some fields are not specified for inter-frame in header, so copy |
+ // them from referenced frame. |
+ fhdr->bit_depth = ref.bit_depth; |
+ fhdr->color_space = ref.color_space; |
+ fhdr->subsampling_x = ref.subsampling_x; |
+ fhdr->subsampling_y = ref.subsampling_y; |
+ } else { |
+ if (fhdr->bit_depth != ref.bit_depth) { |
+ DVLOG(1) << "bit_depth of referenced frame mismatch"; |
+ return false; |
+ } |
+ if (fhdr->color_space != ref.color_space) { |
+ DVLOG(1) << "color_space of referenced frame mismatch"; |
+ return false; |
+ } |
+ if (fhdr->subsampling_x != ref.subsampling_x || |
+ fhdr->subsampling_y != ref.subsampling_y) { |
+ DVLOG(1) << "chroma subsampling of referenced frame mismatch"; |
+ return false; |
+ } |
+ } |
+ } |
+ |
+ if (!ReadFrameSizeFromRefs(fhdr)) |
+ return false; |
+ |
+ fhdr->allow_high_precision_mv = reader_.ReadBool(); |
+ fhdr->interpolation_filter = ReadInterpolationFilter(); |
+ } |
+ } |
+ |
+ if (fhdr->error_resilient_mode) { |
+ fhdr->refresh_frame_context = false; |
+ fhdr->frame_parallel_decoding_mode = true; |
+ } else { |
+ fhdr->refresh_frame_context = reader_.ReadBool(); |
+ fhdr->frame_parallel_decoding_mode = reader_.ReadBool(); |
+ } |
+ |
+ fhdr->frame_context_idx_backup = fhdr->frame_context_idx = |
+ reader_.ReadLiteral(2); |
+ |
+ if (fhdr->IsIntra()) { |
+ SetupPastIndependence(fhdr); |
+ if (fhdr->IsKeyframe() || fhdr->error_resilient_mode || |
+ fhdr->reset_frame_context == 3) { |
+ for (auto& frame_context_manage : context_->frame_context_managers) |
+ frame_context_manage.Update(fhdr->frame_context); |
+ } else if (fhdr->reset_frame_context == 2) { |
+ DCHECK_LT(fhdr->frame_context_idx, |
+ arraysize(context_->frame_context_managers)); |
+ context_->frame_context_managers[fhdr->frame_context_idx].Update( |
+ fhdr->frame_context); |
+ } |
+ fhdr->frame_context_idx = 0; |
+ } |
+ |
+ ReadLoopFilterParams(); |
+ ReadQuantizationParams(&fhdr->quant_params); |
+ if (!ReadSegmentationParams()) |
+ return false; |
+ |
+ if (!ReadTileInfo(fhdr)) |
+ return false; |
+ |
+ fhdr->header_size_in_bytes = reader_.ReadLiteral(16); |
+ if (fhdr->header_size_in_bytes == 0) { |
+ DVLOG(1) << "invalid header size"; |
+ return false; |
+ } |
+ |
+ if (!reader_.ConsumeTrailingBits()) { |
+ DVLOG(1) << "trailing bits are not zero"; |
+ return false; |
+ } |
+ if (!reader_.IsValid()) { |
+ DVLOG(1) << "parser reads beyond the end of buffer"; |
+ return false; |
+ } |
+ fhdr->uncompressed_header_size = reader_.GetBytesRead(); |
+ |
+ return true; |
+} |
+ |
+} // namespace media |