1 // Copyright 2020 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef ARC_CODEC_TEST_MEDIACODEC_ENCODER_H_ 6 #define ARC_CODEC_TEST_MEDIACODEC_ENCODER_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include <media/NdkMediaCodec.h> 12 13 #include "common.h" 14 15 namespace android { 16 17 // Wrapper class to manipulate a MediaCodec video encoder. 18 class MediaCodecEncoder { 19 public: 20 // Checks the argument and create MediaCodecEncoder instance. 21 static std::unique_ptr<MediaCodecEncoder> Create(std::string input_path, VideoCodecType type, 22 Size visible_size, bool use_sw_encoder); 23 MediaCodecEncoder() = delete; 24 ~MediaCodecEncoder(); 25 26 using EncodeInputBufferCb = std::function<void(uint64_t /* time_us */)>; 27 // The callback function that is called when output buffer is ready. 28 using OutputBufferReadyCb = 29 std::function<void(const uint8_t* /* data */, const AMediaCodecBufferInfo& /* info */)>; 30 void SetEncodeInputBufferCb(const EncodeInputBufferCb& cb); 31 void SetOutputBufferReadyCb(const OutputBufferReadyCb& cb); 32 33 // Encoder manipulation methods. 34 // Rewind the frame index to the beginning of the input stream. 35 void Rewind(); 36 37 // Wrapper of AMediaCodec_configure. 38 bool Configure(int32_t bitrate, int32_t framerate); 39 40 // Wrapper of AMediaCodec_start. 41 bool Start(); 42 43 // Encode the test stream. After encoding, send EOS request to the 44 // encoder. Return true if EOS output buffer is received. 45 bool Encode(); 46 47 // Wrapper of AMediaCodec_stop. 48 bool Stop(); 49 50 // Setter and getter method of |num_encoded_frames_|; 51 void set_num_encoded_frames(size_t num_encoded_frames); 52 size_t num_encoded_frames() const; 53 // Setter method of |run_at_fps_|. 54 void set_run_at_fps(bool run_at_fps); 55 56 private: 57 MediaCodecEncoder(AMediaCodec* codec, VideoCodecType type, 58 std::unique_ptr<CachedInputFileStream> inputFile, Size size, 59 size_t bufferSize, size_t numTotalFrames); 60 61 // Read the content from the |input_file_| and feed into the input buffer. 62 // |index| is the index of the target input buffer. 63 bool FeedInputBuffer(size_t index); 64 65 // Feed an empty buffer with EOS flag. 66 // |index| is the index of the target input buffer. 67 bool FeedEOSInputBuffer(size_t index); 68 69 // Receive the output buffer and write into the |mOutputFile|. 70 // |index| is the index of the target output buffer. 71 // |info| is the buffer info of the target output buffer. 72 bool ReceiveOutputBuffer(size_t index, const AMediaCodecBufferInfo& info); 73 74 // The resolution of the input video stream. 75 const Size kVisibleSize; 76 // The buffer size of one frame, i.e. (width * height * 1.5) because now 77 // only YUV I420 is supported. 78 const size_t kBufferSize; 79 // The frame number of the input video stream. 80 const size_t kNumTotalFrames; 81 82 // The target mediacodec encoder. 83 AMediaCodec* codec_; 84 // The output codec type. 85 VideoCodecType type_; 86 // The number of frames to encode. 87 size_t num_encoded_frames_; 88 // The input video raw stream file. The file size must be the multiple of 89 // |kBufferSize|. 90 std::unique_ptr<CachedInputFileStream> input_file_; 91 // The target output bitrate. 92 int bitrate_ = 192000; 93 // The target output framerate. 94 int framerate_ = 30; 95 // Encode the data at the |framerate_|. 96 bool run_at_fps_ = false; 97 98 // The callback function which is called right before queueing one input 99 // buffer. 100 EncodeInputBufferCb encode_input_buffer_cb_; 101 // The callback function which is called when an output buffer is ready. 102 OutputBufferReadyCb output_buffer_ready_cb_; 103 104 // The frame index that indicates which frame is sent to the encoder at 105 // next round. 106 size_t input_frame_index_ = 0; 107 }; 108 109 } // namespace android 110 111 #endif // ARC_CODEC_TEST_MEDIACODEC_ENCODER_H_ 112