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

Side by Side Diff: webrtc/modules/video_coding/h264_sps_pps_tracker.cc

Issue 2916433003: Check H264 NALUs for frametype and insert SPS/PPS packets into the PacketBuffer. (Closed)
Patch Set: Created 3 years, 6 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
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 19 matching lines...) Expand all
30 30
31 H264SpsPpsTracker::PacketAction H264SpsPpsTracker::CopyAndFixBitstream( 31 H264SpsPpsTracker::PacketAction H264SpsPpsTracker::CopyAndFixBitstream(
32 VCMPacket* packet) { 32 VCMPacket* packet) {
33 RTC_DCHECK(packet->codec == kVideoCodecH264); 33 RTC_DCHECK(packet->codec == kVideoCodecH264);
34 34
35 const uint8_t* data = packet->dataPtr; 35 const uint8_t* data = packet->dataPtr;
36 const size_t data_size = packet->sizeBytes; 36 const size_t data_size = packet->sizeBytes;
37 const RTPVideoHeader& video_header = packet->video_header; 37 const RTPVideoHeader& video_header = packet->video_header;
38 const RTPVideoHeaderH264& codec_header = video_header.codecHeader.H264; 38 const RTPVideoHeaderH264& codec_header = video_header.codecHeader.H264;
39 39
40 // Packets that only contains SPS/PPS are not decodable by themselves, and
41 // to avoid frames being created containing only these two nalus we don't
42 // insert them into the PacketBuffer. Instead we save the SPS/PPS and
43 // prepend the bitstream of first packet of an IDR referring to the
44 // corresponding SPS/PPS id.
45 bool insert_packet = codec_header.nalus_length == 0 ? true : false;
46
47 int pps_id = -1; 40 int pps_id = -1;
48 int sps_id = -1; 41 int sps_id = -1;
42 bool append_sps_pps = codec_header.nalus_length == 0;
49 size_t required_size = 0; 43 size_t required_size = 0;
50 for (size_t i = 0; i < codec_header.nalus_length; ++i) { 44 for (size_t i = 0; i < codec_header.nalus_length; ++i) {
51 const NaluInfo& nalu = codec_header.nalus[i]; 45 const NaluInfo& nalu = codec_header.nalus[i];
52 switch (nalu.type) { 46 switch (nalu.type) {
53 case H264::NaluType::kSps: { 47 case H264::NaluType::kSps: {
54 // Save SPS. 48 // Save SPS.
55 sps_data_[nalu.sps_id].size = nalu.size; 49 sps_data_[nalu.sps_id].size = nalu.size;
56 sps_data_[nalu.sps_id].data.reset(new uint8_t[nalu.size]); 50 sps_data_[nalu.sps_id].data.reset(new uint8_t[nalu.size]);
57 memcpy(sps_data_[nalu.sps_id].data.get(), data + nalu.offset, 51 memcpy(sps_data_[nalu.sps_id].data.get(), data + nalu.offset,
58 nalu.size); 52 nalu.size);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 return kRequestKeyframe; 88 return kRequestKeyframe;
95 } 89 }
96 90
97 pps_id = nalu.pps_id; 91 pps_id = nalu.pps_id;
98 required_size += pps->second.size + sizeof(start_code_h264); 92 required_size += pps->second.size + sizeof(start_code_h264);
99 required_size += sps->second.size + sizeof(start_code_h264); 93 required_size += sps->second.size + sizeof(start_code_h264);
100 } 94 }
101 FALLTHROUGH(); 95 FALLTHROUGH();
102 } 96 }
103 default: { 97 default: {
104 // Something other than an SPS/PPS nalu in this packet, then it should 98 // Something other than an SPS/PPS nalu in this packet, then the SPS/PPS
105 // be inserted into the PacketBuffer. 99 // should be appended.
106 insert_packet = true; 100 append_sps_pps = true;
107 } 101 }
108 } 102 }
109 } 103 }
110 104
111 if (!insert_packet) 105 if (!append_sps_pps) {
112 return kDrop; 106 // Two things: Firstly, when we receive a packet the data pointed at by
107 // |dataPtr| is volatile, meaning we have to copy the data into our own
108 // buffer if we want to use it at a later stage. Secondly, when a packet is
109 // inserted into the PacketBuffer it expects the packet to own its own
110 // buffer, and this function copies (and fix) the bitstream of the packet
111 // into its own buffer.
112 //
113 // SPS/PPS packets is a special case. Since we save the SPS/PPS NALU and
114 // append it to the first packet of every IDR frame the SPS/PPS packet
115 // doesn't actually need to contain any bitstream data.
116 packet->dataPtr = nullptr;
117 packet->sizeBytes = 0;
118 return kInsert;
119 }
113 120
114 // Calculate how much space we need for the rest of the bitstream. 121 // Calculate how much space we need for the rest of the bitstream.
115 if (codec_header.packetization_type == kH264StapA) { 122 if (codec_header.packetization_type == kH264StapA) {
116 const uint8_t* nalu_ptr = data + 1; 123 const uint8_t* nalu_ptr = data + 1;
117 while (nalu_ptr < data + data_size) { 124 while (nalu_ptr < data + data_size) {
118 RTC_DCHECK(video_header.is_first_packet_in_frame); 125 RTC_DCHECK(video_header.is_first_packet_in_frame);
119 required_size += sizeof(start_code_h264); 126 required_size += sizeof(start_code_h264);
120 127
121 // The first two bytes describe the length of a segment. 128 // The first two bytes describe the length of a segment.
122 uint16_t segment_length = nalu_ptr[0] << 8 | nalu_ptr[1]; 129 uint16_t segment_length = nalu_ptr[0] << 8 | nalu_ptr[1];
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 pps_info.data.reset(pps_data); 253 pps_info.data.reset(pps_data);
247 pps_data_[parsed_pps->id] = std::move(pps_info); 254 pps_data_[parsed_pps->id] = std::move(pps_info);
248 255
249 LOG(LS_INFO) << "Inserted SPS id " << parsed_sps->id << " and PPS id " 256 LOG(LS_INFO) << "Inserted SPS id " << parsed_sps->id << " and PPS id "
250 << parsed_pps->id << " (referencing SPS " << parsed_pps->sps_id 257 << parsed_pps->id << " (referencing SPS " << parsed_pps->sps_id
251 << ")"; 258 << ")";
252 } 259 }
253 260
254 } // namespace video_coding 261 } // namespace video_coding
255 } // namespace webrtc 262 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/frame_object.cc ('k') | webrtc/modules/video_coding/h264_sps_pps_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698