blob: 5824231d1fce8f0a7ef6c92b2c3fca7b716de3e1 [file] [log] [blame]
Sami Kalliomäkie2410e92017-06-02 14:46:12 +02001/*
2 * Copyright 2017 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
11package org.webrtc;
12
Niels Möller6fd67f02019-06-13 14:37:24 +020013import android.support.annotation.Nullable;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020014import java.nio.ByteBuffer;
sakale172d892017-08-31 02:37:28 -070015import java.util.concurrent.TimeUnit;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020016
17/**
18 * An encoded frame from a video stream. Used as an input for decoders and as an output for
19 * encoders.
20 */
Niels Möller67309ef2019-09-23 12:47:16 +020021public class EncodedImage implements RefCounted {
sakal07a3bd72017-09-04 03:57:21 -070022 // Must be kept in sync with common_types.h FrameType.
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020023 public enum FrameType {
sakal07a3bd72017-09-04 03:57:21 -070024 EmptyFrame(0),
25 VideoFrameKey(3),
26 VideoFrameDelta(4);
27
28 private final int nativeIndex;
29
30 private FrameType(int nativeIndex) {
31 this.nativeIndex = nativeIndex;
32 }
33
34 public int getNative() {
35 return nativeIndex;
36 }
Magnus Jedvert4eb01882017-11-20 22:33:40 +010037
Magnus Jedvert4eb01882017-11-20 22:33:40 +010038 @CalledByNative("FrameType")
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +010039 static FrameType fromNativeIndex(int nativeIndex) {
Magnus Jedvert4eb01882017-11-20 22:33:40 +010040 for (FrameType type : FrameType.values()) {
41 if (type.getNative() == nativeIndex) {
42 return type;
43 }
44 }
45 throw new IllegalArgumentException("Unknown native frame type: " + nativeIndex);
46 }
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020047 }
48
Niels Möller67309ef2019-09-23 12:47:16 +020049 private final RefCountDelegate refCountDelegate;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020050 public final ByteBuffer buffer;
51 public final int encodedWidth;
52 public final int encodedHeight;
sakale172d892017-08-31 02:37:28 -070053 public final long captureTimeMs; // Deprecated
54 public final long captureTimeNs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020055 public final FrameType frameType;
56 public final int rotation;
philipel1b0d5432020-10-28 15:50:15 +010057 // TODO(philipel): Remove when downstream has been updated.
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020058 public final boolean completeFrame;
Niels Möller6fd67f02019-06-13 14:37:24 +020059 public final @Nullable Integer qp;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020060
Niels Möller67309ef2019-09-23 12:47:16 +020061 // TODO(bugs.webrtc.org/9378): Use retain and release from jni code.
62 @Override
63 public void retain() {
64 refCountDelegate.retain();
65 }
66
67 @Override
68 public void release() {
69 refCountDelegate.release();
70 }
71
Niels Möller7c2bed82019-10-01 14:02:58 +020072 @CalledByNative
Niels Möller82f33c52019-10-04 16:17:48 +020073 private EncodedImage(ByteBuffer buffer, @Nullable Runnable releaseCallback, int encodedWidth,
74 int encodedHeight, long captureTimeNs, FrameType frameType, int rotation,
philipel1b0d5432020-10-28 15:50:15 +010075 @Nullable Integer qp) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020076 this.buffer = buffer;
77 this.encodedWidth = encodedWidth;
78 this.encodedHeight = encodedHeight;
sakale172d892017-08-31 02:37:28 -070079 this.captureTimeMs = TimeUnit.NANOSECONDS.toMillis(captureTimeNs);
80 this.captureTimeNs = captureTimeNs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020081 this.frameType = frameType;
82 this.rotation = rotation;
philipel1b0d5432020-10-28 15:50:15 +010083 this.completeFrame = true;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020084 this.qp = qp;
Niels Möller67309ef2019-09-23 12:47:16 +020085 this.refCountDelegate = new RefCountDelegate(releaseCallback);
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020086 }
87
Niels Möller6fd67f02019-06-13 14:37:24 +020088 @CalledByNative
89 private ByteBuffer getBuffer() {
90 return buffer;
91 }
92
93 @CalledByNative
94 private int getEncodedWidth() {
95 return encodedWidth;
96 }
97
98 @CalledByNative
99 private int getEncodedHeight() {
100 return encodedHeight;
101 }
102
103 @CalledByNative
104 private long getCaptureTimeNs() {
105 return captureTimeNs;
106 }
107
108 @CalledByNative
109 private int getFrameType() {
110 return frameType.getNative();
111 }
112
113 @CalledByNative
114 private int getRotation() {
115 return rotation;
116 }
117
118 @CalledByNative
Niels Möller6fd67f02019-06-13 14:37:24 +0200119 private @Nullable Integer getQp() {
120 return qp;
121 }
122
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -0700123 public static Builder builder() {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200124 return new Builder();
125 }
126
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -0700127 public static class Builder {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200128 private ByteBuffer buffer;
Niels Möller67309ef2019-09-23 12:47:16 +0200129 private @Nullable Runnable releaseCallback;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200130 private int encodedWidth;
131 private int encodedHeight;
sakale172d892017-08-31 02:37:28 -0700132 private long captureTimeNs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200133 private EncodedImage.FrameType frameType;
134 private int rotation;
Niels Möller6fd67f02019-06-13 14:37:24 +0200135 private @Nullable Integer qp;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200136
137 private Builder() {}
138
Niels Möller67309ef2019-09-23 12:47:16 +0200139 public Builder setBuffer(ByteBuffer buffer, @Nullable Runnable releaseCallback) {
140 this.buffer = buffer;
141 this.releaseCallback = releaseCallback;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200142 return this;
143 }
144
145 public Builder setEncodedWidth(int encodedWidth) {
146 this.encodedWidth = encodedWidth;
147 return this;
148 }
149
150 public Builder setEncodedHeight(int encodedHeight) {
151 this.encodedHeight = encodedHeight;
152 return this;
153 }
154
sakale172d892017-08-31 02:37:28 -0700155 @Deprecated
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200156 public Builder setCaptureTimeMs(long captureTimeMs) {
sakale172d892017-08-31 02:37:28 -0700157 this.captureTimeNs = TimeUnit.MILLISECONDS.toNanos(captureTimeMs);
158 return this;
159 }
160
161 public Builder setCaptureTimeNs(long captureTimeNs) {
162 this.captureTimeNs = captureTimeNs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200163 return this;
164 }
165
166 public Builder setFrameType(EncodedImage.FrameType frameType) {
167 this.frameType = frameType;
168 return this;
169 }
170
171 public Builder setRotation(int rotation) {
172 this.rotation = rotation;
173 return this;
174 }
175
philipel1b0d5432020-10-28 15:50:15 +0100176 // TODO(philipel): Remove when downstream has been updated.
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200177 public Builder setCompleteFrame(boolean completeFrame) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200178 return this;
179 }
180
Niels Möller6fd67f02019-06-13 14:37:24 +0200181 public Builder setQp(@Nullable Integer qp) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200182 this.qp = qp;
183 return this;
184 }
185
186 public EncodedImage createEncodedImage() {
Niels Möller82f33c52019-10-04 16:17:48 +0200187 return new EncodedImage(buffer, releaseCallback, encodedWidth, encodedHeight, captureTimeNs,
philipel1b0d5432020-10-28 15:50:15 +0100188 frameType, rotation, qp);
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200189 }
190 }
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200191}