rtp_receiver_video.cc revision ff761fba8274d93bd73e76c8b8a1f2d0776dd840
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 "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
12
13#include <assert.h>
14#include <string.h>
15
16#include "webrtc/base/checks.h"
17#include "webrtc/base/logging.h"
18#include "webrtc/base/trace_event.h"
19#include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h"
20#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
21#include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
22#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
23#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
24#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
25
26namespace webrtc {
27
28RTPReceiverStrategy* RTPReceiverStrategy::CreateVideoStrategy(
29    RtpData* data_callback) {
30  return new RTPReceiverVideo(data_callback);
31}
32
33RTPReceiverVideo::RTPReceiverVideo(RtpData* data_callback)
34    : RTPReceiverStrategy(data_callback) {
35}
36
37RTPReceiverVideo::~RTPReceiverVideo() {
38}
39
40bool RTPReceiverVideo::ShouldReportCsrcChanges(uint8_t payload_type) const {
41  // Always do this for video packets.
42  return true;
43}
44
45int32_t RTPReceiverVideo::OnNewPayloadTypeCreated(
46    const char payload_name[RTP_PAYLOAD_NAME_SIZE],
47    int8_t payload_type,
48    uint32_t frequency) {
49  return 0;
50}
51
52int32_t RTPReceiverVideo::ParseRtpPacket(WebRtcRTPHeader* rtp_header,
53                                         const PayloadUnion& specific_payload,
54                                         bool is_red,
55                                         const uint8_t* payload,
56                                         size_t payload_length,
57                                         int64_t timestamp_ms,
58                                         bool is_first_packet) {
59  TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Video::ParseRtp",
60               "seqnum", rtp_header->header.sequenceNumber, "timestamp",
61               rtp_header->header.timestamp);
62  rtp_header->type.Video.codec = specific_payload.Video.videoCodecType;
63
64  RTC_DCHECK_GE(payload_length, rtp_header->header.paddingLength);
65  const size_t payload_data_length =
66      payload_length - rtp_header->header.paddingLength;
67
68  if (payload == NULL || payload_data_length == 0) {
69    return data_callback_->OnReceivedPayloadData(NULL, 0, rtp_header) == 0 ? 0
70                                                                           : -1;
71  }
72
73  // We are not allowed to hold a critical section when calling below functions.
74  rtc::scoped_ptr<RtpDepacketizer> depacketizer(
75      RtpDepacketizer::Create(rtp_header->type.Video.codec));
76  if (depacketizer.get() == NULL) {
77    LOG(LS_ERROR) << "Failed to create depacketizer.";
78    return -1;
79  }
80
81  rtp_header->type.Video.isFirstPacket = is_first_packet;
82  RtpDepacketizer::ParsedPayload parsed_payload;
83  if (!depacketizer->Parse(&parsed_payload, payload, payload_data_length))
84    return -1;
85
86  rtp_header->frameType = parsed_payload.frame_type;
87  rtp_header->type = parsed_payload.type;
88  rtp_header->type.Video.rotation = kVideoRotation_0;
89
90  // Retrieve the video rotation information.
91  if (rtp_header->header.extension.hasVideoRotation) {
92    rtp_header->type.Video.rotation = ConvertCVOByteToVideoRotation(
93        rtp_header->header.extension.videoRotation);
94  }
95
96  return data_callback_->OnReceivedPayloadData(parsed_payload.payload,
97                                               parsed_payload.payload_length,
98                                               rtp_header) == 0
99             ? 0
100             : -1;
101}
102
103int RTPReceiverVideo::GetPayloadTypeFrequency() const {
104  return kVideoPayloadTypeFrequency;
105}
106
107RTPAliveType RTPReceiverVideo::ProcessDeadOrAlive(
108    uint16_t last_payload_length) const {
109  return kRtpDead;
110}
111
112int32_t RTPReceiverVideo::InvokeOnInitializeDecoder(
113    RtpFeedback* callback,
114    int8_t payload_type,
115    const char payload_name[RTP_PAYLOAD_NAME_SIZE],
116    const PayloadUnion& specific_payload) const {
117  // For video we just go with default values.
118  if (-1 ==
119      callback->OnInitializeDecoder(payload_type, payload_name,
120                                    kVideoPayloadTypeFrequency, 1, 0)) {
121    LOG(LS_ERROR) << "Failed to created decoder for payload type: "
122                  << static_cast<int>(payload_type);
123    return -1;
124  }
125  return 0;
126}
127
128}  // namespace webrtc
129