static gboolean gst_marudec_open (GstMaruDec *marudec);
static void gst_marudec_close (GstMaruDec *marudec);
+// for profile
+static GTimer* profile_decode_timer = NULL;
+static gdouble elapsed_decode_time = 0;
+static int decoded_frame_cnt = 0;
+static int last_frame_cnt = 0;
+static GMutex profile_mutex;
+static int profile_init = 0;
+
+static gboolean
+maru_profile_cb (gpointer user_data)
+{
+ int decoding_fps = 0;
+ gdouble decoding_time = 0;
+
+ g_mutex_lock (&profile_mutex);
+ if (decoded_frame_cnt < 0) {
+ decoded_frame_cnt = 0;
+ last_frame_cnt = 0;
+ elapsed_decode_time = 0;
+ g_mutex_unlock (&profile_mutex);
+ return FALSE;
+ }
+
+ decoding_fps = decoded_frame_cnt - last_frame_cnt;
+ last_frame_cnt = decoded_frame_cnt;
+
+ decoding_time = elapsed_decode_time;
+ elapsed_decode_time = 0;
+ g_mutex_unlock (&profile_mutex);
+
+ GST_DEBUG ("decoding fps=%d, latency=%f\n", decoding_fps, decoding_time/decoding_fps);
+ return TRUE;
+}
+
+static void init_codec_profile(void)
+{
+ if (!profile_init) {
+ profile_init = 1;
+ profile_decode_timer = g_timer_new();
+ }
+}
+
+static void reset_codec_profile(void)
+{
+ g_mutex_lock (&profile_mutex);
+ decoded_frame_cnt = -1;
+ g_mutex_lock (&profile_mutex);
+}
+
+static void begin_video_decode_profile(void)
+{
+ g_timer_start(profile_decode_timer);
+}
+
+static void end_video_decode_profile(void)
+{
+ g_timer_stop(profile_decode_timer);
+
+ g_mutex_lock (&profile_mutex);
+ if (decoded_frame_cnt == 0) {
+ g_timeout_add_seconds(1, maru_profile_cb, NULL);
+ }
+
+ elapsed_decode_time += g_timer_elapsed(profile_decode_timer, NULL);
+ decoded_frame_cnt++;
+ g_mutex_unlock (&profile_mutex);
+}
+
+#define INIT_CODEC_PROFILE(fd) \
+ if (interface->get_profile_status(fd)) { \
+ init_codec_profile(); \
+ }
+#define RESET_CODEC_PROFILE(s) \
+ if (profile_init) { \
+ reset_codec_profile(); \
+ }
+#define BEGIN_VIDEO_DECODE_PROFILE() \
+ if (profile_init) { \
+ begin_video_decode_profile(); \
+ }
+#define END_VIDEO_DECODE_PROFILE() \
+ if (profile_init) { \
+ end_video_decode_profile(); \
+ }
+
static const GstTSInfo *
gst_ts_info_store (GstMaruDec *dec, GstClockTime timestamp,
marudec->proportion = 0.0;
marudec->earliest_time = -1;
+ // initialize profile resource
+ INIT_CODEC_PROFILE(marudec->dev->fd);
+
return TRUE;
}
g_free(marudec->dev);
marudec->dev = NULL;
}
+
+ // reset profile resource
+ RESET_CODEC_PROFILE();
}
GST_DEBUG_OBJECT (marudec, "decode video: input buffer size %d", size);
+ // begin video decode profile
+ BEGIN_VIDEO_DECODE_PROFILE();
+
len = interface->decode_video (marudec, data, size,
dec_info->idx, in_offset, outbuf, &have_data);
if (len < 0 || !have_data) {
return len;
}
+ // end video decode profile
+ END_VIDEO_DECODE_PROFILE();
+
*ret = get_output_buffer (marudec, outbuf);
if (G_UNLIKELY (*ret != GST_FLOW_OK)) {
GST_DEBUG_OBJECT (marudec, "no output buffer");
IOCTL_CMD_TRY_SECURE_BUFFER,
IOCTL_CMD_RELEASE_BUFFER,
IOCTL_CMD_INVOKE_API_AND_GET_DATA,
+ IOCTL_CMD_GET_PROFILE_STATUS,
};
typedef struct {
return elements;
}
+static int
+get_profile_status (int fd)
+{
+ uint8_t profile_status;
+ int ret;
+
+ ret = ioctl (fd, IOCTL_RW(IOCTL_CMD_GET_PROFILE_STATUS), &profile_status);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return profile_status;
+}
+
// Interfaces
Interface *interface_version_3 = &(Interface) {
.init = init,
.buffer_alloc_and_copy = buffer_alloc_and_copy,
.get_device_version = get_device_version,
.prepare_elements = prepare_elements,
+ .get_profile_status = get_profile_status,
};