// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//#define LOG_NDEBUG 0
#define LOG_TAG "V4L2Encoder"

#include <v4l2_codec2/components/V4L2Encoder.h>

#include <stdint.h>
#include <optional>
#include <vector>

#include <base/bind.h>
#include <base/files/scoped_file.h>
#include <base/memory/ptr_util.h>
#include <log/log.h>
#include <ui/Rect.h>

#include <v4l2_codec2/common/EncodeHelpers.h>
#include <v4l2_codec2/common/Fourcc.h>
#include <v4l2_codec2/common/V4L2Device.h>
#include <v4l2_codec2/components/BitstreamBuffer.h>

namespace android {

namespace {

const VideoPixelFormat kInputPixelFormat = VideoPixelFormat::NV12;

// The maximum size for output buffer, which is chosen empirically for a 1080p video.
constexpr size_t kMaxBitstreamBufferSizeInBytes = 2 * 1024 * 1024;  // 2MB
// The frame size for 1080p (FHD) video in pixels.
constexpr int k1080PSizeInPixels = 1920 * 1080;
// The frame size for 1440p (QHD) video in pixels.
constexpr int k1440PSizeInPixels = 2560 * 1440;

// Use quadruple size of kMaxBitstreamBufferSizeInBytes when the input frame size is larger than
// 1440p, double if larger than 1080p. This is chosen empirically for some 4k encoding use cases and
// the Android CTS VideoEncoderTest (crbug.com/927284).
size_t GetMaxOutputBufferSize(const ui::Size& size) {
    if (getArea(size) > k1440PSizeInPixels) return kMaxBitstreamBufferSizeInBytes * 4;
    if (getArea(size) > k1080PSizeInPixels) return kMaxBitstreamBufferSizeInBytes * 2;
    return kMaxBitstreamBufferSizeInBytes;
}

// Define V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR control code if not present in header files.
#ifndef V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR
#define V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_BASE + 644)
#endif

}  // namespace

// static
std::unique_ptr<VideoEncoder> V4L2Encoder::create(
        C2Config::profile_t outputProfile, std::optional<uint8_t> level,
        const ui::Size& visibleSize, uint32_t stride, uint32_t keyFramePeriod,
        C2Config::bitrate_mode_t bitrateMode, uint32_t bitrate, std::optional<uint32_t> peakBitrate,
        FetchOutputBufferCB fetchOutputBufferCb, InputBufferDoneCB inputBufferDoneCb,
        OutputBufferDoneCB outputBufferDoneCb, DrainDoneCB drainDoneCb, ErrorCB errorCb,
        scoped_refptr<::base::SequencedTaskRunner> taskRunner) {
    ALOGV("%s()", __func__);

    std::unique_ptr<V4L2Encoder> encoder = ::base::WrapUnique<V4L2Encoder>(new V4L2Encoder(
            std::move(taskRunner), std::move(fetchOutputBufferCb), std::move(inputBufferDoneCb),
            std::move(outputBufferDoneCb), std::move(drainDoneCb), std::move(errorCb)));
    if (!encoder->initialize(outputProfile, level, visibleSize, stride, keyFramePeriod, bitrateMode,
                             bitrate, peakBitrate)) {
        return nullptr;
    }
    return encoder;
}

V4L2Encoder::V4L2Encoder(scoped_refptr<::base::SequencedTaskRunner> taskRunner,
                         FetchOutputBufferCB fetchOutputBufferCb,
                         InputBufferDoneCB inputBufferDoneCb, OutputBufferDoneCB outputBufferDoneCb,
                         DrainDoneCB drainDoneCb, ErrorCB errorCb)
      : mFetchOutputBufferCb(fetchOutputBufferCb),
        mInputBufferDoneCb(inputBufferDoneCb),
        mOutputBufferDoneCb(outputBufferDoneCb),
        mDrainDoneCb(std::move(drainDoneCb)),
        mErrorCb(std::move(errorCb)),
        mTaskRunner(std::move(taskRunner)) {
    ALOGV("%s()", __func__);

    mWeakThis = mWeakThisFactory.GetWeakPtr();
}

V4L2Encoder::~V4L2Encoder() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    mWeakThisFactory.InvalidateWeakPtrs();

    // Flushing the encoder will stop polling and streaming on the V4L2 device queues.
    flush();

    // Deallocate all V4L2 device input and output buffers.
    destroyInputBuffers();
    destroyOutputBuffers();
}

bool V4L2Encoder::encode(std::unique_ptr<InputFrame> frame) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(mState != State::UNINITIALIZED);

    // If we're in the error state we can immediately return, freeing the input buffer.
    if (mState == State::ERROR) {
        return false;
    }

    if (!frame) {
        ALOGW("Empty encode request scheduled");
        return false;
    }

    mEncodeRequests.push(EncodeRequest(std::move(frame)));

    // If we were waiting for encode requests, start encoding again.
    if (mState == State::WAITING_FOR_INPUT_FRAME) {
        setState(State::ENCODING);
        mTaskRunner->PostTask(FROM_HERE,
                              ::base::BindOnce(&V4L2Encoder::handleEncodeRequest, mWeakThis));
    }

    return true;
}

void V4L2Encoder::drain() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    // We can only start draining if all the requests in our input queue has been queued on the V4L2
    // device input queue, so we mark the last item in the input queue as EOS.
    if (!mEncodeRequests.empty()) {
        ALOGV("Marking last item (index: %" PRIu64 ") in encode request queue as EOS",
              mEncodeRequests.back().video_frame->index());
        mEncodeRequests.back().end_of_stream = true;
        return;
    }

    // Start a drain operation on the device. If no buffers are currently queued the device will
    // return an empty buffer with the V4L2_BUF_FLAG_LAST flag set.
    handleDrainRequest();
}

void V4L2Encoder::flush() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    handleFlushRequest();
}

bool V4L2Encoder::setBitrate(uint32_t bitrate) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    if (!mDevice->setExtCtrls(V4L2_CTRL_CLASS_MPEG,
                              {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_BITRATE, bitrate)})) {
        ALOGE("Setting bitrate to %u failed", bitrate);
        return false;
    }
    return true;
}

bool V4L2Encoder::setPeakBitrate(uint32_t peakBitrate) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    if (!mDevice->setExtCtrls(V4L2_CTRL_CLASS_MPEG,
                              {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, peakBitrate)})) {
        // TODO(b/190336806): Our stack doesn't support dynamic peak bitrate changes yet, ignore
        // errors for now.
        ALOGW("Setting peak bitrate to %u failed", peakBitrate);
    }
    return true;
}

bool V4L2Encoder::setFramerate(uint32_t framerate) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    struct v4l2_streamparm parms;
    memset(&parms, 0, sizeof(v4l2_streamparm));
    parms.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    parms.parm.output.timeperframe.numerator = 1;
    parms.parm.output.timeperframe.denominator = framerate;
    if (mDevice->ioctl(VIDIOC_S_PARM, &parms) != 0) {
        ALOGE("Setting framerate to %u failed", framerate);
        return false;
    }
    return true;
}

void V4L2Encoder::requestKeyframe() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    mKeyFrameCounter = 0;
}

VideoPixelFormat V4L2Encoder::inputFormat() const {
    return mInputLayout ? mInputLayout.value().mFormat : VideoPixelFormat::UNKNOWN;
}

bool V4L2Encoder::initialize(C2Config::profile_t outputProfile, std::optional<uint8_t> level,
                             const ui::Size& visibleSize, uint32_t stride, uint32_t keyFramePeriod,
                             C2Config::bitrate_mode_t bitrateMode, uint32_t bitrate,
                             std::optional<uint32_t> peakBitrate) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(keyFramePeriod > 0);

    mVisibleSize = visibleSize;
    mKeyFramePeriod = keyFramePeriod;
    mKeyFrameCounter = 0;

    // Open the V4L2 device for encoding to the requested output format.
    // TODO(dstaessens): Avoid conversion to VideoCodecProfile and use C2Config::profile_t directly.
    uint32_t outputPixelFormat = V4L2Device::C2ProfileToV4L2PixFmt(outputProfile, false);
    if (!outputPixelFormat) {
        ALOGE("Invalid output profile %s", profileToString(outputProfile));
        return false;
    }

    mDevice = V4L2Device::create();
    if (!mDevice) {
        ALOGE("Failed to create V4L2 device");
        return false;
    }

    if (!mDevice->open(V4L2Device::Type::kEncoder, outputPixelFormat)) {
        ALOGE("Failed to open device for profile %s (%s)", profileToString(outputProfile),
              fourccToString(outputPixelFormat).c_str());
        return false;
    }

    // Make sure the device has all required capabilities (multi-planar Memory-To-Memory and
    // streaming I/O), and whether flushing is supported.
    if (!mDevice->hasCapabilities(V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING)) {
        ALOGE("Device doesn't have the required capabilities");
        return false;
    }
    if (!mDevice->isCommandSupported(V4L2_ENC_CMD_STOP)) {
        ALOGE("Device does not support flushing (V4L2_ENC_CMD_STOP)");
        return false;
    }

    // Get input/output queues so we can send encode request to the device and get back the results.
    mInputQueue = mDevice->getQueue(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
    mOutputQueue = mDevice->getQueue(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
    if (!mInputQueue || !mOutputQueue) {
        ALOGE("Failed to get V4L2 device queues");
        return false;
    }

    // Configure the requested bitrate mode and bitrate on the device.
    if (!configureBitrateMode(bitrateMode) || !setBitrate(bitrate)) return false;

    // If the bitrate mode is VBR we also need to configure the peak bitrate on the device.
    if ((bitrateMode == C2Config::BITRATE_VARIABLE) && !setPeakBitrate(*peakBitrate)) return false;

    // First try to configure the specified output format, as changing the output format can affect
    // the configured input format.
    if (!configureOutputFormat(outputProfile)) return false;

    // Configure the input format. If the device doesn't support the specified format we'll use one
    // of the device's preferred formats in combination with an input format convertor.
    if (!configureInputFormat(kInputPixelFormat, stride)) return false;

    // Create input and output buffers.
    if (!createInputBuffers() || !createOutputBuffers()) return false;

    // Configure the device, setting all required controls.
    if (!configureDevice(outputProfile, level)) return false;

    // We're ready to start encoding now.
    setState(State::WAITING_FOR_INPUT_FRAME);
    return true;
}

void V4L2Encoder::handleEncodeRequest() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(mState == State::ENCODING || mState == State::ERROR);

    // If we're in the error state we can immediately return.
    if (mState == State::ERROR) {
        return;
    }

    // It's possible we flushed the encoder since this function was scheduled.
    if (mEncodeRequests.empty()) {
        return;
    }

    // Get the next encode request from the queue.
    EncodeRequest& encodeRequest = mEncodeRequests.front();

    // Check if the device has free input buffers available. If not we'll switch to the
    // WAITING_FOR_INPUT_BUFFERS state, and resume encoding once we've dequeued an input buffer.
    // Note: The input buffers are not copied into the device's input buffers, but rather a memory
    // pointer is imported. We still have to throttle the number of enqueues queued simultaneously
    // on the device however.
    if (mInputQueue->freeBuffersCount() == 0) {
        ALOGV("Waiting for device to return input buffers");
        setState(State::WAITING_FOR_V4L2_BUFFER);
        return;
    }

    // Request the next frame to be a key frame each time the counter reaches 0.
    if (mKeyFrameCounter == 0) {
        if (!mDevice->setExtCtrls(V4L2_CTRL_CLASS_MPEG,
                                  {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME)})) {
            ALOGE("Failed requesting key frame");
            onError();
            return;
        }
    }
    mKeyFrameCounter = (mKeyFrameCounter + 1) % mKeyFramePeriod;

    // Enqueue the input frame in the V4L2 device.
    uint64_t index = encodeRequest.video_frame->index();
    uint64_t timestamp = encodeRequest.video_frame->timestamp();
    bool end_of_stream = encodeRequest.end_of_stream;
    if (!enqueueInputBuffer(std::move(encodeRequest.video_frame))) {
        ALOGE("Failed to enqueue input frame (index: %" PRIu64 ", timestamp: %" PRId64 ")", index,
              timestamp);
        onError();
        return;
    }
    mEncodeRequests.pop();

    // Start streaming and polling on the input and output queue if required.
    if (!mInputQueue->isStreaming()) {
        ALOG_ASSERT(!mOutputQueue->isStreaming());
        if (!mOutputQueue->streamon() || !mInputQueue->streamon()) {
            ALOGE("Failed to start streaming on input and output queue");
            onError();
            return;
        }
        startDevicePoll();
    }

    // Queue buffers on output queue. These buffers will be used to store the encoded bitstream.
    while (mOutputQueue->freeBuffersCount() > 0) {
        if (!enqueueOutputBuffer()) return;
    }

    // Drain the encoder if requested.
    if (end_of_stream) {
        handleDrainRequest();
        return;
    }

    if (mEncodeRequests.empty()) {
        setState(State::WAITING_FOR_INPUT_FRAME);
        return;
    }

    // Schedule the next buffer to be encoded.
    mTaskRunner->PostTask(FROM_HERE,
                          ::base::BindOnce(&V4L2Encoder::handleEncodeRequest, mWeakThis));
}

void V4L2Encoder::handleFlushRequest() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    // Stop the device poll thread.
    stopDevicePoll();

    // Stop streaming on the V4L2 device, which stops all currently queued encode operations and
    // releases all buffers currently in use by the device.
    for (auto& queue : {mInputQueue, mOutputQueue}) {
        if (queue && queue->isStreaming() && !queue->streamoff()) {
            ALOGE("Failed to stop streaming on the device queue");
            onError();
        }
    }

    // Clear all outstanding encode requests and references to input and output queue buffers.
    while (!mEncodeRequests.empty()) {
        mEncodeRequests.pop();
    }
    for (auto& buf : mInputBuffers) {
        buf = nullptr;
    }
    for (auto& buf : mOutputBuffers) {
        buf = nullptr;
    }

    // Streaming and polling on the V4L2 device input and output queues will be resumed once new
    // encode work is queued.
    if (mState != State::ERROR) {
        setState(State::WAITING_FOR_INPUT_FRAME);
    }
}

void V4L2Encoder::handleDrainRequest() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    if (mState == State::DRAINING || mState == State::ERROR) {
        return;
    }

    setState(State::DRAINING);

    // If we're not streaming we can consider the request completed immediately.
    if (!mInputQueue->isStreaming()) {
        onDrainDone(true);
        return;
    }

    struct v4l2_encoder_cmd cmd;
    memset(&cmd, 0, sizeof(v4l2_encoder_cmd));
    cmd.cmd = V4L2_ENC_CMD_STOP;
    if (mDevice->ioctl(VIDIOC_ENCODER_CMD, &cmd) != 0) {
        ALOGE("Failed to stop encoder");
        onDrainDone(false);
        return;
    }
    ALOGV("%s(): Sent STOP command to encoder", __func__);
}

void V4L2Encoder::onDrainDone(bool done) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(mState == State::DRAINING || mState == State::ERROR);

    if (mState == State::ERROR) {
        return;
    }

    if (!done) {
        ALOGE("draining the encoder failed");
        mDrainDoneCb.Run(false);
        onError();
        return;
    }

    ALOGV("Draining done");
    mDrainDoneCb.Run(true);

    // Draining the encoder is done, we can now start encoding again.
    if (!mEncodeRequests.empty()) {
        setState(State::ENCODING);
        mTaskRunner->PostTask(FROM_HERE,
                              ::base::BindOnce(&V4L2Encoder::handleEncodeRequest, mWeakThis));
    } else {
        setState(State::WAITING_FOR_INPUT_FRAME);
    }
}

bool V4L2Encoder::configureInputFormat(VideoPixelFormat inputFormat, uint32_t stride) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(mState == State::UNINITIALIZED);
    ALOG_ASSERT(!mInputQueue->isStreaming());
    ALOG_ASSERT(!isEmpty(mVisibleSize));

    // First try to use the requested pixel format directly.
    std::optional<struct v4l2_format> format;
    auto fourcc = Fourcc::fromVideoPixelFormat(inputFormat, false);
    if (fourcc) {
        format = mInputQueue->setFormat(fourcc->toV4L2PixFmt(), mVisibleSize, 0, stride);
    }

    // If the device doesn't support the requested input format we'll try the device's preferred
    // input pixel formats and use a format convertor. We need to try all formats as some formats
    // might not be supported for the configured output format.
    if (!format) {
        std::vector<uint32_t> preferredFormats =
                mDevice->preferredInputFormat(V4L2Device::Type::kEncoder);
        for (uint32_t i = 0; !format && i < preferredFormats.size(); ++i) {
            format = mInputQueue->setFormat(preferredFormats[i], mVisibleSize, 0, stride);
        }
    }

    if (!format) {
        ALOGE("Failed to set input format to %s", videoPixelFormatToString(inputFormat).c_str());
        return false;
    }

    // Check whether the negotiated input format is valid. The coded size might be adjusted to match
    // encoder minimums, maximums and alignment requirements of the currently selected formats.
    auto layout = V4L2Device::v4L2FormatToVideoFrameLayout(*format);
    if (!layout) {
        ALOGE("Invalid input layout");
        return false;
    }

    mInputLayout = layout.value();
    if (!contains(Rect(mInputLayout->mCodedSize.width, mInputLayout->mCodedSize.height),
                  Rect(mVisibleSize.width, mVisibleSize.height))) {
        ALOGE("Input size %s exceeds encoder capability, encoder can handle %s",
              toString(mVisibleSize).c_str(), toString(mInputLayout->mCodedSize).c_str());
        return false;
    }

    // Calculate the input coded size from the format.
    // TODO(dstaessens): How is this different from mInputLayout->coded_size()?
    mInputCodedSize = V4L2Device::allocatedSizeFromV4L2Format(*format);

    // Configuring the input format might cause the output buffer size to change.
    auto outputFormat = mOutputQueue->getFormat();
    if (!outputFormat.first) {
        ALOGE("Failed to get output format (errno: %i)", outputFormat.second);
        return false;
    }
    uint32_t AdjustedOutputBufferSize = outputFormat.first->fmt.pix_mp.plane_fmt[0].sizeimage;
    if (mOutputBufferSize != AdjustedOutputBufferSize) {
        mOutputBufferSize = AdjustedOutputBufferSize;
        ALOGV("Output buffer size adjusted to: %u", mOutputBufferSize);
    }

    // The coded input size might be different from the visible size due to alignment requirements,
    // So we need to specify the visible rectangle. Note that this rectangle might still be adjusted
    // due to hardware limitations.
    Rect visibleRectangle(mVisibleSize.width, mVisibleSize.height);

    struct v4l2_rect rect;
    memset(&rect, 0, sizeof(rect));
    rect.left = visibleRectangle.left;
    rect.top = visibleRectangle.top;
    rect.width = visibleRectangle.width();
    rect.height = visibleRectangle.height();

    // Try to adjust the visible rectangle using the VIDIOC_S_SELECTION command. If this is not
    // supported we'll try to use the VIDIOC_S_CROP command instead. The visible rectangle might be
    // adjusted to conform to hardware limitations (e.g. round to closest horizontal and vertical
    // offsets, width and height).
    struct v4l2_selection selection_arg;
    memset(&selection_arg, 0, sizeof(selection_arg));
    selection_arg.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    selection_arg.target = V4L2_SEL_TGT_CROP;
    selection_arg.r = rect;
    if (mDevice->ioctl(VIDIOC_S_SELECTION, &selection_arg) == 0) {
        visibleRectangle = Rect(selection_arg.r.left, selection_arg.r.top,
                                selection_arg.r.left + selection_arg.r.width,
                                selection_arg.r.top + selection_arg.r.height);
    } else {
        struct v4l2_crop crop;
        memset(&crop, 0, sizeof(v4l2_crop));
        crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
        crop.c = rect;
        if (mDevice->ioctl(VIDIOC_S_CROP, &crop) != 0 ||
            mDevice->ioctl(VIDIOC_G_CROP, &crop) != 0) {
            ALOGE("Failed to crop to specified visible rectangle");
            return false;
        }
        visibleRectangle = Rect(crop.c.left, crop.c.top, crop.c.left + crop.c.width,
                                crop.c.top + crop.c.height);
    }

    ALOGV("Input format set to %s (size: %s, adjusted size: %dx%d, coded size: %s)",
          videoPixelFormatToString(mInputLayout->mFormat).c_str(), toString(mVisibleSize).c_str(),
          visibleRectangle.width(), visibleRectangle.height(), toString(mInputCodedSize).c_str());

    mVisibleSize.set(visibleRectangle.width(), visibleRectangle.height());
    return true;
}

bool V4L2Encoder::configureOutputFormat(C2Config::profile_t outputProfile) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(mState == State::UNINITIALIZED);
    ALOG_ASSERT(!mOutputQueue->isStreaming());
    ALOG_ASSERT(!isEmpty(mVisibleSize));

    auto format = mOutputQueue->setFormat(V4L2Device::C2ProfileToV4L2PixFmt(outputProfile, false),
                                          mVisibleSize, GetMaxOutputBufferSize(mVisibleSize));
    if (!format) {
        ALOGE("Failed to set output format to %s", profileToString(outputProfile));
        return false;
    }

    // The device might adjust the requested output buffer size to match hardware requirements.
    mOutputBufferSize = format->fmt.pix_mp.plane_fmt[0].sizeimage;

    ALOGV("Output format set to %s (buffer size: %u)", profileToString(outputProfile),
          mOutputBufferSize);
    return true;
}

bool V4L2Encoder::configureDevice(C2Config::profile_t outputProfile,
                                  std::optional<const uint8_t> outputH264Level) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    // Enable frame-level bitrate control. This is the only mandatory general control.
    if (!mDevice->setExtCtrls(V4L2_CTRL_CLASS_MPEG,
                              {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 1)})) {
        ALOGW("Failed enabling bitrate control");
        // TODO(b/161508368): V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE is currently not supported yet,
        // assume the operation was successful for now.
    }

    // Additional optional controls:
    // - Enable macroblock-level bitrate control.
    // - Set GOP length to 0 to disable periodic key frames.
    mDevice->setExtCtrls(V4L2_CTRL_CLASS_MPEG, {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE, 1),
                                                V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0)});

    // All controls below are H.264-specific, so we can return here if the profile is not H.264.
    if (outputProfile >= C2Config::PROFILE_AVC_BASELINE &&
        outputProfile <= C2Config::PROFILE_AVC_ENHANCED_MULTIVIEW_DEPTH_HIGH) {
        return configureH264(outputProfile, outputH264Level);
    }

    return true;
}

bool V4L2Encoder::configureH264(C2Config::profile_t outputProfile,
                                std::optional<const uint8_t> outputH264Level) {
    // When encoding H.264 we want to prepend SPS and PPS to each IDR for resilience. Some
    // devices support this through the V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR control.
    // Otherwise we have to cache the latest SPS and PPS and inject these manually.
    if (mDevice->isCtrlExposed(V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR)) {
        if (!mDevice->setExtCtrls(V4L2_CTRL_CLASS_MPEG,
                                  {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR, 1)})) {
            ALOGE("Failed to configure device to prepend SPS and PPS to each IDR");
            return false;
        }
        mInjectParamsBeforeIDR = false;
        ALOGV("Device supports prepending SPS and PPS to each IDR");
    } else {
        mInjectParamsBeforeIDR = true;
        ALOGV("Device doesn't support prepending SPS and PPS to IDR, injecting manually.");
    }

    std::vector<V4L2ExtCtrl> h264Ctrls;

    // No B-frames, for lowest decoding latency.
    h264Ctrls.emplace_back(V4L2_CID_MPEG_VIDEO_B_FRAMES, 0);
    // Quantization parameter maximum value (for variable bitrate control).
    h264Ctrls.emplace_back(V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 51);

    // Set H.264 profile.
    int32_t profile = V4L2Device::c2ProfileToV4L2H264Profile(outputProfile);
    if (profile < 0) {
        ALOGE("Trying to set invalid H.264 profile");
        return false;
    }
    h264Ctrls.emplace_back(V4L2_CID_MPEG_VIDEO_H264_PROFILE, profile);

    // Set H.264 output level. Use Level 4.0 as fallback default.
    int32_t h264Level =
            static_cast<int32_t>(outputH264Level.value_or(V4L2_MPEG_VIDEO_H264_LEVEL_4_0));
    h264Ctrls.emplace_back(V4L2_CID_MPEG_VIDEO_H264_LEVEL, h264Level);

    // Ask not to put SPS and PPS into separate bitstream buffers.
    h264Ctrls.emplace_back(V4L2_CID_MPEG_VIDEO_HEADER_MODE,
                           V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);

    // Ignore return value as these controls are optional.
    mDevice->setExtCtrls(V4L2_CTRL_CLASS_MPEG, std::move(h264Ctrls));

    return true;
}

bool V4L2Encoder::configureBitrateMode(C2Config::bitrate_mode_t bitrateMode) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    v4l2_mpeg_video_bitrate_mode v4l2BitrateMode =
            V4L2Device::C2BitrateModeToV4L2BitrateMode(bitrateMode);
    if (!mDevice->setExtCtrls(V4L2_CTRL_CLASS_MPEG,
                              {V4L2ExtCtrl(V4L2_CID_MPEG_VIDEO_BITRATE_MODE, v4l2BitrateMode)})) {
        // TODO(b/190336806): Our stack doesn't support bitrate mode changes yet. We default to CBR
        // which is currently the only supported mode so we can safely ignore this for now.
        ALOGW("Setting bitrate mode to %u failed", v4l2BitrateMode);
    }
    return true;
}

bool V4L2Encoder::startDevicePoll() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    if (!mDevice->startPolling(::base::BindRepeating(&V4L2Encoder::serviceDeviceTask, mWeakThis),
                               ::base::BindRepeating(&V4L2Encoder::onPollError, mWeakThis))) {
        ALOGE("Device poll thread failed to start");
        onError();
        return false;
    }

    ALOGV("Device poll started");
    return true;
}

bool V4L2Encoder::stopDevicePoll() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    if (!mDevice->stopPolling()) {
        ALOGE("Failed to stop polling on the device");
        onError();
        return false;
    }

    ALOGV("Device poll stopped");
    return true;
}

void V4L2Encoder::onPollError() {
    ALOGV("%s()", __func__);
    onError();
}

void V4L2Encoder::serviceDeviceTask(bool /*event*/) {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(mState != State::UNINITIALIZED);

    if (mState == State::ERROR) {
        return;
    }

    // Dequeue completed input (VIDEO_OUTPUT) buffers, and recycle to the free list.
    while (mInputQueue->queuedBuffersCount() > 0) {
        if (!dequeueInputBuffer()) break;
    }

    // Dequeue completed output (VIDEO_CAPTURE) buffers, and recycle to the free list.
    while (mOutputQueue->queuedBuffersCount() > 0) {
        if (!dequeueOutputBuffer()) break;
    }

    ALOGV("%s() - done", __func__);
}

bool V4L2Encoder::enqueueInputBuffer(std::unique_ptr<InputFrame> frame) {
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(mInputQueue->freeBuffersCount() > 0);
    ALOG_ASSERT(mState == State::ENCODING);
    ALOG_ASSERT(frame);
    ALOG_ASSERT(mInputLayout->mFormat == frame->pixelFormat());
    ALOG_ASSERT(mInputLayout->mPlanes.size() == frame->planes().size());

    auto format = frame->pixelFormat();
    auto planes = frame->planes();
    auto index = frame->index();
    auto timestamp = frame->timestamp();

    ALOGV("%s(): queuing input buffer (index: %" PRId64 ")", __func__, index);

    auto buffer = mInputQueue->getFreeBuffer();
    if (!buffer) {
        ALOGE("Failed to get free buffer from device input queue");
        return false;
    }

    // Mark the buffer with the frame's timestamp so we can identify the associated output buffers.
    buffer->setTimeStamp(
            {.tv_sec = static_cast<time_t>(timestamp / ::base::Time::kMicrosecondsPerSecond),
             .tv_usec = static_cast<time_t>(timestamp % ::base::Time::kMicrosecondsPerSecond)});
    size_t bufferId = buffer->bufferId();

    for (size_t i = 0; i < planes.size(); ++i) {
        // Single-buffer input format may have multiple color planes, so bytesUsed of the single
        // buffer should be sum of each color planes' size.
        size_t bytesUsed = 0;
        if (planes.size() == 1) {
            bytesUsed = allocationSize(format, mInputLayout->mCodedSize);
        } else {
            bytesUsed = ::base::checked_cast<size_t>(
                    getArea(planeSize(format, i, mInputLayout->mCodedSize)).value());
        }

        // TODO(crbug.com/901264): The way to pass an offset within a DMA-buf is not defined
        // in V4L2 specification, so we abuse data_offset for now. Fix it when we have the
        // right interface, including any necessary validation and potential alignment.
        buffer->setPlaneDataOffset(i, planes[i].mOffset);
        bytesUsed += planes[i].mOffset;
        // Workaround: filling length should not be needed. This is a bug of videobuf2 library.
        buffer->setPlaneSize(i, mInputLayout->mPlanes[i].mSize + planes[i].mOffset);
        buffer->setPlaneBytesUsed(i, bytesUsed);
    }

    if (!std::move(*buffer).queueDMABuf(frame->fds())) {
        ALOGE("Failed to queue input buffer using QueueDMABuf");
        onError();
        return false;
    }

    ALOGV("Queued buffer in input queue (index: %" PRId64 ", timestamp: %" PRId64
          ", bufferId: %zu)",
          index, timestamp, bufferId);

    ALOG_ASSERT(!mInputBuffers[bufferId]);
    mInputBuffers[bufferId] = std::move(frame);

    return true;
}

bool V4L2Encoder::enqueueOutputBuffer() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(mOutputQueue->freeBuffersCount() > 0);

    auto buffer = mOutputQueue->getFreeBuffer();
    if (!buffer) {
        ALOGE("Failed to get free buffer from device output queue");
        onError();
        return false;
    }

    std::unique_ptr<BitstreamBuffer> bitstreamBuffer;
    mFetchOutputBufferCb.Run(mOutputBufferSize, &bitstreamBuffer);
    if (!bitstreamBuffer) {
        ALOGE("Failed to fetch output block");
        onError();
        return false;
    }

    size_t bufferId = buffer->bufferId();

    std::vector<int> fds;
    fds.push_back(bitstreamBuffer->dmabuf->handle()->data[0]);
    if (!std::move(*buffer).queueDMABuf(fds)) {
        ALOGE("Failed to queue output buffer using QueueDMABuf");
        onError();
        return false;
    }

    ALOG_ASSERT(!mOutputBuffers[bufferId]);
    mOutputBuffers[bufferId] = std::move(bitstreamBuffer);
    ALOGV("%s(): Queued buffer in output queue (bufferId: %zu)", __func__, bufferId);
    return true;
}

bool V4L2Encoder::dequeueInputBuffer() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(mState != State::UNINITIALIZED);
    ALOG_ASSERT(mInputQueue->queuedBuffersCount() > 0);

    if (mState == State::ERROR) {
        return false;
    }

    bool success;
    V4L2ReadableBufferRef buffer;
    std::tie(success, buffer) = mInputQueue->dequeueBuffer();
    if (!success) {
        ALOGE("Failed to dequeue buffer from input queue");
        onError();
        return false;
    }
    if (!buffer) {
        // No more buffers ready to be dequeued in input queue.
        return false;
    }

    uint64_t index = mInputBuffers[buffer->bufferId()]->index();
    int64_t timestamp = buffer->getTimeStamp().tv_usec +
                        buffer->getTimeStamp().tv_sec * ::base::Time::kMicrosecondsPerSecond;
    ALOGV("Dequeued buffer from input queue (index: %" PRId64 ", timestamp: %" PRId64
          ", bufferId: %zu)",
          index, timestamp, buffer->bufferId());

    mInputBuffers[buffer->bufferId()] = nullptr;

    mInputBufferDoneCb.Run(index);

    // If we previously used up all input queue buffers we can start encoding again now.
    if ((mState == State::WAITING_FOR_V4L2_BUFFER) && !mEncodeRequests.empty()) {
        setState(State::ENCODING);
        mTaskRunner->PostTask(FROM_HERE,
                              ::base::BindOnce(&V4L2Encoder::handleEncodeRequest, mWeakThis));
    }

    return true;
}

bool V4L2Encoder::dequeueOutputBuffer() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(mState != State::UNINITIALIZED);
    ALOG_ASSERT(mOutputQueue->queuedBuffersCount() > 0);

    if (mState == State::ERROR) {
        return false;
    }

    bool success;
    V4L2ReadableBufferRef buffer;
    std::tie(success, buffer) = mOutputQueue->dequeueBuffer();
    if (!success) {
        ALOGE("Failed to dequeue buffer from output queue");
        onError();
        return false;
    }
    if (!buffer) {
        // No more buffers ready to be dequeued in output queue.
        return false;
    }

    size_t encodedDataSize = buffer->getPlaneBytesUsed(0) - buffer->getPlaneDataOffset(0);
    ::base::TimeDelta timestamp = ::base::TimeDelta::FromMicroseconds(
            buffer->getTimeStamp().tv_usec +
            buffer->getTimeStamp().tv_sec * ::base::Time::kMicrosecondsPerSecond);

    ALOGV("Dequeued buffer from output queue (timestamp: %" PRId64
          ", bufferId: %zu, data size: %zu, EOS: %d)",
          timestamp.InMicroseconds(), buffer->bufferId(), encodedDataSize, buffer->isLast());

    if (!mOutputBuffers[buffer->bufferId()]) {
        ALOGE("Failed to find output block associated with output buffer");
        onError();
        return false;
    }

    std::unique_ptr<BitstreamBuffer> bitstreamBuffer =
            std::move(mOutputBuffers[buffer->bufferId()]);
    if (encodedDataSize > 0) {
        if (!mInjectParamsBeforeIDR) {
            // No need to inject SPS or PPS before IDR frames, we can just return the buffer as-is.
            mOutputBufferDoneCb.Run(encodedDataSize, timestamp.InMicroseconds(),
                                    buffer->isKeyframe(), std::move(bitstreamBuffer));
        } else if (!buffer->isKeyframe()) {
            // We need to inject SPS and PPS before IDR frames, but this frame is not a key frame.
            // We can return the buffer as-is, but need to update our SPS and PPS cache if required.
            C2ConstLinearBlock constBlock = bitstreamBuffer->dmabuf->share(
                    bitstreamBuffer->dmabuf->offset(), encodedDataSize, C2Fence());
            C2ReadView readView = constBlock.map().get();
            extractSPSPPS(readView.data(), encodedDataSize, &mCachedSPS, &mCachedPPS);
            mOutputBufferDoneCb.Run(encodedDataSize, timestamp.InMicroseconds(),
                                    buffer->isKeyframe(), std::move(bitstreamBuffer));
        } else {
            // We need to inject our cached SPS and PPS NAL units to the IDR frame. It's possible
            // this frame already has SPS and PPS NAL units attached, in which case we only need to
            // update our cached SPS and PPS.
            C2ConstLinearBlock constBlock = bitstreamBuffer->dmabuf->share(
                    bitstreamBuffer->dmabuf->offset(), encodedDataSize, C2Fence());
            C2ReadView readView = constBlock.map().get();

            // Allocate a new buffer to copy the data with prepended SPS and PPS into.
            std::unique_ptr<BitstreamBuffer> prependedBitstreamBuffer;
            mFetchOutputBufferCb.Run(mOutputBufferSize, &prependedBitstreamBuffer);
            if (!prependedBitstreamBuffer) {
                ALOGE("Failed to fetch output block");
                onError();
                return false;
            }
            C2WriteView writeView = prependedBitstreamBuffer->dmabuf->map().get();

            // If there is not enough space in the output buffer just return the original buffer.
            size_t newSize = prependSPSPPSToIDR(readView.data(), encodedDataSize, writeView.data(),
                                                writeView.size(), &mCachedSPS, &mCachedPPS);
            if (newSize > 0) {
                mOutputBufferDoneCb.Run(newSize, timestamp.InMicroseconds(), buffer->isKeyframe(),
                                        std::move(prependedBitstreamBuffer));
            } else {
                mOutputBufferDoneCb.Run(encodedDataSize, timestamp.InMicroseconds(),
                                        buffer->isKeyframe(), std::move(bitstreamBuffer));
            }
        }
    }

    // If the buffer is marked as last and we were flushing the encoder, flushing is now done.
    if ((mState == State::DRAINING) && buffer->isLast()) {
        onDrainDone(true);
        // Start the encoder again.
        struct v4l2_encoder_cmd cmd;
        memset(&cmd, 0, sizeof(v4l2_encoder_cmd));
        cmd.cmd = V4L2_ENC_CMD_START;
        if (mDevice->ioctl(VIDIOC_ENCODER_CMD, &cmd) != 0) {
            ALOGE("Failed to restart encoder after draining (V4L2_ENC_CMD_START)");
            onError();
            return false;
        }
    }

    // Queue a new output buffer to replace the one we dequeued.
    buffer = nullptr;
    enqueueOutputBuffer();

    return true;
}

bool V4L2Encoder::createInputBuffers() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(!mInputQueue->isStreaming());
    ALOG_ASSERT(mInputBuffers.empty());

    // No memory is allocated here, we just generate a list of buffers on the input queue, which
    // will hold memory handles to the real buffers.
    if (mInputQueue->allocateBuffers(kInputBufferCount, V4L2_MEMORY_DMABUF) < kInputBufferCount) {
        ALOGE("Failed to create V4L2 input buffers.");
        return false;
    }

    mInputBuffers.resize(mInputQueue->allocatedBuffersCount());
    return true;
}

bool V4L2Encoder::createOutputBuffers() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(!mOutputQueue->isStreaming());
    ALOG_ASSERT(mOutputBuffers.empty());

    // No memory is allocated here, we just generate a list of buffers on the output queue, which
    // will hold memory handles to the real buffers.
    if (mOutputQueue->allocateBuffers(kOutputBufferCount, V4L2_MEMORY_DMABUF) <
        kOutputBufferCount) {
        ALOGE("Failed to create V4L2 output buffers.");
        return false;
    }

    mOutputBuffers.resize(mOutputQueue->allocatedBuffersCount());
    return true;
}

void V4L2Encoder::destroyInputBuffers() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(!mInputQueue->isStreaming());

    if (!mInputQueue || mInputQueue->allocatedBuffersCount() == 0) return;
    mInputQueue->deallocateBuffers();
    mInputBuffers.clear();
}

void V4L2Encoder::destroyOutputBuffers() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());
    ALOG_ASSERT(!mOutputQueue->isStreaming());

    if (!mOutputQueue || mOutputQueue->allocatedBuffersCount() == 0) return;
    mOutputQueue->deallocateBuffers();
    mOutputBuffers.clear();
}

void V4L2Encoder::onError() {
    ALOGV("%s()", __func__);
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    if (mState != State::ERROR) {
        setState(State::ERROR);
        mErrorCb.Run();
    }
}

void V4L2Encoder::setState(State state) {
    ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence());

    // Check whether the state change is valid.
    switch (state) {
    case State::UNINITIALIZED:
        break;
    case State::WAITING_FOR_INPUT_FRAME:
        ALOG_ASSERT(mState != State::ERROR);
        break;
    case State::WAITING_FOR_V4L2_BUFFER:
        ALOG_ASSERT(mState == State::ENCODING);
        break;
    case State::ENCODING:
        ALOG_ASSERT(mState == State::WAITING_FOR_INPUT_FRAME ||
                    mState == State::WAITING_FOR_V4L2_BUFFER || mState == State::DRAINING);
        break;
    case State::DRAINING:
        ALOG_ASSERT(mState == State::ENCODING || mState == State::WAITING_FOR_INPUT_FRAME);
        break;
    case State::ERROR:
        break;
    }

    ALOGV("Changed encoder state from %s to %s", stateToString(mState), stateToString(state));
    mState = state;
}

const char* V4L2Encoder::stateToString(State state) {
    switch (state) {
    case State::UNINITIALIZED:
        return "UNINITIALIZED";
    case State::WAITING_FOR_INPUT_FRAME:
        return "WAITING_FOR_INPUT_FRAME";
    case State::WAITING_FOR_V4L2_BUFFER:
        return "WAITING_FOR_V4L2_BUFFER";
    case State::ENCODING:
        return "ENCODING";
    case State::DRAINING:
        return "DRAINING";
    case State::ERROR:
        return "ERROR";
    }
}

}  // namespace android
