mediacodec: configure name and quirks from mc_api
authorThomas Guillem <thomas@gllm.fr>
Thu, 17 Mar 2016 13:59:39 +0000 (14:59 +0100)
committerThomas Guillem <thomas@gllm.fr>
Wed, 23 Mar 2016 13:47:50 +0000 (14:47 +0100)
modules/codec/omxil/mediacodec.c
modules/codec/omxil/mediacodec.h
modules/codec/omxil/mediacodec_jni.c
modules/codec/omxil/mediacodec_ndk.c

index 552779d..b978a3f 100644 (file)
@@ -27,7 +27,6 @@
 # include "config.h"
 #endif
 
-#include <jni.h>
 #include <stdint.h>
 #include <assert.h>
 
@@ -36,7 +35,6 @@
 #include <vlc_plugin.h>
 #include <vlc_codec.h>
 #include <vlc_block_helper.h>
-#include <vlc_cpu.h>
 #include <vlc_memory.h>
 #include <vlc_timestamp_helper.h>
 #include <vlc_threads.h>
@@ -430,7 +428,7 @@ static int StartMediaCodec(decoder_t *p_dec)
                 args.video.i_angle = 0;
         }
 
-        /* Check again the codec name if h264 profile changed */
+        /* Configure again if h264 profile changed */
         if (p_dec->fmt_in.i_codec == VLC_CODEC_H264
          && !p_sys->u.video.i_h264_profile)
         {
@@ -438,11 +436,8 @@ static int StartMediaCodec(decoder_t *p_dec)
                                    &p_sys->u.video.i_h264_profile, NULL, NULL);
             if (p_sys->u.video.i_h264_profile)
             {
-                free(p_sys->api->psz_name);
-                p_sys->api->psz_name = MediaCodec_GetName(VLC_OBJECT(p_dec),
-                                                          p_sys->api->psz_mime,
-                                                          p_sys->u.video.i_h264_profile);
-                if (!p_sys->api->psz_name)
+                if (p_sys->api->configure(p_sys->api,
+                                          p_sys->u.video.i_h264_profile) != 0 )
                     return VLC_EGENERIC;
             }
         }
@@ -509,6 +504,7 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
     decoder_t *p_dec = (decoder_t *)p_this;
     decoder_sys_t *p_sys;
     mc_api *api;
+    size_t i_h264_profile = 0;
     const char *mime = NULL;
     bool b_late_opening = false;
 
@@ -573,16 +569,26 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
         return VLC_EGENERIC;
     }
 
-    api = calloc(1, sizeof(mc_api));
-    if (!api)
+    if ((api = calloc(1, sizeof(mc_api))) == NULL)
         return VLC_ENOMEM;
     api->p_obj = p_this;
-    api->b_video = p_dec->fmt_in.i_cat == VIDEO_ES;
-    if (pf_init(api) != VLC_SUCCESS)
+    api->i_codec = p_dec->fmt_in.i_codec;
+    api->i_cat = p_dec->fmt_in.i_cat;
+    api->psz_mime = mime;
+
+    if (p_dec->fmt_in.i_codec == VLC_CODEC_H264)
+        h264_get_profile_level(&p_dec->fmt_in, &i_h264_profile, NULL, NULL);
+    if (pf_init(api) != 0)
     {
         free(api);
         return VLC_EGENERIC;
     }
+    if (api->configure(api, i_h264_profile) != 0)
+    {
+        api->clean(api);
+        free(api);
+        return VLC_EGENERIC;
+    }
 
     /* Allocate the memory needed to store the decoder's structure */
     if ((p_sys = calloc(1, sizeof(*p_sys))) == NULL)
@@ -601,7 +607,6 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
     p_dec->fmt_out.i_cat = p_dec->fmt_in.i_cat;
     p_dec->fmt_out.video = p_dec->fmt_in.video;
     p_dec->fmt_out.audio = p_dec->fmt_in.audio;
-    p_sys->api->psz_mime = mime;
 
     vlc_mutex_init(&p_sys->lock);
     vlc_cond_init(&p_sys->cond);
@@ -614,29 +619,16 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
         p_sys->pf_process_output = Video_ProcessOutput;
         p_sys->u.video.i_width = p_dec->fmt_in.video.i_width;
         p_sys->u.video.i_height = p_dec->fmt_in.video.i_height;
+        p_sys->u.video.i_h264_profile = i_h264_profile;
 
         p_sys->u.video.timestamp_fifo = timestamp_FifoNew(32);
         if (!p_sys->u.video.timestamp_fifo)
             goto bailout;
+
         TAB_INIT( p_sys->u.video.i_inflight_pictures,
                   p_sys->u.video.pp_inflight_pictures );
 
-        if (p_dec->fmt_in.i_codec == VLC_CODEC_H264)
-            h264_get_profile_level(&p_dec->fmt_in,
-                                   &p_sys->u.video.i_h264_profile, NULL, NULL);
-
-        p_sys->api->psz_name = MediaCodec_GetName(VLC_OBJECT(p_dec),
-                                                  p_sys->api->psz_mime,
-                                                  p_sys->u.video.i_h264_profile);
-        if (!p_sys->api->psz_name)
-            goto bailout;
-
-        p_sys->i_quirks = OMXCodec_GetQuirks(VIDEO_ES,
-                                             p_dec->fmt_in.i_codec,
-                                             p_sys->api->psz_name,
-                                             strlen(p_sys->api->psz_name));
-
-        if ((p_sys->i_quirks & OMXCODEC_VIDEO_QUIRKS_NEED_SIZE)
+        if ((p_sys->api->i_quirks & MC_API_VIDEO_QUIRKS_NEED_SIZE)
          && (!p_sys->u.video.i_width || !p_sys->u.video.i_height))
         {
             msg_Warn(p_dec, "waiting for a valid video size for codec %4.4s",
@@ -651,23 +643,14 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
         p_sys->pf_process_output = Audio_ProcessOutput;
         p_sys->u.audio.i_channels = p_dec->fmt_in.audio.i_channels;
 
-        p_sys->api->psz_name = MediaCodec_GetName(VLC_OBJECT(p_dec),
-                                                  p_sys->api->psz_mime, 0);
-        if (!p_sys->api->psz_name)
-            goto bailout;
-
-        p_sys->i_quirks = OMXCodec_GetQuirks(AUDIO_ES,
-                                             p_dec->fmt_in.i_codec,
-                                             p_sys->api->psz_name,
-                                             strlen(p_sys->api->psz_name));
-        if ((p_sys->i_quirks & OMXCODEC_AUDIO_QUIRKS_NEED_CHANNELS)
+        if ((p_sys->api->i_quirks & MC_API_AUDIO_QUIRKS_NEED_CHANNELS)
          && !p_sys->u.audio.i_channels)
         {
             msg_Warn(p_dec, "waiting for valid channel count");
             b_late_opening = true;
         }
     }
-    if ((p_sys->i_quirks & OMXCODEC_QUIRKS_NEED_CSD)
+    if ((p_sys->api->i_quirks & MC_API_QUIRKS_NEED_CSD)
      && !p_dec->fmt_in.i_extra)
     {
         msg_Warn(p_dec, "waiting for extra data for codec %4.4s",
@@ -742,7 +725,6 @@ static void CleanDecoder(decoder_t *p_dec)
         if (p_sys->u.video.p_awh)
             AWindowHandler_destroy(p_sys->u.video.p_awh);
     }
-    free(p_sys->api->psz_name);
     free(p_sys->api);
     free(p_sys);
 }
@@ -943,7 +925,7 @@ static int Video_ProcessOutput(decoder_t *p_dec, mc_api_out *p_out,
 
         if (p_sys->u.video.i_pixel_format == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar)
             p_sys->u.video.i_slice_height -= p_out->u.conf.video.crop_top/2;
-        if ((p_sys->i_quirks & OMXCODEC_VIDEO_QUIRKS_IGNORE_PADDING))
+        if ((p_sys->api->i_quirks & MC_API_VIDEO_QUIRKS_IGNORE_PADDING))
         {
             p_sys->u.video.i_slice_height = 0;
             p_sys->u.video.i_stride = p_dec->fmt_out.video.i_width;
@@ -1515,12 +1497,12 @@ static int Video_OnNewBlock(decoder_t *p_dec, block_t *p_block, int *p_flags)
         *p_flags |= NEWBLOCK_FLAG_RESTART;
 
         /* Don't start if we don't have any csd */
-        if ((p_sys->i_quirks & OMXCODEC_QUIRKS_NEED_CSD)
+        if ((p_sys->api->i_quirks & MC_API_QUIRKS_NEED_CSD)
          && !p_dec->fmt_in.i_extra && !p_sys->pp_csd)
             *p_flags &= ~NEWBLOCK_FLAG_RESTART;
 
         /* Don't start if we don't have a valid video size */
-        if ((p_sys->i_quirks & OMXCODEC_VIDEO_QUIRKS_NEED_SIZE)
+        if ((p_sys->api->i_quirks & MC_API_VIDEO_QUIRKS_NEED_SIZE)
          && (!p_sys->u.video.i_width || !p_sys->u.video.i_height))
             *p_flags &= ~NEWBLOCK_FLAG_RESTART;
     }
@@ -1569,12 +1551,12 @@ static int Audio_OnNewBlock(decoder_t *p_dec, block_t *p_block, int *p_flags)
         *p_flags |= NEWBLOCK_FLAG_RESTART;
 
         /* Don't start if we don't have any csd */
-        if ((p_sys->i_quirks & OMXCODEC_QUIRKS_NEED_CSD)
+        if ((p_sys->api->i_quirks & MC_API_QUIRKS_NEED_CSD)
          && !p_dec->fmt_in.i_extra)
             *p_flags &= ~NEWBLOCK_FLAG_RESTART;
 
         /* Don't start if we don't have a valid channels count */
-        if ((p_sys->i_quirks & OMXCODEC_AUDIO_QUIRKS_NEED_CHANNELS)
+        if ((p_sys->api->i_quirks & MC_API_AUDIO_QUIRKS_NEED_CHANNELS)
          && !p_dec->p_sys->u.audio.i_channels)
             *p_flags &= ~NEWBLOCK_FLAG_RESTART;
     }
index 85b0c25..4adbd56 100644 (file)
@@ -30,8 +30,6 @@ typedef struct mc_api_out mc_api_out;
 
 typedef int (*pf_MediaCodecApi_init)(mc_api*);
 
-char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
-                         size_t h264_profile);
 int MediaCodecJni_Init(mc_api*);
 int MediaCodecNdk_Init(mc_api*);
 
@@ -40,6 +38,13 @@ int MediaCodecNdk_Init(mc_api*);
 #define MC_API_INFO_OUTPUT_FORMAT_CHANGED (-12)
 #define MC_API_INFO_OUTPUT_BUFFERS_CHANGED (-13)
 
+/* in sync with OMXCODEC QUIRKS */
+#define MC_API_NO_QUIRKS 0
+#define MC_API_QUIRKS_NEED_CSD 0x1
+#define MC_API_VIDEO_QUIRKS_NEED_SIZE 0x2
+#define MC_API_VIDEO_QUIRKS_IGNORE_PADDING 0x4
+#define MC_API_AUDIO_QUIRKS_NEED_CHANNELS 0x8
+
 struct mc_api_out
 {
     enum {
@@ -98,19 +103,24 @@ union mc_api_args
 
 struct mc_api
 {
-    vlc_object_t *p_obj;
-
     mc_api_sys *p_sys;
 
+    /* Set before init */
+    vlc_object_t *  p_obj;
+    const char *    psz_mime;
+    int             i_cat;
+    vlc_fourcc_t    i_codec;
+
+    /* Set after configure */
+    int  i_quirks;
     char *psz_name;
-    const char *psz_mime;
+    bool b_support_interlaced;
 
     bool b_started;
-    bool b_video;
     bool b_direct_rendering;
-    bool b_support_interlaced;
 
     void (*clean)(mc_api *);
+    int (*configure)(mc_api *, size_t i_h264_profile);
     int (*start)(mc_api *, union mc_api_args *p_args);
     int (*stop)(mc_api *);
     int (*flush)(mc_api *);
index 8f92572..66fd122 100644 (file)
@@ -37,6 +37,9 @@
 
 #include "mediacodec.h"
 
+char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
+                         size_t h264_profile);
+
 #define THREAD_NAME "mediacodec_jni"
 
 #define BUFFER_FLAG_CODEC_CONFIG  2
@@ -503,6 +506,8 @@ static int Start(mc_api *api, union mc_api_args *p_args)
     jobject jbuffer_info = NULL;
     jobject jsurface = NULL;
 
+    assert(api->psz_mime && api->psz_name);
+
     GET_ENV();
 
     jmime = JNI_NEW_STRING(api->psz_mime);
@@ -523,7 +528,7 @@ static int Start(mc_api *api, union mc_api_args *p_args)
     }
     p_sys->codec = (*env)->NewGlobalRef(env, jcodec);
 
-    if (api->b_video)
+    if (api->i_cat == VIDEO_ES)
     {
         jformat = (*env)->CallStaticObjectMethod(env,
                                                  jfields.media_format_class,
@@ -859,7 +864,7 @@ static int GetOutput(mc_api *api, int i_index, mc_api_out *p_out)
 
         p_out->type = MC_OUT_TYPE_CONF;
         p_out->b_eos = false;
-        if (api->b_video)
+        if (api->i_cat == VIDEO_ES)
         {
             p_out->u.conf.video.width         = GET_INTEGER(format, "width");
             p_out->u.conf.video.height        = GET_INTEGER(format, "height");
@@ -931,9 +936,25 @@ static int ReleaseOutput(mc_api *api, int i_index, bool b_render)
  *****************************************************************************/
 static void Clean(mc_api *api)
 {
+    free(api->psz_name);
     free(api->p_sys);
 }
 
+/*****************************************************************************
+ * Configure
+ *****************************************************************************/
+static int Configure(mc_api *api, size_t i_h264_profile)
+{
+    free(api->psz_name);
+    api->psz_name = MediaCodec_GetName(api->p_obj, api->psz_mime,
+                                       i_h264_profile);
+    if (!api->psz_name)
+        return MC_API_ERROR;
+    api->i_quirks = OMXCodec_GetQuirks(api->i_cat, api->i_codec, api->psz_name,
+                                       strlen(api->psz_name));
+    return 0;
+}
+
 /*****************************************************************************
  * MediaCodecJni_New
  *****************************************************************************/
@@ -951,6 +972,7 @@ int MediaCodecJni_Init(mc_api *api)
         return MC_API_ERROR;
 
     api->clean = Clean;
+    api->configure = Configure;
     api->start = Start;
     api->stop = Stop;
     api->flush = Flush;
index ed03419..4c23966 100644 (file)
@@ -38,6 +38,9 @@
 
 #include "mediacodec.h"
 
+char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
+                         size_t h264_profile);
+
 #define THREAD_NAME "mediacodec_ndk"
 
 /* Not in NdkMedia API but we need it since we send config data via input
@@ -303,6 +306,8 @@ static int Start(mc_api *api, union mc_api_args *p_args)
     int i_ret = MC_API_ERROR;
     ANativeWindow *p_anw = NULL;
 
+    assert(api->psz_mime && api->psz_name);
+
     p_sys->p_codec = syms.AMediaCodec.createCodecByName(api->psz_name);
     if (!p_sys->p_codec)
     {
@@ -322,7 +327,7 @@ static int Start(mc_api *api, union mc_api_args *p_args)
     syms.AMediaFormat.setString(p_sys->p_format, "mime", api->psz_mime);
     /* No limits for input size */
     syms.AMediaFormat.setInt32(p_sys->p_format, "max-input-size", 0);
-    if (api->b_video)
+    if (api->i_cat == VIDEO_ES)
     {
         syms.AMediaFormat.setInt32(p_sys->p_format, "width", p_args->video.i_width);
         syms.AMediaFormat.setInt32(p_sys->p_format, "height", p_args->video.i_height);
@@ -508,7 +513,7 @@ static int GetOutput(mc_api *api, int i_index, mc_api_out *p_out)
 
         p_out->type = MC_OUT_TYPE_CONF;
         p_out->b_eos = false;
-        if (api->b_video)
+        if (api->i_cat == VIDEO_ES)
         {
             p_out->u.conf.video.width         = GetFormatInteger(format, "width");
             p_out->u.conf.video.height        = GetFormatInteger(format, "height");
@@ -552,9 +557,25 @@ static int ReleaseOutput(mc_api *api, int i_index, bool b_render)
  *****************************************************************************/
 static void Clean(mc_api *api)
 {
+    free(api->psz_name);
     free(api->p_sys);
 }
 
+/*****************************************************************************
+ * Configure
+ *****************************************************************************/
+static int Configure(mc_api * api, size_t i_h264_profile)
+{
+    free(api->psz_name);
+    api->psz_name = MediaCodec_GetName(api->p_obj, api->psz_mime,
+                                       i_h264_profile);
+    if (!api->psz_name)
+        return MC_API_ERROR;
+    api->i_quirks = OMXCodec_GetQuirks(api->i_cat, api->i_codec, api->psz_name,
+                                       strlen(api->psz_name));
+    return 0;
+}
+
 /*****************************************************************************
  * MediaCodecNdk_Init
  *****************************************************************************/
@@ -568,6 +589,7 @@ int MediaCodecNdk_Init(mc_api *api)
         return MC_API_ERROR;
 
     api->clean = Clean;
+    api->configure = Configure;
     api->start = Start;
     api->stop = Stop;
     api->flush = Flush;