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

Side by Side Diff: content/common/gpu/media/avc_config_record_builder.cc

Issue 10411085: Build AVC decoder configuration record (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/common/gpu/media/avc_config_record_builder.h"
6
7 #include "base/logging.h"
8 #include "content/common/gpu/media/h264_parser.h"
9
10 namespace content {
11
12 AVCConfigRecordBuilder::AVCConfigRecordBuilder()
13 : sps_profile_idc_(0),
14 sps_constraint_setx_flag_(0),
15 sps_level_idc_(0),
16 coded_width_(0),
17 coded_height_(0),
18 can_build_record_(false) {
19 }
20
21 AVCConfigRecordBuilder::~AVCConfigRecordBuilder() {
22 }
23
24 bool AVCConfigRecordBuilder::ProcessNextNALU(H264Parser* parser,
25 const H264NALU* nalu,
26 bool* did_consume_nalu) {
27 DCHECK(!can_build_record_);
28 *did_consume_nalu = true;
29
30 if (nalu->nal_unit_type == H264NALU::kSPS) {
31 return ProcessSPS(parser, nalu);
32 } else if (nalu->nal_unit_type == H264NALU::kPPS) {
33 return ProcessPPS(parser, nalu);
34 } else if (nalu->nal_unit_type >= 1 && nalu->nal_unit_type <= 5) {
35 // Ready to build the AVC decoder configuration record once the first slice
36 // type is encountered.
37 *did_consume_nalu = false;
38 can_build_record_ = true;
Ami GONE FROM CHROMIUM 2012/05/23 19:41:19 The fact that the previous two variables are only
sail 2012/05/28 21:45:46 Done.
39 return true;
40 }
41 // Skip this NALU.
42 return true;
43 }
44
45 std::vector<uint8_t> AVCConfigRecordBuilder::BuildConfigRecord() {
46 DCHECK(can_build_record_);
47
48 // 5 bytes for AVC record header. 1 byte for the number of SPS units.
49 // 1 byte for the number of PPS units.
50 int record_size = 7;
51 for (NALUVector::const_iterator it = sps_nalus_.begin();
52 it != sps_nalus_.end(); ++it) {
53 // Plus 2 bytes to store the SPS size.
54 record_size += (*it)->size() + 2;
55 }
56 for (NALUVector::const_iterator it = pps_nalus_.begin();
57 it != pps_nalus_.end(); ++it) {
58 // Plus 2 bytes to store the PPS size.
59 record_size += (*it)->size() + 2;
60 }
61 std::vector<uint8_t> extra_data(record_size, 0);
Ami GONE FROM CHROMIUM 2012/05/23 19:41:19 , 0 unnecessary
sail 2012/05/28 21:45:46 Done.
62
63 // AVC decoder configuration record version.
64 extra_data[0] = 0x01;
65 // Profile.
66 extra_data[1] = sps_profile_idc_ & 0xff;
67 // Profile compatibility, must match the byte between profile IDC
68 // and level IDC in the SPS.
69 extra_data[2] = sps_constraint_setx_flag_;
70 // AVC level.
71 extra_data[3] = sps_level_idc_ & 0xff;
72
73 // TODO(sail): There's no way to get the NALU field size from the
Ami GONE FROM CHROMIUM 2012/05/23 19:41:19 s/NALU/NALU length/
Ami GONE FROM CHROMIUM 2012/05/23 19:41:19 posciak: do you have thoughts about this?
sail 2012/05/28 21:45:46 Done.
Pawel Osciak 2012/05/30 00:28:40 From what I discussed with Sailesh and saw in the
74 // SPS and PPS data. Just assume 4 for now.
75 const int kNALULengthFieldSize = 4;
76
77 // The first 6 bits are reserved and must be 1. Last two bits are the
Ami GONE FROM CHROMIUM 2012/05/23 19:41:19 s/and must/and must/
sail 2012/05/28 21:45:46 Done.
78 // NALU field size minus 1.
79 extra_data[4] = 0xfc | ((kNALULengthFieldSize - 1) & 0x03);
80
81 // The first 3 bits are reserved and must be 1. Last 5 bits are the
82 // number of SPS units.
83 extra_data[5] = 0xe0 | (sps_nalus_.size() & 0x1f);
84 int index = 6;
85 for (NALUVector::const_iterator it = sps_nalus_.begin();
86 it != sps_nalus_.end(); ++it) {
87 // High byte of the SPS unit size.
88 extra_data[index++] = ((*it)->size() >> 8) & 0xff;
89 // Low byte of the SPS unit size.
90 extra_data[index++] = (*it)->size() & 0xff;
91 // The SPS data.
92 memcpy(&extra_data[index], (*it)->front(), (*it)->size());
93 index += (*it)->size();
94 }
95
96 // The number of PPS units.
Ami GONE FROM CHROMIUM 2012/05/23 19:41:19 Seems like l.83-94 & l.97-107 are near-copies of e
sail 2012/05/28 21:45:46 Done.
97 extra_data[index++] = pps_nalus_.size() & 0xff;
98 for (NALUVector::const_iterator it = pps_nalus_.begin();
99 it != pps_nalus_.end(); ++it) {
100 // High byte of the PPS unit size.
101 extra_data[index++] = ((*it)->size() >> 8) & 0xff;
102 // Low byte of the PPS unit size.
103 extra_data[index++] = (*it)->size() & 0xff;
104 // The PPS data.
105 memcpy(&extra_data[index], (*it)->front(), (*it)->size());
106 index += (*it)->size();
107 }
108
109 return extra_data;
110 }
111
112 bool AVCConfigRecordBuilder::ProcessSPS(H264Parser* parser,
113 const H264NALU* nalu) {
114 int sps_id = 0;
115 H264Parser::Result result = parser->ParseSPS(&sps_id);
116 if (result != H264Parser::kOk)
117 return false;
118
119 std::vector<uint8_t> bytes(nalu->data, nalu->data + nalu->size);
120 sps_nalus_.push_back(base::RefCountedBytes::TakeVector(&bytes));
121
122 const H264SPS* sps = parser->GetSPS(sps_id);
123
124 // Use the last width and height that are encountered.
125 coded_width_ = (sps->pic_width_in_mbs_minus1 + 1) * 16;
126 if (sps->frame_mbs_only_flag)
127 coded_height_ = (sps->pic_height_in_map_units_minus1 + 1) * 16;
128 else
129 coded_height_ = (sps->pic_height_in_map_units_minus1 + 1) * 32;
130
131 // Use the last video profile and flags that are encountered.
132 sps_profile_idc_ = sps->profile_idc;
133 sps_constraint_setx_flag_ = sps->constraint_setx_flag;
134 // Use the largest AVC level that's encountered.
135 sps_level_idc_ = std::max(sps_level_idc_, sps->level_idc);
136
137 return true;
138 }
139
140 bool AVCConfigRecordBuilder::ProcessPPS(H264Parser* parser,
141 const H264NALU* nalu) {
142 int pps_id = 0;
143 H264Parser::Result result = parser->ParsePPS(&pps_id);
144 if (result != H264Parser::kOk)
145 return false;
146
147 std::vector<uint8_t> bytes(nalu->data, nalu->data + nalu->size);
148 pps_nalus_.push_back(base::RefCountedBytes::TakeVector(&bytes));
149 return true;
150 }
151
152 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698