#ifndef MEDIA_GPU_ANDROID_NDK_AUDIO_ENCODER_H_
#define MEDIA_GPU_ANDROID_NDK_AUDIO_ENCODER_H_
#include <memory>
#include "base/android/requires_api.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_encoder.h"
#include "media/base/audio_parameters.h"
#include "media/base/encoder_status.h"
#include "media/formats/mp4/aac.h"
#include "media/gpu/android/ndk_media_codec_wrapper.h"
#include "media/gpu/media_gpu_export.h"
namespace media {
class AudioTimestampHelper;
class ConvertingAudioFifo;
class REQUIRES_ANDROID_API(NDK_MEDIA_CODEC_MIN_API)
MEDIA_GPU_EXPORT NdkAudioEncoder : public AudioEncoder,
public NdkMediaCodecWrapper::Client {
public:
explicit NdkAudioEncoder(scoped_refptr<base::SequencedTaskRunner> runner);
NdkAudioEncoder(const NdkAudioEncoder&) = delete;
NdkAudioEncoder& operator=(const NdkAudioEncoder&) = delete;
~NdkAudioEncoder() override;
void Initialize(const Options& options,
OutputCB output_callback,
EncoderStatusCB done_cb) override;
void Encode(std::unique_ptr<AudioBus> audio_bus,
base::TimeTicks capture_time,
EncoderStatusCB done_cb) override;
void Flush(EncoderStatusCB done_cb) override;
void OnInputAvailable() override;
void OnOutputAvailable() override;
void OnError(media_status_t error) override;
private:
enum class FlushState {
kNone,
kFlushingInputs,
kPendingEOS,
kNeedsMediaCodec,
};
bool CreateAndStartMediaCodec();
void ClearMediaCodec();
void FeedAllInputs();
bool InputReady();
void FeedInput(const AudioBus* audio_bus);
void MaybeFeedEos();
void FeedEos();
void CompleteFlush();
void DrainOutput();
bool DrainConfig();
void LogError(EncoderStatus status);
void LogAndReportError(EncoderStatus status, EncoderStatusCB done_cb);
void ReportPendingError(EncoderStatusCB done_cb);
void ReportOk(EncoderStatusCB done_cb);
SEQUENCE_CHECKER(sequence_checker_);
const scoped_refptr<base::SequencedTaskRunner> task_runner_;
AudioParameters output_params_;
bool error_occurred_ = false;
std::optional<EncoderStatus> pending_error_status_;
FlushState flush_state_ GUARDED_BY_CONTEXT(sequence_checker_) =
NdkAudioEncoder::FlushState::kNone;
EncoderStatusCB pending_flush_cb_;
std::unique_ptr<ConvertingAudioFifo> fifo_
GUARDED_BY_CONTEXT(sequence_checker_);
std::unique_ptr<AudioTimestampHelper> input_timestamp_tracker_
GUARDED_BY_CONTEXT(sequence_checker_);
std::unique_ptr<AudioTimestampHelper> output_timestamp_tracker_
GUARDED_BY_CONTEXT(sequence_checker_);
std::vector<uint8_t> codec_desc_;
std::vector<uint8_t> temp_header_buffer_;
mp4::AAC aac_config_parser_;
std::unique_ptr<NdkMediaCodecWrapper> media_codec_;
};
}
#endif