WebKit roll 138552:138617
[chromium-blink-merge.git] / media / mp4 / avc.cc
blobae28ffd256eead2c91f2ddf692993c3b8ce87600
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.
5 #include "media/mp4/avc.h"
7 #include <algorithm>
8 #include <vector>
10 #include "media/mp4/box_definitions.h"
11 #include "media/mp4/box_reader.h"
13 namespace media {
14 namespace mp4 {
16 static const uint8 kAnnexBStartCode[] = {0, 0, 0, 1};
17 static const int kAnnexBStartCodeSize = 4;
19 static bool ConvertAVCToAnnexBInPlaceForLengthSize4(std::vector<uint8>* buf) {
20 const int kLengthSize = 4;
21 size_t pos = 0;
22 while (pos + kLengthSize < buf->size()) {
23 int nal_size = (*buf)[pos];
24 nal_size = (nal_size << 8) + (*buf)[pos+1];
25 nal_size = (nal_size << 8) + (*buf)[pos+2];
26 nal_size = (nal_size << 8) + (*buf)[pos+3];
27 std::copy(kAnnexBStartCode, kAnnexBStartCode + kAnnexBStartCodeSize,
28 buf->begin() + pos);
29 pos += kLengthSize + nal_size;
31 return pos == buf->size();
34 // static
35 bool AVC::ConvertFrameToAnnexB(int length_size, std::vector<uint8>* buffer) {
36 RCHECK(length_size == 1 || length_size == 2 || length_size == 4);
38 if (length_size == 4)
39 return ConvertAVCToAnnexBInPlaceForLengthSize4(buffer);
41 std::vector<uint8> temp;
42 temp.swap(*buffer);
43 buffer->reserve(temp.size() + 32);
45 size_t pos = 0;
46 while (pos + length_size < temp.size()) {
47 int nal_size = temp[pos];
48 if (length_size == 2) nal_size = (nal_size << 8) + temp[pos+1];
49 pos += length_size;
51 RCHECK(pos + nal_size <= temp.size());
52 buffer->insert(buffer->end(), kAnnexBStartCode,
53 kAnnexBStartCode + kAnnexBStartCodeSize);
54 buffer->insert(buffer->end(), temp.begin() + pos,
55 temp.begin() + pos + nal_size);
56 pos += nal_size;
58 return pos == temp.size();
61 // static
62 bool AVC::ConvertConfigToAnnexB(
63 const AVCDecoderConfigurationRecord& avc_config,
64 std::vector<uint8>* buffer) {
65 DCHECK(buffer->empty());
66 buffer->clear();
67 int total_size = 0;
68 for (size_t i = 0; i < avc_config.sps_list.size(); i++)
69 total_size += avc_config.sps_list[i].size() + kAnnexBStartCodeSize;
70 for (size_t i = 0; i < avc_config.pps_list.size(); i++)
71 total_size += avc_config.pps_list[i].size() + kAnnexBStartCodeSize;
72 buffer->reserve(total_size);
74 for (size_t i = 0; i < avc_config.sps_list.size(); i++) {
75 buffer->insert(buffer->end(), kAnnexBStartCode,
76 kAnnexBStartCode + kAnnexBStartCodeSize);
77 buffer->insert(buffer->end(), avc_config.sps_list[i].begin(),
78 avc_config.sps_list[i].end());
81 for (size_t i = 0; i < avc_config.pps_list.size(); i++) {
82 buffer->insert(buffer->end(), kAnnexBStartCode,
83 kAnnexBStartCode + kAnnexBStartCodeSize);
84 buffer->insert(buffer->end(), avc_config.pps_list[i].begin(),
85 avc_config.pps_list[i].end());
87 return true;
90 } // namespace mp4
91 } // namespace media