blob: b50136c3739bfd04f9e229dff439f76558b37f1b [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;
57 public final boolean completeFrame;
Niels Möller6fd67f02019-06-13 14:37:24 +020058 public final @Nullable Integer qp;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020059
Niels Möller67309ef2019-09-23 12:47:16 +020060 // TODO(bugs.webrtc.org/9378): Use retain and release from jni code.
61 @Override
62 public void retain() {
63 refCountDelegate.retain();
64 }
65
66 @Override
67 public void release() {
68 refCountDelegate.release();
69 }
70
Niels Möller7c2bed82019-10-01 14:02:58 +020071 @CalledByNative
Niels Möller82f33c52019-10-04 16:17:48 +020072 private EncodedImage(ByteBuffer buffer, @Nullable Runnable releaseCallback, int encodedWidth,
73 int encodedHeight, long captureTimeNs, FrameType frameType, int rotation,
74 boolean completeFrame, @Nullable Integer qp) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020075 this.buffer = buffer;
76 this.encodedWidth = encodedWidth;
77 this.encodedHeight = encodedHeight;
sakale172d892017-08-31 02:37:28 -070078 this.captureTimeMs = TimeUnit.NANOSECONDS.toMillis(captureTimeNs);
79 this.captureTimeNs = captureTimeNs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020080 this.frameType = frameType;
81 this.rotation = rotation;
82 this.completeFrame = completeFrame;
83 this.qp = qp;
Niels Möller67309ef2019-09-23 12:47:16 +020084 this.refCountDelegate = new RefCountDelegate(releaseCallback);
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020085 }
86
Niels Möller6fd67f02019-06-13 14:37:24 +020087 @CalledByNative
88 private ByteBuffer getBuffer() {
89 return buffer;
90 }
91
92 @CalledByNative
93 private int getEncodedWidth() {
94 return encodedWidth;
95 }
96
97 @CalledByNative
98 private int getEncodedHeight() {
99 return encodedHeight;
100 }
101
102 @CalledByNative
103 private long getCaptureTimeNs() {
104 return captureTimeNs;
105 }
106
107 @CalledByNative
108 private int getFrameType() {
109 return frameType.getNative();
110 }
111
112 @CalledByNative
113 private int getRotation() {
114 return rotation;
115 }
116
117 @CalledByNative
118 private boolean getCompleteFrame() {
119 return completeFrame;
120 }
121
122 @CalledByNative
123 private @Nullable Integer getQp() {
124 return qp;
125 }
126
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -0700127 public static Builder builder() {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200128 return new Builder();
129 }
130
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -0700131 public static class Builder {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200132 private ByteBuffer buffer;
Niels Möller67309ef2019-09-23 12:47:16 +0200133 private @Nullable Runnable releaseCallback;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200134 private int encodedWidth;
135 private int encodedHeight;
sakale172d892017-08-31 02:37:28 -0700136 private long captureTimeNs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200137 private EncodedImage.FrameType frameType;
138 private int rotation;
139 private boolean completeFrame;
Niels Möller6fd67f02019-06-13 14:37:24 +0200140 private @Nullable Integer qp;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200141
142 private Builder() {}
143
Niels Möller67309ef2019-09-23 12:47:16 +0200144 public Builder setBuffer(ByteBuffer buffer, @Nullable Runnable releaseCallback) {
145 this.buffer = buffer;
146 this.releaseCallback = releaseCallback;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200147 return this;
148 }
149
150 public Builder setEncodedWidth(int encodedWidth) {
151 this.encodedWidth = encodedWidth;
152 return this;
153 }
154
155 public Builder setEncodedHeight(int encodedHeight) {
156 this.encodedHeight = encodedHeight;
157 return this;
158 }
159
sakale172d892017-08-31 02:37:28 -0700160 @Deprecated
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200161 public Builder setCaptureTimeMs(long captureTimeMs) {
sakale172d892017-08-31 02:37:28 -0700162 this.captureTimeNs = TimeUnit.MILLISECONDS.toNanos(captureTimeMs);
163 return this;
164 }
165
166 public Builder setCaptureTimeNs(long captureTimeNs) {
167 this.captureTimeNs = captureTimeNs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200168 return this;
169 }
170
171 public Builder setFrameType(EncodedImage.FrameType frameType) {
172 this.frameType = frameType;
173 return this;
174 }
175
176 public Builder setRotation(int rotation) {
177 this.rotation = rotation;
178 return this;
179 }
180
181 public Builder setCompleteFrame(boolean completeFrame) {
182 this.completeFrame = completeFrame;
183 return this;
184 }
185
Niels Möller6fd67f02019-06-13 14:37:24 +0200186 public Builder setQp(@Nullable Integer qp) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200187 this.qp = qp;
188 return this;
189 }
190
191 public EncodedImage createEncodedImage() {
Niels Möller82f33c52019-10-04 16:17:48 +0200192 return new EncodedImage(buffer, releaseCallback, encodedWidth, encodedHeight, captureTimeNs,
193 frameType, rotation, completeFrame, qp);
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200194 }
195 }
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200196}