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