From: gunsoo83.kim Date: Thu, 4 Dec 2014 07:30:28 +0000 (+0900) Subject: brillcodec: add profile module for decoding fps/latency. X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.2~619^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=05ad031692bd2202924e6665c85a37972eb31d91;p=sdk%2Femulator%2Fqemu.git brillcodec: add profile module for decoding fps/latency. - To profile codec performance in device layer, add profile module to brillcodec device. Change-Id: I1c476927afe69dbac76d6091f7f8c9810d85c691 Signed-off-by: gunsoo83.kim --- diff --git a/tizen/src/hw/pci/maru_brillcodec.c b/tizen/src/hw/pci/maru_brillcodec.c index db7a6e8ac6..5b0d1e97d3 100644 --- a/tizen/src/hw/pci/maru_brillcodec.c +++ b/tizen/src/hw/pci/maru_brillcodec.c @@ -57,6 +57,129 @@ MULTI_DEBUG_CHANNEL(qemu, brillcodec); // misc #define OFFSET_PICTURE_BUFFER (0x100) +// for profile +#include + +static GTimer* profile_decode_timer = NULL; +static GTimer* profile_copy_timer = NULL; +static gdouble elapsed_decode_time = 0; +static gdouble elapsed_copying_time = 0; +static int decoded_frame_cnt = 0; +static int last_frame_cnt = 0; +static QemuMutex profile_mutex; +static int profile_init = 0; + +static gboolean +maru_profile_cb (gpointer user_data) +{ + int decoding_fps = 0; + gdouble decoding_time = 0; + gdouble copying_time = 0; + gdouble total_latency_time = 0; + + qemu_mutex_lock(&profile_mutex); + if (decoded_frame_cnt < 0) { + decoded_frame_cnt = 0; + last_frame_cnt = 0; + elapsed_decode_time = 0; + elapsed_copying_time = 0; + qemu_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; + copying_time = elapsed_copying_time; + elapsed_decode_time = 0; + elapsed_copying_time = 0; + qemu_mutex_unlock(&profile_mutex); + + total_latency_time = decoding_time + copying_time; + INFO("decoding fps=%d, latency=%f(decode=%f + get_picture=%f)\n", + decoding_fps, total_latency_time/decoding_fps, + decoding_time/decoding_fps, copying_time/decoding_fps); + + return TRUE; +} + +static void init_codec_profile(void) +{ + if (!profile_init) { + profile_init = 1; + qemu_mutex_init(&profile_mutex); + profile_decode_timer = g_timer_new(); + profile_copy_timer = g_timer_new(); + } +} + +static void reset_codec_profile(void) +{ + qemu_mutex_lock(&profile_mutex); + decoded_frame_cnt = -1; + qemu_mutex_unlock(&profile_mutex); +} + +static void begin_video_decode_profile(void) +{ + g_timer_start(profile_decode_timer); +} + +static void begin_video_copy_profile(void) +{ + g_timer_start(profile_copy_timer); +} + +static void end_video_decode_profile(void) +{ + g_timer_stop(profile_decode_timer); + + qemu_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++; + qemu_mutex_unlock(&profile_mutex); +} + +static void end_video_copy_profile(void) +{ + g_timer_stop(profile_copy_timer); + + qemu_mutex_lock(&profile_mutex); + elapsed_copying_time += g_timer_elapsed(profile_copy_timer, NULL); + qemu_mutex_unlock(&profile_mutex); +} + +#define INIT_CODEC_PROFILE(s) \ + if ((s)->profile) { \ + init_codec_profile(); \ + } +#define RESET_CODEC_PROFILE() \ + 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(); \ + } +#define BEGIN_VIDEO_COPY_PROFILE() \ + if (profile_init) { \ + begin_video_copy_profile(); \ + } +#define END_VIDEO_COPY_PROFILE() \ + if (profile_init) { \ + end_video_copy_profile(); \ + } + + // // COMMON // @@ -734,12 +857,18 @@ static void copy_video_decode_data(void *dst, void *opaque, size_t dummy) } if (dc->frame) { + // begin video copy profile + BEGIN_VIDEO_COPY_PROFILE(); + // if picture is exist... if (context->is_hwaccel) { plugin->get_picture(dst + dc->picture_buffer_offset, dc->frame); } else { default_get_picture(dst + dc->picture_buffer_offset, dc->frame, dc->avctx->pix_fmt); } + + // end video copy profile + END_VIDEO_COPY_PROFILE(); } g_free(dc); @@ -816,9 +945,15 @@ static uint32_t parse_and_decode_video(AVCodecContext *avctx, AVFrame *picture, TRACE("not using parser %s\n", avctx->codec->name); } + // begin video decode profile + BEGIN_VIDEO_DECODE_PROFILE(); + len = avcodec_decode_video2(avctx, picture, (int *)got_picture, packet); TRACE("decode_video. len %d, got_picture %d\n", len, *got_picture); + // end video decode profile + END_VIDEO_DECODE_PROFILE(); + if (!pctx) { if (len == 0 && (*got_picture) == 0) { ERR("decoding video didn't return any data! ctx_id %d len %d\n", ctx_id, len); @@ -1690,6 +1825,9 @@ static bool init(MaruBrillCodecState *s, int ctx_id, void *data_buf) elem = (DeviceMemEntry *)data_buf; + // initialize profile resource + INIT_CODEC_PROFILE(s); + // allocate AVCodecContext avctx = maru_brill_codec_alloc_context(s, ctx_id); if (!avctx) { @@ -1819,6 +1957,9 @@ static bool deinit(MaruBrillCodecState *s, int ctx_id, void *data_buf) brillcodec_push_writequeue(s, NULL, 0, ctx_id, NULL); + // reset profile resource + RESET_CODEC_PROFILE(); + TRACE("leave: %s\n", __func__); return true; diff --git a/tizen/src/hw/pci/maru_brillcodec.h b/tizen/src/hw/pci/maru_brillcodec.h index 53b3681927..63d2cef1de 100644 --- a/tizen/src/hw/pci/maru_brillcodec.h +++ b/tizen/src/hw/pci/maru_brillcodec.h @@ -100,6 +100,8 @@ struct MaruBrillCodecState { CodecParam ioparam; uint16_t memory_monopolizing; + + uint8_t profile; CodecPlugin *hwaccel_plugin; }; diff --git a/tizen/src/hw/pci/maru_brillcodec_device.c b/tizen/src/hw/pci/maru_brillcodec_device.c index ff028c570a..15e02877d6 100644 --- a/tizen/src/hw/pci/maru_brillcodec_device.c +++ b/tizen/src/hw/pci/maru_brillcodec_device.c @@ -62,6 +62,7 @@ enum device_cmd { DEVICE_CMD_GET_ELEMENT, DEVICE_CMD_GET_CONTEXT_INDEX, DEVICE_CMD_GET_DEVICE_INFO, + DEVICE_CMD_GET_PROFILE_STATUS, }; enum thread_state { @@ -189,6 +190,11 @@ static uint64_t brillcodec_read(void *opaque, TRACE("get context index: %d\n", ret); break; + case DEVICE_CMD_GET_PROFILE_STATUS: + ret = s->profile; + TRACE("profile status: %d\n", s->profile); + break; + default: ERR("no avaiable command for read. %d\n", addr); } @@ -294,6 +300,10 @@ static int brillcodec_initfn(PCIDevice *dev) # endif #endif + if (s->profile) { + INFO("Profile the brillcodec.(%d)\n", s->profile); + } + return 0; } @@ -323,6 +333,11 @@ static void brillcodec_reset(DeviceState *d) memset(&s->ioparam, 0, sizeof(CodecParam)); } +static Property brillcodec_props[] = { + DEFINE_PROP_UINT8("profile", MaruBrillCodecState, profile, 0), + DEFINE_PROP_END_OF_LIST(), +}; + static void brillcodec_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -334,6 +349,7 @@ static void brillcodec_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_VIRTUAL_BRILL_CODEC; k->class_id = PCI_CLASS_OTHERS; dc->reset = brillcodec_reset; + dc->props = brillcodec_props; dc->desc = "Virtual new codec device for Tizen emulator"; }