Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: media/filters/h264_parser.cc

Issue 2268183009: H264SPS: Centralize computation of coded size and visible rect. (Closed)
Patch Set: Make sure fuzzing code actually runs. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/filters/h264_parser.h ('k') | media/filters/h264_parser_fuzzertest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/h264_parser.h" 5 #include "media/filters/h264_parser.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "media/base/decrypt_config.h" 13 #include "media/base/decrypt_config.h"
14 #include "ui/gfx/geometry/rect.h"
15 #include "ui/gfx/geometry/size.h"
14 16
15 namespace media { 17 namespace media {
16 18
17 bool H264SliceHeader::IsPSlice() const { 19 bool H264SliceHeader::IsPSlice() const {
18 return (slice_type % 5 == kPSlice); 20 return (slice_type % 5 == kPSlice);
19 } 21 }
20 22
21 bool H264SliceHeader::IsBSlice() const { 23 bool H264SliceHeader::IsBSlice() const {
22 return (slice_type % 5 == kBSlice); 24 return (slice_type % 5 == kBSlice);
23 } 25 }
(...skipping 11 matching lines...) Expand all
35 } 37 }
36 38
37 H264NALU::H264NALU() { 39 H264NALU::H264NALU() {
38 memset(this, 0, sizeof(*this)); 40 memset(this, 0, sizeof(*this));
39 } 41 }
40 42
41 H264SPS::H264SPS() { 43 H264SPS::H264SPS() {
42 memset(this, 0, sizeof(*this)); 44 memset(this, 0, sizeof(*this));
43 } 45 }
44 46
47 // Based on T-REC-H.264 7.4.2.1.1, "Sequence parameter set data semantics",
48 // available from http://www.itu.int/rec/T-REC-H.264.
49 base::Optional<gfx::Size> H264SPS::GetCodedSize() const {
50 // Interlaced frames are twice the height of each field.
51 const int mb_unit = 16;
52 int map_unit = frame_mbs_only_flag ? 16 : 32;
53
54 // Verify that the values are not too large before multiplying them.
55 // TODO(sandersd): These limits could be much smaller. The currently-largest
56 // specified limit (excluding SVC, multiview, etc., which I didn't bother to
57 // read) is 543 macroblocks (section A.3.1).
58 int max_mb_minus1 = std::numeric_limits<int>::max() / mb_unit - 1;
59 int max_map_units_minus1 = std::numeric_limits<int>::max() / map_unit - 1;
60 if (pic_width_in_mbs_minus1 > max_mb_minus1 ||
61 pic_height_in_map_units_minus1 > max_map_units_minus1) {
62 DVLOG(1) << "Coded size is too large.";
63 return base::nullopt;
64 }
65
66 return gfx::Size(mb_unit * (pic_width_in_mbs_minus1 + 1),
67 map_unit * (pic_height_in_map_units_minus1 + 1));
68 }
69
70 // Also based on section 7.4.2.1.1.
71 base::Optional<gfx::Rect> H264SPS::GetVisibleRect() const {
72 base::Optional<gfx::Size> coded_size = GetCodedSize();
73 if (!coded_size)
74 return base::nullopt;
75
76 if (!frame_cropping_flag)
77 return gfx::Rect(coded_size.value());
78
79 int crop_unit_x;
80 int crop_unit_y;
81 if (chroma_array_type == 0) {
82 crop_unit_x = 1;
83 crop_unit_y = frame_mbs_only_flag ? 1 : 2;
84 } else {
85 // Section 6.2.
86 // |chroma_format_idc| may be:
87 // 1 => 4:2:0
88 // 2 => 4:2:2
89 // 3 => 4:4:4
90 // Everything else has |chroma_array_type| == 0.
91 int sub_width_c = chroma_format_idc > 2 ? 1 : 2;
92 int sub_height_c = chroma_format_idc > 1 ? 1 : 2;
93 crop_unit_x = sub_width_c;
94 crop_unit_y = sub_height_c * (frame_mbs_only_flag ? 1 : 2);
95 }
96
97 // Verify that the values are not too large before multiplying.
98 if (coded_size->width() / crop_unit_x < frame_crop_left_offset ||
99 coded_size->width() / crop_unit_x < frame_crop_right_offset ||
100 coded_size->height() / crop_unit_y < frame_crop_top_offset ||
101 coded_size->height() / crop_unit_y < frame_crop_bottom_offset) {
102 DVLOG(1) << "Frame cropping exceeds coded size.";
103 return base::nullopt;
104 }
105 int crop_left = crop_unit_x * frame_crop_left_offset;
106 int crop_right = crop_unit_x * frame_crop_right_offset;
107 int crop_top = crop_unit_y * frame_crop_top_offset;
108 int crop_bottom = crop_unit_y * frame_crop_bottom_offset;
109
110 // Verify that the values are sane. Note that some decoders also require that
111 // crops are smaller than a macroblock and/or that crops must be adjacent to
112 // at least one corner of the coded frame.
113 if (coded_size->width() - crop_left <= crop_right ||
114 coded_size->height() - crop_top <= crop_bottom) {
115 DVLOG(1) << "Frame cropping excludes entire frame.";
116 return base::nullopt;
117 }
118
119 return gfx::Rect(crop_left, crop_top,
120 coded_size->width() - crop_left - crop_right,
121 coded_size->height() - crop_top - crop_bottom);
122 }
123
45 H264PPS::H264PPS() { 124 H264PPS::H264PPS() {
46 memset(this, 0, sizeof(*this)); 125 memset(this, 0, sizeof(*this));
47 } 126 }
48 127
49 H264SliceHeader::H264SliceHeader() { 128 H264SliceHeader::H264SliceHeader() {
50 memset(this, 0, sizeof(*this)); 129 memset(this, 0, sizeof(*this));
51 } 130 }
52 131
53 H264SEIMessage::H264SEIMessage() { 132 H264SEIMessage::H264SEIMessage() {
54 memset(this, 0, sizeof(*this)); 133 memset(this, 0, sizeof(*this));
(...skipping 1320 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 1454
1376 default: 1455 default:
1377 DVLOG(4) << "Unsupported SEI message"; 1456 DVLOG(4) << "Unsupported SEI message";
1378 break; 1457 break;
1379 } 1458 }
1380 1459
1381 return kOk; 1460 return kOk;
1382 } 1461 }
1383 1462
1384 } // namespace media 1463 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/h264_parser.h ('k') | media/filters/h264_parser_fuzzertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698