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"
10 #include "media/mp4/box_definitions.h"
11 #include "media/mp4/box_reader.h"
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;
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
,
29 pos
+= kLengthSize
+ nal_size
;
31 return pos
== buf
->size();
35 bool AVC::ConvertFrameToAnnexB(int length_size
, std::vector
<uint8
>* buffer
) {
36 RCHECK(length_size
== 1 || length_size
== 2 || length_size
== 4);
39 return ConvertAVCToAnnexBInPlaceForLengthSize4(buffer
);
41 std::vector
<uint8
> temp
;
43 buffer
->reserve(temp
.size() + 32);
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];
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
);
58 return pos
== temp
.size();
62 bool AVC::ConvertConfigToAnnexB(
63 const AVCDecoderConfigurationRecord
& avc_config
,
64 std::vector
<uint8
>* buffer
) {
65 DCHECK(buffer
->empty());
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());