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 3 // found in the LICENSE file. 4 5 #include "media/formats/mp4/avc.h" 6 7 #include <algorithm> 8 #include <vector> 9 10 #include "base/logging.h" 11 #include "media/base/decrypt_config.h" 12 #include "media/filters/h264_parser.h" 13 #include "media/formats/mp4/box_definitions.h" 14 #include "media/formats/mp4/box_reader.h" 15 16 namespace media { 17 namespace mp4 { 18 19 static const uint8 kAnnexBStartCode[] = {0, 0, 0, 1}; 20 static const int kAnnexBStartCodeSize = 4; 21 22 static bool ConvertAVCToAnnexBInPlaceForLengthSize4(std::vector<uint8>* buf) { 23 const int kLengthSize = 4; 24 size_t pos = 0; 25 while (pos + kLengthSize < buf->size()) { 26 uint32 nal_size = (*buf)[pos]; 27 nal_size = (nal_size << 8) + (*buf)[pos+1]; 28 nal_size = (nal_size << 8) + (*buf)[pos+2]; 29 nal_size = (nal_size << 8) + (*buf)[pos+3]; 30 31 if (nal_size == 0) { 32 DVLOG(1) << "nal_size is 0"; 33 return false; 34 } 35 36 std::copy(kAnnexBStartCode, kAnnexBStartCode + kAnnexBStartCodeSize, 37 buf->begin() + pos); 38 pos += kLengthSize + nal_size; 39 } 40 return pos == buf->size(); 41 } 42 43 // static 44 bool AVC::ConvertFrameToAnnexB(int length_size, std::vector<uint8>* buffer) { 45 RCHECK(length_size == 1 || length_size == 2 || length_size == 4); 46 47 if (length_size == 4) 48 return ConvertAVCToAnnexBInPlaceForLengthSize4(buffer); 49 50 std::vector<uint8> temp; 51 temp.swap(*buffer); 52 buffer->reserve(temp.size() + 32); 53 54 size_t pos = 0; 55 while (pos + length_size < temp.size()) { 56 int nal_size = temp[pos]; 57 if (length_size == 2) nal_size = (nal_size << 8) + temp[pos+1]; 58 pos += length_size; 59 60 if (nal_size == 0) { 61 DVLOG(1) << "nal_size is 0"; 62 return false; 63 } 64 65 RCHECK(pos + nal_size <= temp.size()); 66 buffer->insert(buffer->end(), kAnnexBStartCode, 67 kAnnexBStartCode + kAnnexBStartCodeSize); 68 buffer->insert(buffer->end(), temp.begin() + pos, 69 temp.begin() + pos + nal_size); 70 pos += nal_size; 71 } 72 return pos == temp.size(); 73 } 74 75 // static 76 bool AVC::InsertParamSetsAnnexB(const AVCDecoderConfigurationRecord& avc_config, 77 std::vector<uint8>* buffer, 78 std::vector<SubsampleEntry>* subsamples) { 79 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples)); 80 81 scoped_ptr<H264Parser> parser(new H264Parser()); 82 const uint8* start = &(*buffer)[0]; 83 parser->SetEncryptedStream(start, buffer->size(), *subsamples); 84 85 H264NALU nalu; 86 if (parser->AdvanceToNextNALU(&nalu) != H264Parser::kOk) 87 return false; 88 89 std::vector<uint8>::iterator config_insert_point = buffer->begin(); 90 std::vector<SubsampleEntry>::iterator subsamples_insert_point = 91 subsamples->begin(); 92 93 if (nalu.nal_unit_type == H264NALU::kAUD) { 94 // Move insert point to just after the AUD. 95 config_insert_point += (nalu.data + nalu.size) - start; 96 97 if (!subsamples->empty()) { 98 int64 first_subsample_size = 99 (*subsamples)[0].clear_bytes + (*subsamples)[0].cypher_bytes; 100 101 if (first_subsample_size != (config_insert_point - buffer->begin())) 102 return false; 103 104 subsamples_insert_point++; 105 } 106 107 } 108 109 // Clear |parser| and |start| since they aren't needed anymore and 110 // will hold stale pointers once the insert happens. 111 parser.reset(); 112 start = NULL; 113 114 std::vector<uint8> param_sets; 115 std::vector<SubsampleEntry> config_subsamples; 116 RCHECK(AVC::ConvertConfigToAnnexB(avc_config, 117 ¶m_sets, 118 &config_subsamples)); 119 120 if (!subsamples->empty()) { 121 subsamples->insert(subsamples_insert_point, 122 config_subsamples.begin(), 123 config_subsamples.end()); 124 } 125 126 buffer->insert(config_insert_point, 127 param_sets.begin(), param_sets.end()); 128 129 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples)); 130 return true; 131 } 132 133 // static 134 bool AVC::ConvertConfigToAnnexB( 135 const AVCDecoderConfigurationRecord& avc_config, 136 std::vector<uint8>* buffer, 137 std::vector<SubsampleEntry>* subsamples) { 138 DCHECK(buffer->empty()); 139 buffer->clear(); 140 int total_size = 0; 141 for (size_t i = 0; i < avc_config.sps_list.size(); i++) 142 total_size += avc_config.sps_list[i].size() + kAnnexBStartCodeSize; 143 for (size_t i = 0; i < avc_config.pps_list.size(); i++) 144 total_size += avc_config.pps_list[i].size() + kAnnexBStartCodeSize; 145 buffer->reserve(total_size); 146 147 for (size_t i = 0; i < avc_config.sps_list.size(); i++) { 148 buffer->insert(buffer->end(), kAnnexBStartCode, 149 kAnnexBStartCode + kAnnexBStartCodeSize); 150 buffer->insert(buffer->end(), avc_config.sps_list[i].begin(), 151 avc_config.sps_list[i].end()); 152 153 SubsampleEntry entry; 154 entry.clear_bytes = kAnnexBStartCodeSize + avc_config.sps_list[i].size(); 155 entry.cypher_bytes = 0; 156 subsamples->push_back(entry); 157 } 158 159 for (size_t i = 0; i < avc_config.pps_list.size(); i++) { 160 buffer->insert(buffer->end(), kAnnexBStartCode, 161 kAnnexBStartCode + kAnnexBStartCodeSize); 162 buffer->insert(buffer->end(), avc_config.pps_list[i].begin(), 163 avc_config.pps_list[i].end()); 164 165 SubsampleEntry entry; 166 entry.clear_bytes = kAnnexBStartCodeSize + avc_config.pps_list[i].size(); 167 entry.cypher_bytes = 0; 168 subsamples->push_back(entry); 169 } 170 return true; 171 } 172 173 // Verifies AnnexB NALU order according to ISO/IEC 14496-10 Section 7.4.1.2.3 174 bool AVC::IsValidAnnexB(const std::vector<uint8>& buffer, 175 const std::vector<SubsampleEntry>& subsamples) { 176 return IsValidAnnexB(&buffer[0], buffer.size(), subsamples); 177 } 178 179 bool AVC::IsValidAnnexB(const uint8* buffer, size_t size, 180 const std::vector<SubsampleEntry>& subsamples) { 181 DVLOG(1) << __FUNCTION__; 182 DCHECK(buffer); 183 184 if (size == 0) 185 return true; 186 187 H264Parser parser; 188 parser.SetEncryptedStream(buffer, size, subsamples); 189 190 typedef enum { 191 kAUDAllowed, 192 kBeforeFirstVCL, // VCL == nal_unit_types 1-5 193 kAfterFirstVCL, 194 kEOStreamAllowed, 195 kNoMoreDataAllowed, 196 } NALUOrderState; 197 198 H264NALU nalu; 199 NALUOrderState order_state = kAUDAllowed; 200 int last_nalu_type = H264NALU::kUnspecified; 201 bool done = false; 202 while (!done) { 203 switch (parser.AdvanceToNextNALU(&nalu)) { 204 case H264Parser::kOk: 205 DVLOG(1) << "nal_unit_type " << nalu.nal_unit_type; 206 207 switch (nalu.nal_unit_type) { 208 case H264NALU::kAUD: 209 if (order_state > kAUDAllowed) { 210 DVLOG(1) << "Unexpected AUD in order_state " << order_state; 211 return false; 212 } 213 order_state = kBeforeFirstVCL; 214 break; 215 216 case H264NALU::kSEIMessage: 217 case H264NALU::kReserved14: 218 case H264NALU::kReserved15: 219 case H264NALU::kReserved16: 220 case H264NALU::kReserved17: 221 case H264NALU::kReserved18: 222 case H264NALU::kPPS: 223 case H264NALU::kSPS: 224 if (order_state > kBeforeFirstVCL) { 225 DVLOG(1) << "Unexpected NALU type " << nalu.nal_unit_type 226 << " in order_state " << order_state; 227 return false; 228 } 229 order_state = kBeforeFirstVCL; 230 break; 231 232 case H264NALU::kSPSExt: 233 if (last_nalu_type != H264NALU::kSPS) { 234 DVLOG(1) << "SPS extension does not follow an SPS."; 235 return false; 236 } 237 break; 238 239 case H264NALU::kNonIDRSlice: 240 case H264NALU::kSliceDataA: 241 case H264NALU::kSliceDataB: 242 case H264NALU::kSliceDataC: 243 case H264NALU::kIDRSlice: 244 if (order_state > kAfterFirstVCL) { 245 DVLOG(1) << "Unexpected VCL in order_state " << order_state; 246 return false; 247 } 248 order_state = kAfterFirstVCL; 249 break; 250 251 case H264NALU::kCodedSliceAux: 252 if (order_state != kAfterFirstVCL) { 253 DVLOG(1) << "Unexpected extension in order_state " << order_state; 254 return false; 255 } 256 break; 257 258 case H264NALU::kEOSeq: 259 if (order_state != kAfterFirstVCL) { 260 DVLOG(1) << "Unexpected EOSeq in order_state " << order_state; 261 return false; 262 } 263 order_state = kEOStreamAllowed; 264 break; 265 266 case H264NALU::kEOStream: 267 if (order_state < kAfterFirstVCL) { 268 DVLOG(1) << "Unexpected EOStream in order_state " << order_state; 269 return false; 270 } 271 order_state = kNoMoreDataAllowed; 272 break; 273 274 case H264NALU::kFiller: 275 case H264NALU::kUnspecified: 276 if (!(order_state >= kAfterFirstVCL && 277 order_state < kEOStreamAllowed)) { 278 DVLOG(1) << "Unexpected NALU type " << nalu.nal_unit_type 279 << " in order_state " << order_state; 280 return false; 281 } 282 break; 283 284 default: 285 DCHECK_GE(nalu.nal_unit_type, 20); 286 if (nalu.nal_unit_type >= 20 && nalu.nal_unit_type <= 31 && 287 order_state != kAfterFirstVCL) { 288 DVLOG(1) << "Unexpected NALU type " << nalu.nal_unit_type 289 << " in order_state " << order_state; 290 return false; 291 } 292 } 293 last_nalu_type = nalu.nal_unit_type; 294 break; 295 296 case H264Parser::kInvalidStream: 297 return false; 298 299 case H264Parser::kUnsupportedStream: 300 NOTREACHED() << "AdvanceToNextNALU() returned kUnsupportedStream!"; 301 return false; 302 303 case H264Parser::kEOStream: 304 done = true; 305 } 306 } 307 308 return order_state >= kAfterFirstVCL; 309 } 310 } // namespace mp4 311 } // namespace media 312