}
bool FactoryMake(const T element, GstCaps *caps, GstElementFactoryListType type, const char* nickname) {
- GList *factories = NULL;
GList *filtered = NULL;
- GstElementFactory *factory = nullptr;
GstElement* obj = nullptr;
+ bool use_hw = (type & GST_ELEMENT_FACTORY_TYPE_HARDWARE);
if (!caps) {
TRACKRENDERER_ERROR("invalid caps [null]");
return false;
}
+ type &= ~GST_ELEMENT_FACTORY_TYPE_HARDWARE; // control by use_hw flag
+
auto caps_str = gstguard::make_guard(gst_caps_to_string(caps));
TRACKRENDERER_DEBUG("finding factory based on [%s]", caps_str.get());
- /* get all compatible factories for caps */
- factories =
+ // get all compatible factories for caps
+ GList *factories =
gst_element_factory_list_get_elements (type, GST_RANK_MARGINAL);
if (factories) {
filtered =
}
if (filtered) {
+ GstElementFactory *factory = nullptr;
+ GstElementFactory *dec_factory = nullptr;
GList *l = filtered;
- while(l) {
+
+ if (!(type & GST_ELEMENT_FACTORY_TYPE_DECODER)) {
factory = GST_ELEMENT_FACTORY_CAST (l->data);
- /* FIXME : need to skip avdec element for mp3 decoder */
- if (!strstr(GST_OBJECT_NAME(factory), "avdec_mp1float") &&
- !strstr(GST_OBJECT_NAME(factory), "avdec_mp2float") &&
- !strstr(GST_OBJECT_NAME(factory), "avdec_mp3float")) {
- break;
+ } else {
+ for (; l; l = l->next) {
+ factory = GST_ELEMENT_FACTORY_CAST (l->data);
+
+ // FIXME : need to skip avdec element for mp3 decoder -> ini
+ if (strstr(GST_OBJECT_NAME(factory), "avdec_mp1float") ||
+ strstr(GST_OBJECT_NAME(factory), "avdec_mp2float") ||
+ strstr(GST_OBJECT_NAME(factory), "avdec_mp3float")) {
+ TRACKRENDERER_DEBUG("skip %s factory", GST_OBJECT_NAME(factory));
+ continue;
+ }
+
+ const gchar *klass =
+ gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
+
+ if (!(use_hw ^ (strstr(klass, "Hardware") != NULL)))
+ break;
+
+ TRACKRENDERER_DEBUG("skip %s factory", GST_OBJECT_NAME(factory));
+ if (!dec_factory) // keep the highest rank decoder regardless of sw/hw type
+ dec_factory = factory;
}
- TRACKRENDERER_DEBUG("skip %s factory", GST_OBJECT_NAME(factory));
- l = l->next;
+
+ if (!l)
+ factory = dec_factory;
}
+
TRACKRENDERER_DEBUG("factory name : %s", GST_OBJECT_NAME(factory));
obj = gst_element_factory_create(factory, nickname);
gst_plugin_feature_list_free (filtered);
auto parse_caps =
gstguard::make_guard(pipeline_->GetSrcPadCaps(Elements::kParseVideo));
+ GstElementFactoryListType factory_type = GST_ELEMENT_FACTORY_TYPE_DECODER;
+
+ if (!track->use_swdecoder &&
+ !internal::GetIniValue(properties_, "use_default_video_codec_sw"))
+ factory_type |= GST_ELEMENT_FACTORY_TYPE_HARDWARE;
+
if (!pipeline_->FactoryMake(Elements::kDecVideo,
static_cast<GstCaps*>(parse_caps ? parse_caps.get() : caps.GetCaps_()),
- GST_ELEMENT_FACTORY_TYPE_DECODER, NULL)) {
+ factory_type, NULL)) {
const ErrorType err = ErrorType::kNotSupportedVideoCodec;
TRACKRENDERER_ERROR("fail to make decoder");
eventlistener_->OnError(err);
}
}
- bool sw_codec = internal::GetIniValue(properties_, "use_default_video_codec_sw");
- if (!sw_codec && pipeline_->IsFactoryListType(Elements::kDecVideo, GST_ELEMENT_FACTORY_TYPE_HARDWARE)) {
+ if (pipeline_->IsFactoryListType(Elements::kDecVideo, GST_ELEMENT_FACTORY_TYPE_HARDWARE)) {
TRACKRENDERER_INFO("HW codec");
if (videosink_name && strstr(videosink_name, kVideoSinkName))
pipeline_->SetProperty(Elements::kSinkVideo, "use-tbm", true);
- } else { /* sw */
+ } else {
TRACKRENDERER_INFO("SW codec");
pipeline_->FactoryMake(Elements::kVideoQueue, "queue", NULL);
pipeline_->SetProperty(Elements::kVideoQueue, "max-size-buffers", 2);
auto parse_caps =
gstguard::make_guard(pipeline_->GetSrcPadCaps(Elements::kParseVideo));
- if (!pipeline_->FactoryMake(Elements::kDecVideo, (GstCaps*)parse_caps.get(),
- GST_ELEMENT_FACTORY_TYPE_DECODER, NULL)) {
+ GstElementFactoryListType factory_type = GST_ELEMENT_FACTORY_TYPE_DECODER;
+
+ if (!track.use_swdecoder &&
+ !internal::GetIniValue(properties_, "use_default_video_codec_sw"))
+ factory_type |= GST_ELEMENT_FACTORY_TYPE_HARDWARE;
+
+ if (!pipeline_->FactoryMake(Elements::kDecVideo,
+ (GstCaps*)parse_caps.get(), factory_type, NULL)) {
const ErrorType err = ErrorType::kNotSupportedVideoCodec;
eventlistener_->OnError(err);
return false;