如果是使用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中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分别包含了我们常用的软件解码和硬件解码的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的优先级了。
可以使用 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。