2020年8月10日 星期一

[Android]Camera debug for nv 21 and 12 format

 RAW pixels viewer(免安裝的網路資源) : https://rawpixels.net/

7yuv(需下載安裝於電腦中) : http://datahammer.de/



類似RGB的概念 : YUV也是三種色彩元素代稱, Y=明亮度, U=色度, V=濃度

YUV為視訊影像的編碼格式 目前專案僅用到N21與N12兩種格式的驗證應用

YUV文獻 : https://www.itread01.com/content/1542704886.html

N21與N12根據定義為YUV中 UV順序相反,

N21為Y填完再用UV交替填完,例 : YYYYVUVUVU

YUV格式中又分為YUV444,YUV422,YUV420 

     1.YUV 4:4:4取樣,每一個Y對應一組UV分量,一個YUV佔8+8+8 = 24bits 3個位元組。

     2.YUV 4:2:2取樣,每兩個Y共用一組UV分量,一個YUV佔8+4+4 = 16bits 2個位元組。

     3.YUV 4:2:0取樣,每四個Y共用一組UV分量,一個YUV佔8+2+2 = 12bits 1.5個位元組。

YUV420中又分為,YUV420SP與YUV420P


在camera相關案子得應用中有平台影響推流的問題待釐清,就順勢追了一下code

private final Timer timer = new Timer();

private final TimerTask tickTask = new TimerTask() {

public void run() {

VirtualCameraCapturer.this.tick();

}};

private void tick() {

// Log.d("CAM_AntiPushEngine", "VirtualCameraCapturer frame=" + frame + " buffersize=" + frame.getBuffer().getHeight());

capturerObserver.onFrameCaptured(frame);

}


其中frame由另一函式放張圖片來更新再透過tick作推送

try {

            Log.d(TAG, "VirtualCameraCapturer...1");

            inputStream = context.getAssets().open("clip_480x360_Format-0.yuv");

            int size = 480 * 360 * 3 / 2;

            byte[] data = new byte[size];

            inputStream.read(data, 0, size);

            Log.v("NV12","KH123");

            VideoFrame.Buffer frameBuffer = new NV12Buffer(480, 360, 480, 360, ByteBuffer.wrap(data), new Runnable() {

            //VideoFrame.Buffer frameBuffer = new NV21Buffer(data, 480, 360, new Runnable() {

                @Override

                public void run() {

                    Log.d("lhq", "NV21Buffer release");

                }

            });

            Log.v("NV12","KH456");

            long captureTimeNs = TimeUnit.MILLISECONDS.toNanos(SystemClock.elapsedRealtime());

            frame = new VideoFrame(frameBuffer, 0, captureTimeNs);

            Log.v(TAG, "VirtualCameraCapturer...2");

        } catch (IOException e) {

            e.printStackTrace();

        }


由上述程式碼可看到 應用程式新增一個timer tick去定期將camera擷取到的影像frame推送到onFrameCaptured裡面。


此時我們追到另一個code base使用Find in path看誰會去呼叫onFrameCaptured函式。

在webrtc中的Camera1Session.javad查詢到

 private void listenForTextureFrames() {

private void listenForBytebufferFrames() {

會使用到onFrameCaptured


在 listenForTextureFrames()中可在以下程式碼段前後擷取出raw data看其格式及圖片檢查是否正確

inal VideoFrame modifiedFrame = new VideoFrame(

          CameraSession.createTextureBufferWithModifiedTransformMatrix(

              (TextureBufferImpl) frame.getBuffer(),

              /* mirror= */ info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT,

              /* rotation= */ 0),

          /* rotation= */ getFrameOrientation(), frame.getTimestampNs());

      Log.v(TAG, "Modified frame");









沒有留言:

張貼留言