Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 | |
| OLD | NEW |