package com.gnhz.clinic.eitc_erm_app.sightGlass;

import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.util.Log;
import android.view.Surface;

import androidx.annotation.NonNull;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.ArrayBlockingQueue;

public class DecodeUtil {
    private static final String TAG = "czb";
    private MediaCodec mediaCodec;
    public Surface mSurfaceView;
    private MediaMuxer mMuxer;
    private int mVideoTrackIndex, mAudioTrackIndex;
    public static boolean recordMp4Flag = false;
    public static ArrayBlockingQueue<byte[]> arrayBlockingQueue = new ArrayBlockingQueue<>(30);

    public DecodeUtil(Surface mSurfaceView) {
        this.mSurfaceView = mSurfaceView;
    }

    public void StartCodec() {
        //===========================================
        String MIME_TYPE = "video/avc";
        try {
            mediaCodec = MediaCodec.createDecoderByType(MIME_TYPE);
        } catch (IOException e) {
            e.printStackTrace();
        }
        MediaFormat mediaFormat = MediaFormat.createVideoFormat(MIME_TYPE, 1280, 720);
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
        mediaCodec.setCallback(mCallBack);
        mediaCodec.configure(mediaFormat, mSurfaceView, null, 0);
        mediaCodec.start();
        Log.e(TAG, "StartCodec: **************************************************");
    }


    /**
     * @param filePath 需要保存的路径 record path
     * @param width    视频宽度    video width
     * @param height   视频高度   video height
     */
    public void initRecordMp4(String filePath, int width, int height) {
        try {
            mMuxer = new MediaMuxer(filePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
        } catch (IOException e) {
            e.printStackTrace();
        }
        MediaFormat videoMediaformat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, width, height);

        byte[] header_SPS_1080 = {0, 0, 0, 1, 103, 77, 0, 42, -99, -88, 30, 0, -119, -7, 102, -32, 32, 32, 32, 64};
        byte[] header_PPS_1080 = {0, 0, 0, 1, 104, -18, 60, -128};

        byte[] header_SPS_720 = {0, 0, 0, 1, 103, 66, 0, 31, -99, -88, 20, 1, 110, -101, -128, -128, -128, -127};
        byte[] header_PPS_720 = {0, 0, 0, 1, 104, -50, 60, -128};

        byte[] header_SPS_360 = {0, 0, 0, 1, 103, 77, 0, 30, -99, -88, 40, 11, -2, 89, -72, 8, 8, 8, 16};
        byte[] header_PPS_360 = {0, 0, 0, 1, 104, -18, 60, -128};

        if (width == 640 && height == 360) {
            videoMediaformat.setByteBuffer("csd-0", ByteBuffer.wrap(header_SPS_360));
            videoMediaformat.setByteBuffer("csd-1", ByteBuffer.wrap(header_PPS_360));//H264格式的视频需要添加
            videoMediaformat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);//视频数据格式
            videoMediaformat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 640 * 360);//缓冲区最大值
            videoMediaformat.setInteger(MediaFormat.KEY_CAPTURE_RATE, 20);//帧率
        } else if (width == 1280 && height == 720) {
            videoMediaformat.setByteBuffer("csd-0", ByteBuffer.wrap(header_SPS_720));
            videoMediaformat.setByteBuffer("csd-1", ByteBuffer.wrap(header_PPS_720));
            videoMediaformat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);
            videoMediaformat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1280 * 720);
            videoMediaformat.setInteger(MediaFormat.KEY_CAPTURE_RATE, 20);
        } else {
            videoMediaformat.setByteBuffer("csd-0", ByteBuffer.wrap(header_SPS_1080));
            videoMediaformat.setByteBuffer("csd-1", ByteBuffer.wrap(header_PPS_1080));
            videoMediaformat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);
            videoMediaformat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1920 * 1080);
            videoMediaformat.setInteger(MediaFormat.KEY_CAPTURE_RATE, 20);
        }
        videoMediaformat.setInteger(MediaFormat.KEY_BIT_RATE, width * height * 3);
        mVideoTrackIndex = mMuxer.addTrack(videoMediaformat);
        mMuxer.start();//开启合成器
        recordMp4Flag = true;
    }


    public void stopRecordMp4() {
        recordMp4Flag = false;
        try {
            mMuxer.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            mMuxer.release();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected long getPTSUs() {
      /*  long result = System.nanoTime() / 1000L;
        if (result < 0) {
            result = (-result) + result;
        }*/
        return System.nanoTime() / 1000L;
    }

    long timerCount = 0;
    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
    private final MediaCodec.Callback mCallBack = new MediaCodec.Callback() {
        @Override
        public void onInputBufferAvailable(@NonNull MediaCodec codec, int index) {
            byte[] bytes = arrayBlockingQueue.poll();
            if (bytes != null) {
                //  codec.getInputBuffer(index).put(bytes);
                ByteBuffer byteBuffer = codec.getInputBuffer(index);
                byteBuffer.put(bytes, 0, bytes.length);
                if (recordMp4Flag && (bytes.length > 0)) {
                    //  if (isFirstFrame) {
                    // Log.e(TAG, "onInputBufferAvailable: " + bytes[4]);
                    bufferInfo.offset = 0;
                    bufferInfo.size = bytes.length;  ///*naluIndex*/视频流数据的大小;
                    if ((bytes[4] & 0x1f) == 5) {
                        bufferInfo.flags = MediaCodec.BUFFER_FLAG_KEY_FRAME;//I帧
                    } else if ((bytes[4] & 0x1f) == 7 || (bytes[4] & 0x1f) == 8 || (bytes[4] & 0x1f) == 6) {
                        bufferInfo.flags = MediaCodec.BUFFER_FLAG_CODEC_CONFIG;//B,P帧
                    } else {
                        bufferInfo.flags = 0;//SEI
                    }
                    bufferInfo.presentationTimeUs = getPTSUs();
                    mMuxer.writeSampleData(mVideoTrackIndex, byteBuffer, bufferInfo);
                    // }
                }
                codec.queueInputBuffer(index, 0, bytes.length, timerCount++, 0);


            } else {
                codec.queueInputBuffer(index, 0, 0, timerCount++, 0);
            }
        }

        @Override
        public void onOutputBufferAvailable(@NonNull MediaCodec codec, int index, @NonNull MediaCodec.BufferInfo info) {
            codec.releaseOutputBuffer(index, true);
        }

        @Override
        public void onError(@NonNull MediaCodec codec, @NonNull MediaCodec.CodecException e) {

        }

        @Override
        public void onOutputFormatChanged(@NonNull MediaCodec codec, @NonNull MediaFormat format) {

        }
    };


    public void StopCodec() {
        //硬解码是调用c，需要释放掉内存

        //  mediaCodec.setCallback(null);
        try {
            if (mediaCodec != null) {
                mediaCodec.stop();
                Log.e(TAG, "stopShotCodec: stop");
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "StopCodec: 失败了！");
        }
        try {
            if (mediaCodec != null) {
                mediaCodec.release();
                Log.e(TAG, "stopShotCodec: release");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        mediaCodec = null;
    }
}
