1 /*
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 
11 package org.webrtc;
12 
13 import android.support.annotation.Nullable;
14 import java.nio.ByteBuffer;
15 import java.util.concurrent.TimeUnit;
16 
17 /**
18  * An encoded frame from a video stream. Used as an input for decoders and as an output for
19  * encoders.
20  */
21 public class EncodedImage implements RefCounted {
22   // Must be kept in sync with common_types.h FrameType.
23   public enum FrameType {
24     EmptyFrame(0),
25     VideoFrameKey(3),
26     VideoFrameDelta(4);
27 
28     private final int nativeIndex;
29 
FrameType(int nativeIndex)30     private FrameType(int nativeIndex) {
31       this.nativeIndex = nativeIndex;
32     }
33 
getNative()34     public int getNative() {
35       return nativeIndex;
36     }
37 
38     @CalledByNative("FrameType")
fromNativeIndex(int nativeIndex)39     static FrameType fromNativeIndex(int nativeIndex) {
40       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     }
47   }
48 
49   private final RefCountDelegate refCountDelegate;
50   public final ByteBuffer buffer;
51   public final int encodedWidth;
52   public final int encodedHeight;
53   public final long captureTimeMs; // Deprecated
54   public final long captureTimeNs;
55   public final FrameType frameType;
56   public final int rotation;
57   public final boolean completeFrame;
58   public final @Nullable Integer qp;
59 
60   // TODO(bugs.webrtc.org/9378): Use retain and release from jni code.
61   @Override
retain()62   public void retain() {
63     refCountDelegate.retain();
64   }
65 
66   @Override
release()67   public void release() {
68     refCountDelegate.release();
69   }
70 
71   @CalledByNative
EncodedImage(ByteBuffer buffer, @Nullable Runnable releaseCallback, int encodedWidth, int encodedHeight, long captureTimeNs, FrameType frameType, int rotation, boolean completeFrame, @Nullable Integer qp)72   private EncodedImage(ByteBuffer buffer, @Nullable Runnable releaseCallback, int encodedWidth,
73       int encodedHeight, long captureTimeNs, FrameType frameType, int rotation,
74       boolean completeFrame, @Nullable Integer qp) {
75     this.buffer = buffer;
76     this.encodedWidth = encodedWidth;
77     this.encodedHeight = encodedHeight;
78     this.captureTimeMs = TimeUnit.NANOSECONDS.toMillis(captureTimeNs);
79     this.captureTimeNs = captureTimeNs;
80     this.frameType = frameType;
81     this.rotation = rotation;
82     this.completeFrame = completeFrame;
83     this.qp = qp;
84     this.refCountDelegate = new RefCountDelegate(releaseCallback);
85   }
86 
87   @CalledByNative
getBuffer()88   private ByteBuffer getBuffer() {
89     return buffer;
90   }
91 
92   @CalledByNative
getEncodedWidth()93   private int getEncodedWidth() {
94     return encodedWidth;
95   }
96 
97   @CalledByNative
getEncodedHeight()98   private int getEncodedHeight() {
99     return encodedHeight;
100   }
101 
102   @CalledByNative
getCaptureTimeNs()103   private long getCaptureTimeNs() {
104     return captureTimeNs;
105   }
106 
107   @CalledByNative
getFrameType()108   private int getFrameType() {
109     return frameType.getNative();
110   }
111 
112   @CalledByNative
getRotation()113   private int getRotation() {
114     return rotation;
115   }
116 
117   @CalledByNative
getCompleteFrame()118   private boolean getCompleteFrame() {
119     return completeFrame;
120   }
121 
122   @CalledByNative
getQp()123   private @Nullable Integer getQp() {
124     return qp;
125   }
126 
builder()127   public static Builder builder() {
128     return new Builder();
129   }
130 
131   public static class Builder {
132     private ByteBuffer buffer;
133     private @Nullable Runnable releaseCallback;
134     private int encodedWidth;
135     private int encodedHeight;
136     private long captureTimeNs;
137     private EncodedImage.FrameType frameType;
138     private int rotation;
139     private boolean completeFrame;
140     private @Nullable Integer qp;
141 
Builder()142     private Builder() {}
143 
setBuffer(ByteBuffer buffer, @Nullable Runnable releaseCallback)144     public Builder setBuffer(ByteBuffer buffer, @Nullable Runnable releaseCallback) {
145       this.buffer = buffer;
146       this.releaseCallback = releaseCallback;
147       return this;
148     }
149 
setEncodedWidth(int encodedWidth)150     public Builder setEncodedWidth(int encodedWidth) {
151       this.encodedWidth = encodedWidth;
152       return this;
153     }
154 
setEncodedHeight(int encodedHeight)155     public Builder setEncodedHeight(int encodedHeight) {
156       this.encodedHeight = encodedHeight;
157       return this;
158     }
159 
160     @Deprecated
setCaptureTimeMs(long captureTimeMs)161     public Builder setCaptureTimeMs(long captureTimeMs) {
162       this.captureTimeNs = TimeUnit.MILLISECONDS.toNanos(captureTimeMs);
163       return this;
164     }
165 
setCaptureTimeNs(long captureTimeNs)166     public Builder setCaptureTimeNs(long captureTimeNs) {
167       this.captureTimeNs = captureTimeNs;
168       return this;
169     }
170 
setFrameType(EncodedImage.FrameType frameType)171     public Builder setFrameType(EncodedImage.FrameType frameType) {
172       this.frameType = frameType;
173       return this;
174     }
175 
setRotation(int rotation)176     public Builder setRotation(int rotation) {
177       this.rotation = rotation;
178       return this;
179     }
180 
setCompleteFrame(boolean completeFrame)181     public Builder setCompleteFrame(boolean completeFrame) {
182       this.completeFrame = completeFrame;
183       return this;
184     }
185 
setQp(@ullable Integer qp)186     public Builder setQp(@Nullable Integer qp) {
187       this.qp = qp;
188       return this;
189     }
190 
createEncodedImage()191     public EncodedImage createEncodedImage() {
192       return new EncodedImage(buffer, releaseCallback, encodedWidth, encodedHeight, captureTimeNs,
193           frameType, rotation, completeFrame, qp);
194     }
195   }
196 }
197