summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/video_coding/generic_decoder.h
blob: b1fb1f39f4e6c94ad974eba888a42a9941217dbc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef MODULES_VIDEO_CODING_GENERIC_DECODER_H_
#define MODULES_VIDEO_CODING_GENERIC_DECODER_H_

#include <cstdint>
#include <deque>
#include <string>
#include <utility>

#include "api/field_trials_view.h"
#include "api/sequence_checker.h"
#include "api/video/encoded_frame.h"
#include "api/video_codecs/video_decoder.h"
#include "modules/video_coding/encoded_frame.h"
#include "modules/video_coding/timing/timing.h"
#include "rtc_base/synchronization/mutex.h"

namespace webrtc {

class VCMReceiveCallback;

struct FrameInfo {
  FrameInfo() = default;
  FrameInfo(const FrameInfo&) = delete;
  FrameInfo& operator=(const FrameInfo&) = delete;
  FrameInfo(FrameInfo&&) = default;
  FrameInfo& operator=(FrameInfo&&) = default;

  uint32_t rtp_timestamp;
  // This is likely not optional, but some inputs seem to sometimes be negative.
  // TODO(bugs.webrtc.org/13756): See if this can be replaced with Timestamp
  // once all inputs to this field use Timestamp instead of an integer.
  absl::optional<Timestamp> render_time;
  absl::optional<Timestamp> decode_start;
  VideoRotation rotation;
  VideoContentType content_type;
  EncodedImage::Timing timing;
  int64_t ntp_time_ms;
  RtpPacketInfos packet_infos;
  // ColorSpace is not stored here, as it might be modified by decoders.
  VideoFrameType frame_type;
};

class VCMDecodedFrameCallback : public DecodedImageCallback {
 public:
  VCMDecodedFrameCallback(VCMTiming* timing,
                          Clock* clock,
                          const FieldTrialsView& field_trials);
  ~VCMDecodedFrameCallback() override;
  void SetUserReceiveCallback(VCMReceiveCallback* receiveCallback);
  VCMReceiveCallback* UserReceiveCallback();

  int32_t Decoded(VideoFrame& decodedImage) override;
  int32_t Decoded(VideoFrame& decodedImage, int64_t decode_time_ms) override;
  void Decoded(VideoFrame& decodedImage,
               absl::optional<int32_t> decode_time_ms,
               absl::optional<uint8_t> qp) override;

  void OnDecoderInfoChanged(const VideoDecoder::DecoderInfo& decoder_info);

  void Map(FrameInfo frameInfo);
  void ClearTimestampMap();

 private:
  std::pair<absl::optional<FrameInfo>, size_t> FindFrameInfo(
      uint32_t rtp_timestamp) RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_);

  SequenceChecker construction_thread_;
  Clock* const _clock;
  // This callback must be set before the decoder thread starts running
  // and must only be unset when external threads (e.g decoder thread)
  // have been stopped. Due to that, the variable should regarded as const
  // while there are more than one threads involved, it must be set
  // from the same thread, and therfore a lock is not required to access it.
  VCMReceiveCallback* _receiveCallback = nullptr;
  VCMTiming* _timing;
  Mutex lock_;
  std::deque<FrameInfo> frame_infos_ RTC_GUARDED_BY(lock_);
  int64_t ntp_offset_;
};

class VCMGenericDecoder {
 public:
  explicit VCMGenericDecoder(VideoDecoder* decoder);
  ~VCMGenericDecoder();

  /**
   * Initialize the decoder with the information from the `settings`
   */
  bool Configure(const VideoDecoder::Settings& settings);

  /**
   * Decode to a raw I420 frame,
   *
   * inputVideoBuffer reference to encoded video frame
   */
  // TODO(https://bugs.webrtc.org/9378): Remove VCMEncodedFrame variant
  // once the usage from code in deprecated/ is gone.
  int32_t Decode(const VCMEncodedFrame& inputFrame, Timestamp now);
  int32_t Decode(const EncodedFrame& inputFrame, Timestamp now);

  /**
   * Set decode callback. Deregistering while decoding is illegal.
   */
  int32_t RegisterDecodeCompleteCallback(VCMDecodedFrameCallback* callback);

  bool IsSameDecoder(VideoDecoder* decoder) const {
    return decoder_ == decoder;
  }

 private:
  int32_t Decode(const EncodedImage& frame,
                 Timestamp now,
                 int64_t render_time_ms);
  VCMDecodedFrameCallback* _callback = nullptr;
  VideoDecoder* const decoder_;
  VideoContentType _last_keyframe_content_type;
  VideoDecoder::DecoderInfo decoder_info_;
};

}  // namespace webrtc

#endif  // MODULES_VIDEO_CODING_GENERIC_DECODER_H_