|
|
@@ -2,6 +2,8 @@
|
|
|
|
|
|
#include "device_audios.h"
|
|
|
#include "encoder_video_define.h"
|
|
|
+#include "encoder_video.h"
|
|
|
+#include "encoder_aac.h"
|
|
|
|
|
|
#include "record_audio_factory.h"
|
|
|
#include "record_desktop_factory.h"
|
|
|
@@ -55,6 +57,10 @@ public:
|
|
|
|
|
|
void set_preview_enabled(bool enable);
|
|
|
|
|
|
+ // Expose underlying encoders for diagnostics
|
|
|
+ encoder_video* get_video_encoder();
|
|
|
+ encoder_aac* get_audio_encoder();
|
|
|
+
|
|
|
private:
|
|
|
void on_preview_yuv(const uint8_t *data, int size, int width, int height, int type);
|
|
|
void get_valid_out_resolution(int src_width, int src_height, int *out_width, int *out_height);
|
|
|
@@ -327,6 +333,26 @@ void recorder::set_preview_enabled(bool enable)
|
|
|
_muxer->set_preview_enabled(enable);
|
|
|
}
|
|
|
|
|
|
+encoder_video* recorder::get_video_encoder()
|
|
|
+{
|
|
|
+ lock_guard lock(_mutex);
|
|
|
+ if (!_inited || _muxer == nullptr)
|
|
|
+ return nullptr;
|
|
|
+ auto mf = dynamic_cast<muxer_ffmpeg*>(_muxer);
|
|
|
+ if (!mf) return nullptr;
|
|
|
+ return mf->get_video_encoder();
|
|
|
+}
|
|
|
+
|
|
|
+encoder_aac* recorder::get_audio_encoder()
|
|
|
+{
|
|
|
+ lock_guard lock(_mutex);
|
|
|
+ if (!_inited || _muxer == nullptr)
|
|
|
+ return nullptr;
|
|
|
+ auto mf = dynamic_cast<muxer_ffmpeg*>(_muxer);
|
|
|
+ if (!mf) return nullptr;
|
|
|
+ return mf->get_audio_encoder();
|
|
|
+}
|
|
|
+
|
|
|
void recorder::on_preview_yuv(const uint8_t *data, int size, int width, int height, int type)
|
|
|
{
|
|
|
if (_callbacks.func_preview_yuv != NULL)
|
|
|
@@ -513,3 +539,74 @@ AMRECORDER_API void recorder_set_logpath(const char *path)
|
|
|
{
|
|
|
AMLog *log = AMLog::get(path);
|
|
|
}
|
|
|
+
|
|
|
+// ================= Ring buffer diagnostics =================
|
|
|
+AMRECORDER_API uint64_t recorder_get_video_rb_dropped()
|
|
|
+{
|
|
|
+ auto enc = am::recorder::instance()->get_video_encoder();
|
|
|
+ if (!enc) return 0;
|
|
|
+ return enc->rb_dropped_frames();
|
|
|
+}
|
|
|
+
|
|
|
+AMRECORDER_API int recorder_get_video_rb_pending()
|
|
|
+{
|
|
|
+ auto enc = am::recorder::instance()->get_video_encoder();
|
|
|
+ if (!enc) return 0;
|
|
|
+ return enc->rb_pending_frames();
|
|
|
+}
|
|
|
+
|
|
|
+AMRECORDER_API int recorder_get_video_rb_max()
|
|
|
+{
|
|
|
+ auto enc = am::recorder::instance()->get_video_encoder();
|
|
|
+ if (!enc) return 0;
|
|
|
+ return enc->rb_max_frames();
|
|
|
+}
|
|
|
+
|
|
|
+AMRECORDER_API void recorder_set_video_rb_max(int max_frames)
|
|
|
+{
|
|
|
+ auto enc = am::recorder::instance()->get_video_encoder();
|
|
|
+ if (!enc) return;
|
|
|
+ enc->rb_set_max_frames(max_frames);
|
|
|
+}
|
|
|
+
|
|
|
+AMRECORDER_API void recorder_reset_video_rb_dropped()
|
|
|
+{
|
|
|
+ auto enc = am::recorder::instance()->get_video_encoder();
|
|
|
+ if (!enc) return;
|
|
|
+ enc->rb_reset_dropped();
|
|
|
+}
|
|
|
+
|
|
|
+AMRECORDER_API uint64_t recorder_get_audio_rb_dropped()
|
|
|
+{
|
|
|
+ auto enc = am::recorder::instance()->get_audio_encoder();
|
|
|
+ if (!enc) return 0;
|
|
|
+ return enc->rb_dropped_frames();
|
|
|
+}
|
|
|
+
|
|
|
+AMRECORDER_API int recorder_get_audio_rb_pending()
|
|
|
+{
|
|
|
+ auto enc = am::recorder::instance()->get_audio_encoder();
|
|
|
+ if (!enc) return 0;
|
|
|
+ return enc->rb_pending_frames();
|
|
|
+}
|
|
|
+
|
|
|
+AMRECORDER_API int recorder_get_audio_rb_max()
|
|
|
+{
|
|
|
+ auto enc = am::recorder::instance()->get_audio_encoder();
|
|
|
+ if (!enc) return 0;
|
|
|
+ return enc->rb_max_frames();
|
|
|
+}
|
|
|
+
|
|
|
+AMRECORDER_API void recorder_set_audio_rb_max(int max_frames)
|
|
|
+{
|
|
|
+ auto enc = am::recorder::instance()->get_audio_encoder();
|
|
|
+ if (!enc) return;
|
|
|
+ enc->rb_set_max_frames(max_frames);
|
|
|
+}
|
|
|
+
|
|
|
+AMRECORDER_API void recorder_reset_audio_rb_dropped()
|
|
|
+{
|
|
|
+ auto enc = am::recorder::instance()->get_audio_encoder();
|
|
|
+ if (!enc) return;
|
|
|
+ enc->rb_reset_dropped();
|
|
|
+}
|