Записанное видео подлагивает (FFMPEG)

208
12 декабря 2017, 19:27

Исходник взят отсюда.

Инициализирую так:

private void initRecorder() {
        Log.i(LOG_TAG, "init mFrameRecorder");
        String recordedTime = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
                .format(new Date());
        mVideo = CameraHelper.getOutputMediaFile(recordedTime, CameraHelper.MEDIA_TYPE_VIDEO);
        Log.i(LOG_TAG, "Output Video: " + mVideo);
        mFrameRecorder = new FFmpegFrameRecorder(mVideo, videoWidth, videoHeight, 1);
        mFrameRecorder.setFormat("mp4");
        mFrameRecorder.setSampleRate(sampleAudioRateInHz);
        mFrameRecorder.setFrameRate(frameRate);
        // Use H264
        mFrameRecorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        mFrameRecorder.setVideoQuality(2);
        mFrameRecorder.setVideoOption("crf", "20");
        mFrameRecorder.setVideoOption("preset", "superfast");
        mFrameRecorder.setVideoOption("tune", "zerolatency");
        Log.i(LOG_TAG, "mFrameRecorder initialize success");
    }

где frameRate = 60;

А тут уже запись видео:

class VideoRecordThread extends RunningThread {
        @Override
        public void run() {
            List<String> filters = new ArrayList<>();
            // Transpose
            String transpose = null;
            android.hardware.Camera.CameraInfo info =
                    new android.hardware.Camera.CameraInfo();
            android.hardware.Camera.getCameraInfo(mCameraId, info);
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                switch (info.orientation) {
                    case 270:
//                        transpose = "transpose=clock_flip"; // Same as preview display
                        transpose = "transpose=cclock"; // Mirrored horizontally as preview display
                        break;
                    case 90:
//                        transpose = "transpose=cclock_flip"; // Same as preview display
                        transpose = "transpose=clock"; // Mirrored horizontally as preview display
                        break;
                }
            } else {
                switch (info.orientation) {
                    case 270:
                        transpose = "transpose=cclock";
                        break;
                    case 90:
                        transpose = "transpose=clock";
                        break;
                }
            }
            if (transpose != null) {
                filters.add(transpose);
            }
            // Crop (only vertically)
            int width = previewHeight;
            int height = width * videoHeight / videoWidth;
            String crop = String.format(Locale.getDefault(),"crop=%d:%d:%d:%d",
                    width, height,
                    (previewHeight - width) / 2, (previewWidth - height) / 2);
            filters.add(crop);
            // Scale (to designated size)
            String scale = String.format(Locale.getDefault(),"scale=%d:%d", videoHeight, videoWidth);
            filters.add(scale);
            FFmpegFrameFilter frameFilter = new FFmpegFrameFilter(TextUtils.join(",", filters),
                    previewWidth, previewHeight);
            frameFilter.setPixelFormat(avutil.AV_PIX_FMT_NV21);
            frameFilter.setFrameRate(frameRate);
            try {
                frameFilter.start();
            } catch (FrameFilter.Exception e) {
                e.printStackTrace();
            }
            isRunning = true;
            FrameToRecord recordedFrame;
            while (isRunning || !mFrameToRecordQueue.isEmpty()) {
                try {
                    recordedFrame = mFrameToRecordQueue.take();
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                    try {
                        frameFilter.stop();
                    } catch (FrameFilter.Exception e) {
                        e.printStackTrace();
                    }
                    break;
                }
                if (mFrameRecorder != null) {
                    long timestamp = recordedFrame.getTimestamp();
                    if (timestamp > mFrameRecorder.getTimestamp()) {
                        mFrameRecorder.setTimestamp(timestamp);
                    }
                    long startTime = System.currentTimeMillis();
//                    Frame filteredFrame = recordedFrame.getFrame();
                    Frame filteredFrame = null;
                    try {
                        frameFilter.push(recordedFrame.getFrame());
                        filteredFrame = frameFilter.pull();
                    } catch (FrameFilter.Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        mFrameRecorder.record(filteredFrame);
                    } catch (FFmpegFrameRecorder.Exception e) {
                        e.printStackTrace();
                    }
                    long endTime = System.currentTimeMillis();
                    long processTime = endTime - startTime;
                    mTotalProcessFrameTime += processTime;
                    Log.d(LOG_TAG, "This frame process time: " + processTime + "ms");
                    long totalAvg = mTotalProcessFrameTime / ++mFrameRecordedCount;
                    Log.d(LOG_TAG, "Avg frame process time: " + totalAvg + "ms");

                }
                Log.d(LOG_TAG, mFrameRecordedCount + " / " + mFrameToRecordCount);
                mRecycledFrameQueue.offer(recordedFrame);
            }
        }
        public void stopRunning() {
            super.stopRunning();
            if (getState() == WAITING) {
                interrupt();
            }
        }
    }

Дело в том, что при записи видео никаких лагов не заметно. После записи видео, когда если хорошенько присмотреться, заметны лаги мелкие, а если при записи видео быстро двигать телефоном(камерой), то после записи видны подтормаживания, будто приклеили несколько гифок.

Перепробовал все что мог: фреймрэйт менял на 30, на 60, на 100. Менял Качество видео, pixelFormat(хотя не знаю для чего) и много чего, которые не понимал. Но все равно без толку.

Может есть кто разбирается. Подскажите как исправить эти искажения?

READ ALSO
Скрытие клавиатуры и перенос каретки в EditText

Скрытие клавиатуры и перенос каретки в EditText

Нужно при нажатии "Enter" скрыть клавиатуруВсё работает, но при закрытии клавиатуры каретка переходит на новую строку

284
как отправить метод Send в брокер RabbitMQ?

как отправить метод Send в брокер RabbitMQ?

Красным полем помечена строчка с factorynewConnection()

261
Перевод строки в двоичный код

Перевод строки в двоичный код

Необходимо преобразовать строку состоящую из символов (Пример String a = "abc") в массив битов (Пример вывода : 01001101 01010100 01101011) Как это лучше реализовать...

423
Spring boot, Сравнивание данных из БД с входящими

Spring boot, Сравнивание данных из БД с входящими

Здравствуйте, подскажите пожалуйста, как получить данные из БД, сравнить с полученнымиЭто необходимо для авторизации на сайте

278