From: Sejun Park Date: Thu, 28 Apr 2016 10:54:51 +0000 (+0900) Subject: [ACR-567] Add API for getting media packet pool X-Git-Tag: submit/tizen/20160519.011519~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ada5bb5e21ce631cb5b4b5056dfcc7a2c6cb1ac4;p=platform%2Fcore%2Fapi%2Fmediacodec.git [ACR-567] Add API for getting media packet pool Change-Id: I69065d859700f1680761ba36548c75449abdd8dd --- diff --git a/include/media_codec.h b/include/media_codec.h index 827853e..011d5ba 100755 --- a/include/media_codec.h +++ b/include/media_codec.h @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -563,6 +564,27 @@ int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_suppo */ int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type); +/** + * @brief Gets the media packet pool allocated for recycling media packets. + * @details The user can get the pool allocated with the number of packets are required to be used in codecs.\n + * It is recomended to use media packet pool for better stability and performance. + * @since_tizen 3.0 + * @remarks The @a pool should be released using media_packet_pool_deallocate() and destroyed using media_packet_pool_destroy(). + * @param[in] mediacodec The mediacodec handle + * @param[out] pool The allocated pool handle + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIACODEC_ERROR_NONE Successful + * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MEDIACODEC_ERROR_INVALID_OPERATION The user calls mediacodec_get_packet_pool() before calling mediacodec_prepare(). + * @pre mediacodec_get_packet_pool() should be called after calling mediacodec_prepare(). + * @post If the pool is used, media_packet_pool_deallocate() and media_packet_pool_destroy() should be called. + * @see media_packet_pool_acquire_packet() + * @see media_packet_pool_release_packet() + * @see media_packet_pool_deallocate() + * @see media_packet_pool_destroy() + */ +int mediacodec_get_packet_pool(mediacodec_h mediacodec, media_packet_pool_h *pool); /** * @} diff --git a/include/media_codec_port.h b/include/media_codec_port.h index 23074eb..5d3975c 100755 --- a/include/media_codec_port.h +++ b/include/media_codec_port.h @@ -63,26 +63,27 @@ */ typedef enum { - MC_ERROR_NONE = 0, - MC_ERROR = -1, /**< codec happens error */ - MC_MEMORY_ERROR = -2, /**< codec memory is not enough */ - MC_PARAM_ERROR = -3, /**< codec parameter is error */ - MC_INVALID_ARG = -4, /** < codec has invalid arguments */ - MC_PERMISSION_DENIED = -5, - MC_INVALID_STATUS = -6, /**< codec works at invalid status */ - MC_NOT_SUPPORTED = -7, /**< codec can't support this specific video format */ - MC_INVALID_IN_BUF = -8, - MC_INVALID_OUT_BUF = -9, - MC_INTERNAL_ERROR = -10, - MC_HW_ERROR = -11, /**< codec happens hardware error */ - MC_NOT_INITIALIZED = -12, - MC_INVALID_STREAM = -13, - MC_CODEC_NOT_FOUND = -14, - MC_ERROR_DECODE = -15, - MC_OUTPUT_BUFFER_EMPTY = -16, - MC_OUTPUT_BUFFER_OVERFLOW = -17, /**< codec output buffer is overflow */ - MC_MEMORY_ALLOCED = -18, /**< codec has got memory and can decode one frame */ - MC_COURRPTED_INI = -19, + MC_ERROR_NONE = 0, + MC_ERROR = -1, /**< codec happens error */ + MC_MEMORY_ERROR = -2, /**< codec memory is not enough */ + MC_PARAM_ERROR = -3, /**< codec parameter is error */ + MC_INVALID_ARG = -4, /** < codec has invalid arguments */ + MC_PERMISSION_DENIED = -5, + MC_INVALID_STATUS = -6, /**< codec works at invalid status */ + MC_NOT_SUPPORTED = -7, /**< codec can't support this specific video format */ + MC_INVALID_IN_BUF = -8, + MC_INVALID_OUT_BUF = -9, + MC_INTERNAL_ERROR = -10, + MC_HW_ERROR = -11, /**< codec happens hardware error */ + MC_NOT_INITIALIZED = -12, + MC_INVALID_STREAM = -13, + MC_CODEC_NOT_FOUND = -14, + MC_ERROR_DECODE = -15, + MC_OUTPUT_BUFFER_EMPTY = -16, + MC_OUTPUT_BUFFER_OVERFLOW = -17, /**< codec output buffer is overflow */ + MC_MEMORY_ALLOCED = -18, /**< codec has got memory and can decode one frame */ + MC_COURRPTED_INI = -19, + MC_OUT_OF_MEMORY = -20, /**< when memory is not allocated */ } mc_ret_e; /*--------------------------------------------------------------------------- @@ -237,6 +238,8 @@ int mc_get_output(MMHandleType mediacodec, media_packet_h *outbuf, uint64_t time int mc_flush_buffers(MMHandleType mediacodec); int mc_get_supported_type(MMHandleType mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type); +int mc_get_packet_pool(MMHandleType mediacodec, media_packet_pool_h *pool); + int mc_set_empty_buffer_cb(MMHandleType mediacodec, mediacodec_input_buffer_used_cb callback, void* user_data); int mc_unset_empty_buffer_cb(MMHandleType mediacodec); @@ -253,6 +256,7 @@ int mc_set_buffer_status_cb(MMHandleType mediacodec, mediacodec_buffer_status_cb int mc_unset_buffer_status_cb(MMHandleType mediacodec); int mc_set_supported_codec_cb(MMHandleType mediacodec, mediacodec_supported_codec_cb callback, void* user_data); int _mediacodec_foreach_supported_codec(MMHandleType mediacodec, mediacodec_supported_codec_cb callback, void* user_data); + #ifdef __cplusplus } #endif diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index bbc2c23..4a396ef 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -50,6 +50,7 @@ extern "C" { #define SCMN_IMGB_MAX_PLANE 4 #define TBM_API_CHANGE +#define DEFAULT_POOL_SIZE 20 /* gst port layer */ typedef struct _mc_gst_port_t mc_gst_port_t; @@ -201,10 +202,6 @@ int __mc_aenc_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, int __mc_adec_vorbis_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); int __mc_adec_flac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); int __mc_adec_wma_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, gboolean codec_config); -bool _mc_is_voss (unsigned char *p, int size, int *codec_size); -bool _mc_is_ivop (unsigned char *p, int size, int pos); -bool _mc_is_vop (unsigned char *p, int size, int pos); - void _mc_create_codec_map_from_ini(mc_handle_t *mc_handle, mc_codec_spec_t *spec_emul); void _mc_create_decoder_map_from_ini(mc_handle_t *mc_handle); @@ -223,6 +220,8 @@ mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint6 mc_ret_e mc_gst_flush_buffers(mc_handle_t *mc_handle); +mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pkt_pool); + #ifdef __cplusplus } #endif diff --git a/src/media_codec.c b/src/media_codec.c index a9b48ec..0bfcaf2 100755 --- a/src/media_codec.c +++ b/src/media_codec.c @@ -96,6 +96,10 @@ int __convert_error_code(int code, char *func_name) ret = MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE; msg = "MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE"; break; + case MC_OUT_OF_MEMORY: + ret = MEDIACODEC_ERROR_OUT_OF_MEMORY; + msg = "MEDIACODEC_ERROR_OUT_OF_MEMORY"; + break; default: ret = MEDIACODEC_ERROR_INTERNAL; msg = "MEDIACODEC_ERROR_INTERNAL"; @@ -486,6 +490,19 @@ int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_suppo } +int mediacodec_get_packet_pool(mediacodec_h mediacodec,media_packet_pool_h *pkt_pool) +{ + MEDIACODEC_INSTANCE_CHECK(mediacodec); + mediacodec_s *handle = (mediacodec_s *)mediacodec; + MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY); + int ret = mc_get_packet_pool(handle->mc_handle,pkt_pool); + + if (ret != MEDIACODEC_ERROR_NONE) + return MEDIACODEC_ERROR_INVALID_OPERATION; + else + return MEDIACODEC_ERROR_NONE; +} + static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data) { if (user_data == NULL || pkt == NULL) diff --git a/src/media_codec_port.c b/src/media_codec_port.c index 0ab33d9..a7e15af 100755 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -715,3 +715,34 @@ CALLBACK_ERROR: return ret; } +int mc_get_packet_pool(MMHandleType mediacodec, media_packet_pool_h *pool) +{ + int ret = MC_ERROR_NONE; + mc_handle_t *mc_handle = (mc_handle_t *)mediacodec; + + if (!mc_handle) { + LOGE("fail invaild param\n"); + return MC_INVALID_ARG; + } + + /* setting core details */ + switch (mc_handle->port_type) { + case MEDIACODEC_PORT_TYPE_GENERAL: + break; + + case MEDIACODEC_PORT_TYPE_OMX: + break; + + case MEDIACODEC_PORT_TYPE_GST: + ret = mc_gst_get_packet_pool(mc_handle, pool); + break; + + default: + break; + } + + return ret; +} + + + diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 2a397c9..76bf0b4 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -84,6 +84,8 @@ static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, static void _mc_send_eos_signal(mc_gst_core_t *core); static void _mc_wait_for_eos(mc_gst_core_t *core); +static int _mediacodec_get_mime(mc_gst_core_t *core); + /* video vtable */ int(*vdec_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_vdec_packet_with_outbuf, &__mc_vdec_caps}; int(*venc_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_venc_packet_with_outbuf, &__mc_venc_caps}; @@ -3251,3 +3253,151 @@ const gchar * _mc_error_to_string(mc_ret_e err) } } +int _mediacodec_get_mime(mc_gst_core_t *core) +{ + media_format_mimetype_e mime; + + switch (core->codec_id) { + case MEDIACODEC_H264: + if (core->encoder) + mime = (core->is_hw) ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420; + else + mime = MEDIA_FORMAT_H264_SP; + break; + case MEDIACODEC_MPEG4: + if (core->encoder) + mime = (core->is_hw) ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420; + else + mime = MEDIA_FORMAT_MPEG4_SP; + + break; + case MEDIACODEC_H263: + if (core->encoder) + mime = (core->is_hw) ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420; + else + mime = MEDIA_FORMAT_H263P; + + break; + case MEDIACODEC_AAC: + if (core->encoder) + mime = MEDIA_FORMAT_PCM; + else + mime = MEDIA_FORMAT_AAC; + + break; + case MEDIACODEC_AAC_HE: + if (core->encoder) + mime = MEDIA_FORMAT_PCM; + else + mime = MEDIA_FORMAT_AAC_HE; + + break; + case MEDIACODEC_AAC_HE_PS: + break; + case MEDIACODEC_MP3: + mime = MEDIA_FORMAT_MP3; + break; + case MEDIACODEC_VORBIS: + break; + case MEDIACODEC_FLAC: + break; + case MEDIACODEC_WMAV1: + break; + case MEDIACODEC_WMAV2: + break; + case MEDIACODEC_WMAPRO: + break; + case MEDIACODEC_WMALSL: + break; + case MEDIACODEC_AMR_NB: + mime = MEDIA_FORMAT_AMR_NB; + break; + case MEDIACODEC_AMR_WB: + mime = MEDIA_FORMAT_AMR_WB; + break; + default: + LOGE("NOT SUPPORTED!!!!"); + break; + } + return mime; +} + +mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pkt_pool) +{ + int curr_size; + int max_size, min_size; + media_format_mimetype_e mime_format; + media_format_h *fmt_handle = NULL; + mc_gst_core_t *core = NULL; + + if (!mc_handle) + return MC_PARAM_ERROR; + + core = (mc_gst_core_t *)mc_handle->core; + + int ret = media_packet_pool_create(pkt_pool); + + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_pool_create failed"); + return MC_ERROR; + } + + if (media_format_create(&fmt_handle) != MEDIA_FORMAT_ERROR_NONE) { + LOGE("media format create failed"); + return MC_ERROR; + } + + mime_format = _mediacodec_get_mime(core); + + if (core->video) { + if (core->encoder) { + media_format_set_video_mime(fmt_handle, mime_format); + media_format_set_video_width(fmt_handle, mc_handle->info.encoder.width); + media_format_set_video_height(fmt_handle, mc_handle->info.encoder.height); + media_format_set_video_avg_bps(fmt_handle, mc_handle->info.encoder.bitrate); + } else { + media_format_set_video_mime(fmt_handle, mime_format); + media_format_set_video_width(fmt_handle, mc_handle->info.decoder.width); + media_format_set_video_height(fmt_handle, mc_handle->info.decoder.height); + } + + } else { + if (core->encoder) { + media_format_set_audio_mime(fmt_handle, mime_format); + media_format_set_audio_channel(fmt_handle, mc_handle->info.encoder.channel); + media_format_set_audio_samplerate(fmt_handle, mc_handle->info.encoder.samplerate); + media_format_set_audio_bit(fmt_handle, mc_handle->info.encoder.bit); + } else { + media_format_set_audio_mime(fmt_handle, mime_format); + media_format_set_audio_channel(fmt_handle, mc_handle->info.decoder.channel); + media_format_set_audio_samplerate(fmt_handle, mc_handle->info.decoder.samplerate); + media_format_set_audio_bit(fmt_handle, mc_handle->info.decoder.bit); + } + } + + ret = media_packet_pool_set_media_format(*pkt_pool, fmt_handle); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_pool_set_media_format failed"); + return MC_ERROR; + } + + /* will use default size temporarily */ + max_size = DEFAULT_POOL_SIZE; + + min_size = max_size; + ret = media_packet_pool_set_size(*pkt_pool, min_size, max_size); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_pool_set_size failed"); + return MC_ERROR; + } + + media_packet_pool_get_size(*pkt_pool, &min_size, &max_size, &curr_size); + LOGD("curr_size is %d min_size is %d and max_size is %d \n", curr_size, min_size, max_size); + + ret = media_packet_pool_allocate(*pkt_pool); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_pool_allocate failed"); + return MC_OUT_OF_MEMORY; + } + return MC_ERROR_NONE; +}