blob: 84c420c425c0eb3369853580a90bbec26cf63ad5 [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;
Niels Möller6fd67f02019-06-13 14:37:24 +020057 public final @Nullable Integer qp;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020058
Niels Möller67309ef2019-09-23 12:47:16 +020059 // TODO(bugs.webrtc.org/9378): Use retain and release from jni code.
60 @Override
61 public void retain() {
62 refCountDelegate.retain();
63 }
64
65 @Override
66 public void release() {
67 refCountDelegate.release();
68 }
69
Niels Möller7c2bed82019-10-01 14:02:58 +020070 @CalledByNative
Niels Möller82f33c52019-10-04 16:17:48 +020071 private EncodedImage(ByteBuffer buffer, @Nullable Runnable releaseCallback, int encodedWidth,
72 int encodedHeight, long captureTimeNs, FrameType frameType, int rotation,
philipel1b0d5432020-10-28 15:50:15 +010073 @Nullable Integer qp) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020074 this.buffer = buffer;
75 this.encodedWidth = encodedWidth;
76 this.encodedHeight = encodedHeight;
sakale172d892017-08-31 02:37:28 -070077 this.captureTimeMs = TimeUnit.NANOSECONDS.toMillis(captureTimeNs);
78 this.captureTimeNs = captureTimeNs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020079 this.frameType = frameType;
80 this.rotation = rotation;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020081 this.qp = qp;
Niels Möller67309ef2019-09-23 12:47:16 +020082 this.refCountDelegate = new RefCountDelegate(releaseCallback);
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020083 }
84
Niels Möller6fd67f02019-06-13 14:37:24 +020085 @CalledByNative
86 private ByteBuffer getBuffer() {
87 return buffer;
88 }
89
90 @CalledByNative
91 private int getEncodedWidth() {
92 return encodedWidth;
93 }
94
95 @CalledByNative
96 private int getEncodedHeight() {
97 return encodedHeight;
98 }
99
100 @CalledByNative
101 private long getCaptureTimeNs() {
102 return captureTimeNs;
103 }
104
105 @CalledByNative
106 private int getFrameType() {
107 return frameType.getNative();
108 }
109
110 @CalledByNative
111 private int getRotation() {
112 return rotation;
113 }
114
115 @CalledByNative
Niels Möller6fd67f02019-06-13 14:37:24 +0200116 private @Nullable Integer getQp() {
117 return qp;
118 }
119
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -0700120 public static Builder builder() {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200121 return new Builder();
122 }
123
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -0700124 public static class Builder {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200125 private ByteBuffer buffer;
Niels Möller67309ef2019-09-23 12:47:16 +0200126 private @Nullable Runnable releaseCallback;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200127 private int encodedWidth;
128 private int encodedHeight;
sakale172d892017-08-31 02:37:28 -0700129 private long captureTimeNs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200130 private EncodedImage.FrameType frameType;
131 private int rotation;
Niels Möller6fd67f02019-06-13 14:37:24 +0200132 private @Nullable Integer qp;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200133
134 private Builder() {}
135
Niels Möller67309ef2019-09-23 12:47:16 +0200136 public Builder setBuffer(ByteBuffer buffer, @Nullable Runnable releaseCallback) {
137 this.buffer = buffer;
138 this.releaseCallback = releaseCallback;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200139 return this;
140 }
141
142 public Builder setEncodedWidth(int encodedWidth) {
143 this.encodedWidth = encodedWidth;
144 return this;
145 }
146
147 public Builder setEncodedHeight(int encodedHeight) {
148 this.encodedHeight = encodedHeight;
149 return this;
150 }
151
sakale172d892017-08-31 02:37:28 -0700152 @Deprecated
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200153 public Builder setCaptureTimeMs(long captureTimeMs) {
sakale172d892017-08-31 02:37:28 -0700154 this.captureTimeNs = TimeUnit.MILLISECONDS.toNanos(captureTimeMs);
155 return this;
156 }
157
158 public Builder setCaptureTimeNs(long captureTimeNs) {
159 this.captureTimeNs = captureTimeNs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200160 return this;
161 }
162
163 public Builder setFrameType(EncodedImage.FrameType frameType) {
164 this.frameType = frameType;
165 return this;
166 }
167
168 public Builder setRotation(int rotation) {
169 this.rotation = rotation;
170 return this;
171 }
172
Niels Möller6fd67f02019-06-13 14:37:24 +0200173 public Builder setQp(@Nullable Integer qp) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200174 this.qp = qp;
175 return this;
176 }
177
178 public EncodedImage createEncodedImage() {
Niels Möller82f33c52019-10-04 16:17:48 +0200179 return new EncodedImage(buffer, releaseCallback, encodedWidth, encodedHeight, captureTimeNs,
philipel1b0d5432020-10-28 15:50:15 +0100180 frameType, rotation, qp);
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200181 }
182 }
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200183}