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 androidx.annotation.Nullable;
14 import java.nio.ByteBuffer;
15 
16 public class NV21Buffer implements VideoFrame.Buffer {
17   private final byte[] data;
18   private final int width;
19   private final int height;
20   private final RefCountDelegate refCountDelegate;
21 
NV21Buffer(byte[] data, int width, int height, @Nullable Runnable releaseCallback)22   public NV21Buffer(byte[] data, int width, int height, @Nullable Runnable releaseCallback) {
23     this.data = data;
24     this.width = width;
25     this.height = height;
26     this.refCountDelegate = new RefCountDelegate(releaseCallback);
27   }
28 
29   @Override
getWidth()30   public int getWidth() {
31     return width;
32   }
33 
34   @Override
getHeight()35   public int getHeight() {
36     return height;
37   }
38 
39   @Override
toI420()40   public VideoFrame.I420Buffer toI420() {
41     // Cropping converts the frame to I420. Just crop and scale to the whole image.
42     return (VideoFrame.I420Buffer) cropAndScale(0 /* cropX */, 0 /* cropY */, width /* cropWidth */,
43         height /* cropHeight */, width /* scaleWidth */, height /* scaleHeight */);
44   }
45 
46   @Override
retain()47   public void retain() {
48     refCountDelegate.retain();
49   }
50 
51   @Override
release()52   public void release() {
53     refCountDelegate.release();
54   }
55 
56   @Override
cropAndScale( int cropX, int cropY, int cropWidth, int cropHeight, int scaleWidth, int scaleHeight)57   public VideoFrame.Buffer cropAndScale(
58       int cropX, int cropY, int cropWidth, int cropHeight, int scaleWidth, int scaleHeight) {
59     JavaI420Buffer newBuffer = JavaI420Buffer.allocate(scaleWidth, scaleHeight);
60     nativeCropAndScale(cropX, cropY, cropWidth, cropHeight, scaleWidth, scaleHeight, data, width,
61         height, newBuffer.getDataY(), newBuffer.getStrideY(), newBuffer.getDataU(),
62         newBuffer.getStrideU(), newBuffer.getDataV(), newBuffer.getStrideV());
63     return newBuffer;
64   }
65 
nativeCropAndScale(int cropX, int cropY, int cropWidth, int cropHeight, int scaleWidth, int scaleHeight, byte[] src, int srcWidth, int srcHeight, ByteBuffer dstY, int dstStrideY, ByteBuffer dstU, int dstStrideU, ByteBuffer dstV, int dstStrideV)66   private static native void nativeCropAndScale(int cropX, int cropY, int cropWidth, int cropHeight,
67       int scaleWidth, int scaleHeight, byte[] src, int srcWidth, int srcHeight, ByteBuffer dstY,
68       int dstStrideY, ByteBuffer dstU, int dstStrideU, ByteBuffer dstV, int dstStrideV);
69 }
70