blob: c7a74904c884fef40af263cf048c40561f7ec320 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgddab60b2012-04-23 14:52:15 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/video_coding/encoded_frame.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <string.h>
14
15#include "absl/types/variant.h"
16#include "api/video/video_timing.h"
17#include "modules/video_coding/codecs/interface/common_constants.h"
18#include "modules/video_coding/codecs/vp8/include/vp8_globals.h"
19#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
20
niklase@google.com470e71d2011-07-07 08:21:25 +000021namespace webrtc {
22
23VCMEncodedFrame::VCMEncodedFrame()
guoweis@webrtc.org54d072e2015-03-17 21:54:50 +000024 : webrtc::EncodedImage(),
25 _renderTimeMs(-1),
26 _payloadType(0),
27 _missingFrame(false),
Kári Tristan Helgason84ccb2d2018-08-16 14:35:26 +020028 _codec(kVideoCodecGeneric),
guoweis@webrtc.org54d072e2015-03-17 21:54:50 +000029 _rotation_set(false) {
Kári Tristan Helgason84ccb2d2018-08-16 14:35:26 +020030 _codecSpecificInfo.codecType = kVideoCodecGeneric;
niklase@google.com470e71d2011-07-07 08:21:25 +000031}
32
philipel6c42d922019-06-20 11:13:03 +020033VCMEncodedFrame::VCMEncodedFrame(const VCMEncodedFrame&) = default;
34
philipel9d3ab612015-12-21 04:12:39 -080035VCMEncodedFrame::~VCMEncodedFrame() {
philipel9d3ab612015-12-21 04:12:39 -080036 Reset();
niklase@google.com470e71d2011-07-07 08:21:25 +000037}
38
philipel9d3ab612015-12-21 04:12:39 -080039void VCMEncodedFrame::Reset() {
Niels Möller23775882018-08-16 10:24:12 +020040 SetTimestamp(0);
Sergey Silkin61832dd2018-12-20 14:32:14 +010041 SetSpatialIndex(absl::nullopt);
philipel9d3ab612015-12-21 04:12:39 -080042 _renderTimeMs = -1;
philipel9d3ab612015-12-21 04:12:39 -080043 _payloadType = 0;
Niels Möller8f7ce222019-03-21 15:43:58 +010044 _frameType = VideoFrameType::kVideoFrameDelta;
philipel9d3ab612015-12-21 04:12:39 -080045 _encodedWidth = 0;
46 _encodedHeight = 0;
47 _completeFrame = false;
48 _missingFrame = false;
Niels Möller77536a22019-01-15 08:50:01 +010049 set_size(0);
Kári Tristan Helgason84ccb2d2018-08-16 14:35:26 +020050 _codecSpecificInfo.codecType = kVideoCodecGeneric;
51 _codec = kVideoCodecGeneric;
perkj414dda12016-07-04 01:45:23 -070052 rotation_ = kVideoRotation_0;
ilnik00d802b2017-04-11 10:34:31 -070053 content_type_ = VideoContentType::UNSPECIFIED;
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +020054 timing_.flags = VideoSendTiming::kInvalid;
philipel9d3ab612015-12-21 04:12:39 -080055 _rotation_set = false;
niklase@google.com470e71d2011-07-07 08:21:25 +000056}
57
philipel9d3ab612015-12-21 04:12:39 -080058void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header) {
stefan@webrtc.org2ec56062014-07-31 14:59:24 +000059 if (header) {
60 switch (header->codec) {
Niels Möller520ca4e2018-06-04 11:14:38 +020061 case kVideoCodecVP8: {
Philip Eliassond52a1a62018-09-07 13:03:55 +000062 const auto& vp8_header =
63 absl::get<RTPVideoHeaderVP8>(header->video_type_header);
stefan@webrtc.org2ec56062014-07-31 14:59:24 +000064 if (_codecSpecificInfo.codecType != kVideoCodecVP8) {
65 // This is the first packet for this frame.
stefan@webrtc.org2ec56062014-07-31 14:59:24 +000066 _codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0;
67 _codecSpecificInfo.codecSpecific.VP8.layerSync = false;
68 _codecSpecificInfo.codecSpecific.VP8.keyIdx = -1;
69 _codecSpecificInfo.codecType = kVideoCodecVP8;
henrik.lundin@webrtc.org473bac82011-08-17 09:47:33 +000070 }
stefan@webrtc.org2ec56062014-07-31 14:59:24 +000071 _codecSpecificInfo.codecSpecific.VP8.nonReference =
Philip Eliassond52a1a62018-09-07 13:03:55 +000072 vp8_header.nonReference;
73 if (vp8_header.temporalIdx != kNoTemporalIdx) {
stefan@webrtc.org2ec56062014-07-31 14:59:24 +000074 _codecSpecificInfo.codecSpecific.VP8.temporalIdx =
Philip Eliassond52a1a62018-09-07 13:03:55 +000075 vp8_header.temporalIdx;
76 _codecSpecificInfo.codecSpecific.VP8.layerSync = vp8_header.layerSync;
stefan@webrtc.org2ec56062014-07-31 14:59:24 +000077 }
Philip Eliassond52a1a62018-09-07 13:03:55 +000078 if (vp8_header.keyIdx != kNoKeyIdx) {
79 _codecSpecificInfo.codecSpecific.VP8.keyIdx = vp8_header.keyIdx;
stefan@webrtc.org2ec56062014-07-31 14:59:24 +000080 }
81 break;
82 }
Niels Möller520ca4e2018-06-04 11:14:38 +020083 case kVideoCodecVP9: {
philipel29d88462018-08-08 14:26:00 +020084 const auto& vp9_header =
85 absl::get<RTPVideoHeaderVP9>(header->video_type_header);
asaperssona9455ab2015-07-31 06:10:09 -070086 if (_codecSpecificInfo.codecType != kVideoCodecVP9) {
87 // This is the first packet for this frame.
asaperssona9455ab2015-07-31 06:10:09 -070088 _codecSpecificInfo.codecSpecific.VP9.temporal_idx = 0;
asaperssona9455ab2015-07-31 06:10:09 -070089 _codecSpecificInfo.codecSpecific.VP9.gof_idx = 0;
90 _codecSpecificInfo.codecSpecific.VP9.inter_layer_predicted = false;
asaperssona9455ab2015-07-31 06:10:09 -070091 _codecSpecificInfo.codecType = kVideoCodecVP9;
92 }
93 _codecSpecificInfo.codecSpecific.VP9.inter_pic_predicted =
philipel29d88462018-08-08 14:26:00 +020094 vp9_header.inter_pic_predicted;
asaperssona9455ab2015-07-31 06:10:09 -070095 _codecSpecificInfo.codecSpecific.VP9.flexible_mode =
philipel29d88462018-08-08 14:26:00 +020096 vp9_header.flexible_mode;
philipelcfc319b2015-11-10 07:17:23 -080097 _codecSpecificInfo.codecSpecific.VP9.num_ref_pics =
philipel29d88462018-08-08 14:26:00 +020098 vp9_header.num_ref_pics;
99 for (uint8_t r = 0; r < vp9_header.num_ref_pics; ++r) {
philipelcfc319b2015-11-10 07:17:23 -0800100 _codecSpecificInfo.codecSpecific.VP9.p_diff[r] =
philipel29d88462018-08-08 14:26:00 +0200101 vp9_header.pid_diff[r];
philipelcfc319b2015-11-10 07:17:23 -0800102 }
asaperssona9455ab2015-07-31 06:10:09 -0700103 _codecSpecificInfo.codecSpecific.VP9.ss_data_available =
philipel29d88462018-08-08 14:26:00 +0200104 vp9_header.ss_data_available;
105 if (vp9_header.temporal_idx != kNoTemporalIdx) {
asaperssona9455ab2015-07-31 06:10:09 -0700106 _codecSpecificInfo.codecSpecific.VP9.temporal_idx =
philipel29d88462018-08-08 14:26:00 +0200107 vp9_header.temporal_idx;
asaperssona9455ab2015-07-31 06:10:09 -0700108 _codecSpecificInfo.codecSpecific.VP9.temporal_up_switch =
philipel29d88462018-08-08 14:26:00 +0200109 vp9_header.temporal_up_switch;
asaperssona9455ab2015-07-31 06:10:09 -0700110 }
philipel29d88462018-08-08 14:26:00 +0200111 if (vp9_header.spatial_idx != kNoSpatialIdx) {
asaperssona9455ab2015-07-31 06:10:09 -0700112 _codecSpecificInfo.codecSpecific.VP9.inter_layer_predicted =
philipel29d88462018-08-08 14:26:00 +0200113 vp9_header.inter_layer_predicted;
Sergey Silkin61832dd2018-12-20 14:32:14 +0100114 SetSpatialIndex(vp9_header.spatial_idx);
asaperssona9455ab2015-07-31 06:10:09 -0700115 }
philipel29d88462018-08-08 14:26:00 +0200116 if (vp9_header.gof_idx != kNoGofIdx) {
117 _codecSpecificInfo.codecSpecific.VP9.gof_idx = vp9_header.gof_idx;
asaperssona9455ab2015-07-31 06:10:09 -0700118 }
philipel29d88462018-08-08 14:26:00 +0200119 if (vp9_header.ss_data_available) {
asaperssona9455ab2015-07-31 06:10:09 -0700120 _codecSpecificInfo.codecSpecific.VP9.num_spatial_layers =
philipel29d88462018-08-08 14:26:00 +0200121 vp9_header.num_spatial_layers;
asaperssona9455ab2015-07-31 06:10:09 -0700122 _codecSpecificInfo.codecSpecific.VP9
123 .spatial_layer_resolution_present =
philipel29d88462018-08-08 14:26:00 +0200124 vp9_header.spatial_layer_resolution_present;
125 if (vp9_header.spatial_layer_resolution_present) {
126 for (size_t i = 0; i < vp9_header.num_spatial_layers; ++i) {
asaperssona9455ab2015-07-31 06:10:09 -0700127 _codecSpecificInfo.codecSpecific.VP9.width[i] =
philipel29d88462018-08-08 14:26:00 +0200128 vp9_header.width[i];
asaperssona9455ab2015-07-31 06:10:09 -0700129 _codecSpecificInfo.codecSpecific.VP9.height[i] =
philipel29d88462018-08-08 14:26:00 +0200130 vp9_header.height[i];
asaperssona9455ab2015-07-31 06:10:09 -0700131 }
132 }
133 _codecSpecificInfo.codecSpecific.VP9.gof.CopyGofInfoVP9(
philipel29d88462018-08-08 14:26:00 +0200134 vp9_header.gof);
asaperssona9455ab2015-07-31 06:10:09 -0700135 }
136 break;
137 }
Niels Möller520ca4e2018-06-04 11:14:38 +0200138 case kVideoCodecH264: {
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000139 _codecSpecificInfo.codecType = kVideoCodecH264;
Johnny Lee1a1c52b2019-02-08 14:25:40 -0500140
141 // The following H264 codec specific data are not used elsewhere.
142 // Instead they are read directly from the frame marking extension.
143 // These codec specific data structures should be removed
144 // when frame marking is used.
145 _codecSpecificInfo.codecSpecific.H264.temporal_idx = kNoTemporalIdx;
146 if (header->frame_marking.temporal_id != kNoTemporalIdx) {
147 _codecSpecificInfo.codecSpecific.H264.temporal_idx =
148 header->frame_marking.temporal_id;
149 _codecSpecificInfo.codecSpecific.H264.base_layer_sync =
150 header->frame_marking.base_layer_sync;
151 _codecSpecificInfo.codecSpecific.H264.idr_frame =
152 header->frame_marking.independent_frame;
153 }
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000154 break;
155 }
Niels Möller520ca4e2018-06-04 11:14:38 +0200156 default: {
Kári Tristan Helgason84ccb2d2018-08-16 14:35:26 +0200157 _codecSpecificInfo.codecType = kVideoCodecGeneric;
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000158 break;
159 }
henrik.lundin@webrtc.org473bac82011-08-17 09:47:33 +0000160 }
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000161 }
henrik.lundin@webrtc.org473bac82011-08-17 09:47:33 +0000162}
163
philipel9d3ab612015-12-21 04:12:39 -0800164void VCMEncodedFrame::VerifyAndAllocate(size_t minimumSize) {
Niels Möller48a79462018-12-07 16:21:18 +0100165 size_t old_capacity = capacity();
166 if (minimumSize > old_capacity) {
Niels Möller4d504c72019-06-18 15:56:56 +0200167 // TODO(nisse): EncodedImage::Allocate is implemented as a realloc
168 // operation, and is deprecated. Refactor to use EncodedImageBuffer::Realloc
169 // instead.
Niels Möller938dd9f2019-02-07 00:02:17 +0100170 Allocate(minimumSize);
philipel9d3ab612015-12-21 04:12:39 -0800171 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000172}
173
pbos22993e12015-10-19 02:39:06 -0700174} // namespace webrtc