Sync with tizen 4.0
[platform/core/api/mediacodec.git] / src / media_codec_port.c
old mode 100644 (file)
new mode 100755 (executable)
index cf6843a..804a7cb
@@ -27,6 +27,9 @@
 #include <media_codec_spec_emul.h>
 #include <media_codec_ini.h>
 
+static gboolean _check_support_audio_info(mediacodec_codec_type_e codec_id, int samplerate, int channel, int bit_depth);
+static gboolean _check_support_video_info(mediacodec_codec_type_e codec_id, int width, int height);
+
 int mc_create(MMHandleType *mediacodec)
 {
        mc_handle_t *new_mediacodec = NULL;
@@ -168,7 +171,7 @@ int mc_set_vdec_info(MMHandleType mediacodec, int width, int height)
                return MC_INVALID_ARG;
        }
 
-       if ((width <= 0) || (height <= 0))
+       if (!_check_support_video_info(mc_handle->codec_id, width, height))
                return MC_PARAM_ERROR;
 
        MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && !mc_handle->is_encoder,
@@ -192,7 +195,7 @@ int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, in
                return MC_INVALID_ARG;
        }
 
-       if ((width <= 0) || (height <= 0))
+       if (!_check_support_video_info(mc_handle->codec_id, width, height) || fps < 0 || target_bits < 0)
                return MC_PARAM_ERROR;
 
        MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && mc_handle->is_encoder,
@@ -217,7 +220,7 @@ int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int b
                return MC_INVALID_ARG;
        }
 
-       if ((samplerate <= 0) || (channel <= 0) || (bit <= 0))
+       if (!_check_support_audio_info(mc_handle->codec_id, samplerate, channel, bit))
                return MC_PARAM_ERROR;
 
        MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && !mc_handle->is_encoder,
@@ -241,7 +244,7 @@ int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int b
                return MC_INVALID_ARG;
        }
 
-       if ((samplerate <= 0) || (channel <= 0) || (bit <= 0))
+       if (!_check_support_audio_info(mc_handle->codec_id, samplerate, channel, bit))
                return MC_PARAM_ERROR;
 
        MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && mc_handle->is_encoder,
@@ -287,8 +290,10 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags)
        if (type == MEDIA_FORMAT_AUDIO) {
                media_format_get_audio_info(format, &mimetype, &channel, &samplerate, &bit, &bitrate);
 
+               codec_id = mimetype & codec_mask;
+
                if (GET_IS_ENCODER(flags)) {
-                       if ((samplerate <= 0) || (channel <= 0) || (bit <= 0) || (bitrate <= 0)) {
+                       if (!_check_support_audio_info(codec_id, samplerate, channel, bit)) {
                                LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d, bitrate : %d",
                                        samplerate, channel, bit, bitrate);
                                return MC_PARAM_ERROR;
@@ -299,7 +304,7 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags)
                        mc_handle->info.audio.bit_depth = bit;
                        mc_handle->info.audio.bitrate = bitrate * 1000;
                } else if (GET_IS_DECODER(flags)) {
-                       if ((samplerate <= 0) || (channel <= 0) || (bit <= 0)) {
+                       if (!_check_support_audio_info(codec_id, samplerate, channel, bit)) {
                                LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d",
                                        samplerate, channel, bit);
                                return MC_PARAM_ERROR;
@@ -314,9 +319,10 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags)
        } else if (type == MEDIA_FORMAT_VIDEO) {
                media_format_get_video_info(format, &mimetype, &width, &height, &bitrate, NULL);
                media_format_get_video_frame_rate(format, &fps);
+               codec_id = mimetype & codec_mask;
 
                if (GET_IS_ENCODER(flags)) {
-                       if ((width <= 0) || (height <= 0) || (bitrate <= 0) || (fps <= 0)) {
+                       if (!_check_support_video_info(codec_id, width, height) || fps <= 0 || bitrate <= 0) {
                                LOGE("invalid pram is set : width : %d, height : %d, bitrate : %d, fps : %d",
                                        width, height, bitrate, fps);
                                return MC_PARAM_ERROR;
@@ -327,7 +333,7 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags)
                        mc_handle->info.video.framerate = fps;
                        mc_handle->info.video.bitrate = bitrate * 1000;
                } else if (GET_IS_DECODER(flags)) {
-                       if ((width <= 0) || (height <= 0)) {
+                       if (!_check_support_video_info(codec_id, width, height)) {
                                LOGE("invalid pram is set : width : %d, height : %d",
                                        width, height);
                                return MC_PARAM_ERROR;
@@ -347,8 +353,6 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags)
        if (!GET_IS_HW(flags) && !GET_IS_SW(flags))
                flags |= MEDIACODEC_SUPPORT_TYPE_SW;
 
-       codec_id = mimetype & codec_mask;
-
        for (i = 0; i < mc_handle->ini->num_supported_codecs; i++) {
                if ((codec_id == spec_emul[i].codec_id) && (flags == spec_emul[i].codec_type))
                        break;
@@ -988,7 +992,7 @@ void _mc_create_codec_map_from_ini_static(mc_ini_t *ini, mc_codec_spec_t *spec_e
        return;
 }
 
-const codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id)
+codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id)
 {
        guint media_codec_id_u = (guint)media_codec_id;
 
@@ -1052,7 +1056,7 @@ const codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e medi
        }
 }
 
-const codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id)
+mediacodec_codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id)
 {
        guint codec_id_u = (guint)codec_id;
 
@@ -1115,3 +1119,136 @@ const codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id)
                return NONE;
        }
 }
+
+gboolean _check_support_audio_info(mediacodec_codec_type_e codec_id, int samplerate, int channel, int bit_depth)
+{
+       gint i = 0;
+       gint maxchannels = 2;
+       gint n_rates = 0;
+       gint s_bit_depth = 32;
+
+       switch (codec_id) {
+       case MEDIACODEC_AMR_NB:
+       {
+               const static gint l_rates[] = { 8000 };
+               maxchannels = 1;
+               n_rates = G_N_ELEMENTS(l_rates);
+               s_bit_depth = 16;       /* NOTE: amrnbenc/amrnbdec surpports S16LE as format*/
+
+               while (i < n_rates) {
+                       if (l_rates[i] == samplerate)
+                               break;
+                       i++;
+               }
+
+               if (i == n_rates) {
+                       LOGE("Invalid samplerate set");
+                       return false;
+               }
+               break;
+       }
+       case MEDIACODEC_AAC_LC:
+       case MEDIACODEC_AAC_HE:
+       {
+               const static gint l_rates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 };
+               maxchannels = 6;
+               n_rates = G_N_ELEMENTS(l_rates);
+               s_bit_depth = 32;       /* NOTE: avdec_aac/avenc_aac surpports S32LE as format*/
+
+               while (i < n_rates) {
+                       if (l_rates[i] == samplerate)
+                               break;
+                       i++;
+               }
+
+               if (i == n_rates) {
+                       LOGE("Invalid samplerate set");
+                       return false;
+               }
+               break;
+       }
+       case MEDIACODEC_MP3:
+       {
+               s_bit_depth = 16;       /* NOTE: amrenc/amrnbdec surpports S16LE as format*/
+               break;
+       }
+       case MEDIACODEC_VORBIS:
+       {
+               s_bit_depth = 32;       /* NOTE:  vorbisenc/vorbisdec surpports S32LE as format */
+               break;
+       }
+       case MEDIACODEC_FLAC:
+       {
+               s_bit_depth = 32;       /* NOTE: avdec_flac surpports S32LE as format */
+               break;
+       }
+       default:
+               break;
+       }
+
+       if (channel < 0 || channel > maxchannels) {
+               LOGE("Invalid channel set");
+               return false;
+       }
+
+       if (bit_depth != s_bit_depth) {
+               LOGE("Invalid bit set");
+               return false;
+       }
+
+       return true;
+}
+
+gboolean _check_support_video_info(mediacodec_codec_type_e codec_id, int width, int height)
+{
+       gint i = 0;
+       gint n_sizes = 0;
+
+       if (width <= 0 || height <= 0) {
+               LOGE("Invalid resolution set");
+               return false;
+       }
+
+       switch (codec_id) {
+       case MEDIACODEC_H261:
+       {
+               const static gint widths[] = { 352, 176 };
+               const static gint heights[] = { 288, 144 };
+               n_sizes = G_N_ELEMENTS(widths);
+
+               while (i < n_sizes) {
+                       if ((widths[i] == width) && (heights[i] == height))
+                               break;
+                       i++;
+               }
+
+               if (i == n_sizes) {
+                       LOGE("Invalid resolution set");
+                       return false;
+               }
+               break;
+       }
+       case MEDIACODEC_H263:
+       {
+               const static gint widths[] = { 352, 704, 176, 1408, 128 };
+               const static gint heights[] = { 288, 576, 144, 1152, 96 };
+               n_sizes = G_N_ELEMENTS(widths);
+
+               while (i < n_sizes) {
+                       if ((widths[i] == width) && (heights[i] == height))
+                               break;
+                       i++;
+               }
+
+               if (i == n_sizes) {
+                       LOGE("Invalid resolution set");
+                       return false;
+               }
+               break;
+       }
+       default:
+               break;
+       }
+
+       return true;
+}