1ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander/* 2ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * 4ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * Use of this source code is governed by a BSD-style license 5ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * that can be found in the LICENSE file in the root of the source 6ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * tree. An additional intellectual property rights grant can be found 7ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * in the file PATENTS. All contributing project authors may 8ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * be found in the AUTHORS file in the root of the source tree. 9ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander */ 10ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 11ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#ifndef WEBRTC_MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ 12ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#define WEBRTC_MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ 13ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 14ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include <assert.h> 15ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include <string.h> // memcpy 16ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 17ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include <algorithm> 18ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include <limits> 19ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 20ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/base/constructormagic.h" 21ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/common_types.h" 22ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/common_video/rotation.h" 23ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/typedefs.h" 24ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 25ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellandernamespace webrtc { 26ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 27ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderstruct RTPAudioHeader { 28ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t numEnergy; // number of valid entries in arrOfEnergy 29ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t arrOfEnergy[kRtpCsrcSize]; // one energy byte (0-9) per channel 30ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool isCNG; // is this CNG 316955870806624479723addfae6dcf5d13968796cPeter Kasting size_t channel; // number of channels 2 = stereo 32ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 33ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 34ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst int16_t kNoPictureId = -1; 35ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst int16_t kMaxOneBytePictureId = 0x7F; // 7 bits 36ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst int16_t kMaxTwoBytePictureId = 0x7FFF; // 15 bits 37ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst int16_t kNoTl0PicIdx = -1; 38ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst uint8_t kNoTemporalIdx = 0xFF; 39ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst uint8_t kNoSpatialIdx = 0xFF; 40ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst uint8_t kNoGofIdx = 0xFF; 41cfc319be1d6afec77bd41eeb70d3e7886dd524dbphilipelconst uint8_t kNumVp9Buffers = 8; 42ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst size_t kMaxVp9RefPics = 3; 43ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst size_t kMaxVp9FramesInGof = 0xFF; // 8 bits 44ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst size_t kMaxVp9NumberOfSpatialLayers = 8; 45ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderconst int kNoKeyIdx = -1; 46ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 47ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderstruct RTPVideoHeaderVP8 { 48ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void InitRTPVideoHeaderVP8() { 49ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander nonReference = false; 50ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander pictureId = kNoPictureId; 51ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander tl0PicIdx = kNoTl0PicIdx; 52ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporalIdx = kNoTemporalIdx; 53ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander layerSync = false; 54ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander keyIdx = kNoKeyIdx; 55ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander partitionId = 0; 56ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander beginningOfPartition = false; 57ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 58ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 59ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool nonReference; // Frame is discardable. 60ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int16_t pictureId; // Picture ID index, 15 bits; 61ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // kNoPictureId if PictureID does not exist. 62ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int16_t tl0PicIdx; // TL0PIC_IDX, 8 bits; 63ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // kNoTl0PicIdx means no value provided. 64ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t temporalIdx; // Temporal layer index, or kNoTemporalIdx. 65ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool layerSync; // This frame is a layer sync frame. 66ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Disabled if temporalIdx == kNoTemporalIdx. 67ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int keyIdx; // 5 bits; kNoKeyIdx means not used. 68ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int partitionId; // VP8 partition ID 69ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool beginningOfPartition; // True if this packet is the first 70ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // in a VP8 partition. Otherwise false 71ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 72ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 73ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderenum TemporalStructureMode { 74ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kTemporalStructureMode1, // 1 temporal layer structure - i.e., IPPP... 75ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kTemporalStructureMode2, // 2 temporal layers 0-1-0-1... 76ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kTemporalStructureMode3 // 3 temporal layers 0-2-1-2-0-2-1-2... 77ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 78ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 79ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderstruct GofInfoVP9 { 80ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void SetGofInfoVP9(TemporalStructureMode tm) { 81ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander switch (tm) { 82ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander case kTemporalStructureMode1: 83ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_frames_in_gof = 1; 84ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_idx[0] = 0; 85ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_up_switch[0] = false; 86ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_ref_pics[0] = 1; 87ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander pid_diff[0][0] = 1; 88ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander break; 89ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander case kTemporalStructureMode2: 90ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_frames_in_gof = 2; 91ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_idx[0] = 0; 92ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_up_switch[0] = false; 93ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_ref_pics[0] = 1; 94ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander pid_diff[0][0] = 2; 95ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 96ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_idx[1] = 1; 97ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_up_switch[1] = true; 98ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_ref_pics[1] = 1; 99ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander pid_diff[1][0] = 1; 100ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander break; 101ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander case kTemporalStructureMode3: 102ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_frames_in_gof = 4; 103ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_idx[0] = 0; 104ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_up_switch[0] = false; 105ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_ref_pics[0] = 1; 106ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander pid_diff[0][0] = 4; 107ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 108ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_idx[1] = 2; 109ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_up_switch[1] = true; 110ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_ref_pics[1] = 1; 111ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander pid_diff[1][0] = 1; 112ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 113ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_idx[2] = 1; 114ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_up_switch[2] = true; 115ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_ref_pics[2] = 1; 116ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander pid_diff[2][0] = 2; 117ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 118ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_idx[3] = 2; 119ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_up_switch[3] = false; 120ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_ref_pics[3] = 2; 121ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander pid_diff[3][0] = 1; 122ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander pid_diff[3][1] = 2; 123ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander break; 124ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander default: 125ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert(false); 126ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 127ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 128ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 129ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void CopyGofInfoVP9(const GofInfoVP9& src) { 130ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_frames_in_gof = src.num_frames_in_gof; 131ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander for (size_t i = 0; i < num_frames_in_gof; ++i) { 132ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_idx[i] = src.temporal_idx[i]; 133ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_up_switch[i] = src.temporal_up_switch[i]; 134ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_ref_pics[i] = src.num_ref_pics[i]; 135c253a1c00eefd966aa59e00885fae4714806094fasapersson for (uint8_t r = 0; r < num_ref_pics[i]; ++r) { 136ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander pid_diff[i][r] = src.pid_diff[i][r]; 137ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 138ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 139ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 140ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 141ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander size_t num_frames_in_gof; 142ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t temporal_idx[kMaxVp9FramesInGof]; 143ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool temporal_up_switch[kMaxVp9FramesInGof]; 144c253a1c00eefd966aa59e00885fae4714806094fasapersson uint8_t num_ref_pics[kMaxVp9FramesInGof]; 145c253a1c00eefd966aa59e00885fae4714806094fasapersson uint8_t pid_diff[kMaxVp9FramesInGof][kMaxVp9RefPics]; 146ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 147ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 148ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderstruct RTPVideoHeaderVP9 { 149ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void InitRTPVideoHeaderVP9() { 150ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander inter_pic_predicted = false; 151ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander flexible_mode = false; 152ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander beginning_of_frame = false; 153ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander end_of_frame = false; 154ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander ss_data_available = false; 155ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander picture_id = kNoPictureId; 156ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander max_picture_id = kMaxTwoBytePictureId; 157ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander tl0_pic_idx = kNoTl0PicIdx; 158ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_idx = kNoTemporalIdx; 159ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander spatial_idx = kNoSpatialIdx; 160ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander temporal_up_switch = false; 161ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander inter_layer_predicted = false; 162ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander gof_idx = kNoGofIdx; 163ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_ref_pics = 0; 164ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_spatial_layers = 1; 165ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 166ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 167ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool inter_pic_predicted; // This layer frame is dependent on previously 168ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // coded frame(s). 169ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool flexible_mode; // This frame is in flexible mode. 170ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool beginning_of_frame; // True if this packet is the first in a VP9 layer 171ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // frame. 172ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool end_of_frame; // True if this packet is the last in a VP9 layer frame. 173ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool ss_data_available; // True if SS data is available in this payload 174ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // descriptor. 175ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int16_t picture_id; // PictureID index, 15 bits; 176ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // kNoPictureId if PictureID does not exist. 177ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int16_t max_picture_id; // Maximum picture ID index; either 0x7F or 0x7FFF; 178ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int16_t tl0_pic_idx; // TL0PIC_IDX, 8 bits; 179ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // kNoTl0PicIdx means no value provided. 180ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t temporal_idx; // Temporal layer index, or kNoTemporalIdx. 181ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t spatial_idx; // Spatial layer index, or kNoSpatialIdx. 182ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool temporal_up_switch; // True if upswitch to higher frame rate is possible 183ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // starting from this frame. 184ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool inter_layer_predicted; // Frame is dependent on directly lower spatial 185ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // layer frame. 186ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 187ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t gof_idx; // Index to predefined temporal frame info in SS data. 188ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 189c253a1c00eefd966aa59e00885fae4714806094fasapersson uint8_t num_ref_pics; // Number of reference pictures used by this layer 190c253a1c00eefd966aa59e00885fae4714806094fasapersson // frame. 191c253a1c00eefd966aa59e00885fae4714806094fasapersson uint8_t pid_diff[kMaxVp9RefPics]; // P_DIFF signaled to derive the PictureID 192ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // of the reference pictures. 193ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int16_t ref_picture_id[kMaxVp9RefPics]; // PictureID of reference pictures. 194ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 195ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // SS data. 196ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander size_t num_spatial_layers; // Always populated. 197ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool spatial_layer_resolution_present; 198ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t width[kMaxVp9NumberOfSpatialLayers]; 199ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t height[kMaxVp9NumberOfSpatialLayers]; 200ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander GofInfoVP9 gof; 201ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 202ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 203ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// The packetization types that we support: single, aggregated, and fragmented. 204ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderenum H264PacketizationTypes { 205ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kH264SingleNalu, // This packet contains a single NAL unit. 206ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kH264StapA, // This packet contains STAP-A (single time 207ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // aggregation) packets. If this packet has an 208ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // associated NAL unit type, it'll be for the 209ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // first such aggregated packet. 210ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kH264FuA, // This packet contains a FU-A (fragmentation 211ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // unit) packet, meaning it is a part of a frame 212ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // that was too large to fit into a single packet. 213ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 214ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 215ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderstruct RTPVideoHeaderH264 { 216ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t nalu_type; // The NAL unit type. If this is a header for a 217ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // fragmented packet, it's the NAL unit type of 218ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // the original data. If this is the header for an 219ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // aggregated packet, it's the NAL unit type of 220ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // the first NAL unit in the packet. 221ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander H264PacketizationTypes packetization_type; 222ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 223ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 224ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderunion RTPVideoTypeHeader { 225ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTPVideoHeaderVP8 VP8; 226ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTPVideoHeaderVP9 VP9; 227ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTPVideoHeaderH264 H264; 228ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 229ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 230ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderenum RtpVideoCodecTypes { 231ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kRtpVideoNone, 232ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kRtpVideoGeneric, 233ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kRtpVideoVp8, 234ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kRtpVideoVp9, 235ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kRtpVideoH264 236ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 237ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// Since RTPVideoHeader is used as a member of a union, it can't have a 238ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// non-trivial default constructor. 239ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderstruct RTPVideoHeader { 240ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t width; // size 241ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t height; 242ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander VideoRotation rotation; 243ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 244ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool isFirstPacket; // first packet in frame 245ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t simulcastIdx; // Index if the simulcast encoder creating 246ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // this frame, 0 if not using simulcast. 247ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RtpVideoCodecTypes codec; 248ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTPVideoTypeHeader codecHeader; 249ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 250ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderunion RTPTypeHeader { 251ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTPAudioHeader Audio; 252ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTPVideoHeader Video; 253ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 254ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 255ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderstruct WebRtcRTPHeader { 256ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTPHeader header; 257ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander FrameType frameType; 258ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTPTypeHeader type; 259ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // NTP time of the capture time in local timebase in milliseconds. 260ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int64_t ntp_time_ms; 261ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 262ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 263ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderclass RTPFragmentationHeader { 264ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander public: 265ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTPFragmentationHeader() 266ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander : fragmentationVectorSize(0), 267ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationOffset(NULL), 268ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationLength(NULL), 269ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationTimeDiff(NULL), 270ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationPlType(NULL) {}; 271ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 272ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander ~RTPFragmentationHeader() { 273ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] fragmentationOffset; 274ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] fragmentationLength; 275ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] fragmentationTimeDiff; 276ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] fragmentationPlType; 277ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 278ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 279ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void CopyFrom(const RTPFragmentationHeader& src) { 280ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (this == &src) { 281ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return; 282ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 283ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 284ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationVectorSize != fragmentationVectorSize) { 285ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // new size of vectors 286ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 287ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // delete old 288ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] fragmentationOffset; 289ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationOffset = NULL; 290ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] fragmentationLength; 291ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationLength = NULL; 292ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] fragmentationTimeDiff; 293ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationTimeDiff = NULL; 294ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] fragmentationPlType; 295ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationPlType = NULL; 296ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 297ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationVectorSize > 0) { 298ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // allocate new 299ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationOffset) { 300ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationOffset = new size_t[src.fragmentationVectorSize]; 301ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 302ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationLength) { 303ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationLength = new size_t[src.fragmentationVectorSize]; 304ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 305ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationTimeDiff) { 306ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationTimeDiff = new uint16_t[src.fragmentationVectorSize]; 307ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 308ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationPlType) { 309ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationPlType = new uint8_t[src.fragmentationVectorSize]; 310ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 311ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 312ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // set new size 313ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationVectorSize = src.fragmentationVectorSize; 314ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 315ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 316ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationVectorSize > 0) { 317ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // copy values 318ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationOffset) { 319ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(fragmentationOffset, src.fragmentationOffset, 320ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander src.fragmentationVectorSize * sizeof(size_t)); 321ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 322ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationLength) { 323ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(fragmentationLength, src.fragmentationLength, 324ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander src.fragmentationVectorSize * sizeof(size_t)); 325ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 326ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationTimeDiff) { 327ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(fragmentationTimeDiff, src.fragmentationTimeDiff, 328ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander src.fragmentationVectorSize * sizeof(uint16_t)); 329ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 330ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (src.fragmentationPlType) { 331ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(fragmentationPlType, src.fragmentationPlType, 332ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander src.fragmentationVectorSize * sizeof(uint8_t)); 333ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 334ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 335ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 336ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 337ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void VerifyAndAllocateFragmentationHeader(const size_t size) { 338ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert(size <= std::numeric_limits<uint16_t>::max()); 339ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander const uint16_t size16 = static_cast<uint16_t>(size); 340ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (fragmentationVectorSize < size16) { 341ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t oldVectorSize = fragmentationVectorSize; 342ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander { 343ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // offset 344ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander size_t* oldOffsets = fragmentationOffset; 345ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationOffset = new size_t[size16]; 346ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memset(fragmentationOffset + oldVectorSize, 0, 347ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sizeof(size_t) * (size16 - oldVectorSize)); 348ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // copy old values 349ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(fragmentationOffset, oldOffsets, 350ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sizeof(size_t) * oldVectorSize); 351ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] oldOffsets; 352ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 353ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // length 354ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander { 355ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander size_t* oldLengths = fragmentationLength; 356ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationLength = new size_t[size16]; 357ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memset(fragmentationLength + oldVectorSize, 0, 358ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sizeof(size_t) * (size16 - oldVectorSize)); 359ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(fragmentationLength, oldLengths, 360ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sizeof(size_t) * oldVectorSize); 361ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] oldLengths; 362ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 363ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // time diff 364ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander { 365ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t* oldTimeDiffs = fragmentationTimeDiff; 366ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationTimeDiff = new uint16_t[size16]; 367ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memset(fragmentationTimeDiff + oldVectorSize, 0, 368ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sizeof(uint16_t) * (size16 - oldVectorSize)); 369ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(fragmentationTimeDiff, oldTimeDiffs, 370ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sizeof(uint16_t) * oldVectorSize); 371ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] oldTimeDiffs; 372ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 373ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // payload type 374ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander { 375ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t* oldTimePlTypes = fragmentationPlType; 376ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationPlType = new uint8_t[size16]; 377ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memset(fragmentationPlType + oldVectorSize, 0, 378ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sizeof(uint8_t) * (size16 - oldVectorSize)); 379ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(fragmentationPlType, oldTimePlTypes, 380ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sizeof(uint8_t) * oldVectorSize); 381ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delete[] oldTimePlTypes; 382ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 383ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander fragmentationVectorSize = size16; 384ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 385ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 386ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 387ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t fragmentationVectorSize; // Number of fragmentations 388ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander size_t* fragmentationOffset; // Offset of pointer to data for each 389ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // fragmentation 390ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander size_t* fragmentationLength; // Data size for each fragmentation 391ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t* fragmentationTimeDiff; // Timestamp difference relative "now" for 392ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // each fragmentation 393ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t* fragmentationPlType; // Payload type of each fragmentation 394ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 395ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander private: 396ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTC_DISALLOW_COPY_AND_ASSIGN(RTPFragmentationHeader); 397ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 398ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 399ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderstruct RTCPVoIPMetric { 400ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // RFC 3611 4.7 401ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t lossRate; 402ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t discardRate; 403ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t burstDensity; 404ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t gapDensity; 405ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t burstDuration; 406ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t gapDuration; 407ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t roundTripDelay; 408ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t endSystemDelay; 409ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t signalLevel; 410ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t noiseLevel; 411ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t RERL; 412ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t Gmin; 413ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t Rfactor; 414ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t extRfactor; 415ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t MOSLQ; 416ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t MOSCQ; 417ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint8_t RXconfig; 418ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t JBnominal; 419ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t JBmax; 420ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t JBabsMax; 421ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 422ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 423ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// Types for the FEC packet masks. The type |kFecMaskRandom| is based on a 424ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// random loss model. The type |kFecMaskBursty| is based on a bursty/consecutive 425ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// loss model. The packet masks are defined in 426ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// modules/rtp_rtcp/fec_private_tables_random(bursty).h 427ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderenum FecMaskType { 428ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kFecMaskRandom, 429ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kFecMaskBursty, 430ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 431ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 432ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// Struct containing forward error correction settings. 433ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderstruct FecProtectionParams { 434ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int fec_rate; 435ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool use_uep_protection; 436ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int max_fec_frames; 437ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander FecMaskType fec_mask_type; 438ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 439ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 440ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// Interface used by the CallStats class to distribute call statistics. 441ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// Callbacks will be triggered as soon as the class has been registered to a 442ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// CallStats object using RegisterStatsObserver. 443ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderclass CallStatsObserver { 444ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander public: 445ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander virtual void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) = 0; 446ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 447ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander virtual ~CallStatsObserver() {} 448ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 449ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 450ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderstruct VideoContentMetrics { 451ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander VideoContentMetrics() 452ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander : motion_magnitude(0.0f), 453ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander spatial_pred_err(0.0f), 454ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander spatial_pred_err_h(0.0f), 455ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander spatial_pred_err_v(0.0f) {} 456ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 457ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void Reset() { 458ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander motion_magnitude = 0.0f; 459ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander spatial_pred_err = 0.0f; 460ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander spatial_pred_err_h = 0.0f; 461ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander spatial_pred_err_v = 0.0f; 462ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 463ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander float motion_magnitude; 464ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander float spatial_pred_err; 465ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander float spatial_pred_err_h; 466ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander float spatial_pred_err_v; 467ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 468ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 469ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander/* This class holds up to 60 ms of super-wideband (32 kHz) stereo audio. It 470ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * allows for adding and subtracting frames while keeping track of the resulting 471ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * states. 472ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * 473ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * Notes 474ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * - The total number of samples in |data_| is 475ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * samples_per_channel_ * num_channels_ 476ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * 477ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * - Stereo data is interleaved starting with the left channel. 478ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * 479ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * - The +operator assume that you would never add exactly opposite frames when 480ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander * deciding the resulting state. To do this use the -operator. 481ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander */ 482ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderclass AudioFrame { 483ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander public: 484ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Stereo, 32 kHz, 60 ms (2 * 32 * 60) 485ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander static const size_t kMaxDataSizeSamples = 3840; 486ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 487ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander enum VADActivity { 488ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kVadActive = 0, 489ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kVadPassive = 1, 490ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kVadUnknown = 2 491ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander }; 492ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander enum SpeechType { 493ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kNormalSpeech = 0, 494ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kPLC = 1, 495ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kCNG = 2, 496ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kPLCCNG = 3, 497ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander kUndefined = 4 498ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander }; 499ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 500ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander AudioFrame(); 501ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander virtual ~AudioFrame() {} 502ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 503ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Resets all members to their default state (except does not modify the 504ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // contents of |data_|). 505ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void Reset(); 506ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 507ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // |interleaved_| is not changed by this method. 508ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void UpdateFrame(int id, uint32_t timestamp, const int16_t* data, 509ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander size_t samples_per_channel, int sample_rate_hz, 510ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander SpeechType speech_type, VADActivity vad_activity, 5116955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_channels = 1, uint32_t energy = -1); 512ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 513ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander AudioFrame& Append(const AudioFrame& rhs); 514ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 515ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void CopyFrom(const AudioFrame& src); 516ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 517ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void Mute(); 518ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 519ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander AudioFrame& operator>>=(const int rhs); 520ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander AudioFrame& operator+=(const AudioFrame& rhs); 521ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander AudioFrame& operator-=(const AudioFrame& rhs); 522ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 523ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int id_; 524ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // RTP timestamp of the first sample in the AudioFrame. 525ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint32_t timestamp_; 526ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Time since the first frame in milliseconds. 527ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // -1 represents an uninitialized value. 528ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int64_t elapsed_time_ms_; 529ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // NTP time of the estimated capture time in local timebase in milliseconds. 530ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // -1 represents an uninitialized value. 531ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int64_t ntp_time_ms_; 532ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int16_t data_[kMaxDataSizeSamples]; 533ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander size_t samples_per_channel_; 534ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int sample_rate_hz_; 5356955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_channels_; 536ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander SpeechType speech_type_; 537ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander VADActivity vad_activity_; 538ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Note that there is no guarantee that |energy_| is correct. Any user of this 539ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // member must verify that the value is correct. 540ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // TODO(henrike) Remove |energy_|. 541ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // See https://code.google.com/p/webrtc/issues/detail?id=3315. 542ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint32_t energy_; 543ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool interleaved_; 544ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 545ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander private: 546ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander RTC_DISALLOW_COPY_AND_ASSIGN(AudioFrame); 547ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 548ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 549ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline AudioFrame::AudioFrame() 550ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander : data_() { 551ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander Reset(); 552ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 553ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 554ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline void AudioFrame::Reset() { 555ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander id_ = -1; 556ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // TODO(wu): Zero is a valid value for |timestamp_|. We should initialize 557ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // to an invalid value, or add a new member to indicate invalidity. 558ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander timestamp_ = 0; 559ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander elapsed_time_ms_ = -1; 560ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander ntp_time_ms_ = -1; 561ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander samples_per_channel_ = 0; 562ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sample_rate_hz_ = 0; 563ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_channels_ = 0; 564ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander speech_type_ = kUndefined; 565ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander vad_activity_ = kVadUnknown; 566ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander energy_ = 0xffffffff; 567ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander interleaved_ = true; 568ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 569ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 570ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline void AudioFrame::UpdateFrame(int id, 571ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint32_t timestamp, 572ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander const int16_t* data, 573ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander size_t samples_per_channel, 574ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int sample_rate_hz, 575ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander SpeechType speech_type, 576ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander VADActivity vad_activity, 5776955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_channels, 578ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint32_t energy) { 579ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander id_ = id; 580ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander timestamp_ = timestamp; 581ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander samples_per_channel_ = samples_per_channel; 582ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sample_rate_hz_ = sample_rate_hz; 583ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander speech_type_ = speech_type; 584ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander vad_activity_ = vad_activity; 585ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_channels_ = num_channels; 586ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander energy_ = energy; 587ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 588ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander const size_t length = samples_per_channel * num_channels; 589ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert(length <= kMaxDataSizeSamples); 590ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (data != NULL) { 591ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(data_, data, sizeof(int16_t) * length); 592ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } else { 593ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memset(data_, 0, sizeof(int16_t) * length); 594ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 595ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 596ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 597ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline void AudioFrame::CopyFrom(const AudioFrame& src) { 598ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (this == &src) return; 599ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 600ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander id_ = src.id_; 601ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander timestamp_ = src.timestamp_; 602ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander elapsed_time_ms_ = src.elapsed_time_ms_; 603ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander ntp_time_ms_ = src.ntp_time_ms_; 604ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander samples_per_channel_ = src.samples_per_channel_; 605ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sample_rate_hz_ = src.sample_rate_hz_; 606ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander speech_type_ = src.speech_type_; 607ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander vad_activity_ = src.vad_activity_; 608ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander num_channels_ = src.num_channels_; 609ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander energy_ = src.energy_; 610ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander interleaved_ = src.interleaved_; 611ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 612ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander const size_t length = samples_per_channel_ * num_channels_; 613ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert(length <= kMaxDataSizeSamples); 614ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(data_, src.data_, sizeof(int16_t) * length); 615ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 616ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 617ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline void AudioFrame::Mute() { 618ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memset(data_, 0, samples_per_channel_ * num_channels_ * sizeof(int16_t)); 619ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 620ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 621ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline AudioFrame& AudioFrame::operator>>=(const int rhs) { 622ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert((num_channels_ > 0) && (num_channels_ < 3)); 623ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if ((num_channels_ > 2) || (num_channels_ < 1)) return *this; 624ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 625ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander for (size_t i = 0; i < samples_per_channel_ * num_channels_; i++) { 626ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander data_[i] = static_cast<int16_t>(data_[i] >> rhs); 627ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 628ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return *this; 629ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 630ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 631ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline AudioFrame& AudioFrame::Append(const AudioFrame& rhs) { 632ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Sanity check 633ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert((num_channels_ > 0) && (num_channels_ < 3)); 634ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert(interleaved_ == rhs.interleaved_); 635ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if ((num_channels_ > 2) || (num_channels_ < 1)) return *this; 636ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (num_channels_ != rhs.num_channels_) return *this; 637ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 638ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if ((vad_activity_ == kVadActive) || rhs.vad_activity_ == kVadActive) { 639ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander vad_activity_ = kVadActive; 640ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } else if (vad_activity_ == kVadUnknown || rhs.vad_activity_ == kVadUnknown) { 641ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander vad_activity_ = kVadUnknown; 642ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 643ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (speech_type_ != rhs.speech_type_) { 644ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander speech_type_ = kUndefined; 645ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 646ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 647ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander size_t offset = samples_per_channel_ * num_channels_; 648ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander for (size_t i = 0; i < rhs.samples_per_channel_ * rhs.num_channels_; i++) { 649ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander data_[offset + i] = rhs.data_[i]; 650ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 651ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander samples_per_channel_ += rhs.samples_per_channel_; 652ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return *this; 653ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 654ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 655ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellandernamespace { 656ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline int16_t ClampToInt16(int32_t input) { 657ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (input < -0x00008000) { 658ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return -0x8000; 659ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } else if (input > 0x00007FFF) { 660ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return 0x7FFF; 661ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } else { 662ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return static_cast<int16_t>(input); 663ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 664ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 665ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 666ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 667ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline AudioFrame& AudioFrame::operator+=(const AudioFrame& rhs) { 668ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Sanity check 669ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert((num_channels_ > 0) && (num_channels_ < 3)); 670ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert(interleaved_ == rhs.interleaved_); 671ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if ((num_channels_ > 2) || (num_channels_ < 1)) return *this; 672ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (num_channels_ != rhs.num_channels_) return *this; 673ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 674ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander bool noPrevData = false; 675ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (samples_per_channel_ != rhs.samples_per_channel_) { 676ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (samples_per_channel_ == 0) { 677ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // special case we have no data to start with 678ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander samples_per_channel_ = rhs.samples_per_channel_; 679ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander noPrevData = true; 680ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } else { 681ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return *this; 682ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 683ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 684ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 685ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if ((vad_activity_ == kVadActive) || rhs.vad_activity_ == kVadActive) { 686ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander vad_activity_ = kVadActive; 687ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } else if (vad_activity_ == kVadUnknown || rhs.vad_activity_ == kVadUnknown) { 688ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander vad_activity_ = kVadUnknown; 689ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 690ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 691ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (speech_type_ != rhs.speech_type_) speech_type_ = kUndefined; 692ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 693ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (noPrevData) { 694ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander memcpy(data_, rhs.data_, 695ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander sizeof(int16_t) * rhs.samples_per_channel_ * num_channels_); 696ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } else { 697ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // IMPROVEMENT this can be done very fast in assembly 698ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander for (size_t i = 0; i < samples_per_channel_ * num_channels_; i++) { 699ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int32_t wrap_guard = 700ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander static_cast<int32_t>(data_[i]) + static_cast<int32_t>(rhs.data_[i]); 701ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander data_[i] = ClampToInt16(wrap_guard); 702ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 703ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 704ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander energy_ = 0xffffffff; 705ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return *this; 706ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 707ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 708ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline AudioFrame& AudioFrame::operator-=(const AudioFrame& rhs) { 709ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Sanity check 710ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert((num_channels_ > 0) && (num_channels_ < 3)); 711ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander assert(interleaved_ == rhs.interleaved_); 712ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if ((num_channels_ > 2) || (num_channels_ < 1)) return *this; 713ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 714ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if ((samples_per_channel_ != rhs.samples_per_channel_) || 715ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander (num_channels_ != rhs.num_channels_)) { 716ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return *this; 717ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 718ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if ((vad_activity_ != kVadPassive) || rhs.vad_activity_ != kVadPassive) { 719ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander vad_activity_ = kVadUnknown; 720ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 721ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander speech_type_ = kUndefined; 722ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 723ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander for (size_t i = 0; i < samples_per_channel_ * num_channels_; i++) { 724ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int32_t wrap_guard = 725ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander static_cast<int32_t>(data_[i]) - static_cast<int32_t>(rhs.data_[i]); 726ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander data_[i] = ClampToInt16(wrap_guard); 727ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 728ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander energy_ = 0xffffffff; 729ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return *this; 730ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 731ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 732ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline bool IsNewerSequenceNumber(uint16_t sequence_number, 733ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t prev_sequence_number) { 734ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Distinguish between elements that are exactly 0x8000 apart. 735ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // If s1>s2 and |s1-s2| = 0x8000: IsNewer(s1,s2)=true, IsNewer(s2,s1)=false 736ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // rather than having IsNewer(s1,s2) = IsNewer(s2,s1) = false. 737ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (static_cast<uint16_t>(sequence_number - prev_sequence_number) == 0x8000) { 738ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return sequence_number > prev_sequence_number; 739ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 740ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return sequence_number != prev_sequence_number && 741ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander static_cast<uint16_t>(sequence_number - prev_sequence_number) < 0x8000; 742ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 743ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 744ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) { 745ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Distinguish between elements that are exactly 0x80000000 apart. 746ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // If t1>t2 and |t1-t2| = 0x80000000: IsNewer(t1,t2)=true, 747ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // IsNewer(t2,t1)=false 748ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // rather than having IsNewer(t1,t2) = IsNewer(t2,t1) = false. 749ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (static_cast<uint32_t>(timestamp - prev_timestamp) == 0x80000000) { 750ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return timestamp > prev_timestamp; 751ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 752ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return timestamp != prev_timestamp && 753ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander static_cast<uint32_t>(timestamp - prev_timestamp) < 0x80000000; 754ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 755ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 756ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline uint16_t LatestSequenceNumber(uint16_t sequence_number1, 757ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t sequence_number2) { 758ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return IsNewerSequenceNumber(sequence_number1, sequence_number2) 759ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander ? sequence_number1 760ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander : sequence_number2; 761ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 762ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 763ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderinline uint32_t LatestTimestamp(uint32_t timestamp1, uint32_t timestamp2) { 764ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return IsNewerTimestamp(timestamp1, timestamp2) ? timestamp1 : timestamp2; 765ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} 766ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 767ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// Utility class to unwrap a sequence number to a larger type, for easier 768ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// handling large ranges. Note that sequence numbers will never be unwrapped 769ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander// to a negative value. 770ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellanderclass SequenceNumberUnwrapper { 771ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander public: 772ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander SequenceNumberUnwrapper() : last_seq_(-1) {} 773ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 774ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Get the unwrapped sequence, but don't update the internal state. 775ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int64_t UnwrapWithoutUpdate(uint16_t sequence_number) { 776ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (last_seq_ == -1) 777ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return sequence_number; 778ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 779ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander uint16_t cropped_last = static_cast<uint16_t>(last_seq_); 780ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int64_t delta = sequence_number - cropped_last; 781ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (IsNewerSequenceNumber(sequence_number, cropped_last)) { 782ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander if (delta < 0) 783ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delta += (1 << 16); // Wrap forwards. 784ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } else if (delta > 0 && (last_seq_ + delta - (1 << 16)) >= 0) { 785ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // If sequence_number is older but delta is positive, this is a backwards 786ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // wrap-around. However, don't wrap backwards past 0 (unwrapped). 787ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander delta -= (1 << 16); 788ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 789ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 790ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return last_seq_ + delta; 791ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 792ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 793ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Only update the internal state to the specified last (unwrapped) sequence. 794ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander void UpdateLast(int64_t last_sequence) { last_seq_ = last_sequence; } 795ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 796ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander // Unwrap the sequence number and update the internal state. 797ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int64_t Unwrap(uint16_t sequence_number) { 798ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int64_t unwrapped = UnwrapWithoutUpdate(sequence_number); 799ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander UpdateLast(unwrapped); 800ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander return unwrapped; 801ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander } 802ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 803ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander private: 804ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander int64_t last_seq_; 805ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander}; 806ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 807ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander} // namespace webrtc 808ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander 809ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#endif // WEBRTC_MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ 810