GStreamer修改解码器默认优先级

什么场景下需要修改解码器的优先级?

如果是使用GStreamer低层element来构建pipeline(不使用高层接口),因为可以直接指定解码器,所以自然不需要去修改编解码器的默认优先级。
如下,使用gst-launch播放一个flac的音频,我们就直接指定了omxflacdec作为音频解码器:

gst-launch-1.0 filesrc location=/backup/1.flac ! flacparse ! omxflacdec ! alsasink

但是,当我们直接使用高层的playbin来进行媒体播放时,没有可操作的途径来选择解码器,只能通过调整默认的解码器优先级来实现选择。

gst-launch-1.0 playbin uri=file:///backup/1.flac audiosink=alsasink

GStreamer中关于Element的优先级的定义

GStreamer中demuxer,decoder,encoder类型的element都有自己的优先级,在注册时通过rank值指定。该值的基本类型定义在 gst/gstpluginfeature.h 中,如下:

/**
 * GstRank:
 * @GST_RANK_NONE: will be chosen last or not at all
 * @GST_RANK_MARGINAL: unlikely to be chosen
 * @GST_RANK_SECONDARY: likely to be chosen
 * @GST_RANK_PRIMARY: will be chosen first
 *
 * Element priority ranks. Defines the order in which the autoplugger (or
 * similar rank-picking mechanisms, such as e.g. gst_element_make_from_uri())
 * will choose this element over an alternative one with the same function.
 *
 * These constants serve as a rough guidance for defining the rank of a
 * #GstPluginFeature. Any value is valid, including values bigger than
 * @GST_RANK_PRIMARY.
 */
typedef enum
{
	GST_RANK_NONE 		= 0,
	GST_RANK_MARGINAL 	= 64,
	GST_RANK_SECONDARY 	= 128,
	GST_RANK_PRIMARY 	= 256
} GstRank;

这些element的优先级,通过注册element时传入的rank值决定,注册element的API位于 gst/gstelementfactory.h中,如下:

gboolean gst_element_register(GstPlugin *plugin, const gchar *name, guint rank, GType type);

修改gst-libav和gst-omx中相关解码器的默认优先级

gst-libav和gst-omx分别包含了我们常用的软件解码和硬件解码的element。
gst-libav中音频解码器的注册逻辑位于ext/libav/gstavauddec.c中,如下:

gboolean
gst_ffmpegauddec_register (GstPlugin * plugin)
{
	...

    /* (Ronald) MPEG-4 gets a higher priority because it has been well-
     * tested and by far outperforms divxdec/xviddec - so we prefer it.
     * msmpeg4v3 same, as it outperforms divxdec for divx3 playback.
     * VC1/WMV3 are not working and thus unpreferred for now. */
    switch (in_plugin->id) {
      case AV_CODEC_ID_RA_144:
      case AV_CODEC_ID_RA_288:
      case AV_CODEC_ID_COOK:
        rank = GST_RANK_PRIMARY;
        break;
        /* SIPR: decoder should have a higher rank than realaudiodec.
         */
      case AV_CODEC_ID_SIPR:
        rank = GST_RANK_SECONDARY;
        break;
      case AV_CODEC_ID_MP3:
        rank = GST_RANK_NONE;
        break;
      default:
        rank = GST_RANK_MARGINAL;
        break;
    }
    if (!gst_element_register (plugin, type_name, rank, type)) {
      g_warning ("Failed to register %s", type_name);
      g_free (type_name);
      return FALSE;
    }
    
	...
  }

可以看到gst-libav中音频解码器的默认优先级大部分为GST_RANK_MARGINAL。类似的视频解码器注册位于 ext/libav/gstavviddec.c中。可以修改该部分代码,按需求给特定的element定义rank值。

gst-omx属于wrapper plugins,每个硬件产商提供的代码可能会不同。目前我在telechips平台上做开发,其解码器的注册位于omx/gstomx.c中,和上面gst-libav略有不同,通过读取gstomx.conf这个配置文件中的信息来注册element(换汤不换药而已)。

static gboolean plugin_init(GstPlugin *plugin)
{
	...
	static const gchar *config_name[] = { "gstomx.conf", NULL };
	...
	elements = g_key_file_get_groups(config, &n_elements);
	for(i = 0; i < n_elements; i++)
	{
		...
		gint rank;
		GST_DEBUG("Registering element '%s'", elements[i]);
		...
		rank = g_key_file_get_integer(config, elements[i], "rank", &err);
		...
		ret |= gst_element_register(plugin, elements[i], rank, subtype);
	}
	...
}

看一下gstomx.conf这个配置文件:

...

[omxaacdec]
type-name=GstOMXAACDec
core-name=/nand1/tccgst/lib/libomxil-tcc.so.0
component-name=OMX.TCC.aacdec
rank=257
in-port-index=0
out-port-index=1
hacks=no-disable-outport;event-port-settings-changed-ndata-parameter-swap;no-empty-eos-buffer;

[omxflacdec]
type-name=GstOMXFLACDec
core-name=/nand1/tccgst/lib/libomxil-tcc.so.0
component-name=OMX.TCC.flacdec
rank=257
in-port-index=0
out-port-index=1
hacks=no-disable-outport;event-port-settings-changed-ndata-parameter-swap;no-empty-eos-buffer;

...

其中包含了每个element的rank值定义,可以看到硬件解码element的优先级默认都是很高的。所以,修改这个值就可以修改对应element的优先级了。

如何查看当前系统中各element的优先级

可以使用 gst-inspect 工具。 比如想查看一下当前flac相关的解码element有哪些:

root@telechips-tcc8971-lcn-2:# gst-inspect-1.0 | grep flac
libav:  avdec_flac: libav FLAC (Free Lossless Audio Codec) decoder
omx:  omxflacdec: Free Lossless audio decoder
audioparsers:  flacparse: FLAC audio parser
typefindfunctions: application/x-id3v2: mp3, mp2, mp1, mpga, ogg, flac, tta
typefindfunctions: application/x-id3v1: mp3, mp2, mp1, mpga, ogg, flac, tta
typefindfunctions: audio/x-flac: flac

可以看到有来自gst-libav plugin的avdec_flac以及来自gst-omx plugin的omxflacdec两个组件(element)
使用gst-inspect分别查看其优先级:

root@telechips-tcc8971-lcn-2:# gst-inspect-1.0 avdec_flac
Factory Details:
  Rank                     marginal (64)
  Long-name                libav FLAC (Free Lossless Audio Codec) decoder
  Klass                    Codec/Decoder/Audio
  ...

root@telechips-tcc8971-lcn-2:# gst-inspect-1.0 omxflacdec
Factory Details:
  Rank                     primary + 1 (257)
  Long-name                Free Lossless audio decoder
  Klass                    Codec/Decoder/Audio
  ...

可以看到其rank分别为64和257。

你可能感兴趣的:(音视频开发)