// Copyright 2020 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef ARC_CODEC_TEST_MEDIACODEC_ENCODER_H_ #define ARC_CODEC_TEST_MEDIACODEC_ENCODER_H_ #include #include #include #include "common.h" namespace android { // Wrapper class to manipulate a MediaCodec video encoder. class MediaCodecEncoder { public: // Checks the argument and create MediaCodecEncoder instance. static std::unique_ptr Create(std::string input_path, VideoCodecType type, Size visible_size, bool use_sw_encoder); MediaCodecEncoder() = delete; ~MediaCodecEncoder(); using EncodeInputBufferCb = std::function; // The callback function that is called when output buffer is ready. using OutputBufferReadyCb = std::function; void SetEncodeInputBufferCb(const EncodeInputBufferCb& cb); void SetOutputBufferReadyCb(const OutputBufferReadyCb& cb); // Encoder manipulation methods. // Rewind the frame index to the beginning of the input stream. void Rewind(); // Wrapper of AMediaCodec_configure. bool Configure(int32_t bitrate, int32_t framerate); // Wrapper of AMediaCodec_start. bool Start(); // Encode the test stream. After encoding, send EOS request to the // encoder. Return true if EOS output buffer is received. bool Encode(); // Wrapper of AMediaCodec_stop. bool Stop(); // Setter and getter method of |num_encoded_frames_|; void set_num_encoded_frames(size_t num_encoded_frames); size_t num_encoded_frames() const; // Setter method of |run_at_fps_|. void set_run_at_fps(bool run_at_fps); private: MediaCodecEncoder(AMediaCodec* codec, VideoCodecType type, std::unique_ptr inputFile, Size size, size_t bufferSize, size_t numTotalFrames); // Read the content from the |input_file_| and feed into the input buffer. // |index| is the index of the target input buffer. bool FeedInputBuffer(size_t index); // Feed an empty buffer with EOS flag. // |index| is the index of the target input buffer. bool FeedEOSInputBuffer(size_t index); // Receive the output buffer and write into the |mOutputFile|. // |index| is the index of the target output buffer. // |info| is the buffer info of the target output buffer. bool ReceiveOutputBuffer(size_t index, const AMediaCodecBufferInfo& info); // The resolution of the input video stream. const Size kVisibleSize; // The buffer size of one frame, i.e. (width * height * 1.5) because now // only YUV I420 is supported. const size_t kBufferSize; // The frame number of the input video stream. const size_t kNumTotalFrames; // The target mediacodec encoder. AMediaCodec* codec_; // The output codec type. VideoCodecType type_; // The number of frames to encode. size_t num_encoded_frames_; // The input video raw stream file. The file size must be the multiple of // |kBufferSize|. std::unique_ptr input_file_; // The target output bitrate. int bitrate_ = 192000; // The target output framerate. int framerate_ = 30; // Encode the data at the |framerate_|. bool run_at_fps_ = false; // The callback function which is called right before queueing one input // buffer. EncodeInputBufferCb encode_input_buffer_cb_; // The callback function which is called when an output buffer is ready. OutputBufferReadyCb output_buffer_ready_cb_; // The frame index that indicates which frame is sent to the encoder at // next round. size_t input_frame_index_ = 0; }; } // namespace android #endif // ARC_CODEC_TEST_MEDIACODEC_ENCODER_H_