1f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson/* 2f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson * 4f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson * Use of this source code is governed by a BSD-style license 5f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson * that can be found in the LICENSE file in the root of the source 6f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson * tree. An additional intellectual property rights grant can be found 7f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson * in the file PATENTS. All contributing project authors may 8f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson * be found in the AUTHORS file in the root of the source tree. 9f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson */ 10f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 11f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson#include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h" 12f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 13f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson#include <assert.h> 14f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson#include <string.h> 15f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 16f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson#include <cmath> 17f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 18f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson#include "webrtc/base/bitbuffer.h" 19f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson#include "webrtc/base/checks.h" 20ebc0b4e99365443111857a0c7cfcc8944d8f1b6ePeter Boström#include "webrtc/base/logging.h" 21f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 22f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson#define RETURN_FALSE_ON_ERROR(x) \ 23f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (!(x)) { \ 24f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; \ 25f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 26f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 27f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonnamespace webrtc { 28f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonnamespace { 29f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Length of VP9 payload descriptors' fixed part. 30f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonconst size_t kFixedPayloadDescriptorBytes = 1; 31f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 32f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Packet fragmentation mode. If true, packets are split into (almost) equal 33f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// sizes. Otherwise, as many bytes as possible are fit into one packet. 34f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonconst bool kBalancedMode = true; 35f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 36f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonconst uint32_t kReservedBitValue0 = 0; 37f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 38f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonuint8_t TemporalIdxField(const RTPVideoHeaderVP9& hdr, uint8_t def) { 39f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return (hdr.temporal_idx == kNoTemporalIdx) ? def : hdr.temporal_idx; 40f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 41f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 42f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonuint8_t SpatialIdxField(const RTPVideoHeaderVP9& hdr, uint8_t def) { 43f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return (hdr.spatial_idx == kNoSpatialIdx) ? def : hdr.spatial_idx; 44f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 45f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 46f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonint16_t Tl0PicIdxField(const RTPVideoHeaderVP9& hdr, uint8_t def) { 47f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return (hdr.tl0_pic_idx == kNoTl0PicIdx) ? def : hdr.tl0_pic_idx; 48f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 49f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 50f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Picture ID: 51f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 52f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 53f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// I: |M| PICTURE ID | M:0 => picture id is 7 bits. 54f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ M:1 => picture id is 15 bits. 55f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// M: | EXTENDED PID | 56f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 57f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 58f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonsize_t PictureIdLength(const RTPVideoHeaderVP9& hdr) { 59f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (hdr.picture_id == kNoPictureId) 60f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return 0; 61f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return (hdr.max_picture_id == kMaxOneBytePictureId) ? 1 : 2; 62f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 63f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 64f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool PictureIdPresent(const RTPVideoHeaderVP9& hdr) { 65f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return PictureIdLength(hdr) > 0; 66f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 67f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 68f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Layer indices: 69f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 70f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Flexible mode (F=1): Non-flexible mode (F=0): 71f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 72f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ 73394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson// L: | T |U| S |D| | T |U| S |D| 74f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ 75f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | TL0PICIDX | 76f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 77f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 78f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonsize_t LayerInfoLength(const RTPVideoHeaderVP9& hdr) { 79394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson if (hdr.temporal_idx == kNoTemporalIdx && 80394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson hdr.spatial_idx == kNoSpatialIdx) { 81394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson return 0; 82f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 83394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson return hdr.flexible_mode ? 1 : 2; 84f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 85f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 86f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool LayerInfoPresent(const RTPVideoHeaderVP9& hdr) { 87f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return LayerInfoLength(hdr) > 0; 88f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 89f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 90f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Reference indices: 91f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 9232df5efc6db394ff4c535c2049c079b8c0e31183asapersson// +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index 9332df5efc6db394ff4c535c2049c079b8c0e31183asapersson// P,F: | P_DIFF |N| up to 3 times has to be specified. 9432df5efc6db394ff4c535c2049c079b8c0e31183asapersson// +-+-+-+-+-+-+-+-+ N=1: An additional P_DIFF follows 9532df5efc6db394ff4c535c2049c079b8c0e31183asapersson// current P_DIFF. 9632df5efc6db394ff4c535c2049c079b8c0e31183asapersson// 97f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonsize_t RefIndicesLength(const RTPVideoHeaderVP9& hdr) { 98f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (!hdr.inter_pic_predicted || !hdr.flexible_mode) 99f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return 0; 100f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 10191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_GT(hdr.num_ref_pics, 0U); 10291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_LE(hdr.num_ref_pics, kMaxVp9RefPics); 10332df5efc6db394ff4c535c2049c079b8c0e31183asapersson return hdr.num_ref_pics; 104f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 105f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 106f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Scalability structure (SS). 107f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 108f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 1096449990387f57e04f9912e8002c620a0f247eed5asapersson// V: | N_S |Y|G|-|-|-| 110f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ -| 111f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Y: | WIDTH | (OPTIONAL) . 112f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// + + . 113f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | | (OPTIONAL) . 114f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ . N_S + 1 times 115f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | HEIGHT | (OPTIONAL) . 116f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// + + . 117f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | | (OPTIONAL) . 1186449990387f57e04f9912e8002c620a0f247eed5asapersson// +-+-+-+-+-+-+-+-+ -| 1196449990387f57e04f9912e8002c620a0f247eed5asapersson// G: | N_G | (OPTIONAL) 1206449990387f57e04f9912e8002c620a0f247eed5asapersson// +-+-+-+-+-+-+-+-+ -| 121f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// N_G: | T |U| R |-|-| (OPTIONAL) . 1226449990387f57e04f9912e8002c620a0f247eed5asapersson// +-+-+-+-+-+-+-+-+ -| . N_G times 123f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | P_DIFF | (OPTIONAL) . R times . 124f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ -| -| 125f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 126f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonsize_t SsDataLength(const RTPVideoHeaderVP9& hdr) { 127f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (!hdr.ss_data_available) 128f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return 0; 129f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 13091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_GT(hdr.num_spatial_layers, 0U); 13191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_LE(hdr.num_spatial_layers, kMaxVp9NumberOfSpatialLayers); 13291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_LE(hdr.gof.num_frames_in_gof, kMaxVp9FramesInGof); 133f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t length = 1; // V 134f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (hdr.spatial_layer_resolution_present) { 135f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson length += 4 * hdr.num_spatial_layers; // Y 136f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 1376449990387f57e04f9912e8002c620a0f247eed5asapersson if (hdr.gof.num_frames_in_gof > 0) { 1386449990387f57e04f9912e8002c620a0f247eed5asapersson ++length; // G 1396449990387f57e04f9912e8002c620a0f247eed5asapersson } 140f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson // N_G 141f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson length += hdr.gof.num_frames_in_gof; // T, U, R 142f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson for (size_t i = 0; i < hdr.gof.num_frames_in_gof; ++i) { 14391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_LE(hdr.gof.num_ref_pics[i], kMaxVp9RefPics); 144f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson length += hdr.gof.num_ref_pics[i]; // R times 145f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 146f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return length; 147f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 148f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 149f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonsize_t PayloadDescriptorLengthMinusSsData(const RTPVideoHeaderVP9& hdr) { 150f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return kFixedPayloadDescriptorBytes + PictureIdLength(hdr) + 151f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LayerInfoLength(hdr) + RefIndicesLength(hdr); 152f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 153f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 154f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonsize_t PayloadDescriptorLength(const RTPVideoHeaderVP9& hdr) { 155f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return PayloadDescriptorLengthMinusSsData(hdr) + SsDataLength(hdr); 156f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 157f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 158f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonvoid QueuePacket(size_t start_pos, 159f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t size, 160f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool layer_begin, 161f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool layer_end, 162f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RtpPacketizerVp9::PacketInfoQueue* packets) { 163f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RtpPacketizerVp9::PacketInfo packet_info; 164f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson packet_info.payload_start_pos = start_pos; 165f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson packet_info.size = size; 166f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson packet_info.layer_begin = layer_begin; 167f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson packet_info.layer_end = layer_end; 168f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson packets->push(packet_info); 169f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 170f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 171f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Picture ID: 172f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 173f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 174f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// I: |M| PICTURE ID | M:0 => picture id is 7 bits. 175f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ M:1 => picture id is 15 bits. 176f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// M: | EXTENDED PID | 177f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 178f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 179f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool WritePictureId(const RTPVideoHeaderVP9& vp9, 180f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson rtc::BitBufferWriter* writer) { 181f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool m_bit = (PictureIdLength(vp9) == 2); 182f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(m_bit ? 1 : 0, 1)); 183f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.picture_id, m_bit ? 15 : 7)); 184f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 185f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 186f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 187f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Layer indices: 188f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 189f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Flexible mode (F=1): 190f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 191f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 192f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// L: | T |U| S |D| 193f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 194f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 195394c537b21e6e2d6a93f2982f1e01d57497a98dcasaperssonbool WriteLayerInfoCommon(const RTPVideoHeaderVP9& vp9, 196394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson rtc::BitBufferWriter* writer) { 197f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(TemporalIdxField(vp9, 0), 3)); 198f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.temporal_up_switch ? 1 : 0, 1)); 199f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(SpatialIdxField(vp9, 0), 3)); 200f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.inter_layer_predicted ? 1: 0, 1)); 201f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 202f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 203f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 204f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Non-flexible mode (F=0): 205f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 206f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 207394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson// L: | T |U| S |D| 208f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 209f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | TL0PICIDX | 210f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 211f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 212f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool WriteLayerInfoNonFlexibleMode(const RTPVideoHeaderVP9& vp9, 213f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson rtc::BitBufferWriter* writer) { 214f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteUInt8(Tl0PicIdxField(vp9, 0))); 215f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 216f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 217f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 218f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool WriteLayerInfo(const RTPVideoHeaderVP9& vp9, 219f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson rtc::BitBufferWriter* writer) { 220394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson if (!WriteLayerInfoCommon(vp9, writer)) 221394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson return false; 222394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson 223394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson if (vp9.flexible_mode) 224394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson return true; 225394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson 226394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson return WriteLayerInfoNonFlexibleMode(vp9, writer); 227f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 228f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 229f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Reference indices: 230f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 23132df5efc6db394ff4c535c2049c079b8c0e31183asapersson// +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index 23232df5efc6db394ff4c535c2049c079b8c0e31183asapersson// P,F: | P_DIFF |N| up to 3 times has to be specified. 23332df5efc6db394ff4c535c2049c079b8c0e31183asapersson// +-+-+-+-+-+-+-+-+ N=1: An additional P_DIFF follows 23432df5efc6db394ff4c535c2049c079b8c0e31183asapersson// current P_DIFF. 23532df5efc6db394ff4c535c2049c079b8c0e31183asapersson// 236f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool WriteRefIndices(const RTPVideoHeaderVP9& vp9, 237f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson rtc::BitBufferWriter* writer) { 238f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (!PictureIdPresent(vp9) || 239f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9.num_ref_pics == 0 || vp9.num_ref_pics > kMaxVp9RefPics) { 240f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 241f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 242c253a1c00eefd966aa59e00885fae4714806094fasapersson for (uint8_t i = 0; i < vp9.num_ref_pics; ++i) { 243f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool n_bit = !(i == vp9.num_ref_pics - 1); 24432df5efc6db394ff4c535c2049c079b8c0e31183asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.pid_diff[i], 7)); 24532df5efc6db394ff4c535c2049c079b8c0e31183asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(n_bit ? 1 : 0, 1)); 246f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 247f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 248f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 249f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 250f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Scalability structure (SS). 251f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 252f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 2536449990387f57e04f9912e8002c620a0f247eed5asapersson// V: | N_S |Y|G|-|-|-| 254f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ -| 255f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Y: | WIDTH | (OPTIONAL) . 256f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// + + . 257f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | | (OPTIONAL) . 258f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ . N_S + 1 times 259f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | HEIGHT | (OPTIONAL) . 260f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// + + . 261f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | | (OPTIONAL) . 2626449990387f57e04f9912e8002c620a0f247eed5asapersson// +-+-+-+-+-+-+-+-+ -| 2636449990387f57e04f9912e8002c620a0f247eed5asapersson// G: | N_G | (OPTIONAL) 2646449990387f57e04f9912e8002c620a0f247eed5asapersson// +-+-+-+-+-+-+-+-+ -| 265f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// N_G: | T |U| R |-|-| (OPTIONAL) . 2666449990387f57e04f9912e8002c620a0f247eed5asapersson// +-+-+-+-+-+-+-+-+ -| . N_G times 267f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | P_DIFF | (OPTIONAL) . R times . 268f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ -| -| 269f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 270f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool WriteSsData(const RTPVideoHeaderVP9& vp9, rtc::BitBufferWriter* writer) { 27191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_GT(vp9.num_spatial_layers, 0U); 27291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_LE(vp9.num_spatial_layers, kMaxVp9NumberOfSpatialLayers); 27391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_LE(vp9.gof.num_frames_in_gof, kMaxVp9FramesInGof); 2746449990387f57e04f9912e8002c620a0f247eed5asapersson bool g_bit = vp9.gof.num_frames_in_gof > 0; 275f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 276f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.num_spatial_layers - 1, 3)); 277f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR( 278f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson writer->WriteBits(vp9.spatial_layer_resolution_present ? 1 : 0, 1)); 2796449990387f57e04f9912e8002c620a0f247eed5asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(g_bit ? 1 : 0, 1)); // G 2806449990387f57e04f9912e8002c620a0f247eed5asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(kReservedBitValue0, 3)); 281f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 282f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (vp9.spatial_layer_resolution_present) { 283f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson for (size_t i = 0; i < vp9.num_spatial_layers; ++i) { 284f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteUInt16(vp9.width[i])); 285f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteUInt16(vp9.height[i])); 286f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 287f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 2886449990387f57e04f9912e8002c620a0f247eed5asapersson if (g_bit) { 2896449990387f57e04f9912e8002c620a0f247eed5asapersson RETURN_FALSE_ON_ERROR(writer->WriteUInt8(vp9.gof.num_frames_in_gof)); 2906449990387f57e04f9912e8002c620a0f247eed5asapersson } 291f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson for (size_t i = 0; i < vp9.gof.num_frames_in_gof; ++i) { 292f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.gof.temporal_idx[i], 3)); 293f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR( 294f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson writer->WriteBits(vp9.gof.temporal_up_switch[i] ? 1 : 0, 1)); 295f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.gof.num_ref_pics[i], 2)); 296f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteBits(kReservedBitValue0, 2)); 297c253a1c00eefd966aa59e00885fae4714806094fasapersson for (uint8_t r = 0; r < vp9.gof.num_ref_pics[i]; ++r) { 298f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer->WriteUInt8(vp9.gof.pid_diff[i][r])); 299f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 300f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 301f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 302f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 303f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 304f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Picture ID: 305f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 306f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 307f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// I: |M| PICTURE ID | M:0 => picture id is 7 bits. 308f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ M:1 => picture id is 15 bits. 309f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// M: | EXTENDED PID | 310f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 311f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 312f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool ParsePictureId(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { 313f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint32_t picture_id; 314f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint32_t m_bit; 315f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&m_bit, 1)); 316f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (m_bit) { 317f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&picture_id, 15)); 318f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->max_picture_id = kMaxTwoBytePictureId; 319f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } else { 320f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&picture_id, 7)); 321f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->max_picture_id = kMaxOneBytePictureId; 322f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 323f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->picture_id = picture_id; 324f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 325f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 326f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 327f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Layer indices (flexible mode): 328f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 329f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 330f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// L: | T |U| S |D| 331f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 332f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 333394c537b21e6e2d6a93f2982f1e01d57497a98dcasaperssonbool ParseLayerInfoCommon(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { 334f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint32_t t, u_bit, s, d_bit; 335f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&t, 3)); 336f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&u_bit, 1)); 337f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&s, 3)); 338f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&d_bit, 1)); 339f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->temporal_idx = t; 340f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->temporal_up_switch = u_bit ? true : false; 341f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->spatial_idx = s; 342f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->inter_layer_predicted = d_bit ? true : false; 343f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 344f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 345f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 346f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Layer indices (non-flexible mode): 347f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 348f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 349394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson// L: | T |U| S |D| 350f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 351f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | TL0PICIDX | 352f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 353f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 354f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool ParseLayerInfoNonFlexibleMode(rtc::BitBuffer* parser, 355f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RTPVideoHeaderVP9* vp9) { 356f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint8_t tl0picidx; 357f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&tl0picidx)); 358f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->tl0_pic_idx = tl0picidx; 359f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 360f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 361f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 362f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool ParseLayerInfo(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { 363394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson if (!ParseLayerInfoCommon(parser, vp9)) 364394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson return false; 365394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson 366394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson if (vp9->flexible_mode) 367394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson return true; 368394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson 369394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson return ParseLayerInfoNonFlexibleMode(parser, vp9); 370f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 371f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 372f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Reference indices: 373f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 37432df5efc6db394ff4c535c2049c079b8c0e31183asapersson// +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index 37532df5efc6db394ff4c535c2049c079b8c0e31183asapersson// P,F: | P_DIFF |N| up to 3 times has to be specified. 37632df5efc6db394ff4c535c2049c079b8c0e31183asapersson// +-+-+-+-+-+-+-+-+ N=1: An additional P_DIFF follows 37732df5efc6db394ff4c535c2049c079b8c0e31183asapersson// current P_DIFF. 37832df5efc6db394ff4c535c2049c079b8c0e31183asapersson// 379f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool ParseRefIndices(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { 380f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (vp9->picture_id == kNoPictureId) 381f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 382f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 383f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->num_ref_pics = 0; 384f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint32_t n_bit; 385f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson do { 386f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (vp9->num_ref_pics == kMaxVp9RefPics) 387f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 388f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 38932df5efc6db394ff4c535c2049c079b8c0e31183asapersson uint32_t p_diff; 39032df5efc6db394ff4c535c2049c079b8c0e31183asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&p_diff, 7)); 391f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&n_bit, 1)); 392f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 393f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->pid_diff[vp9->num_ref_pics] = p_diff; 394f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint32_t scaled_pid = vp9->picture_id; 39532df5efc6db394ff4c535c2049c079b8c0e31183asapersson if (p_diff > scaled_pid) { 39632df5efc6db394ff4c535c2049c079b8c0e31183asapersson // TODO(asapersson): Max should correspond to the picture id of last wrap. 397f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson scaled_pid += vp9->max_picture_id + 1; 398f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 399f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->ref_picture_id[vp9->num_ref_pics++] = scaled_pid - p_diff; 400f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } while (n_bit); 401f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 402f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 403f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 404f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 405f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Scalability structure (SS). 406f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 407f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 4086449990387f57e04f9912e8002c620a0f247eed5asapersson// V: | N_S |Y|G|-|-|-| 409f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ -| 410f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Y: | WIDTH | (OPTIONAL) . 411f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// + + . 412f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | | (OPTIONAL) . 413f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ . N_S + 1 times 414f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | HEIGHT | (OPTIONAL) . 415f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// + + . 416f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | | (OPTIONAL) . 4176449990387f57e04f9912e8002c620a0f247eed5asapersson// +-+-+-+-+-+-+-+-+ -| 4186449990387f57e04f9912e8002c620a0f247eed5asapersson// G: | N_G | (OPTIONAL) 4196449990387f57e04f9912e8002c620a0f247eed5asapersson// +-+-+-+-+-+-+-+-+ -| 420f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// N_G: | T |U| R |-|-| (OPTIONAL) . 4216449990387f57e04f9912e8002c620a0f247eed5asapersson// +-+-+-+-+-+-+-+-+ -| . N_G times 422f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | P_DIFF | (OPTIONAL) . R times . 423f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ -| -| 424f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 425f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool ParseSsData(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { 4266449990387f57e04f9912e8002c620a0f247eed5asapersson uint32_t n_s, y_bit, g_bit; 427f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&n_s, 3)); 428f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&y_bit, 1)); 4296449990387f57e04f9912e8002c620a0f247eed5asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&g_bit, 1)); 4306449990387f57e04f9912e8002c620a0f247eed5asapersson RETURN_FALSE_ON_ERROR(parser->ConsumeBits(3)); 431f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->num_spatial_layers = n_s + 1; 432f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->spatial_layer_resolution_present = y_bit ? true : false; 4336449990387f57e04f9912e8002c620a0f247eed5asapersson vp9->gof.num_frames_in_gof = 0; 434f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 435f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (y_bit) { 436f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson for (size_t i = 0; i < vp9->num_spatial_layers; ++i) { 437f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadUInt16(&vp9->width[i])); 438f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadUInt16(&vp9->height[i])); 439f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 440f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 4416449990387f57e04f9912e8002c620a0f247eed5asapersson if (g_bit) { 4426449990387f57e04f9912e8002c620a0f247eed5asapersson uint8_t n_g; 4436449990387f57e04f9912e8002c620a0f247eed5asapersson RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&n_g)); 4446449990387f57e04f9912e8002c620a0f247eed5asapersson vp9->gof.num_frames_in_gof = n_g; 4456449990387f57e04f9912e8002c620a0f247eed5asapersson } 446f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson for (size_t i = 0; i < vp9->gof.num_frames_in_gof; ++i) { 447f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint32_t t, u_bit, r; 448f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&t, 3)); 449f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&u_bit, 1)); 450f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadBits(&r, 2)); 451f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ConsumeBits(2)); 452f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->gof.temporal_idx[i] = t; 453f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->gof.temporal_up_switch[i] = u_bit ? true : false; 454f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->gof.num_ref_pics[i] = r; 455f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 456c253a1c00eefd966aa59e00885fae4714806094fasapersson for (uint8_t p = 0; p < vp9->gof.num_ref_pics[i]; ++p) { 457f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint8_t p_diff; 458f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&p_diff)); 459f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->gof.pid_diff[i][p] = p_diff; 460f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 461f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 462f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 463f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 464f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 465f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Gets the size of next payload chunk to send. Returns 0 on error. 466f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonsize_t CalcNextSize(size_t max_length, size_t rem_bytes) { 467f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (max_length == 0 || rem_bytes == 0) { 468f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return 0; 469f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 470f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (kBalancedMode) { 471f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t num_frags = std::ceil(static_cast<double>(rem_bytes) / max_length); 472f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return static_cast<size_t>( 473f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson static_cast<double>(rem_bytes) / num_frags + 0.5); 474f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 475f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return max_length >= rem_bytes ? rem_bytes : max_length; 476f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 477f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} // namespace 478f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 479f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 480f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonRtpPacketizerVp9::RtpPacketizerVp9(const RTPVideoHeaderVP9& hdr, 481f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t max_payload_length) 482f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson : hdr_(hdr), 483f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson max_payload_length_(max_payload_length), 484f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson payload_(nullptr), 485f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson payload_size_(0) { 486f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 487f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 488f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonRtpPacketizerVp9::~RtpPacketizerVp9() { 489f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 490f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 491f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonProtectionType RtpPacketizerVp9::GetProtectionType() { 492f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool protect = 493f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson hdr_.temporal_idx == 0 || hdr_.temporal_idx == kNoTemporalIdx; 494f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return protect ? kProtectedPacket : kUnprotectedPacket; 495f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 496f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 497f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonStorageType RtpPacketizerVp9::GetStorageType(uint32_t retransmission_settings) { 498f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson StorageType storage = kAllowRetransmission; 499f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (hdr_.temporal_idx == 0 && 500f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson !(retransmission_settings & kRetransmitBaseLayer)) { 501f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson storage = kDontRetransmit; 502f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } else if (hdr_.temporal_idx != kNoTemporalIdx && hdr_.temporal_idx > 0 && 503f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson !(retransmission_settings & kRetransmitHigherLayers)) { 504f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson storage = kDontRetransmit; 505f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 506f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return storage; 507f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 508f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 509f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonstd::string RtpPacketizerVp9::ToString() { 510f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return "RtpPacketizerVp9"; 511f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 512f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 513f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonvoid RtpPacketizerVp9::SetPayloadData( 514f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson const uint8_t* payload, 515f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t payload_size, 516f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson const RTPFragmentationHeader* fragmentation) { 517f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson payload_ = payload; 518f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson payload_size_ = payload_size; 519f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson GeneratePackets(); 520f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 521f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 522f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonvoid RtpPacketizerVp9::GeneratePackets() { 523f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (max_payload_length_ < PayloadDescriptorLength(hdr_) + 1) { 524f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Payload header and one payload byte won't fit."; 525f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return; 526f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 527f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t bytes_processed = 0; 528f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson while (bytes_processed < payload_size_) { 529f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t rem_bytes = payload_size_ - bytes_processed; 530f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t rem_payload_len = max_payload_length_ - 531f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson (bytes_processed ? PayloadDescriptorLengthMinusSsData(hdr_) 532f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson : PayloadDescriptorLength(hdr_)); 533f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 534f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t packet_bytes = CalcNextSize(rem_payload_len, rem_bytes); 535f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (packet_bytes == 0) { 536f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Failed to generate VP9 packets."; 537f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson while (!packets_.empty()) 538f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson packets_.pop(); 539f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return; 540f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 541f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson QueuePacket(bytes_processed, packet_bytes, bytes_processed == 0, 542f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson rem_bytes == packet_bytes, &packets_); 543f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bytes_processed += packet_bytes; 544f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 545f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson assert(bytes_processed == payload_size_); 546f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 547f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 548f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool RtpPacketizerVp9::NextPacket(uint8_t* buffer, 549f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t* bytes_to_send, 550f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool* last_packet) { 551f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (packets_.empty()) { 552f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 553f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 554f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson PacketInfo packet_info = packets_.front(); 555f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson packets_.pop(); 556f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 557f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (!WriteHeaderAndPayload(packet_info, buffer, bytes_to_send)) { 558f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 559f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 5607f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica *last_packet = 5617f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica packets_.empty() && (hdr_.spatial_idx == kNoSpatialIdx || 5627f6a6fc0b23795cd4f0aacbf707618c1f3d0a878ivica hdr_.spatial_idx == hdr_.num_spatial_layers - 1); 563f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 564f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 565f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 566f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// VP9 format: 567f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 568f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Payload descriptor for F = 1 (flexible mode) 569f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 0 1 2 3 4 5 6 7 570f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 571f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// |I|P|L|F|B|E|V|-| (REQUIRED) 572f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 573f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// I: |M| PICTURE ID | (RECOMMENDED) 574f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 575f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// M: | EXTENDED PID | (RECOMMENDED) 576f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 577f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// L: | T |U| S |D| (CONDITIONALLY RECOMMENDED) 578f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ -| 57932df5efc6db394ff4c535c2049c079b8c0e31183asapersson// P,F: | P_DIFF |N| (CONDITIONALLY RECOMMENDED) . up to 3 times 580f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ -| 581f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// V: | SS | 582f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | .. | 583f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 584f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 585f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// Payload descriptor for F = 0 (non-flexible mode) 586f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// 0 1 2 3 4 5 6 7 587f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 588f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// |I|P|L|F|B|E|V|-| (REQUIRED) 589f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 590f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// I: |M| PICTURE ID | (RECOMMENDED) 591f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 592f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// M: | EXTENDED PID | (RECOMMENDED) 593f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 594394c537b21e6e2d6a93f2982f1e01d57497a98dcasapersson// L: | T |U| S |D| (CONDITIONALLY RECOMMENDED) 595f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 596f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | TL0PICIDX | (CONDITIONALLY REQUIRED) 597f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 598f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// V: | SS | 599f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// | .. | 600f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson// +-+-+-+-+-+-+-+-+ 601f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 602f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool RtpPacketizerVp9::WriteHeaderAndPayload(const PacketInfo& packet_info, 603f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint8_t* buffer, 604f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t* bytes_to_send) const { 605f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t header_length; 606f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (!WriteHeader(packet_info, buffer, &header_length)) 607f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 608f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 609f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson // Copy payload data. 610f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson memcpy(&buffer[header_length], 611f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson &payload_[packet_info.payload_start_pos], packet_info.size); 612f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 613f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson *bytes_to_send = header_length + packet_info.size; 614f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 615f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 616f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 617f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool RtpPacketizerVp9::WriteHeader(const PacketInfo& packet_info, 618f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint8_t* buffer, 619f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t* header_length) const { 620f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson // Required payload descriptor byte. 621f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool i_bit = PictureIdPresent(hdr_); 622f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool p_bit = hdr_.inter_pic_predicted; 623f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool l_bit = LayerInfoPresent(hdr_); 624f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool f_bit = hdr_.flexible_mode; 625a9455ab235e1169572f9eae3175cd9310d6729e2asapersson bool b_bit = packet_info.layer_begin; 626a9455ab235e1169572f9eae3175cd9310d6729e2asapersson bool e_bit = packet_info.layer_end; 627f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson bool v_bit = hdr_.ss_data_available && b_bit; 628f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 629f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson rtc::BitBufferWriter writer(buffer, max_payload_length_); 630f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer.WriteBits(i_bit ? 1 : 0, 1)); 631f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer.WriteBits(p_bit ? 1 : 0, 1)); 632f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer.WriteBits(l_bit ? 1 : 0, 1)); 633f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer.WriteBits(f_bit ? 1 : 0, 1)); 634f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer.WriteBits(b_bit ? 1 : 0, 1)); 635f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer.WriteBits(e_bit ? 1 : 0, 1)); 636f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer.WriteBits(v_bit ? 1 : 0, 1)); 637f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(writer.WriteBits(kReservedBitValue0, 1)); 638f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 639f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson // Add fields that are present. 640f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (i_bit && !WritePictureId(hdr_, &writer)) { 641f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Failed writing VP9 picture id."; 642f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 643f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 644f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (l_bit && !WriteLayerInfo(hdr_, &writer)) { 645f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Failed writing VP9 layer info."; 646f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 647f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 648f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (p_bit && f_bit && !WriteRefIndices(hdr_, &writer)) { 649f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Failed writing VP9 ref indices."; 650f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 651f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 652f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (v_bit && !WriteSsData(hdr_, &writer)) { 653f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Failed writing VP9 SS data."; 654f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 655f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 656f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 657f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t offset_bytes = 0; 658f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t offset_bits = 0; 659f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson writer.GetCurrentOffset(&offset_bytes, &offset_bits); 660f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson assert(offset_bits == 0); 661f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 662f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson *header_length = offset_bytes; 663f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 664f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 665f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 666f38ea3caa39887c63e7d4862dcf420d4a35c1073asaperssonbool RtpDepacketizerVp9::Parse(ParsedPayload* parsed_payload, 667f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson const uint8_t* payload, 668f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson size_t payload_length) { 669f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson assert(parsed_payload != nullptr); 670f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (payload_length == 0) { 671f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Payload length is zero."; 672f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 673f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 674f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 675f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson // Parse mandatory first byte of payload descriptor. 676f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson rtc::BitBuffer parser(payload, payload_length); 677f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint32_t i_bit, p_bit, l_bit, f_bit, b_bit, e_bit, v_bit; 678f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser.ReadBits(&i_bit, 1)); 679f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser.ReadBits(&p_bit, 1)); 680f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser.ReadBits(&l_bit, 1)); 681f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser.ReadBits(&f_bit, 1)); 682f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser.ReadBits(&b_bit, 1)); 683f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser.ReadBits(&e_bit, 1)); 684f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser.ReadBits(&v_bit, 1)); 685f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RETURN_FALSE_ON_ERROR(parser.ConsumeBits(1)); 686f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 687f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson // Parsed payload. 688f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson parsed_payload->type.Video.width = 0; 689f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson parsed_payload->type.Video.height = 0; 690f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson parsed_payload->type.Video.simulcastIdx = 0; 691f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson parsed_payload->type.Video.codec = kRtpVideoVp9; 692f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 693f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson parsed_payload->frame_type = p_bit ? kVideoFrameDelta : kVideoFrameKey; 694f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 695f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson RTPVideoHeaderVP9* vp9 = &parsed_payload->type.Video.codecHeader.VP9; 696f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->InitRTPVideoHeaderVP9(); 697f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->inter_pic_predicted = p_bit ? true : false; 698f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->flexible_mode = f_bit ? true : false; 699f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->beginning_of_frame = b_bit ? true : false; 700f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->end_of_frame = e_bit ? true : false; 701f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->ss_data_available = v_bit ? true : false; 702f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson vp9->spatial_idx = 0; 703f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 704f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson // Parse fields that are present. 705f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (i_bit && !ParsePictureId(&parser, vp9)) { 706f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Failed parsing VP9 picture id."; 707f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 708f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 709f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (l_bit && !ParseLayerInfo(&parser, vp9)) { 710f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Failed parsing VP9 layer info."; 711f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 712f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 713f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (p_bit && f_bit && !ParseRefIndices(&parser, vp9)) { 714f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Failed parsing VP9 ref indices."; 715f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 716f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 717f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (v_bit) { 718f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (!ParseSsData(&parser, vp9)) { 719f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Failed parsing VP9 SS data."; 720f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 721f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 722f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (vp9->spatial_layer_resolution_present) { 723f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson // TODO(asapersson): Add support for spatial layers. 724f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson parsed_payload->type.Video.width = vp9->width[0]; 725f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson parsed_payload->type.Video.height = vp9->height[0]; 726f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 727f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 728cfc319be1d6afec77bd41eeb70d3e7886dd524dbphilipel parsed_payload->type.Video.isFirstPacket = 729cfc319be1d6afec77bd41eeb70d3e7886dd524dbphilipel b_bit && (!l_bit || !vp9->inter_layer_predicted); 730f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 731f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson uint64_t rem_bits = parser.RemainingBitCount(); 732f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson assert(rem_bits % 8 == 0); 733f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson parsed_payload->payload_length = rem_bits / 8; 734f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson if (parsed_payload->payload_length == 0) { 735f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson LOG(LS_ERROR) << "Failed parsing VP9 payload data."; 736f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return false; 737f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson } 738f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson parsed_payload->payload = 739f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson payload + payload_length - parsed_payload->payload_length; 740f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson 741f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson return true; 742f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} 743f38ea3caa39887c63e7d4862dcf420d4a35c1073asapersson} // namespace webrtc 744