262
317
templ_caps = _get_sub_caps (factory);
264
319
if (is_renderer && have_video_sink && templ_caps) {
267
320
GST_DEBUG ("Found renderer element %s (%s) with caps %" GST_PTR_FORMAT,
268
321
gst_element_factory_get_longname (factory),
269
322
gst_plugin_feature_get_name (feature), templ_caps);
270
tmp = gst_caps_union (*subcaps, templ_caps);
271
gst_caps_unref (templ_caps);
272
gst_caps_replace (subcaps, tmp);
273
gst_caps_unref (tmp);
323
gst_caps_merge (*subcaps, templ_caps);
275
325
} else if (!is_renderer && !have_video_sink && templ_caps) {
278
326
GST_DEBUG ("Found parser element %s (%s) with caps %" GST_PTR_FORMAT,
279
327
gst_element_factory_get_longname (factory),
280
328
gst_plugin_feature_get_name (feature), templ_caps);
281
tmp = gst_caps_union (*subcaps, templ_caps);
282
gst_caps_unref (templ_caps);
283
gst_caps_replace (subcaps, tmp);
284
gst_caps_unref (tmp);
329
gst_caps_merge (*subcaps, templ_caps);
918
979
gst_object_unref (sink);
919
980
gst_object_unref (src);
921
if (G_UNLIKELY (!_create_element (self, &self->post_colorspace,
922
"ffmpegcolorspace", NULL, "post-colorspace", FALSE))) {
926
src = gst_element_get_static_pad (overlay, "src");
927
if (G_UNLIKELY (!src)) {
928
GST_WARNING_OBJECT (self, "Can't get src pad from overlay");
932
sink = gst_element_get_static_pad (self->post_colorspace, "sink");
933
if (G_UNLIKELY (!sink)) {
934
GST_WARNING_OBJECT (self, "Can't get sink pad from ffmpegcolorspace");
935
gst_object_unref (src);
939
if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) {
940
GST_WARNING_OBJECT (self, "Can't link overlay with ffmpegcolorspace");
941
gst_object_unref (src);
942
gst_object_unref (sink);
945
gst_object_unref (src);
946
gst_object_unref (sink);
948
if (G_UNLIKELY (!_create_element (self, &self->pre_colorspace,
949
"ffmpegcolorspace", NULL, "pre-colorspace", FALSE))) {
953
sink = gst_element_get_static_pad (overlay, "video_sink");
954
if (G_UNLIKELY (!sink)) {
955
GST_WARNING_OBJECT (self, "Can't get video sink from textoverlay");
959
src = gst_element_get_static_pad (self->pre_colorspace, "src");
960
if (G_UNLIKELY (!src)) {
961
GST_WARNING_OBJECT (self, "Can't get srcpad from ffmpegcolorspace");
962
gst_object_unref (sink);
966
if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) {
967
GST_WARNING_OBJECT (self, "Can't link ffmpegcolorspace to textoverlay");
968
gst_object_unref (src);
969
gst_object_unref (sink);
972
gst_object_unref (src);
973
gst_object_unref (sink);
975
/* Set src ghostpad target */
976
src = gst_element_get_static_pad (self->post_colorspace, "src");
977
if (G_UNLIKELY (!src)) {
978
GST_WARNING_OBJECT (self, "Can't get src pad from ffmpegcolorspace");
982
if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST
983
(self->srcpad), src))) {
984
GST_WARNING_OBJECT (self, "Can't set srcpad target");
985
gst_object_unref (src);
988
gst_object_unref (src);
982
/* If we are working with video/x-surface, we do not add
983
* colorspace conversion elements */
984
if (is_video && !is_hw) {
985
if (G_UNLIKELY (!_create_element (self, &self->post_colorspace,
986
COLORSPACE, NULL, "post-colorspace", FALSE))) {
990
src = gst_element_get_static_pad (overlay, "src");
991
if (G_UNLIKELY (!src)) {
992
GST_WARNING_OBJECT (self, "Can't get src pad from overlay");
996
sink = gst_element_get_static_pad (self->post_colorspace, "sink");
997
if (G_UNLIKELY (!sink)) {
998
GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE);
999
gst_object_unref (src);
1003
if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) {
1004
GST_WARNING_OBJECT (self, "Can't link overlay with " COLORSPACE);
1005
gst_object_unref (src);
1006
gst_object_unref (sink);
1009
gst_object_unref (src);
1010
gst_object_unref (sink);
1012
if (G_UNLIKELY (!_create_element (self, &self->pre_colorspace,
1013
"identity", NULL, "pre-colorspace", FALSE))) {
1017
sink = gst_element_get_static_pad (overlay, "video_sink");
1018
if (G_UNLIKELY (!sink)) {
1019
GST_WARNING_OBJECT (self, "Can't get video sink from textoverlay");
1023
src = gst_element_get_static_pad (self->pre_colorspace, "src");
1024
if (G_UNLIKELY (!src)) {
1025
GST_WARNING_OBJECT (self, "Can't get srcpad from " COLORSPACE);
1026
gst_object_unref (sink);
1030
if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) {
1031
GST_WARNING_OBJECT (self, "Can't link " COLORSPACE " to textoverlay");
1032
gst_object_unref (src);
1033
gst_object_unref (sink);
1036
gst_object_unref (src);
1037
gst_object_unref (sink);
1039
/* Set src ghostpad target */
1040
src = gst_element_get_static_pad (self->post_colorspace, "src");
1041
if (G_UNLIKELY (!src)) {
1042
GST_WARNING_OBJECT (self, "Can't get src pad from " COLORSPACE);
1046
if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST
1047
(self->srcpad), src))) {
1048
GST_WARNING_OBJECT (self, "Can't set srcpad target");
1049
gst_object_unref (src);
1052
gst_object_unref (src);
1054
GST_DEBUG_OBJECT (self,
1055
"Is Hardware, not adding colorspace converters, ");
1056
/* Set src ghostpad target */
1057
src = gst_element_get_static_pad (self->overlay, "src");
1058
if (G_UNLIKELY (!src)) {
1059
GST_WARNING_OBJECT (self, "Can't get src pad from textoverlay");
1063
if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST
1064
(self->srcpad), src))) {
1065
GST_WARNING_OBJECT (self, "Can't set srcpad target");
1066
gst_object_unref (src);
1069
gst_object_unref (src);
990
1072
/* Send segments to the parser/overlay if necessary. These are not sent
991
1073
* outside this element because of the proxy pad event function */
992
1074
if (self->video_segment.format != GST_FORMAT_UNDEFINED) {
993
1075
GstEvent *event1, *event2;
995
sink = gst_element_get_static_pad (self->pre_colorspace, "sink");
996
if (G_UNLIKELY (!sink)) {
997
GST_WARNING_OBJECT (self, "Can't get sink pad from ffmpegcolorspace");
1078
sink = gst_element_get_static_pad (self->pre_colorspace, "sink");
1079
if (G_UNLIKELY (!sink)) {
1080
GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE);
1084
sink = gst_element_get_static_pad (self->overlay, "video_sink");
1085
if (G_UNLIKELY (!sink)) {
1086
GST_WARNING_OBJECT (self, "Can't get sink pad from textoverlay");
1001
1091
_generate_update_newsegment_event (&self->video_segment, &event1,
1086
1185
g_object_set (self->renderer, "font-desc", self->font_desc, NULL);
1089
/* First link everything internally */
1090
if (G_UNLIKELY (!_create_element (self, &self->post_colorspace,
1091
"ffmpegcolorspace", NULL, "post-colorspace", FALSE))) {
1095
src = gst_element_get_static_pad (element, "src");
1096
if (G_UNLIKELY (!src)) {
1097
GST_WARNING_OBJECT (self, "Can't get src pad from renderer");
1101
sink = gst_element_get_static_pad (self->post_colorspace, "sink");
1102
if (G_UNLIKELY (!sink)) {
1103
GST_WARNING_OBJECT (self, "Can't get sink pad from ffmpegcolorspace");
1104
gst_object_unref (src);
1108
if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) {
1109
GST_WARNING_OBJECT (self, "Can't link renderer with ffmpegcolorspace");
1110
gst_object_unref (src);
1111
gst_object_unref (sink);
1114
gst_object_unref (src);
1115
gst_object_unref (sink);
1117
if (G_UNLIKELY (!_create_element (self, &self->pre_colorspace,
1118
"ffmpegcolorspace", NULL, "pre-colorspace", FALSE))) {
1122
sink = _get_video_pad (element);
1123
if (G_UNLIKELY (!sink)) {
1124
GST_WARNING_OBJECT (self, "Can't get video sink from renderer");
1128
src = gst_element_get_static_pad (self->pre_colorspace, "src");
1129
if (G_UNLIKELY (!src)) {
1130
GST_WARNING_OBJECT (self, "Can't get srcpad from ffmpegcolorspace");
1131
gst_object_unref (sink);
1135
if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) {
1136
GST_WARNING_OBJECT (self, "Can't link ffmpegcolorspace to renderer");
1137
gst_object_unref (src);
1138
gst_object_unref (sink);
1141
gst_object_unref (src);
1142
gst_object_unref (sink);
1144
/* Set src ghostpad target */
1145
src = gst_element_get_static_pad (self->post_colorspace, "src");
1146
if (G_UNLIKELY (!src)) {
1147
GST_WARNING_OBJECT (self, "Can't get src pad from ffmpegcolorspace");
1189
gboolean render_is_hw;
1191
/* First check that renderer also supports the video format */
1192
sink = _get_video_pad (element);
1193
if (G_UNLIKELY (!sink)) {
1194
GST_WARNING_OBJECT (self, "Can't get video sink from renderer");
1198
if (is_video != _is_video_pad (sink, &render_is_hw) ||
1199
is_hw != render_is_hw) {
1200
GST_DEBUG_OBJECT (self, "Renderer doesn't support %s video",
1201
is_hw ? "surface" : "raw");
1202
gst_object_unref (sink);
1205
gst_object_unref (sink);
1208
/* First link everything internally */
1209
if (G_UNLIKELY (!_create_element (self, &self->post_colorspace,
1210
COLORSPACE, NULL, "post-colorspace", FALSE))) {
1213
src = gst_element_get_static_pad (element, "src");
1214
if (G_UNLIKELY (!src)) {
1215
GST_WARNING_OBJECT (self, "Can't get src pad from renderer");
1219
sink = gst_element_get_static_pad (self->post_colorspace, "sink");
1220
if (G_UNLIKELY (!sink)) {
1221
GST_WARNING_OBJECT (self, "Can't get sink pad from " COLORSPACE);
1222
gst_object_unref (src);
1226
if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) {
1227
GST_WARNING_OBJECT (self, "Can't link renderer with " COLORSPACE);
1228
gst_object_unref (src);
1229
gst_object_unref (sink);
1232
gst_object_unref (src);
1233
gst_object_unref (sink);
1235
if (G_UNLIKELY (!_create_element (self, &self->pre_colorspace,
1236
COLORSPACE, NULL, "pre-colorspace", FALSE))) {
1240
sink = _get_video_pad (element);
1241
if (G_UNLIKELY (!sink)) {
1242
GST_WARNING_OBJECT (self, "Can't get video sink from renderer");
1246
src = gst_element_get_static_pad (self->pre_colorspace, "src");
1247
if (G_UNLIKELY (!src)) {
1248
GST_WARNING_OBJECT (self, "Can't get srcpad from " COLORSPACE);
1249
gst_object_unref (sink);
1253
if (G_UNLIKELY (gst_pad_link (src, sink) != GST_PAD_LINK_OK)) {
1254
GST_WARNING_OBJECT (self, "Can't link " COLORSPACE " to renderer");
1255
gst_object_unref (src);
1256
gst_object_unref (sink);
1259
gst_object_unref (src);
1260
gst_object_unref (sink);
1262
/* Set src ghostpad target */
1263
src = gst_element_get_static_pad (self->post_colorspace, "src");
1264
if (G_UNLIKELY (!src)) {
1265
GST_WARNING_OBJECT (self, "Can't get src pad from " COLORSPACE);
1269
/* Set src ghostpad target in the harware accelerated case */
1271
src = gst_element_get_static_pad (self->renderer, "src");
1272
if (G_UNLIKELY (!src)) {
1273
GST_WARNING_OBJECT (self, "Can't get src pad from renderer");
1277
} else { /* No video pad */
1278
GstCaps *allowed_caps, *video_caps = NULL;
1280
gboolean can_intersect = FALSE;
1282
video_peer = gst_pad_get_peer (self->video_sinkpad);
1284
video_caps = gst_pad_get_negotiated_caps (video_peer);
1286
video_caps = gst_pad_get_caps_reffed (video_peer);
1288
gst_object_unref (video_peer);
1291
sink = _get_video_pad (element);
1292
if (G_UNLIKELY (!sink)) {
1293
GST_WARNING_OBJECT (self, "Can't get video sink from renderer");
1296
allowed_caps = gst_pad_get_caps_reffed (sink);
1297
gst_object_unref (sink);
1299
if (allowed_caps && video_caps)
1300
can_intersect = gst_caps_can_intersect (allowed_caps, video_caps);
1303
gst_caps_unref (allowed_caps);
1306
gst_caps_unref (video_caps);
1308
if (G_UNLIKELY (!can_intersect)) {
1309
GST_WARNING_OBJECT (self, "Renderer with custom caps is not "
1310
"compatible with video stream");
1314
src = gst_element_get_static_pad (element, "src");
1315
if (G_UNLIKELY (!src)) {
1316
GST_WARNING_OBJECT (self, "Can't get src pad from renderer");
1151
1321
if (G_UNLIKELY (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST
1644
1814
gst_subtitle_overlay_video_sink_setcaps (GstPad * pad, GstCaps * caps)
1646
1816
GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (gst_pad_get_parent (pad));
1647
1818
gboolean ret = TRUE;
1648
1819
gint fps_n, fps_d;
1650
1821
GST_DEBUG_OBJECT (pad, "Setting caps: %" GST_PTR_FORMAT, caps);
1823
target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (self->video_sinkpad));
1825
GST_SUBTITLE_OVERLAY_LOCK (self);
1827
if (!target || !gst_pad_accept_caps (target, caps)) {
1828
GST_DEBUG_OBJECT (pad, "Target did not accept caps -- reconfiguring");
1830
gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE,
1831
_pad_blocked_cb, self, NULL);
1833
gst_pad_set_blocked_async_full (self->video_block_pad, TRUE,
1834
_pad_blocked_cb, self, NULL);
1652
1837
if (!gst_video_parse_caps_framerate (caps, &fps_n, &fps_d)) {
1653
1838
GST_ERROR_OBJECT (pad, "Failed to parse framerate from caps");
1840
GST_SUBTITLE_OVERLAY_UNLOCK (self);
1658
GST_SUBTITLE_OVERLAY_LOCK (self);
1659
1844
if (self->fps_n != fps_n || self->fps_d != fps_d) {
1660
1845
GST_DEBUG_OBJECT (self, "New video fps: %d/%d", fps_n, fps_d);
1661
1846
self->fps_n = fps_n;
1877
2058
self->subtitle_error = FALSE;
1879
2060
gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE,
1880
_pad_blocked_cb, gst_object_ref (self),
1881
(GDestroyNotify) gst_object_unref);
2061
_pad_blocked_cb, self, NULL);
1883
2063
gst_pad_set_blocked_async_full (self->video_block_pad, TRUE,
1884
_pad_blocked_cb, gst_object_ref (self),
1885
(GDestroyNotify) gst_object_unref);
2064
_pad_blocked_cb, self, NULL);
1886
2065
GST_SUBTITLE_OVERLAY_UNLOCK (self);
1887
2066
gst_caps_unref (caps);
1890
ret = self->subtitle_sink_link (pad, peer);
2069
ret = gst_ghost_pad_link_default (pad, peer);
1892
2071
gst_object_unref (self);
1906
2085
GST_DEBUG_OBJECT (pad, "Pad unlinking");
1907
2086
gst_caps_replace (&self->subcaps, NULL);
1909
self->subtitle_sink_unlink (pad);
2088
gst_ghost_pad_unlink_default (pad);
1911
2090
GST_SUBTITLE_OVERLAY_LOCK (self);
1912
2091
self->subtitle_error = FALSE;
1914
2093
if (self->subtitle_block_pad)
1915
2094
gst_pad_set_blocked_async_full (self->subtitle_block_pad, TRUE,
1916
_pad_blocked_cb, gst_object_ref (self),
1917
(GDestroyNotify) gst_object_unref);
2095
_pad_blocked_cb, self, NULL);
1919
2097
if (self->video_block_pad)
1920
2098
gst_pad_set_blocked_async_full (self->video_block_pad, TRUE,
1921
_pad_blocked_cb, gst_object_ref (self),
1922
(GDestroyNotify) gst_object_unref);
2099
_pad_blocked_cb, self, NULL);
1923
2100
GST_SUBTITLE_OVERLAY_UNLOCK (self);
1925
2102
gst_object_unref (self);
2040
2214
templ = gst_static_pad_template_get (&srctemplate);
2041
2215
self->srcpad = gst_ghost_pad_new_no_target_from_template ("src", templ);
2042
it = gst_pad_iterate_internal_links (self->srcpad);
2044
|| gst_iterator_next (it, (gpointer) & proxypad) != GST_ITERATOR_OK
2045
|| proxypad == NULL)) {
2046
GST_ERROR_OBJECT (self, "Failed to get proxypad of srcpad");
2048
self->src_proxy_event = GST_PAD_EVENTFUNC (proxypad);
2049
gst_pad_set_event_function (proxypad,
2050
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_src_proxy_event));
2051
self->src_proxy_chain = GST_PAD_CHAINFUNC (proxypad);
2052
gst_pad_set_chain_function (proxypad,
2053
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_src_proxy_chain));
2054
gst_object_unref (proxypad);
2057
gst_iterator_free (it);
2216
gst_object_unref (templ);
2219
GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (self->srcpad)));
2220
gst_pad_set_event_function (proxypad,
2221
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_src_proxy_event));
2222
gst_pad_set_chain_function (proxypad,
2223
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_src_proxy_chain));
2224
gst_object_unref (proxypad);
2059
2226
gst_element_add_pad (GST_ELEMENT_CAST (self), self->srcpad);
2061
2228
templ = gst_static_pad_template_get (&video_sinktemplate);
2062
2229
self->video_sinkpad =
2063
2230
gst_ghost_pad_new_no_target_from_template ("video_sink", templ);
2064
self->video_sink_event = GST_PAD_EVENTFUNC (self->video_sinkpad);
2231
gst_object_unref (templ);
2065
2232
gst_pad_set_event_function (self->video_sinkpad,
2066
2233
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_video_sink_event));
2067
self->video_sink_setcaps = GST_PAD_SETCAPSFUNC (self->video_sinkpad);
2068
2234
gst_pad_set_setcaps_function (self->video_sinkpad,
2069
2235
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_video_sink_setcaps));
2070
self->video_sink_chain = GST_PAD_CHAINFUNC (self->video_sinkpad);
2071
2236
gst_pad_set_chain_function (self->video_sinkpad,
2072
2237
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_video_sink_chain));
2075
it = gst_pad_iterate_internal_links (self->video_sinkpad);
2077
|| gst_iterator_next (it, (gpointer) & proxypad) != GST_ITERATOR_OK
2078
|| proxypad == NULL)) {
2079
GST_ERROR_OBJECT (self,
2080
"Failed to get internally linked pad from video sinkpad");
2083
gst_iterator_free (it);
2240
GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
2241
(self->video_sinkpad)));
2084
2242
self->video_block_pad = proxypad;
2243
gst_object_unref (proxypad);
2085
2244
gst_element_add_pad (GST_ELEMENT_CAST (self), self->video_sinkpad);
2087
2246
templ = gst_static_pad_template_get (&subtitle_sinktemplate);
2088
2247
self->subtitle_sinkpad =
2089
2248
gst_ghost_pad_new_no_target_from_template ("subtitle_sink", templ);
2090
self->subtitle_sink_link = GST_PAD_LINKFUNC (self->subtitle_sinkpad);
2249
gst_object_unref (templ);
2091
2250
gst_pad_set_link_function (self->subtitle_sinkpad,
2092
2251
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_link));
2093
self->subtitle_sink_unlink = GST_PAD_UNLINKFUNC (self->subtitle_sinkpad);
2094
2252
gst_pad_set_unlink_function (self->subtitle_sinkpad,
2095
2253
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_unlink));
2096
self->subtitle_sink_event = GST_PAD_EVENTFUNC (self->subtitle_sinkpad);
2097
2254
gst_pad_set_event_function (self->subtitle_sinkpad,
2098
2255
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_event));
2099
self->subtitle_sink_setcaps = GST_PAD_SETCAPSFUNC (self->subtitle_sinkpad);
2100
2256
gst_pad_set_setcaps_function (self->subtitle_sinkpad,
2101
2257
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_setcaps));
2102
self->subtitle_sink_chain = GST_PAD_CHAINFUNC (self->subtitle_sinkpad);
2103
2258
gst_pad_set_chain_function (self->subtitle_sinkpad,
2104
2259
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_chain));
2105
2260
gst_pad_set_getcaps_function (self->subtitle_sinkpad,