1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
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 
11 #include "modules/video_coding/encoded_frame.h"
12 
13 #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 
21 namespace webrtc {
22 
VCMEncodedFrame()23 VCMEncodedFrame::VCMEncodedFrame()
24     : webrtc::EncodedImage(),
25       _renderTimeMs(-1),
26       _payloadType(0),
27       _missingFrame(false),
28       _codec(kVideoCodecGeneric) {
29   _codecSpecificInfo.codecType = kVideoCodecGeneric;
30 }
31 
32 VCMEncodedFrame::VCMEncodedFrame(const VCMEncodedFrame&) = default;
33 
~VCMEncodedFrame()34 VCMEncodedFrame::~VCMEncodedFrame() {
35   Reset();
36 }
37 
Reset()38 void VCMEncodedFrame::Reset() {
39   SetTimestamp(0);
40   SetSpatialIndex(absl::nullopt);
41   _renderTimeMs = -1;
42   _payloadType = 0;
43   _frameType = VideoFrameType::kVideoFrameDelta;
44   _encodedWidth = 0;
45   _encodedHeight = 0;
46   _missingFrame = false;
47   set_size(0);
48   _codecSpecificInfo.codecType = kVideoCodecGeneric;
49   _codec = kVideoCodecGeneric;
50   rotation_ = kVideoRotation_0;
51   content_type_ = VideoContentType::UNSPECIFIED;
52   timing_.flags = VideoSendTiming::kInvalid;
53 }
54 
CopyCodecSpecific(const RTPVideoHeader * header)55 void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header) {
56   if (header) {
57     switch (header->codec) {
58       case kVideoCodecVP8: {
59         const auto& vp8_header =
60             absl::get<RTPVideoHeaderVP8>(header->video_type_header);
61         if (_codecSpecificInfo.codecType != kVideoCodecVP8) {
62           // This is the first packet for this frame.
63           _codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0;
64           _codecSpecificInfo.codecSpecific.VP8.layerSync = false;
65           _codecSpecificInfo.codecSpecific.VP8.keyIdx = -1;
66           _codecSpecificInfo.codecType = kVideoCodecVP8;
67         }
68         _codecSpecificInfo.codecSpecific.VP8.nonReference =
69             vp8_header.nonReference;
70         if (vp8_header.temporalIdx != kNoTemporalIdx) {
71           _codecSpecificInfo.codecSpecific.VP8.temporalIdx =
72               vp8_header.temporalIdx;
73           _codecSpecificInfo.codecSpecific.VP8.layerSync = vp8_header.layerSync;
74         }
75         if (vp8_header.keyIdx != kNoKeyIdx) {
76           _codecSpecificInfo.codecSpecific.VP8.keyIdx = vp8_header.keyIdx;
77         }
78         break;
79       }
80       case kVideoCodecVP9: {
81         const auto& vp9_header =
82             absl::get<RTPVideoHeaderVP9>(header->video_type_header);
83         if (_codecSpecificInfo.codecType != kVideoCodecVP9) {
84           // This is the first packet for this frame.
85           _codecSpecificInfo.codecSpecific.VP9.temporal_idx = 0;
86           _codecSpecificInfo.codecSpecific.VP9.gof_idx = 0;
87           _codecSpecificInfo.codecSpecific.VP9.inter_layer_predicted = false;
88           _codecSpecificInfo.codecType = kVideoCodecVP9;
89         }
90         _codecSpecificInfo.codecSpecific.VP9.inter_pic_predicted =
91             vp9_header.inter_pic_predicted;
92         _codecSpecificInfo.codecSpecific.VP9.flexible_mode =
93             vp9_header.flexible_mode;
94         _codecSpecificInfo.codecSpecific.VP9.num_ref_pics =
95             vp9_header.num_ref_pics;
96         for (uint8_t r = 0; r < vp9_header.num_ref_pics; ++r) {
97           _codecSpecificInfo.codecSpecific.VP9.p_diff[r] =
98               vp9_header.pid_diff[r];
99         }
100         _codecSpecificInfo.codecSpecific.VP9.ss_data_available =
101             vp9_header.ss_data_available;
102         if (vp9_header.temporal_idx != kNoTemporalIdx) {
103           _codecSpecificInfo.codecSpecific.VP9.temporal_idx =
104               vp9_header.temporal_idx;
105           _codecSpecificInfo.codecSpecific.VP9.temporal_up_switch =
106               vp9_header.temporal_up_switch;
107         }
108         if (vp9_header.spatial_idx != kNoSpatialIdx) {
109           _codecSpecificInfo.codecSpecific.VP9.inter_layer_predicted =
110               vp9_header.inter_layer_predicted;
111           SetSpatialIndex(vp9_header.spatial_idx);
112         }
113         if (vp9_header.gof_idx != kNoGofIdx) {
114           _codecSpecificInfo.codecSpecific.VP9.gof_idx = vp9_header.gof_idx;
115         }
116         if (vp9_header.ss_data_available) {
117           _codecSpecificInfo.codecSpecific.VP9.num_spatial_layers =
118               vp9_header.num_spatial_layers;
119           _codecSpecificInfo.codecSpecific.VP9
120               .spatial_layer_resolution_present =
121               vp9_header.spatial_layer_resolution_present;
122           if (vp9_header.spatial_layer_resolution_present) {
123             for (size_t i = 0; i < vp9_header.num_spatial_layers; ++i) {
124               _codecSpecificInfo.codecSpecific.VP9.width[i] =
125                   vp9_header.width[i];
126               _codecSpecificInfo.codecSpecific.VP9.height[i] =
127                   vp9_header.height[i];
128             }
129           }
130           _codecSpecificInfo.codecSpecific.VP9.gof.CopyGofInfoVP9(
131               vp9_header.gof);
132         }
133         break;
134       }
135       case kVideoCodecH264: {
136         _codecSpecificInfo.codecType = kVideoCodecH264;
137         break;
138       }
139       default: {
140         _codecSpecificInfo.codecType = kVideoCodecGeneric;
141         break;
142       }
143     }
144   }
145 }
146 
147 }  // namespace webrtc
148