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

Side by Side Diff: media/formats/mp4/hevc.cc

Issue 816353010: Implemented HEVC video demuxing and parsing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase to ToT Created 5 years, 3 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
OLDNEW
(Empty)
1 // Copyright 2015 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/hevc.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/h265_parser.h"
13 #include "media/formats/mp4/avc.h"
14 #include "media/formats/mp4/box_definitions.h"
15 #include "media/formats/mp4/box_reader.h"
16
17 namespace media {
18 namespace mp4 {
19
20 static const uint8 kAnnexBStartCode[] = {0, 0, 0, 1};
21 static const int kAnnexBStartCodeSize = 4;
22
23 bool HEVC::InsertParamSetsAnnexB(
24 const HEVCDecoderConfigurationRecord& hevc_config,
25 std::vector<uint8>* buffer,
26 std::vector<SubsampleEntry>* subsamples) {
27 DCHECK(HEVC::IsValidAnnexB(*buffer, *subsamples));
28
29 scoped_ptr<H265Parser> parser(new H265Parser());
30 const uint8* start = &(*buffer)[0];
31 parser->SetEncryptedStream(start, buffer->size(), *subsamples);
32
33 H265NALU nalu;
34 if (parser->AdvanceToNextNALU(&nalu) != H265Parser::kOk)
35 return false;
36
37 std::vector<uint8>::iterator config_insert_point = buffer->begin();
38
39 if (nalu.nal_unit_type == H265NALU::AUD_NUT) {
40 // Move insert point to just after the AUD.
41 config_insert_point += (nalu.data + nalu.size) - start;
42 }
43
44 // Clear |parser| and |start| since they aren't needed anymore and
45 // will hold stale pointers once the insert happens.
46 parser.reset();
47 start = NULL;
48
49 std::vector<uint8> param_sets;
50 RCHECK(HEVC::ConvertConfigToAnnexB(hevc_config, &param_sets));
51 DVLOG(4) << __FUNCTION__ << " converted hvcC to AnnexB "
52 << " size=" << param_sets.size() << " inserted at "
53 << (int)(config_insert_point - buffer->begin());
54
55 if (subsamples && !subsamples->empty()) {
56 int subsample_index = AVC::FindSubsampleIndex(*buffer, subsamples,
57 &(*config_insert_point));
58 // Update the size of the subsample where SPS/PPS is to be inserted.
59 (*subsamples)[subsample_index].clear_bytes += param_sets.size();
60 }
61
62 buffer->insert(config_insert_point,
63 param_sets.begin(), param_sets.end());
64
65 DCHECK(HEVC::IsValidAnnexB(*buffer, *subsamples));
66 return true;
67 }
68
69 bool HEVC::ConvertConfigToAnnexB(
70 const HEVCDecoderConfigurationRecord& hevc_config,
71 std::vector<uint8>* buffer) {
72 DCHECK(buffer->empty());
73 buffer->clear();
74
75 for (size_t j = 0; j < hevc_config.arrays.size(); j++) {
76 uint8 naluType = hevc_config.arrays[j].first_byte & 0x3f;
77 for (size_t i = 0; i < hevc_config.arrays[j].units.size(); ++i) {
78 DVLOG(3) << __FUNCTION__ << " naluType=" << (int)naluType
79 << " size=" << hevc_config.arrays[j].units[i].size();
80 buffer->insert(buffer->end(), kAnnexBStartCode,
81 kAnnexBStartCode + kAnnexBStartCodeSize);
82 buffer->insert(buffer->end(), hevc_config.arrays[j].units[i].begin(),
83 hevc_config.arrays[j].units[i].end());
84 }
85 }
86
87 return true;
88 }
89
90 // Verifies AnnexB NALU order according to section 7.4.2.4.4 of ISO/IEC 23008-2.
91 bool HEVC::IsValidAnnexB(const std::vector<uint8>& buffer,
92 const std::vector<SubsampleEntry>& subsamples) {
93 return IsValidAnnexB(&buffer[0], buffer.size(), subsamples);
94 }
95
96 bool HEVC::IsValidAnnexB(const uint8* buffer, size_t size,
97 const std::vector<SubsampleEntry>& subsamples) {
98 DCHECK(buffer);
99
100 if (size == 0)
101 return true;
102
103 // TODO(servolk): Implement this
wolenetz 2015/09/02 20:43:18 nit: reference a bug?
servolk 2015/09/03 00:17:51 Done, crbug.com/527595
104 return true;
105 }
106
107 HEVCBitstreamConverter::HEVCBitstreamConverter(
108 scoped_ptr<HEVCDecoderConfigurationRecord> hevc_config)
109 : hevc_config_(hevc_config.Pass()) {
110 DCHECK(hevc_config_);
111 }
112
113 HEVCBitstreamConverter::~HEVCBitstreamConverter() {
114 }
115
116 bool HEVCBitstreamConverter::ConvertFrame(
117 std::vector<uint8>* frame_buf,
118 bool is_keyframe,
119 std::vector<SubsampleEntry>* subsamples) const {
120 RCHECK(AVC::ConvertFrameToAnnexB(hevc_config_->lengthSizeMinusOne + 1,
121 frame_buf, subsamples));
122
123 if (is_keyframe) {
124 // If this is a keyframe, we (re-)inject HEVC params headers at the start of
125 // a frame. If subsample info is present, we also update the clear byte
126 // count for that first subsample.
127 RCHECK(HEVC::InsertParamSetsAnnexB(*hevc_config_, frame_buf, subsamples));
128 }
129
130 DCHECK(HEVC::IsValidAnnexB(*frame_buf, *subsamples));
131 return true;
132 }
133
134 } // namespace mp4
135 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698