New upstream version 1.22.5
Jeremy Bícha
8 months ago
0 | === release 1.22.5 === | |
1 | ||
2 | 2023-07-20 15:22:48 +0100 Tim-Philipp Müller <tim@centricular.com> | |
3 | ||
4 | * NEWS: | |
5 | * RELEASE: | |
6 | * docs/gst_plugins_cache.json: | |
7 | * gst-plugins-good.doap: | |
8 | * meson.build: | |
9 | Release 1.22.5 | |
10 | ||
11 | 2023-02-15 17:32:39 +0100 Edward Hervey <edward@centricular.com> | |
12 | ||
13 | * ext/adaptivedemux2/hls/gsthlsdemux.c: | |
14 | hlsdemux2: Don't set a referer when updating playlists | |
15 | In the same way we don't for regular playlists in the base class. | |
16 | If there is a referer specified by the app/user, the downloadhelper will set it | |
17 | accordingly. | |
18 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5057> | |
19 | ||
20 | 2023-02-15 18:06:36 +0100 Edward Hervey <edward@centricular.com> | |
21 | ||
22 | * ext/adaptivedemux2/gstadaptivedemux-stream.c: | |
23 | adaptivedemux2: Don't blindly set the main manifest URI as referer | |
24 | There's no guarantee it will *actually* be the URI which refered to what we are | |
25 | downloading. It could be a stream URI or anything else. | |
26 | Instead of putting something wrong, put no (specific) referer as a better choice | |
27 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5057> | |
28 | ||
29 | 2023-07-11 17:00:57 +0200 Bastien Nocera <hadess@hadess.net> | |
30 | ||
31 | * ext/gtk/gtkgstbasewidget.c: | |
32 | gtk: Fix critical caused by pointer movement when stream is getting ready | |
33 | This check fixes a critical warning that can happen when a pointer motion | |
34 | happens and the video doesn't have its width/height information available. | |
35 | GStreamer-Video-CRITICAL **: gst_video_center_rect: assertion 'src->h != 0' failed | |
36 | #0 g_logv (log_domain=0x7ffff705e176 "GStreamer-Video", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=<optimized out>) at ../../../../Projects/jhbuild/glib/glib/gmessages.c:1422 | |
37 | #1 0x00007ffff7e1a81d in g_log (log_domain=<optimized out>, log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff7e77a9d "%s: assertion '%s' failed") at ../../../../Projects/jhbuild/glib/glib/gmessages.c:1460 | |
38 | #2 0x00007ffff7e1b749 in g_return_if_fail_warning (log_domain=<optimized out>, pretty_function=<optimized out>, expression=<optimized out>) at ../../../../Projects/jhbuild/glib/glib/gmessages.c:2930 | |
39 | #3 0x00007ffff701d90b in gst_video_sink_center_rect (src=..., dst=..., result=result@entry=0x7fffffffc6d0, scaling=scaling@entry=1) at ../../../../Projects/jhbuild/gstreamer/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideosink.c:105 | |
40 | #4 0x00007fffe5652dbb in _fit_stream_to_allocated_size (result=0x7fffffffc6d0, allocation=0x7fffffffc6c0, base_widget=0x9396f0) at ../../../../Projects/jhbuild/gstreamer/subprojects/gst-plugins-good/ext/gtk/gtkgstbasewidget.c:326 | |
41 | #5 gtk_gst_base_widget_display_size_to_stream_size (base_widget=base_widget@entry=0x9396f0, x=1207.7109375, y=811.84765625, stream_x=stream_x@entry=0x7fffffffc720, stream_y=stream_y@entry=0x7fffffffc728) at ../../../../Projects/jhbuild/gstreamer/subprojects/gst-plugins-good/ext/gtk/gtkgstbasewidget.c:344 | |
42 | #6 0x00007fffe5651a4b in gst_gtk_base_sink_navigation_send_event (navigation=0x5ff990, event=0x178a730) at ../../../../Projects/jhbuild/gstreamer/subprojects/gst-plugins-good/ext/gtk/gstgtkbasesink.c:340 | |
43 | #7 0x00007fffe5652432 in gtk_gst_base_widget_motion_event (widget=<optimized out>, event=event@entry=0x1f14b60) at ../../../../Projects/jhbuild/gstreamer/subprojects/gst-plugins-good/ext/gtk/gtkgstbasewidget.c:404 | |
44 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5051> | |
45 | ||
46 | 2023-07-13 16:27:05 +0200 Michael Tretter <m.tretter@pengutronix.de> | |
47 | ||
48 | * sys/v4l2/gstv4l2videoenc.c: | |
49 | v4l2videoenc: remove empty sink_query | |
50 | The sink_query() function simply calls the sink_query() function of the parent | |
51 | videoencoder class. Remove the override to simply directly call the parent's | |
52 | function. | |
53 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5036> | |
54 | ||
55 | 2023-07-13 16:16:44 +0200 Michael Tretter <m.tretter@pengutronix.de> | |
56 | ||
57 | * sys/v4l2/gstv4l2videoenc.c: | |
58 | v4l2videoenc: replace custom QUERY_CAPS handling with getcaps callback | |
59 | The videoencoder base class uses getcaps() to ask a subclass for the caps in its | |
60 | sink_query_default() implementation. | |
61 | Replace the custom handling of the QUERY_CAPS in the v4l2videoenc with an | |
62 | implementation of getcaps() that returns the caps that are supported by the | |
63 | v4l2videoenc to return these caps in the query. | |
64 | This getcaps() implementation also calls the provided proxy_getcaps(), which | |
65 | sends a caps query to downstream. This fixes the v4l2videoenc element to respect | |
66 | limits of downstream elements in a sink query. | |
67 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5036> | |
68 | ||
69 | 2023-07-11 21:41:46 +0200 Carlos Rafael Giani <crg7475@mailbox.org> | |
70 | ||
71 | * meson.build: | |
72 | gl: Take into account viv-fb vs. viv_fb naming in meson scripts | |
73 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4959> | |
74 | ||
75 | 2023-05-16 21:24:44 +1000 Matthew Waters <matthew@centricular.com> | |
76 | ||
77 | * ext/qt/gstqtglutility.cc: | |
78 | * ext/qt/meson.build: | |
79 | * meson.build: | |
80 | gl: provide a pkg-config/gir file for the viv-fb backend | |
81 | Required to be able to generate coherent bindings for window system | |
82 | specific APIs due to limitations in gobject-introspection. | |
83 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4959> | |
84 | ||
85 | 2023-07-10 22:45:49 +0900 Seungha Yang <seungha@centricular.com> | |
86 | ||
87 | * ext/qt6/qt6glitem.cc: | |
88 | qt6: Set sampler filtering method | |
89 | QQuickItem::smooth property doesn't seem to be propagated to | |
90 | newly created QSGSimpleTextureNode automatically. | |
91 | Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2793 | |
92 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5016> | |
93 | ||
94 | 2023-07-09 17:44:03 +0200 David Craven <david@craven.ch> | |
95 | ||
96 | * gst/matroska/matroska-read-common.c: | |
97 | matroska: demux: Strip signal byte from encrypted blocks | |
98 | Removes the signal byte when the frame is unencrypted to | |
99 | be consistent with when the frame is encrypted. | |
100 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5014> | |
101 | ||
102 | 2023-06-26 17:10:33 -0400 Nicolas Dufresne <nicolas.dufresne@collabora.com> | |
103 | ||
104 | * sys/v4l2/gstv4l2videodec.c: | |
105 | v4l2: videodec: Don't wait for src_ch if active | |
106 | If the capture pool is already active, like when handling gaps at the | |
107 | start of a stream, do not setup the decoder to wait for src_ch event. | |
108 | Otherwise the decoder will endup waiting for that at the wrong moment | |
109 | and exit the decoding thread unexpectedly. | |
110 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4996> | |
111 | ||
112 | 2023-06-26 17:08:57 -0400 Nicolas Dufresne <nicolas.dufresne@collabora.com> | |
113 | ||
114 | * sys/v4l2/gstv4l2videodec.c: | |
115 | v4l2: videodec: Move pool setup inside negotiate() | |
116 | Move all the pool configuration inside the negotiate() virtual function. | |
117 | This allow settting up a pool with default format whenever the base | |
118 | class wants to start without input data, like gaps. | |
119 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4996> | |
120 | ||
121 | 2023-07-06 17:44:48 +0800 Hou Qi <qi.hou@nxp.com> | |
122 | ||
123 | * sys/v4l2/gstv4l2videodec.c: | |
124 | v4l2videodec: correctly register v4l2mpeg2dec | |
125 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4992> | |
126 | ||
127 | 2023-07-07 12:33:37 +0200 Guillaume Desmottes <guillaume.desmottes@onestream.live> | |
128 | ||
129 | * gst/videofilter/gstvideoflip.c: | |
130 | videoflip: fix critical when tag list is not writable | |
131 | Fix this pipeline where the tag list is not writable: | |
132 | gst-launch-1.0 videotestsrc ! taginject tags="image-orientation=rotate-90" ! videoflip video-direction=auto \ | |
133 | ! autovideosink | |
134 | GStreamer-CRITICAL **: 12:34:36.310: gst_tag_list_add: assertion 'gst_tag_list_is_writable (list)' failed | |
135 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4990> | |
136 | ||
137 | 2023-07-06 14:27:42 +0200 Michael Olbrich <m.olbrich@pengutronix.de> | |
138 | ||
139 | * sys/v4l2/gstv4l2src.c: | |
140 | v4l2src: handle resolution change when buffers are copied | |
141 | When buffers are copied then GST_V4L2_FLOW_RESOLUTION_CHANGE is returned by | |
142 | gst_v4l2_buffer_pool_process() so do renegotiation here as well. | |
143 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4985> | |
144 | ||
145 | 2023-07-04 23:11:53 +0900 Seungha Yang <seungha@centricular.com> | |
146 | ||
147 | * gst/rtsp/gstrtspsrc.c: | |
148 | rtspsrc: Fix crash when is-live=false | |
149 | The pad's parent (i.e., rtspsrc) can be nullptr since we add pads | |
150 | later. | |
151 | Co-authored-by: Jan Schmidt <jan@centricular.com> | |
152 | Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2751 | |
153 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4971> | |
154 | ||
155 | 2023-07-04 10:57:01 +0200 Edward Hervey <edward@centricular.com> | |
156 | ||
157 | * ext/adaptivedemux2/hls/gsthlsdemux-util.c: | |
158 | hlsdemux2: Ensure processed webvtt ends with empty new line | |
159 | Parsers downstream will use empty new lines to detect where an entry | |
160 | ends. Failure to have a newline would cause the entry to be either | |
161 | discarded or (wrongly) concatenated with the next entry | |
162 | Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2752 | |
163 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4970> | |
164 | ||
165 | 2023-06-21 17:05:47 +0200 Edward Hervey <edward@centricular.com> | |
166 | ||
167 | * gst/matroska/matroska-demux.c: | |
168 | matroska-demux: Properly handle early time-based segments | |
169 | Refusing an incoming segment in < GST_MATROSKA_READ_STATE_DATA should only be | |
170 | done if the incoming segment is not in GST_FORMAT_TIME. | |
171 | In GST_FORMAT_TIME, we are just storing the values and returning, so we can | |
172 | invert the order of the checks. | |
173 | Fixes proper segment propagation in matroska/webm DASH use-cases | |
174 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4922> | |
175 | ||
176 | 2023-02-10 15:26:20 +0100 Edward Hervey <edward@centricular.com> | |
177 | ||
178 | * ext/adaptivedemux2/gstadaptivedemux.c: | |
179 | adaptivedemux2: Handle early SEEKING query | |
180 | No pads are present yet, but we can still answer the query | |
181 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4922> | |
182 | ||
183 | 2023-02-09 17:22:34 +0100 Edward Hervey <edward@centricular.com> | |
184 | ||
185 | * ext/adaptivedemux2/gstadaptivedemux.c: | |
186 | adaptivedemux2: Fix non-accurate seeking | |
187 | If no accurate positioning was required, default to snap to the previous segment | |
188 | for improved responsiveness | |
189 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4922> | |
190 | ||
191 | 2023-02-09 14:54:27 +0100 Edward Hervey <edward@centricular.com> | |
192 | ||
193 | * ext/adaptivedemux2/gstadaptivedemux.c: | |
194 | adaptivedemux2: Handle return in seek handling | |
195 | Various code path were repeating the same logic, and risk forgetting a lock | |
196 | release. | |
197 | Unify all of them | |
198 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4922> | |
199 | ||
200 | 2023-02-09 14:45:01 +0100 Edward Hervey <edward@centricular.com> | |
201 | ||
202 | * ext/adaptivedemux2/gstadaptivedemux.c: | |
203 | adaptivedemux2: Move API lock usage | |
204 | It is not needed so early | |
205 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4922> | |
206 | ||
207 | 2023-02-08 17:24:18 +0100 Edward Hervey <edward@centricular.com> | |
208 | ||
209 | * ext/adaptivedemux2/gstadaptivedemux-private.h: | |
210 | * ext/adaptivedemux2/gstadaptivedemux-stream.c: | |
211 | * ext/adaptivedemux2/gstadaptivedemux.c: | |
212 | adaptivedemux2: Handle early key-unit seek | |
213 | Is a seek is done on stream-collection post, there are no selected streams | |
214 | yet. Therefore none would be chosen to adjust the key-unit seek. | |
215 | If no streams are selected, fallback to a default stream (i.e. one which has | |
216 | track(s) with GST_STREAM_FLAG_SELECT). | |
217 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4922> | |
218 | ||
219 | 2023-02-08 12:02:45 +0100 Edward Hervey <edward@centricular.com> | |
220 | ||
221 | * ext/adaptivedemux2/gstadaptivedemux-track.c: | |
222 | adaptivedemux2: Fix early seeking | |
223 | When seeking is handled by the collection posting thread, there is a possibility | |
224 | that some leftover data will be pushed by the stream thread. | |
225 | Properly detect and reject those early segments (and buffers) by comparing it to | |
226 | the main segment seqnum | |
227 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4922> | |
228 | ||
229 | 2023-06-06 11:34:03 +0200 Guillaume Desmottes <guillaume.desmottes@onestream.live> | |
230 | ||
231 | * gst/videofilter/gstvideoflip.c: | |
232 | videoflip: update orientation tag in auto mode | |
233 | The frames are flipped according to the tag orientation so it's no longer accurate. | |
234 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4796> | |
235 | ||
236 | 2023-06-20 14:56:44 +0200 François Laignel <francois@centricular.com> | |
237 | ||
238 | * gst/isomp4/qtdemux.c: | |
239 | qtdemux: opus: set entry as sampled | |
240 | ... otherwise streams with constant size samples defined with a single | |
241 | `sample_size` for all samples in the `stsz` box fall in the category | |
242 | `chunks_are_samples` in `qtdemux_stbl_init`, overriding the actual | |
243 | sample count. | |
244 | `FOURCC_soun` would set this automatically for `compression_id == 0xfffe`, | |
245 | however `compression_id` is read from the Audio Sample Entry box at an offset | |
246 | marked as "pre-defined" in some version of the spec and set to 0 both by | |
247 | GStreamer and FFmpeg for opus streams. | |
248 | Considering the stream `sampled` flag is set explicitely by other fourcc | |
249 | variants, doing so for opus seems consistent. | |
250 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4908> | |
251 | ||
252 | 2023-06-20 19:10:38 +0100 Tim-Philipp Müller <tim@centricular.com> | |
253 | ||
254 | * docs/gst_plugins_cache.json: | |
255 | * meson.build: | |
256 | Back to development | |
257 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4907> | |
258 | ||
0 | 259 | === release 1.22.4 === |
1 | 260 | |
2 | 261 | 2023-06-20 17:42:25 +0100 Tim-Philipp Müller <tim@centricular.com> |
1 | 1 | |
2 | 2 | GStreamer 1.22.0 was originally released on 23 January 2023. |
3 | 3 | |
4 | The latest bug-fix release in the stable 1.22 series is 1.22.4 and was | |
5 | released on 20 June 2023. | |
4 | The latest bug-fix release in the stable 1.22 series is 1.22.5 and was | |
5 | released on 20 July 2023. | |
6 | 6 | |
7 | 7 | See https://gstreamer.freedesktop.org/releases/1.22/ for the latest |
8 | 8 | version of this document. |
9 | 9 | |
10 | Last updated: Tuesday 20 June 2023, 16:30 UTC (log) | |
10 | Last updated: Thursday 20 July 2023, 12:00 UTC (log) | |
11 | 11 | |
12 | 12 | Introduction |
13 | 13 | |
2007 | 2007 | - List of Merge Requests applied in 1.22.4 |
2008 | 2008 | - List of Issues fixed in 1.22.4 |
2009 | 2009 | |
2010 | 1.22.5 | |
2011 | ||
2012 | The fifth 1.22 bug-fix release (1.22.5) was released on 20 July 2023. | |
2013 | ||
2014 | This release only contains bugfixes and security fixes and it should be | |
2015 | safe to update from 1.22.x. | |
2016 | ||
2017 | Highlighted bugfixes in 1.22.5 | |
2018 | ||
2019 | - Security fixes for the RealMedia demuxer | |
2020 | - vaapi decoders, postproc: Disable DMAbuf from caps negotiation to | |
2021 | fix garbled video in some cases | |
2022 | - decodebin3, playbin3, parsebin fixes, especially for stream | |
2023 | reconfiguration | |
2024 | - hlsdemux2: fix early seeking; don’t pass referer when updating | |
2025 | playlists; webvtt fixes | |
2026 | - gtk: Fix critical caused by pointer movement when stream is getting | |
2027 | ready | |
2028 | - qt6: Set sampler filtering method, fixes bad quality with qml6glsink | |
2029 | and gstqt6d3d11 | |
2030 | - v4l2src: handle resolution change when buffers are copied | |
2031 | - videoflip: update orientation tag in auto mode | |
2032 | - video timecode: Add support for framerates lower than 1fps and | |
2033 | accept 119.88 (120/1.001) fps | |
2034 | - webrtcsink: fixes for x264enc and NVIDIA encoders | |
2035 | - cerbero: Pull ninja from system if possible, avoid spurious | |
2036 | bootstrap of cmake | |
2037 | - packages: Recipe updates for ffmpeg, libsoup, orc | |
2038 | - various bug fixes, memory leak fixes, and other stability and | |
2039 | reliability improvements | |
2040 | ||
2041 | gstreamer | |
2042 | ||
2043 | - taglist, plugins: fix compiler warnings with GLib >= 2.76 | |
2044 | - tracerutils: allow casting parameter types | |
2045 | - inputselector: fix playing variable is never set | |
2046 | ||
2047 | gst-plugins-base | |
2048 | ||
2049 | - appsink: add missing make_writable call | |
2050 | - audioaggregator: Do not post message before being constructed | |
2051 | - decodebin3: Prevent a critical warning when reassigning output slots | |
2052 | - decodebin3: Fix slot input linking when the associated stream has | |
2053 | changed | |
2054 | - decodebin3: Remove spurious input locking during parsebin | |
2055 | reconfiguration | |
2056 | - urisourcebin: Set source element to READY before querying it | |
2057 | - gl/viv-fb: meson build updates | |
2058 | - plugins: fix compiler warnings with GLib >= 2.76 | |
2059 | - subtitleoverlay: fix mutex error if sink caps is not video | |
2060 | - video: timecode: Add support for framerates lower than 1fps | |
2061 | - video: accept timecode of 119.88 (120/1.001) FPS | |
2062 | - video: cannot attach time code meta when frame rate is 119.88 | |
2063 | (120000/1001) | |
2064 | - videodecoder: fix copying buffer metas | |
2065 | ||
2066 | gst-plugins-good | |
2067 | ||
2068 | - adaptivedemux2: Fix early seeking | |
2069 | - hlsdemux2: Ensure processed webvtt ends with empty new line | |
2070 | - hlsdemux2: Don’t set a referer when updating playlists | |
2071 | - matroska: demux: Strip signal byte when encrypted | |
2072 | - rtspsrc: Fix crash when is-live=false | |
2073 | - gtk: Fix critical caused by pointer movement when stream is getting | |
2074 | ready | |
2075 | - qt6: Set sampler filtering method, fixes bad quality with qml6glsink | |
2076 | and gstqt6d3d11 | |
2077 | - qtdemux: opus: set entry as sampled | |
2078 | - v4l2src: handle resolution change when buffers are copied | |
2079 | - v4l2videodec: Fix handling of initial gaps | |
2080 | - v4l2videodec: correctly register v4l2mpeg2dec | |
2081 | - v4l2videoenc: replace custom QUERY_CAPS handling with getcaps | |
2082 | callback | |
2083 | - videoflip: update orientation tag in auto mode | |
2084 | - videoflip: fix critical when tag list is not writable | |
2085 | ||
2086 | gst-plugins-bad | |
2087 | ||
2088 | - d3d11bufferpool: Fix heavy CPU usage in case of fixed-size pool | |
2089 | - jpegparser: jpegdecoder: Don’t pollute bus and comply with spec | |
2090 | - plugins: fix compiler warnings with GLib >= 2.76 | |
2091 | - webrtcbin: Prevent critical warning when creating an additional data | |
2092 | channel | |
2093 | - webrtcstats: Properly report IceCandidate type | |
2094 | ||
2095 | gst-plugins-ugly | |
2096 | ||
2097 | - rmdemux: add some integer overflow checks | |
2098 | ||
2099 | gst-plugins-rs | |
2100 | ||
2101 | - fallbackswitch: Change the threshold for trailing buffers | |
2102 | - fallbackswitch: Fix pad health calculation and notifies | |
2103 | - fmp4mux: Fix draining in chunk mode if keyframes are too late | |
2104 | - livesync: Wait for the end timestamp of the previous buffer before | |
2105 | looking at queue | |
2106 | - livesync: Improve EOS handling | |
2107 | - togglerecord: Clip segment before calculating timestamp/duration | |
2108 | - togglerecord: Error out if main stream buffer has no valid running | |
2109 | time | |
2110 | - webrtcsink: fix pipeline when input caps contain max-framerate | |
2111 | - webrtcsink: Configure only 4 threads for x264enc | |
2112 | - webrtcsink: Translate force-keyunit events to force-IDR action | |
2113 | signal for NVIDIA encoders | |
2114 | - webrtcsink: Set config-interval=-1 and aggregate-mode=zero-latency | |
2115 | on rtph264pay and rtph265pay | |
2116 | - webrtcsink: Set VP8/VP9 payloader based on payloader element factory | |
2117 | name | |
2118 | - webrtcink: Use correct property types for nvvideoconvert | |
2119 | - webrtc/signalling: fix race condition in message ordering | |
2120 | - videofx: Minimize dependencies of the image crate | |
2121 | ||
2122 | gst-libav | |
2123 | ||
2124 | - No changes | |
2125 | ||
2126 | gst-rtsp-server | |
2127 | ||
2128 | - No changes | |
2129 | ||
2130 | gstreamer-vaapi | |
2131 | ||
2132 | - vaapidecode,vaapipostproc: Disable DMAbuf from caps negotiation. | |
2133 | ||
2134 | gstreamer-sharp | |
2135 | ||
2136 | - No changes | |
2137 | ||
2138 | gst-omx | |
2139 | ||
2140 | - No changes | |
2141 | ||
2142 | gst-python | |
2143 | ||
2144 | - No changes | |
2145 | ||
2146 | gst-editing-services | |
2147 | ||
2148 | - ges: some fixes for 32-bit systems | |
2149 | - ges, nle: Avoid setting state or sending query when constructing | |
2150 | objects | |
2151 | ||
2152 | gst-validate + gst-integration-testsuites | |
2153 | ||
2154 | - No changes | |
2155 | ||
2156 | gst-examples | |
2157 | ||
2158 | - No changes | |
2159 | ||
2160 | Development build environment | |
2161 | ||
2162 | - No changes | |
2163 | ||
2164 | Cerbero build tool and packaging changes in 1.22.5 | |
2165 | ||
2166 | - Pull ninja from system if possible, avoid spurious bootstrap of | |
2167 | cmake | |
2168 | - ffmpeg: update to 5.0.3 | |
2169 | - libsoup: update to 2.74.3 | |
2170 | - orc: update to 0.4.34 | |
2171 | ||
2172 | Contributors to 1.22.5 | |
2173 | ||
2174 | Andoni Morales Alastruey, Bastien Nocera, Carlos Rafael Giani, David | |
2175 | Craven, Doug Nazar, Edward Hervey, François Laignel, Guillaume | |
2176 | Desmottes, He Junyan, Hou Qi, Jan Alexander Steffens (heftig), Jan | |
2177 | Schmidt, Maksym Khomenko, Mathieu Duponchelle, Matthew Waters, Michael | |
2178 | Olbrich, Michael Tretter, Nicolas Dufresne, Nirbheek Chauhan, Philippe | |
2179 | Normand, Ruslan Khamidullin, Sebastian Dröge, Seungha Yang, Théo | |
2180 | Maillart, Thibault Saunier, Tim-Philipp Müller, Víctor Manuel Jáquez | |
2181 | Leal, Vivia Nikolaidou, Yatin Maan, | |
2182 | ||
2183 | … and many others who have contributed bug reports, translations, sent | |
2184 | suggestions or helped testing. Thank you all! | |
2185 | ||
2186 | List of merge requests and issues fixed in 1.22.5 | |
2187 | ||
2188 | - List of Merge Requests applied in 1.22.5 | |
2189 | - List of Issues fixed in 1.22.5 | |
2190 | ||
2010 | 2191 | Schedule for 1.24 |
2011 | 2192 | |
2012 | 2193 | Our next major feature release will be 1.24, and 1.23 will be the |
0 | This is GStreamer gst-plugins-good 1.22.4. | |
0 | This is GStreamer gst-plugins-good 1.22.5. | |
1 | 1 | |
2 | 2 | The GStreamer team is thrilled to announce a new major feature release |
3 | 3 | of your favourite cross-platform multimedia framework! |
7026 | 7026 | "construct": false, |
7027 | 7027 | "construct-only": false, |
7028 | 7028 | "controllable": false, |
7029 | "default": "GStreamer 1.22.4 FLV muxer", | |
7029 | "default": "GStreamer 1.22.5 FLV muxer", | |
7030 | 7030 | "mutable": "null", |
7031 | 7031 | "readable": true, |
7032 | 7032 | "type": "gchararray", |
7038 | 7038 | "construct": false, |
7039 | 7039 | "construct-only": false, |
7040 | 7040 | "controllable": false, |
7041 | "default": "GStreamer 1.22.4 FLV muxer", | |
7041 | "default": "GStreamer 1.22.5 FLV muxer", | |
7042 | 7042 | "mutable": "null", |
7043 | 7043 | "readable": true, |
7044 | 7044 | "type": "gchararray", |
21256 | 21256 | "construct": false, |
21257 | 21257 | "construct-only": false, |
21258 | 21258 | "controllable": false, |
21259 | "default": "GStreamer/1.22.4", | |
21259 | "default": "GStreamer/1.22.5", | |
21260 | 21260 | "mutable": "null", |
21261 | 21261 | "readable": true, |
21262 | 21262 | "type": "gchararray", |
21815 | 21815 | "construct": false, |
21816 | 21816 | "construct-only": false, |
21817 | 21817 | "controllable": false, |
21818 | "default": "GStreamer 1.22.4", | |
21818 | "default": "GStreamer 1.22.5", | |
21819 | 21819 | "mutable": "null", |
21820 | 21820 | "readable": true, |
21821 | 21821 | "type": "gchararray", |
23252 | 23252 | "construct": false, |
23253 | 23253 | "construct-only": false, |
23254 | 23254 | "controllable": false, |
23255 | "default": "GStreamer souphttpsrc 1.22.4 ", | |
23255 | "default": "GStreamer souphttpsrc 1.22.5 ", | |
23256 | 23256 | "mutable": "null", |
23257 | 23257 | "readable": true, |
23258 | 23258 | "type": "gchararray", |
190 | 190 | gboolean gst_adaptive_demux2_stream_in_live_seek_range (GstAdaptiveDemux * demux, |
191 | 191 | GstAdaptiveDemux2Stream * stream); |
192 | 192 | gboolean gst_adaptive_demux2_stream_is_selected_locked (GstAdaptiveDemux2Stream *stream); |
193 | gboolean gst_adaptive_demux2_stream_is_default_locked (GstAdaptiveDemux2Stream *stream); | |
193 | 194 | |
194 | 195 | gboolean gst_adaptive_demux_has_next_period (GstAdaptiveDemux * demux); |
195 | 196 | void gst_adaptive_demux_advance_period (GstAdaptiveDemux * demux); |
1426 | 1426 | } |
1427 | 1427 | |
1428 | 1428 | if (!downloadhelper_submit_request (demux->download_helper, |
1429 | demux->manifest_uri, DOWNLOAD_FLAG_NONE, request, NULL)) | |
1429 | NULL, DOWNLOAD_FLAG_NONE, request, NULL)) | |
1430 | 1430 | return GST_FLOW_ERROR; |
1431 | 1431 | |
1432 | 1432 | stream->download_active = TRUE; |
2096 | 2096 | return FALSE; |
2097 | 2097 | } |
2098 | 2098 | |
2099 | gboolean | |
2100 | gst_adaptive_demux2_stream_is_default_locked (GstAdaptiveDemux2Stream * stream) | |
2101 | { | |
2102 | GList *tmp; | |
2103 | ||
2104 | for (tmp = stream->tracks; tmp; tmp = tmp->next) { | |
2105 | GstAdaptiveDemuxTrack *track = tmp->data; | |
2106 | if (track->flags & GST_STREAM_FLAG_SELECT) | |
2107 | return TRUE; | |
2108 | } | |
2109 | ||
2110 | return FALSE; | |
2111 | } | |
2112 | ||
2099 | 2113 | /** |
2100 | 2114 | * gst_adaptive_demux2_stream_is_selected: |
2101 | 2115 | * @stream: A #GstAdaptiveDemux2Stream |
508 | 508 | GST_DEBUG_OBJECT (pad, "buffer %" GST_PTR_FORMAT, buffer); |
509 | 509 | |
510 | 510 | TRACKS_LOCK (demux); |
511 | ||
512 | /* Discard buffers that are received outside of a valid segment. This can | |
513 | * happen if a flushing seek (which resets the track segment seqnums) was | |
514 | * received but the stream is still providing buffers before returning. | |
515 | */ | |
516 | if (track->input_segment_seqnum == GST_SEQNUM_INVALID) { | |
517 | GST_DEBUG_OBJECT (pad, | |
518 | "Dropping buffer because we do not have a valid input segment"); | |
519 | gst_buffer_unref (buffer); | |
520 | TRACKS_UNLOCK (demux); | |
521 | return GST_FLOW_OK; | |
522 | } | |
511 | 523 | |
512 | 524 | ts = GST_BUFFER_DTS_OR_PTS (buffer); |
513 | 525 | |
658 | 670 | return TRUE; |
659 | 671 | } |
660 | 672 | |
673 | if (seg_seqnum != demux->priv->segment_seqnum) { | |
674 | GST_DEBUG_OBJECT (pad, "Ignoring non-current segment"); | |
675 | gst_event_unref (event); | |
676 | TRACKS_UNLOCK (demux); | |
677 | ||
678 | return TRUE; | |
679 | } | |
680 | ||
661 | 681 | track->input_segment_seqnum = seg_seqnum; |
662 | 682 | gst_event_copy_segment (event, &track->input_segment); |
663 | 683 | if (track->input_segment.rate >= 0) |
1388 | 1388 | } |
1389 | 1389 | |
1390 | 1390 | static gboolean |
1391 | gst_adaptive_demux_query (GstElement * element, GstQuery * query) | |
1392 | { | |
1393 | GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (element); | |
1394 | ||
1395 | GST_LOG_OBJECT (demux, "%" GST_PTR_FORMAT, query); | |
1396 | ||
1397 | switch (GST_QUERY_TYPE (query)) { | |
1398 | case GST_QUERY_BUFFERING: | |
1399 | { | |
1400 | GstFormat format; | |
1401 | gst_query_parse_buffering_range (query, &format, NULL, NULL, NULL); | |
1402 | ||
1403 | if (!demux->output_period) { | |
1404 | if (format != GST_FORMAT_TIME) { | |
1405 | GST_DEBUG_OBJECT (demux, | |
1406 | "No period setup yet, can't answer non-TIME buffering queries"); | |
1407 | return FALSE; | |
1408 | } | |
1409 | ||
1410 | GST_DEBUG_OBJECT (demux, | |
1411 | "No period setup yet, but still answering buffering query"); | |
1412 | return TRUE; | |
1413 | } | |
1414 | } | |
1415 | default: | |
1416 | break; | |
1417 | } | |
1418 | ||
1419 | return GST_ELEMENT_CLASS (parent_class)->query (element, query); | |
1420 | } | |
1421 | ||
1422 | static gboolean | |
1423 | 1391 | gst_adaptive_demux_send_event (GstElement * element, GstEvent * event) |
1424 | 1392 | { |
1425 | 1393 | GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (element); |
2009 | 1977 | gint64 start, stop; |
2010 | 1978 | guint32 seqnum; |
2011 | 1979 | gboolean update; |
2012 | gboolean ret; | |
1980 | gboolean ret = FALSE; | |
2013 | 1981 | GstSegment oldsegment; |
2014 | 1982 | GstEvent *flush_event; |
2015 | 1983 | |
2016 | 1984 | GST_INFO_OBJECT (demux, "Received seek event"); |
2017 | 1985 | |
2018 | GST_API_LOCK (demux); | |
2019 | ||
2020 | 1986 | gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start, |
2021 | 1987 | &stop_type, &stop); |
2022 | 1988 | |
2023 | 1989 | if (format != GST_FORMAT_TIME) { |
2024 | GST_API_UNLOCK (demux); | |
2025 | 1990 | GST_WARNING_OBJECT (demux, |
2026 | 1991 | "Adaptive demuxers only support TIME-based seeking"); |
2027 | 1992 | gst_event_unref (event); |
2030 | 1995 | |
2031 | 1996 | if (flags & GST_SEEK_FLAG_SEGMENT) { |
2032 | 1997 | GST_FIXME_OBJECT (demux, "Handle segment seeks"); |
2033 | GST_API_UNLOCK (demux); | |
2034 | 1998 | gst_event_unref (event); |
2035 | 1999 | return FALSE; |
2036 | 2000 | } |
2037 | 2001 | |
2038 | 2002 | seqnum = gst_event_get_seqnum (event); |
2039 | 2003 | |
2004 | GST_API_LOCK (demux); | |
2040 | 2005 | if (!GST_ADAPTIVE_SCHEDULER_LOCK (demux)) { |
2041 | 2006 | GST_LOG_OBJECT (demux, "Failed to acquire scheduler context"); |
2007 | GST_API_UNLOCK (demux); | |
2042 | 2008 | return FALSE; |
2043 | 2009 | } |
2044 | 2010 | |
2059 | 2025 | GST_ERROR_OBJECT (demux, |
2060 | 2026 | "Instant rate change seeks only supported in the " |
2061 | 2027 | "same direction, without flushing and position change"); |
2062 | GST_ADAPTIVE_SCHEDULER_UNLOCK (demux); | |
2063 | GST_API_UNLOCK (demux); | |
2064 | return FALSE; | |
2028 | goto unlock_return; | |
2065 | 2029 | } |
2066 | 2030 | |
2067 | 2031 | rate_multiplier = rate / demux->segment.rate; |
2077 | 2041 | demux->instant_rate_multiplier = rate_multiplier; |
2078 | 2042 | GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux); |
2079 | 2043 | } |
2080 | ||
2081 | GST_ADAPTIVE_SCHEDULER_UNLOCK (demux); | |
2082 | GST_API_UNLOCK (demux); | |
2083 | gst_event_unref (event); | |
2084 | ||
2085 | return ret; | |
2086 | } | |
2087 | ||
2088 | if (!gst_adaptive_demux_can_seek (demux)) { | |
2089 | GST_ADAPTIVE_SCHEDULER_UNLOCK (demux); | |
2090 | ||
2091 | GST_API_UNLOCK (demux); | |
2092 | gst_event_unref (event); | |
2093 | return FALSE; | |
2094 | } | |
2044 | goto unlock_return; | |
2045 | } | |
2046 | ||
2047 | if (!gst_adaptive_demux_can_seek (demux)) | |
2048 | goto unlock_return; | |
2095 | 2049 | |
2096 | 2050 | /* We can only accept flushing seeks from this point onward */ |
2097 | 2051 | if (!(flags & GST_SEEK_FLAG_FLUSH)) { |
2098 | 2052 | GST_ERROR_OBJECT (demux, |
2099 | 2053 | "Non-flushing non-instant-rate seeks are not possible"); |
2100 | ||
2101 | GST_ADAPTIVE_SCHEDULER_UNLOCK (demux); | |
2102 | ||
2103 | GST_API_UNLOCK (demux); | |
2104 | gst_event_unref (event); | |
2105 | return FALSE; | |
2054 | goto unlock_return; | |
2106 | 2055 | } |
2107 | 2056 | |
2108 | 2057 | if (gst_adaptive_demux_is_live (demux)) { |
2112 | 2061 | |
2113 | 2062 | if (!gst_adaptive_demux_get_live_seek_range (demux, &range_start, |
2114 | 2063 | &range_stop)) { |
2115 | GST_ADAPTIVE_SCHEDULER_UNLOCK (demux); | |
2116 | GST_API_UNLOCK (demux); | |
2117 | gst_event_unref (event); | |
2118 | 2064 | GST_WARNING_OBJECT (demux, "Failure getting the live seek ranges"); |
2119 | return FALSE; | |
2065 | goto unlock_return; | |
2120 | 2066 | } |
2121 | 2067 | |
2122 | 2068 | GST_DEBUG_OBJECT (demux, |
2178 | 2124 | } |
2179 | 2125 | |
2180 | 2126 | /* If the seek position is still outside of the seekable range, refuse the seek */ |
2181 | if (!start_valid || !stop_valid) { | |
2182 | GST_ADAPTIVE_SCHEDULER_UNLOCK (demux); | |
2183 | GST_API_UNLOCK (demux); | |
2184 | gst_event_unref (event); | |
2185 | return FALSE; | |
2186 | } | |
2127 | if (!start_valid || !stop_valid) | |
2128 | goto unlock_return; | |
2187 | 2129 | |
2188 | 2130 | /* Re-create seek event with changed/updated values */ |
2189 | 2131 | if (changed) { |
2211 | 2153 | |
2212 | 2154 | GST_ADAPTIVE_DEMUX_SEGMENT_LOCK (demux); |
2213 | 2155 | |
2214 | /* | |
2215 | * Handle snap seeks as follows: | |
2216 | * 1) do the snap seeking a (random) active stream | |
2217 | * 2) use the final position on this stream to seek | |
2218 | * on the other streams to the same position | |
2219 | * | |
2220 | * We can't snap at all streams at the same time as they might end in | |
2221 | * different positions, so just pick one and align all others to that | |
2222 | * position. | |
2223 | */ | |
2224 | ||
2225 | GstAdaptiveDemux2Stream *stream = NULL; | |
2226 | GList *iter; | |
2227 | /* Pick a random active stream on which to do the stream seek */ | |
2228 | for (iter = demux->output_period->streams; iter; iter = iter->next) { | |
2229 | GstAdaptiveDemux2Stream *cand = iter->data; | |
2230 | if (gst_adaptive_demux2_stream_is_selected_locked (cand)) { | |
2231 | stream = cand; | |
2232 | break; | |
2233 | } | |
2234 | } | |
2235 | ||
2236 | if (stream && IS_SNAP_SEEK (flags)) { | |
2237 | GstClockTimeDiff ts; | |
2238 | GstSeekFlags stream_seek_flags = flags; | |
2239 | ||
2240 | /* snap-seek on the chosen stream and then | |
2241 | * use the resulting position to seek on all streams */ | |
2242 | if (rate >= 0) { | |
2243 | if (start_type != GST_SEEK_TYPE_NONE) | |
2244 | ts = start; | |
2245 | else { | |
2246 | ts = gst_segment_position_from_running_time (&demux->segment, | |
2247 | GST_FORMAT_TIME, demux->priv->global_output_position); | |
2248 | start_type = GST_SEEK_TYPE_SET; | |
2156 | if (!IS_SNAP_SEEK (flags) && !(flags & GST_SEEK_FLAG_ACCURATE)) { | |
2157 | /* If no accurate seeking was specified, we want to default to seeking to | |
2158 | * the previous segment for efficient/fast playback. */ | |
2159 | flags |= GST_SEEK_FLAG_KEY_UNIT; | |
2160 | } | |
2161 | ||
2162 | if (IS_SNAP_SEEK (flags)) { | |
2163 | GstAdaptiveDemux2Stream *default_stream = NULL; | |
2164 | GstAdaptiveDemux2Stream *stream = NULL; | |
2165 | GList *iter; | |
2166 | /* | |
2167 | * Handle snap seeks as follows: | |
2168 | * 1) do the snap seeking a (random) active stream | |
2169 | * 1.1) If none are active yet (early-seek), pick a random default one | |
2170 | * 2) use the final position on this stream to seek | |
2171 | * on the other streams to the same position | |
2172 | * | |
2173 | * We can't snap at all streams at the same time as they might end in | |
2174 | * different positions, so just pick one and align all others to that | |
2175 | * position. | |
2176 | */ | |
2177 | ||
2178 | /* Pick a random active stream on which to do the stream seek */ | |
2179 | for (iter = demux->output_period->streams; iter; iter = iter->next) { | |
2180 | GstAdaptiveDemux2Stream *cand = iter->data; | |
2181 | if (gst_adaptive_demux2_stream_is_selected_locked (cand)) { | |
2182 | stream = cand; | |
2183 | break; | |
2249 | 2184 | } |
2250 | } else { | |
2251 | if (stop_type != GST_SEEK_TYPE_NONE) | |
2252 | ts = stop; | |
2253 | else { | |
2254 | stop_type = GST_SEEK_TYPE_SET; | |
2255 | ts = gst_segment_position_from_running_time (&demux->segment, | |
2256 | GST_FORMAT_TIME, demux->priv->global_output_position); | |
2185 | if (default_stream == NULL | |
2186 | && gst_adaptive_demux2_stream_is_default_locked (cand)) | |
2187 | default_stream = cand; | |
2188 | } | |
2189 | ||
2190 | if (stream == NULL) | |
2191 | stream = default_stream; | |
2192 | ||
2193 | if (stream) { | |
2194 | GstClockTimeDiff ts; | |
2195 | GstSeekFlags stream_seek_flags = flags; | |
2196 | ||
2197 | /* snap-seek on the chosen stream and then | |
2198 | * use the resulting position to seek on all streams */ | |
2199 | if (rate >= 0) { | |
2200 | if (start_type != GST_SEEK_TYPE_NONE) | |
2201 | ts = start; | |
2202 | else { | |
2203 | ts = gst_segment_position_from_running_time (&demux->segment, | |
2204 | GST_FORMAT_TIME, demux->priv->global_output_position); | |
2205 | start_type = GST_SEEK_TYPE_SET; | |
2206 | } | |
2207 | } else { | |
2208 | if (stop_type != GST_SEEK_TYPE_NONE) | |
2209 | ts = stop; | |
2210 | else { | |
2211 | stop_type = GST_SEEK_TYPE_SET; | |
2212 | ts = gst_segment_position_from_running_time (&demux->segment, | |
2213 | GST_FORMAT_TIME, demux->priv->global_output_position); | |
2214 | } | |
2257 | 2215 | } |
2258 | } | |
2259 | ||
2260 | if (gst_adaptive_demux2_stream_seek (stream, rate >= 0, stream_seek_flags, | |
2261 | ts, &ts) != GST_FLOW_OK) { | |
2262 | GST_ADAPTIVE_SCHEDULER_UNLOCK (demux); | |
2263 | ||
2264 | GST_API_UNLOCK (demux); | |
2216 | ||
2217 | if (gst_adaptive_demux2_stream_seek (stream, rate >= 0, stream_seek_flags, | |
2218 | ts, &ts) != GST_FLOW_OK) { | |
2219 | GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux); | |
2220 | goto unlock_return; | |
2221 | } | |
2222 | /* replace event with a new one without snapping to seek on all streams */ | |
2265 | 2223 | gst_event_unref (event); |
2266 | return FALSE; | |
2267 | } | |
2268 | ||
2269 | /* replace event with a new one without snapping to seek on all streams */ | |
2270 | gst_event_unref (event); | |
2271 | if (rate >= 0) { | |
2272 | start = ts; | |
2273 | } else { | |
2274 | stop = ts; | |
2275 | } | |
2276 | event = | |
2277 | gst_event_new_seek (rate, format, REMOVE_SNAP_FLAGS (flags), | |
2278 | start_type, start, stop_type, stop); | |
2279 | GST_DEBUG_OBJECT (demux, "Adapted snap seek to %" GST_PTR_FORMAT, event); | |
2224 | if (rate >= 0) { | |
2225 | start = ts; | |
2226 | } else { | |
2227 | stop = ts; | |
2228 | } | |
2229 | event = | |
2230 | gst_event_new_seek (rate, format, REMOVE_SNAP_FLAGS (flags), | |
2231 | start_type, start, stop_type, stop); | |
2232 | GST_DEBUG_OBJECT (demux, "Adapted snap seek to %" GST_PTR_FORMAT, event); | |
2233 | } | |
2280 | 2234 | } |
2281 | 2235 | |
2282 | 2236 | ret = gst_segment_do_seek (&demux->segment, rate, format, flags, start_type, |
2328 | 2282 | /* Restart the demux */ |
2329 | 2283 | gst_adaptive_demux_start_tasks (demux); |
2330 | 2284 | |
2285 | unlock_return: | |
2331 | 2286 | GST_ADAPTIVE_SCHEDULER_UNLOCK (demux); |
2332 | 2287 | GST_API_UNLOCK (demux); |
2333 | 2288 | gst_event_unref (event); |
2570 | 2525 | } |
2571 | 2526 | |
2572 | 2527 | static gboolean |
2528 | gst_adaptive_demux_handle_query_seeking (GstAdaptiveDemux * demux, | |
2529 | GstQuery * query) | |
2530 | { | |
2531 | GstFormat fmt = GST_FORMAT_UNDEFINED; | |
2532 | gint64 stop = -1; | |
2533 | gint64 start = 0; | |
2534 | gboolean ret = FALSE; | |
2535 | ||
2536 | if (!g_atomic_int_get (&demux->priv->have_manifest)) { | |
2537 | GST_INFO_OBJECT (demux, | |
2538 | "Don't have manifest yet, can't answer seeking query"); | |
2539 | return FALSE; /* can't answer without manifest */ | |
2540 | } | |
2541 | ||
2542 | GST_MANIFEST_LOCK (demux); | |
2543 | ||
2544 | gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); | |
2545 | GST_INFO_OBJECT (demux, "Received GST_QUERY_SEEKING with format %d", fmt); | |
2546 | if (fmt == GST_FORMAT_TIME) { | |
2547 | GstClockTime duration; | |
2548 | gboolean can_seek = gst_adaptive_demux_can_seek (demux); | |
2549 | ||
2550 | ret = TRUE; | |
2551 | if (can_seek) { | |
2552 | if (gst_adaptive_demux_is_live (demux)) { | |
2553 | ret = gst_adaptive_demux_get_live_seek_range (demux, &start, &stop); | |
2554 | ||
2555 | if (!ret) { | |
2556 | GST_MANIFEST_UNLOCK (demux); | |
2557 | GST_INFO_OBJECT (demux, "can't answer seeking query"); | |
2558 | return FALSE; | |
2559 | } | |
2560 | } else { | |
2561 | duration = demux->priv->duration; | |
2562 | if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) | |
2563 | stop = duration; | |
2564 | } | |
2565 | } | |
2566 | gst_query_set_seeking (query, fmt, can_seek, start, stop); | |
2567 | GST_INFO_OBJECT (demux, "GST_QUERY_SEEKING returning with start : %" | |
2568 | GST_TIME_FORMAT ", stop : %" GST_TIME_FORMAT, | |
2569 | GST_TIME_ARGS (start), GST_TIME_ARGS (stop)); | |
2570 | } | |
2571 | GST_MANIFEST_UNLOCK (demux); | |
2572 | return ret; | |
2573 | } | |
2574 | ||
2575 | static gboolean | |
2573 | 2576 | gst_adaptive_demux_src_query (GstPad * pad, GstObject * parent, |
2574 | 2577 | GstQuery * query) |
2575 | 2578 | { |
2578 | 2581 | |
2579 | 2582 | if (query == NULL) |
2580 | 2583 | return FALSE; |
2581 | ||
2582 | 2584 | |
2583 | 2585 | switch (query->type) { |
2584 | 2586 | case GST_QUERY_DURATION:{ |
2616 | 2618 | ret = TRUE; |
2617 | 2619 | break; |
2618 | 2620 | } |
2619 | case GST_QUERY_SEEKING:{ | |
2620 | GstFormat fmt; | |
2621 | gint64 stop = -1; | |
2622 | gint64 start = 0; | |
2623 | ||
2624 | if (!g_atomic_int_get (&demux->priv->have_manifest)) { | |
2625 | GST_INFO_OBJECT (demux, | |
2626 | "Don't have manifest yet, can't answer seeking query"); | |
2627 | return FALSE; /* can't answer without manifest */ | |
2628 | } | |
2629 | ||
2630 | GST_MANIFEST_LOCK (demux); | |
2631 | ||
2632 | gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); | |
2633 | GST_INFO_OBJECT (demux, "Received GST_QUERY_SEEKING with format %d", fmt); | |
2634 | if (fmt == GST_FORMAT_TIME) { | |
2635 | GstClockTime duration; | |
2636 | gboolean can_seek = gst_adaptive_demux_can_seek (demux); | |
2637 | ||
2638 | ret = TRUE; | |
2639 | if (can_seek) { | |
2640 | if (gst_adaptive_demux_is_live (demux)) { | |
2641 | ret = gst_adaptive_demux_get_live_seek_range (demux, &start, &stop); | |
2642 | if (!ret) { | |
2643 | GST_MANIFEST_UNLOCK (demux); | |
2644 | GST_INFO_OBJECT (demux, "can't answer seeking query"); | |
2645 | return FALSE; | |
2646 | } | |
2647 | } else { | |
2648 | duration = demux->priv->duration; | |
2649 | if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) | |
2650 | stop = duration; | |
2651 | } | |
2652 | } | |
2653 | gst_query_set_seeking (query, fmt, can_seek, start, stop); | |
2654 | GST_INFO_OBJECT (demux, "GST_QUERY_SEEKING returning with start : %" | |
2655 | GST_TIME_FORMAT ", stop : %" GST_TIME_FORMAT, | |
2656 | GST_TIME_ARGS (start), GST_TIME_ARGS (stop)); | |
2657 | } | |
2658 | GST_MANIFEST_UNLOCK (demux); | |
2659 | break; | |
2660 | } | |
2621 | case GST_QUERY_SEEKING: | |
2622 | ret = gst_adaptive_demux_handle_query_seeking (demux, query); | |
2623 | break; | |
2661 | 2624 | case GST_QUERY_URI: |
2662 | 2625 | |
2663 | 2626 | GST_MANIFEST_LOCK (demux); |
2685 | 2648 | } |
2686 | 2649 | |
2687 | 2650 | return ret; |
2651 | } | |
2652 | ||
2653 | static gboolean | |
2654 | gst_adaptive_demux_query (GstElement * element, GstQuery * query) | |
2655 | { | |
2656 | GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (element); | |
2657 | ||
2658 | GST_LOG_OBJECT (demux, "%" GST_PTR_FORMAT, query); | |
2659 | ||
2660 | switch (GST_QUERY_TYPE (query)) { | |
2661 | case GST_QUERY_BUFFERING: | |
2662 | { | |
2663 | GstFormat format; | |
2664 | gst_query_parse_buffering_range (query, &format, NULL, NULL, NULL); | |
2665 | ||
2666 | if (!demux->output_period) { | |
2667 | if (format != GST_FORMAT_TIME) { | |
2668 | GST_DEBUG_OBJECT (demux, | |
2669 | "No period setup yet, can't answer non-TIME buffering queries"); | |
2670 | return FALSE; | |
2671 | } | |
2672 | ||
2673 | GST_DEBUG_OBJECT (demux, | |
2674 | "No period setup yet, but still answering buffering query"); | |
2675 | return TRUE; | |
2676 | } | |
2677 | } | |
2678 | case GST_QUERY_SEEKING: | |
2679 | { | |
2680 | /* Source pads might not be present early on which would cause the default | |
2681 | * element query handler to fail, yet we can answer this query */ | |
2682 | return gst_adaptive_demux_handle_query_seeking (demux, query); | |
2683 | } | |
2684 | default: | |
2685 | break; | |
2686 | } | |
2687 | ||
2688 | return GST_ELEMENT_CLASS (parent_class)->query (element, query); | |
2688 | 2689 | } |
2689 | 2690 | |
2690 | 2691 | gboolean |
943 | 943 | out: |
944 | 944 | if (ret) { |
945 | 945 | gchar *newfile; |
946 | ||
947 | /* Ensure file always ends with an empty newline by adding an empty | |
948 | * line. This helps downstream parsers properly detect entries */ | |
949 | g_ptr_array_add (builder, g_strdup ("\n")); | |
946 | 950 | /* Add NULL-terminator to string list */ |
947 | 951 | g_ptr_array_add (builder, NULL); |
948 | 952 | newfile = g_strjoinv ("\n", (gchar **) builder->pdata); |
1856 | 1856 | GstHLSMediaPlaylist * current) |
1857 | 1857 | { |
1858 | 1858 | GstAdaptiveDemux *adaptive_demux; |
1859 | const gchar *main_uri; | |
1860 | 1859 | DownloadRequest *download; |
1861 | 1860 | GstBuffer *buf; |
1862 | 1861 | gchar *playlist_data; |
1865 | 1864 | gboolean playlist_uri_change = FALSE; |
1866 | 1865 | |
1867 | 1866 | adaptive_demux = GST_ADAPTIVE_DEMUX (demux); |
1868 | main_uri = gst_adaptive_demux_get_manifest_ref_uri (adaptive_demux); | |
1869 | 1867 | |
1870 | 1868 | /* If there's no previous playlist, or the URI changed this |
1871 | 1869 | * is not a refresh/update but a switch to a new playlist */ |
1877 | 1875 | |
1878 | 1876 | download = |
1879 | 1877 | downloadhelper_fetch_uri (adaptive_demux->download_helper, |
1880 | uri, main_uri, DOWNLOAD_FLAG_COMPRESS | DOWNLOAD_FLAG_FORCE_REFRESH, err); | |
1878 | uri, NULL, DOWNLOAD_FLAG_COMPRESS | DOWNLOAD_FLAG_FORCE_REFRESH, err); | |
1881 | 1879 | |
1882 | 1880 | if (download == NULL) |
1883 | 1881 | return NULL; |
322 | 322 | dst.w = allocation->width; |
323 | 323 | dst.h = allocation->height; |
324 | 324 | |
325 | gst_video_sink_center_rect (src, dst, result, TRUE); | |
325 | if (base_widget->display_width > 0 && base_widget->display_height > 0) | |
326 | gst_video_sink_center_rect (src, dst, result, TRUE); | |
326 | 327 | } else { |
327 | 328 | result->x = 0; |
328 | 329 | result->y = 0; |
43 | 43 | #include <gst/gl/wayland/gstgldisplay_wayland.h> |
44 | 44 | #endif |
45 | 45 | |
46 | #if GST_GL_HAVE_WINDOW_VIV_FB | |
46 | #if GST_GL_HAVE_WINDOW_VIV_FB && defined (HAVE_QT_VIV_FB) | |
47 | 47 | #include <gst/gl/viv-fb/gstgldisplay_viv_fb.h> |
48 | 48 | #endif |
49 | 49 | |
116 | 116 | } |
117 | 117 | #elif GST_GL_HAVE_PLATFORM_EGL && defined (HAVE_QT_EGLFS) |
118 | 118 | if (QString::fromUtf8("eglfs") == app->platformName()) { |
119 | #if GST_GL_HAVE_WINDOW_VIV_FB | |
119 | #if GST_GL_HAVE_WINDOW_VIV_FB && defined (HAVE_QT_VIV_FB) | |
120 | 120 | /* FIXME: Could get the display directly from Qt like this |
121 | 121 | * QPlatformNativeInterface *native = |
122 | 122 | * QGuiApplication::platformNativeInterface(); |
201 | 201 | } |
202 | 202 | #endif |
203 | 203 | #if GST_GL_HAVE_PLATFORM_EGL && defined (HAVE_QT_EGLFS) |
204 | #if GST_GL_HAVE_WINDOW_VIV_FB | |
204 | #if GST_GL_HAVE_WINDOW_VIV_FB && defined (HAVE_QT_VIV_FB) | |
205 | 205 | if (GST_IS_GL_DISPLAY_VIV_FB (display)) { |
206 | 206 | #else |
207 | 207 | if (GST_IS_GL_DISPLAY_EGL (display)) { |
183 | 183 | endif |
184 | 184 | endif |
185 | 185 | |
186 | # EGL windowing for Vivante Framebuffer (e.g. i.MX6) | |
187 | qt5_viv_fb = qt5_egl \ | |
188 | .require(host_system == 'linux') \ | |
189 | .require(gstglviv_fb_dep.found(), error_message: 'gstreamer-gl-viv_fb-1.0 is required') \ | |
190 | .require(gst_gl_have_platform_egl, error_message: 'egl platform support in gstreamer-gl is required') | |
191 | if qt5_viv_fb.allowed() | |
192 | qt_defines += ['-DHAVE_QT_VIV_FB'] | |
193 | optional_deps += gstglviv_fb_dep | |
194 | have_qt_windowing = true | |
195 | endif | |
196 | ||
186 | 197 | if qt5_option.require(have_qt_windowing).allowed() |
187 | 198 | # rpath is needed to be able to load the plugin on macOS inside the devenv |
188 | 199 | qmlgl_kwargs = {} |
290 | 290 | gst_gl_context_activate (this->priv->other_context, TRUE); |
291 | 291 | |
292 | 292 | if (!texNode) { |
293 | bool is_smooth = this->smooth (); | |
293 | 294 | texNode = new GstQSG6OpenGLNode (this); |
295 | texNode->setFiltering (is_smooth ? QSGTexture::Filtering::Linear : | |
296 | QSGTexture::Filtering::Nearest); | |
294 | 297 | this->priv->m_node = texNode; |
295 | 298 | } |
296 | 299 |
12977 | 12977 | channel_mapping_family, stream_count, coupled_count, |
12978 | 12978 | channel_mapping); |
12979 | 12979 | g_free (channel_mapping); |
12980 | ||
12981 | entry->sampled = TRUE; | |
12982 | ||
12980 | 12983 | break; |
12981 | 12984 | } |
12982 | 12985 | default: |
6230 | 6230 | "received format %d segment %" GST_SEGMENT_FORMAT, segment->format, |
6231 | 6231 | segment); |
6232 | 6232 | |
6233 | if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) { | |
6234 | GST_DEBUG_OBJECT (demux, "still starting"); | |
6235 | goto exit; | |
6236 | } | |
6237 | ||
6238 | 6233 | if (segment->format == GST_FORMAT_TIME) { |
6239 | 6234 | demux->upstream_format_is_time = TRUE; |
6240 | 6235 | demux->segment_seqnum = gst_event_get_seqnum (event); |
6241 | 6236 | gst_segment_copy_into (segment, &demux->common.segment); |
6242 | 6237 | GST_DEBUG_OBJECT (demux, "Got segment in TIME format: %" GST_PTR_FORMAT, |
6243 | 6238 | event); |
6239 | goto exit; | |
6240 | } | |
6241 | ||
6242 | if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) { | |
6243 | GST_DEBUG_OBJECT (demux, "still starting"); | |
6244 | 6244 | goto exit; |
6245 | 6245 | } |
6246 | 6246 |
447 | 447 | |
448 | 448 | /* Unencrypted buffer */ |
449 | 449 | if (!(signal_byte & GST_MATROSKA_BLOCK_ENCRYPTED)) { |
450 | *size_out = gst_byte_reader_get_remaining (&reader); | |
451 | gst_byte_reader_get_data (&reader, *size_out, (const guint8 **) data_out); | |
450 | 452 | return TRUE; |
451 | 453 | } |
452 | 454 |
3155 | 3155 | GstEvent * event) |
3156 | 3156 | { |
3157 | 3157 | GstRTSPStream *stream; |
3158 | GstRTSPSrc *self = GST_RTSPSRC (GST_OBJECT_PARENT (parent)); | |
3159 | 3158 | |
3160 | 3159 | stream = gst_pad_get_element_private (pad); |
3161 | 3160 | |
3162 | event = gst_rtspsrc_update_src_event (self, stream, event); | |
3161 | event = gst_rtspsrc_update_src_event (stream->parent, stream, event); | |
3163 | 3162 | |
3164 | 3163 | return gst_pad_push_event (stream->srcpad, event); |
3165 | 3164 | } |
1787 | 1787 | |
1788 | 1788 | if (gst_video_orientation_from_tag (taglist, &method)) { |
1789 | 1789 | gst_video_flip_set_method (vf, method, TRUE); |
1790 | ||
1791 | if (vf->method == GST_VIDEO_ORIENTATION_AUTO) { | |
1792 | /* update the orientation tag as we rotate the video accordingly */ | |
1793 | if (gst_tag_list_is_writable (taglist)) { | |
1794 | gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, | |
1795 | "image-orientation", "rotate-0", NULL); | |
1796 | } else { | |
1797 | taglist = gst_tag_list_copy (taglist); | |
1798 | ||
1799 | gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, | |
1800 | "image-orientation", "rotate-0", NULL); | |
1801 | ||
1802 | gst_event_unref (event); | |
1803 | event = gst_event_new_tag (taglist); | |
1804 | } | |
1805 | } | |
1790 | 1806 | } |
1791 | 1807 | break; |
1792 | 1808 | default: |
33 | 33 | |
34 | 34 | <release> |
35 | 35 | <Version> |
36 | <revision>1.22.5</revision> | |
37 | <branch>1.22</branch> | |
38 | <name></name> | |
39 | <created>2023-07-20</created> | |
40 | <file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-1.22.5.tar.xz" /> | |
41 | </Version> | |
42 | </release> | |
43 | ||
44 | <release> | |
45 | <Version> | |
36 | 46 | <revision>1.22.4</revision> |
37 | 47 | <branch>1.22</branch> |
38 | 48 | <name></name> |
0 | 0 | project('gst-plugins-good', 'c', |
1 | version : '1.22.4', | |
1 | version : '1.22.5', | |
2 | 2 | meson_version : '>= 0.62', |
3 | 3 | default_options : [ 'warning_level=1', |
4 | 4 | 'buildtype=debugoptimized' ]) |
320 | 320 | gstglx11_dep = dependency('', required : false) |
321 | 321 | gstglwayland_dep = dependency('', required : false) |
322 | 322 | gstglegl_dep = dependency('', required : false) |
323 | gstglviv_fb_dep = dependency('', required : false) | |
323 | 324 | |
324 | 325 | have_gstgl = gstgl_dep.found() |
325 | 326 | |
339 | 340 | message('GStreamer OpenGL platforms: @0@'.format(' '.join(gst_gl_platforms))) |
340 | 341 | message('GStreamer OpenGL apis: @0@'.format(' '.join(gst_gl_apis))) |
341 | 342 | |
342 | foreach ws : ['x11', 'wayland', 'android', 'cocoa', 'eagl', 'win32', 'dispmanx', 'viv_fb'] | |
343 | foreach ws : ['x11', 'wayland', 'android', 'cocoa', 'eagl', 'win32', 'dispmanx'] | |
343 | 344 | set_variable('gst_gl_have_window_@0@'.format(ws), gst_gl_winsys.contains(ws)) |
344 | 345 | endforeach |
346 | # Handling viv-fb separately, because the winsys is called "viv-fb", but the | |
347 | # variable suffix must be "viv_fb" (dashes are not allowed in variable names). | |
348 | set_variable('gst_gl_have_window_viv_fb', gst_gl_winsys.contains('viv-fb')) | |
345 | 349 | |
346 | 350 | foreach p : ['glx', 'egl', 'cgl', 'eagl', 'wgl'] |
347 | 351 | set_variable('gst_gl_have_platform_@0@'.format(p), gst_gl_platforms.contains(p)) |
368 | 372 | if gst_gl_have_platform_egl |
369 | 373 | gstglegl_dep = dependency('gstreamer-gl-egl-1.0', version : gst_req, |
370 | 374 | fallback : ['gst-plugins-base', 'gstglegl_dep'], required: true) |
375 | endif | |
376 | if gst_gl_have_window_viv_fb | |
377 | gstglviv_fb_dep = dependency('gstreamer-gl-viv-fb-1.0', version : gst_req, | |
378 | fallback : ['gst-plugins-base', 'gstglviv_fb_dep'], required: true) | |
371 | 379 | endif |
372 | 380 | endif |
373 | 381 |
5 | 5 | #, fuzzy |
6 | 6 | msgid "" |
7 | 7 | msgstr "" |
8 | "Project-Id-Version: gst-plugins-good-1.22.4\n" | |
8 | "Project-Id-Version: gst-plugins-good-1.22.5\n" | |
9 | 9 | "Report-Msgid-Bugs-To: \n" |
10 | "POT-Creation-Date: 2023-06-20 17:45+0100\n" | |
10 | "POT-Creation-Date: 2023-07-20 15:24+0100\n" | |
11 | 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
12 | 12 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
13 | 13 | "Language-Team: LANGUAGE <LL@li.org>\n" |
110 | 110 | #: gst/isomp4/qtdemux.c:4364 gst/isomp4/qtdemux.c:8521 |
111 | 111 | #: gst/isomp4/qtdemux.c:8528 gst/isomp4/qtdemux.c:9836 |
112 | 112 | #: gst/isomp4/qtdemux.c:10278 gst/isomp4/qtdemux.c:10285 |
113 | #: gst/isomp4/qtdemux.c:13522 | |
113 | #: gst/isomp4/qtdemux.c:13525 | |
114 | 114 | msgid "This file is corrupt and cannot be played." |
115 | 115 | msgstr "" |
116 | 116 | |
134 | 134 | msgid "The video in this file might not play correctly." |
135 | 135 | msgstr "" |
136 | 136 | |
137 | #: gst/rtsp/gstrtspsrc.c:7894 | |
137 | #: gst/rtsp/gstrtspsrc.c:7893 | |
138 | 138 | msgid "" |
139 | 139 | "No supported stream was found. You might need to install a GStreamer RTSP " |
140 | 140 | "extension plugin for Real media streams." |
141 | 141 | msgstr "" |
142 | 142 | |
143 | #: gst/rtsp/gstrtspsrc.c:7899 | |
143 | #: gst/rtsp/gstrtspsrc.c:7898 | |
144 | 144 | msgid "" |
145 | 145 | "No supported stream was found. You might need to allow more transport " |
146 | 146 | "protocols or may otherwise be missing the right GStreamer RTSP extension " |
347 | 347 | msgid "Failed to allocated required memory." |
348 | 348 | msgstr "" |
349 | 349 | |
350 | #: sys/v4l2/gstv4l2src.c:977 sys/v4l2/gstv4l2videodec.c:695 | |
351 | #: sys/v4l2/gstv4l2videodec.c:1064 sys/v4l2/gstv4l2videoenc.c:861 | |
350 | #: sys/v4l2/gstv4l2src.c:977 sys/v4l2/gstv4l2videodec.c:525 | |
351 | #: sys/v4l2/gstv4l2videodec.c:1048 sys/v4l2/gstv4l2videoenc.c:881 | |
352 | 352 | msgid "Failed to allocate required memory." |
353 | 353 | msgstr "" |
354 | 354 | |
367 | 367 | msgid "Decoder on device %s has no supported input format" |
368 | 368 | msgstr "" |
369 | 369 | |
370 | #: sys/v4l2/gstv4l2videodec.c:1078 | |
370 | #: sys/v4l2/gstv4l2videodec.c:1062 | |
371 | 371 | msgid "Failed to start decoding thread." |
372 | 372 | msgstr "" |
373 | 373 | |
374 | #: sys/v4l2/gstv4l2videodec.c:1085 sys/v4l2/gstv4l2videoenc.c:882 | |
374 | #: sys/v4l2/gstv4l2videodec.c:1069 sys/v4l2/gstv4l2videoenc.c:902 | |
375 | 375 | msgid "Failed to process frame." |
376 | 376 | msgstr "" |
377 | 377 | |
385 | 385 | msgid "Encoder on device %s has no supported input format" |
386 | 386 | msgstr "" |
387 | 387 | |
388 | #: sys/v4l2/gstv4l2videoenc.c:826 | |
388 | #: sys/v4l2/gstv4l2videoenc.c:846 | |
389 | 389 | msgid "Failed to force keyframe." |
390 | 390 | msgstr "" |
391 | 391 | |
392 | #: sys/v4l2/gstv4l2videoenc.c:874 | |
392 | #: sys/v4l2/gstv4l2videoenc.c:894 | |
393 | 393 | msgid "Failed to start encoding thread." |
394 | 394 | msgstr "" |
395 | 395 |
5 | 5 | #, fuzzy |
6 | 6 | msgid "" |
7 | 7 | msgstr "" |
8 | "Project-Id-Version: gst-plugins-good-1.22.4\n" | |
8 | "Project-Id-Version: gst-plugins-good-1.22.5\n" | |
9 | 9 | "Report-Msgid-Bugs-To: \n" |
10 | "POT-Creation-Date: 2023-06-20 17:45+0100\n" | |
10 | "POT-Creation-Date: 2023-07-20 15:24+0100\n" | |
11 | 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
12 | 12 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
13 | 13 | "Language-Team: LANGUAGE <LL@li.org>\n" |
110 | 110 | #: gst/isomp4/qtdemux.c:4364 gst/isomp4/qtdemux.c:8521 |
111 | 111 | #: gst/isomp4/qtdemux.c:8528 gst/isomp4/qtdemux.c:9836 |
112 | 112 | #: gst/isomp4/qtdemux.c:10278 gst/isomp4/qtdemux.c:10285 |
113 | #: gst/isomp4/qtdemux.c:13522 | |
113 | #: gst/isomp4/qtdemux.c:13525 | |
114 | 114 | msgid "This file is corrupt and cannot be played." |
115 | 115 | msgstr "" |
116 | 116 | |
134 | 134 | msgid "The video in this file might not play correctly." |
135 | 135 | msgstr "" |
136 | 136 | |
137 | #: gst/rtsp/gstrtspsrc.c:7894 | |
137 | #: gst/rtsp/gstrtspsrc.c:7893 | |
138 | 138 | msgid "" |
139 | 139 | "No supported stream was found. You might need to install a GStreamer RTSP " |
140 | 140 | "extension plugin for Real media streams." |
141 | 141 | msgstr "" |
142 | 142 | |
143 | #: gst/rtsp/gstrtspsrc.c:7899 | |
143 | #: gst/rtsp/gstrtspsrc.c:7898 | |
144 | 144 | msgid "" |
145 | 145 | "No supported stream was found. You might need to allow more transport " |
146 | 146 | "protocols or may otherwise be missing the right GStreamer RTSP extension " |
347 | 347 | msgid "Failed to allocated required memory." |
348 | 348 | msgstr "" |
349 | 349 | |
350 | #: sys/v4l2/gstv4l2src.c:977 sys/v4l2/gstv4l2videodec.c:695 | |
351 | #: sys/v4l2/gstv4l2videodec.c:1064 sys/v4l2/gstv4l2videoenc.c:861 | |
350 | #: sys/v4l2/gstv4l2src.c:977 sys/v4l2/gstv4l2videodec.c:525 | |
351 | #: sys/v4l2/gstv4l2videodec.c:1048 sys/v4l2/gstv4l2videoenc.c:881 | |
352 | 352 | msgid "Failed to allocate required memory." |
353 | 353 | msgstr "" |
354 | 354 | |
367 | 367 | msgid "Decoder on device %s has no supported input format" |
368 | 368 | msgstr "" |
369 | 369 | |
370 | #: sys/v4l2/gstv4l2videodec.c:1078 | |
370 | #: sys/v4l2/gstv4l2videodec.c:1062 | |
371 | 371 | msgid "Failed to start decoding thread." |
372 | 372 | msgstr "" |
373 | 373 | |
374 | #: sys/v4l2/gstv4l2videodec.c:1085 sys/v4l2/gstv4l2videoenc.c:882 | |
374 | #: sys/v4l2/gstv4l2videodec.c:1069 sys/v4l2/gstv4l2videoenc.c:902 | |
375 | 375 | msgid "Failed to process frame." |
376 | 376 | msgstr "" |
377 | 377 | |
385 | 385 | msgid "Encoder on device %s has no supported input format" |
386 | 386 | msgstr "" |
387 | 387 | |
388 | #: sys/v4l2/gstv4l2videoenc.c:826 | |
388 | #: sys/v4l2/gstv4l2videoenc.c:846 | |
389 | 389 | msgid "Failed to force keyframe." |
390 | 390 | msgstr "" |
391 | 391 | |
392 | #: sys/v4l2/gstv4l2videoenc.c:874 | |
392 | #: sys/v4l2/gstv4l2videoenc.c:894 | |
393 | 393 | msgid "Failed to start encoding thread." |
394 | 394 | msgstr "" |
395 | 395 |
1147 | 1147 | return ret; |
1148 | 1148 | } |
1149 | 1149 | |
1150 | static gboolean | |
1151 | gst_v4l2src_handle_resolution_change (GstV4l2Src * v4l2src) | |
1152 | { | |
1153 | GST_INFO_OBJECT (v4l2src, "Resolution change detected."); | |
1154 | ||
1155 | /* It is required to always cycle through streamoff, we also need to | |
1156 | * streamoff in order to allow locking a new DV_TIMING which will | |
1157 | * influence the output of TRY_FMT */ | |
1158 | gst_v4l2src_stop (GST_BASE_SRC (v4l2src)); | |
1159 | ||
1160 | /* Force renegotiation */ | |
1161 | v4l2src->renegotiation_adjust = v4l2src->offset + 1; | |
1162 | v4l2src->pending_set_fmt = TRUE; | |
1163 | ||
1164 | return gst_base_src_negotiate (GST_BASE_SRC (v4l2src)); | |
1165 | } | |
1166 | ||
1150 | 1167 | static GstFlowReturn |
1151 | 1168 | gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf) |
1152 | 1169 | { |
1165 | 1182 | |
1166 | 1183 | if (G_UNLIKELY (ret != GST_FLOW_OK)) { |
1167 | 1184 | if (ret == GST_V4L2_FLOW_RESOLUTION_CHANGE) { |
1168 | GST_INFO_OBJECT (v4l2src, "Resolution change detected."); | |
1169 | ||
1170 | /* It is required to always cycle through streamoff, we also need to | |
1171 | * streamoff in order to allow locking a new DV_TIMING which will | |
1172 | * influence the output of TRY_FMT */ | |
1173 | gst_v4l2src_stop (GST_BASE_SRC (src)); | |
1174 | ||
1175 | /* Force renegotiation */ | |
1176 | v4l2src->renegotiation_adjust = v4l2src->offset + 1; | |
1177 | v4l2src->pending_set_fmt = TRUE; | |
1178 | ||
1179 | if (!gst_base_src_negotiate (GST_BASE_SRC (src))) { | |
1185 | if (!gst_v4l2src_handle_resolution_change (v4l2src)) { | |
1180 | 1186 | ret = GST_FLOW_NOT_NEGOTIATED; |
1181 | 1187 | goto error; |
1182 | 1188 | } |
1192 | 1198 | ret = gst_v4l2_buffer_pool_process (obj_pool, buf, NULL); |
1193 | 1199 | if (obj_pool) |
1194 | 1200 | gst_object_unref (obj_pool); |
1201 | ||
1202 | if (G_UNLIKELY (ret == GST_V4L2_FLOW_RESOLUTION_CHANGE)) { | |
1203 | if (!gst_v4l2src_handle_resolution_change (v4l2src)) { | |
1204 | ret = GST_FLOW_NOT_NEGOTIATED; | |
1205 | goto error; | |
1206 | } | |
1207 | } | |
1195 | 1208 | } |
1196 | 1209 | |
1197 | 1210 | } while (ret == GST_V4L2_FLOW_CORRUPTED_BUFFER || |
358 | 358 | } |
359 | 359 | |
360 | 360 | static gboolean |
361 | gst_v4l2_video_remove_padding (GstCapsFeatures * features, | |
362 | GstStructure * structure, gpointer user_data) | |
363 | { | |
364 | GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (user_data); | |
365 | GstVideoAlignment *align = &self->v4l2capture->align; | |
366 | GstVideoInfo *info = &self->v4l2capture->info; | |
367 | int width, height; | |
368 | ||
369 | if (!gst_structure_get_int (structure, "width", &width)) | |
370 | return TRUE; | |
371 | ||
372 | if (!gst_structure_get_int (structure, "height", &height)) | |
373 | return TRUE; | |
374 | ||
375 | if (align->padding_left != 0 || align->padding_top != 0 || | |
376 | height != info->height + align->padding_bottom) | |
377 | return TRUE; | |
378 | ||
379 | if (height == info->height + align->padding_bottom) { | |
380 | /* Some drivers may round up width to the padded with */ | |
381 | if (width == info->width + align->padding_right) | |
382 | gst_structure_set (structure, | |
383 | "width", G_TYPE_INT, width - align->padding_right, | |
384 | "height", G_TYPE_INT, height - align->padding_bottom, NULL); | |
385 | /* Some drivers may keep visible width and only round up bytesperline */ | |
386 | else if (width == info->width) | |
387 | gst_structure_set (structure, | |
388 | "height", G_TYPE_INT, height - align->padding_bottom, NULL); | |
389 | } | |
390 | ||
391 | return TRUE; | |
392 | } | |
393 | ||
394 | static gboolean | |
361 | 395 | gst_v4l2_video_dec_negotiate (GstVideoDecoder * decoder) |
362 | 396 | { |
363 | 397 | GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder); |
398 | GstV4l2Error error = GST_V4L2_ERROR_INIT; | |
399 | GstVideoInfo info; | |
400 | GstVideoCodecState *output_state; | |
401 | GstCaps *acquired_caps, *fixation_caps, *available_caps, *caps, *filter; | |
402 | GstStructure *st; | |
403 | gboolean active; | |
404 | GstBufferPool *cpool; | |
405 | gboolean ret; | |
364 | 406 | |
365 | 407 | /* We don't allow renegotiation without careful disabling the pool */ |
366 | { | |
367 | GstBufferPool *cpool = gst_v4l2_object_get_buffer_pool (self->v4l2capture); | |
368 | if (cpool) { | |
369 | gboolean is_active = gst_buffer_pool_is_active (cpool); | |
370 | gst_object_unref (cpool); | |
371 | if (is_active) | |
372 | return TRUE; | |
373 | } | |
374 | } | |
375 | ||
376 | return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder); | |
408 | cpool = gst_v4l2_object_get_buffer_pool (self->v4l2capture); | |
409 | if (cpool) { | |
410 | gboolean is_active = gst_buffer_pool_is_active (cpool); | |
411 | gst_object_unref (cpool); | |
412 | if (is_active) | |
413 | return TRUE; | |
414 | } | |
415 | ||
416 | /* init capture fps according to output */ | |
417 | self->v4l2capture->info.fps_d = self->v4l2output->info.fps_d; | |
418 | self->v4l2capture->info.fps_n = self->v4l2output->info.fps_n; | |
419 | ||
420 | /* For decoders G_FMT returns coded size, G_SELECTION returns visible size | |
421 | * in the compose rectangle. gst_v4l2_object_acquire_format() checks both | |
422 | * and returns the visible size as with/height and the coded size as | |
423 | * padding. */ | |
424 | if (!gst_v4l2_object_acquire_format (self->v4l2capture, &info)) | |
425 | goto not_negotiated; | |
426 | ||
427 | /* gst_v4l2_object_acquire_format() does not set fps, copy from sink */ | |
428 | info.fps_n = self->v4l2output->info.fps_n; | |
429 | info.fps_d = self->v4l2output->info.fps_d; | |
430 | ||
431 | gst_caps_replace (&self->probed_srccaps, NULL); | |
432 | self->probed_srccaps = gst_v4l2_object_probe_caps (self->v4l2capture, | |
433 | gst_v4l2_object_get_raw_caps ()); | |
434 | /* Create caps from the acquired format, remove the format field */ | |
435 | acquired_caps = gst_video_info_to_caps (&info); | |
436 | GST_DEBUG_OBJECT (self, "Acquired caps: %" GST_PTR_FORMAT, acquired_caps); | |
437 | fixation_caps = gst_caps_copy (acquired_caps); | |
438 | st = gst_caps_get_structure (fixation_caps, 0); | |
439 | gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site", | |
440 | NULL); | |
441 | ||
442 | /* Probe currently available pixel formats */ | |
443 | available_caps = gst_caps_copy (self->probed_srccaps); | |
444 | GST_DEBUG_OBJECT (self, "Available caps: %" GST_PTR_FORMAT, available_caps); | |
445 | ||
446 | /* Replace coded size with visible size, we want to negotiate visible size | |
447 | * with downstream, not coded size. */ | |
448 | gst_caps_map_in_place (available_caps, gst_v4l2_video_remove_padding, self); | |
449 | ||
450 | filter = gst_caps_intersect_full (available_caps, fixation_caps, | |
451 | GST_CAPS_INTERSECT_FIRST); | |
452 | GST_DEBUG_OBJECT (self, "Filtered caps: %" GST_PTR_FORMAT, filter); | |
453 | gst_caps_unref (fixation_caps); | |
454 | gst_caps_unref (available_caps); | |
455 | caps = gst_pad_peer_query_caps (decoder->srcpad, filter); | |
456 | gst_caps_unref (filter); | |
457 | ||
458 | GST_DEBUG_OBJECT (self, "Possible decoded caps: %" GST_PTR_FORMAT, caps); | |
459 | if (gst_caps_is_empty (caps)) { | |
460 | gst_caps_unref (caps); | |
461 | goto not_negotiated; | |
462 | } | |
463 | ||
464 | /* Prefer the acquired caps over anything suggested downstream, this ensure | |
465 | * that we preserves the bit depth, as we don't have any fancy fixation | |
466 | * process */ | |
467 | if (gst_caps_is_subset (acquired_caps, caps)) { | |
468 | gst_caps_unref (acquired_caps); | |
469 | goto use_acquired_caps; | |
470 | } | |
471 | ||
472 | /* Fixate pixel format */ | |
473 | caps = gst_caps_fixate (caps); | |
474 | ||
475 | GST_DEBUG_OBJECT (self, "Chosen decoded caps: %" GST_PTR_FORMAT, caps); | |
476 | ||
477 | /* Try to set negotiated format, on success replace acquired format */ | |
478 | if (gst_v4l2_object_set_format (self->v4l2capture, caps, &error)) | |
479 | gst_video_info_from_caps (&info, caps); | |
480 | else | |
481 | gst_v4l2_clear_error (&error); | |
482 | ||
483 | use_acquired_caps: | |
484 | gst_caps_unref (caps); | |
485 | ||
486 | /* catch possible bogus driver that don't enumerate the format it actually | |
487 | * returned from G_FMT */ | |
488 | if (!self->v4l2capture->fmtdesc) | |
489 | goto not_negotiated; | |
490 | ||
491 | output_state = gst_video_decoder_set_output_state (decoder, | |
492 | info.finfo->format, info.width, info.height, self->input_state); | |
493 | ||
494 | /* Copy the rest of the information, there might be more in the future */ | |
495 | output_state->info.interlace_mode = info.interlace_mode; | |
496 | output_state->info.colorimetry = info.colorimetry; | |
497 | gst_video_codec_state_unref (output_state); | |
498 | ||
499 | ret = GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder); | |
500 | if (!ret) | |
501 | goto not_negotiated; | |
502 | ||
503 | /* The pool may be created through gst_video_decoder_negotiate(), so must | |
504 | * be kept after */ | |
505 | cpool = gst_v4l2_object_get_buffer_pool (self->v4l2capture); | |
506 | gst_v4l2_buffer_pool_enable_resolution_change (GST_V4L2_BUFFER_POOL (cpool)); | |
507 | ||
508 | /* Ensure our internal pool is activated */ | |
509 | active = gst_buffer_pool_set_active (cpool, TRUE); | |
510 | if (cpool) | |
511 | gst_object_unref (cpool); | |
512 | if (!active) | |
513 | goto activate_failed; | |
514 | ||
515 | return TRUE; | |
516 | ||
517 | not_negotiated: | |
518 | GST_ERROR_OBJECT (self, "not negotiated"); | |
519 | gst_v4l2_error (self, &error); | |
520 | gst_v4l2_object_stop (self->v4l2capture); | |
521 | return FALSE; | |
522 | activate_failed: | |
523 | GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS, | |
524 | (_("Failed to allocate required memory.")), | |
525 | ("Buffer pool activation failed")); | |
526 | gst_v4l2_object_stop (self->v4l2capture); | |
527 | return FALSE; | |
377 | 528 | } |
378 | 529 | |
379 | 530 | static gboolean |
531 | 682 | return FALSE; |
532 | 683 | } |
533 | 684 | |
534 | static gboolean | |
535 | gst_v4l2_video_remove_padding (GstCapsFeatures * features, | |
536 | GstStructure * structure, gpointer user_data) | |
537 | { | |
538 | GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (user_data); | |
539 | GstVideoAlignment *align = &self->v4l2capture->align; | |
540 | GstVideoInfo *info = &self->v4l2capture->info; | |
541 | int width, height; | |
542 | ||
543 | if (!gst_structure_get_int (structure, "width", &width)) | |
544 | return TRUE; | |
545 | ||
546 | if (!gst_structure_get_int (structure, "height", &height)) | |
547 | return TRUE; | |
548 | ||
549 | if (align->padding_left != 0 || align->padding_top != 0 || | |
550 | height != info->height + align->padding_bottom) | |
551 | return TRUE; | |
552 | ||
553 | if (height == info->height + align->padding_bottom) { | |
554 | /* Some drivers may round up width to the padded with */ | |
555 | if (width == info->width + align->padding_right) | |
556 | gst_structure_set (structure, | |
557 | "width", G_TYPE_INT, width - align->padding_right, | |
558 | "height", G_TYPE_INT, height - align->padding_bottom, NULL); | |
559 | /* Some drivers may keep visible width and only round up bytesperline */ | |
560 | else if (width == info->width) | |
561 | gst_structure_set (structure, | |
562 | "height", G_TYPE_INT, height - align->padding_bottom, NULL); | |
563 | } | |
564 | ||
565 | return TRUE; | |
566 | } | |
567 | ||
568 | static GstFlowReturn | |
569 | gst_v4l2_video_dec_setup_capture (GstVideoDecoder * decoder) | |
570 | { | |
571 | GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder); | |
572 | GstV4l2Error error = GST_V4L2_ERROR_INIT; | |
573 | GstVideoInfo info; | |
574 | GstVideoCodecState *output_state; | |
575 | GstCaps *acquired_caps, *fixation_caps, *available_caps, *caps, *filter; | |
576 | GstStructure *st; | |
577 | GstBufferPool *cpool; | |
578 | gboolean active; | |
579 | ||
580 | if (G_UNLIKELY (!GST_V4L2_IS_ACTIVE (self->v4l2capture))) { | |
581 | /* init capture fps according to output */ | |
582 | self->v4l2capture->info.fps_d = self->v4l2output->info.fps_d; | |
583 | self->v4l2capture->info.fps_n = self->v4l2output->info.fps_n; | |
584 | ||
585 | /* For decoders G_FMT returns coded size, G_SELECTION returns visible size | |
586 | * in the compose rectangle. gst_v4l2_object_acquire_format() checks both | |
587 | * and returns the visible size as with/height and the coded size as | |
588 | * padding. */ | |
589 | if (!gst_v4l2_object_acquire_format (self->v4l2capture, &info)) | |
590 | goto not_negotiated; | |
591 | ||
592 | /* gst_v4l2_object_acquire_format() does not set fps, copy from sink */ | |
593 | info.fps_n = self->v4l2output->info.fps_n; | |
594 | info.fps_d = self->v4l2output->info.fps_d; | |
595 | ||
596 | gst_caps_replace (&self->probed_srccaps, NULL); | |
597 | self->probed_srccaps = gst_v4l2_object_probe_caps (self->v4l2capture, | |
598 | gst_v4l2_object_get_raw_caps ()); | |
599 | /* Create caps from the acquired format, remove the format field */ | |
600 | acquired_caps = gst_video_info_to_caps (&info); | |
601 | GST_DEBUG_OBJECT (self, "Acquired caps: %" GST_PTR_FORMAT, acquired_caps); | |
602 | fixation_caps = gst_caps_copy (acquired_caps); | |
603 | st = gst_caps_get_structure (fixation_caps, 0); | |
604 | gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site", | |
605 | NULL); | |
606 | ||
607 | /* Probe currently available pixel formats */ | |
608 | available_caps = gst_caps_copy (self->probed_srccaps); | |
609 | GST_DEBUG_OBJECT (self, "Available caps: %" GST_PTR_FORMAT, available_caps); | |
610 | ||
611 | /* Replace coded size with visible size, we want to negotiate visible size | |
612 | * with downstream, not coded size. */ | |
613 | gst_caps_map_in_place (available_caps, gst_v4l2_video_remove_padding, self); | |
614 | ||
615 | filter = gst_caps_intersect_full (available_caps, fixation_caps, | |
616 | GST_CAPS_INTERSECT_FIRST); | |
617 | GST_DEBUG_OBJECT (self, "Filtered caps: %" GST_PTR_FORMAT, filter); | |
618 | gst_caps_unref (fixation_caps); | |
619 | gst_caps_unref (available_caps); | |
620 | caps = gst_pad_peer_query_caps (decoder->srcpad, filter); | |
621 | gst_caps_unref (filter); | |
622 | ||
623 | GST_DEBUG_OBJECT (self, "Possible decoded caps: %" GST_PTR_FORMAT, caps); | |
624 | if (gst_caps_is_empty (caps)) { | |
625 | gst_caps_unref (caps); | |
626 | goto not_negotiated; | |
627 | } | |
628 | ||
629 | /* Prefer the acquired caps over anything suggested downstream, this ensure | |
630 | * that we preserves the bit depth, as we don't have any fancy fixation | |
631 | * process */ | |
632 | if (gst_caps_is_subset (acquired_caps, caps)) { | |
633 | gst_caps_unref (acquired_caps); | |
634 | goto use_acquired_caps; | |
635 | } | |
636 | ||
637 | /* Fixate pixel format */ | |
638 | caps = gst_caps_fixate (caps); | |
639 | ||
640 | GST_DEBUG_OBJECT (self, "Chosen decoded caps: %" GST_PTR_FORMAT, caps); | |
641 | ||
642 | /* Try to set negotiated format, on success replace acquired format */ | |
643 | if (gst_v4l2_object_set_format (self->v4l2capture, caps, &error)) | |
644 | gst_video_info_from_caps (&info, caps); | |
645 | else | |
646 | gst_v4l2_clear_error (&error); | |
647 | ||
648 | use_acquired_caps: | |
649 | gst_caps_unref (caps); | |
650 | ||
651 | /* catch possible bogus driver that don't enumerate the format it actually | |
652 | * returned from G_FMT */ | |
653 | if (!self->v4l2capture->fmtdesc) | |
654 | goto not_negotiated; | |
655 | ||
656 | output_state = gst_video_decoder_set_output_state (decoder, | |
657 | info.finfo->format, info.width, info.height, self->input_state); | |
658 | ||
659 | /* Copy the rest of the information, there might be more in the future */ | |
660 | output_state->info.interlace_mode = info.interlace_mode; | |
661 | output_state->info.colorimetry = info.colorimetry; | |
662 | gst_video_codec_state_unref (output_state); | |
663 | ||
664 | if (!gst_video_decoder_negotiate (decoder)) { | |
665 | if (GST_PAD_IS_FLUSHING (decoder->srcpad)) | |
666 | goto flushing; | |
667 | else | |
668 | goto not_negotiated; | |
669 | } | |
670 | ||
671 | /* The pool may be created through gst_video_decoder_negotiate(), so must | |
672 | * be kept after */ | |
673 | cpool = gst_v4l2_object_get_buffer_pool (self->v4l2capture); | |
674 | gst_v4l2_buffer_pool_enable_resolution_change (GST_V4L2_BUFFER_POOL | |
675 | (cpool)); | |
676 | ||
677 | /* Ensure our internal pool is activated */ | |
678 | active = gst_buffer_pool_set_active (cpool, TRUE); | |
679 | if (cpool) | |
680 | gst_object_unref (cpool); | |
681 | if (!active) | |
682 | goto activate_failed; | |
683 | } | |
684 | ||
685 | return GST_FLOW_OK; | |
686 | ||
687 | not_negotiated: | |
688 | GST_ERROR_OBJECT (self, "not negotiated"); | |
689 | gst_v4l2_error (self, &error); | |
690 | gst_v4l2_object_stop (self->v4l2capture); | |
691 | return GST_FLOW_NOT_NEGOTIATED; | |
692 | activate_failed: | |
693 | GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS, | |
694 | (_("Failed to allocate required memory.")), | |
695 | ("Buffer pool activation failed")); | |
696 | gst_v4l2_object_stop (self->v4l2capture); | |
697 | return GST_FLOW_ERROR; | |
698 | flushing: | |
699 | gst_v4l2_object_stop (self->v4l2capture); | |
700 | return GST_FLOW_FLUSHING; | |
701 | } | |
702 | ||
703 | 685 | /* Only used initially to wait for a SRC_CH event |
704 | 686 | * called with decoder stream lock */ |
705 | 687 | static GstFlowReturn |
750 | 732 | } |
751 | 733 | |
752 | 734 | GST_DEBUG_OBJECT (decoder, "Setup the capture queue"); |
753 | ret = gst_v4l2_video_dec_setup_capture (decoder); | |
754 | /* FIXME not super nice ? */ | |
755 | if (ret == GST_FLOW_FLUSHING || GST_PAD_IS_FLUSHING (decoder->sinkpad) | |
756 | || GST_PAD_IS_FLUSHING (decoder->srcpad)) { | |
757 | ret = GST_FLOW_FLUSHING; | |
758 | GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); | |
759 | goto beach; | |
760 | } | |
761 | if (ret != GST_FLOW_OK) { | |
762 | GST_ERROR_OBJECT (decoder, "Failed to setup capture queue"); | |
763 | GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); | |
764 | goto beach; | |
765 | } | |
766 | ||
767 | /* just a safety, as introducing mistakes in setup_capture seems rather | |
735 | if (G_UNLIKELY (!GST_V4L2_IS_ACTIVE (self->v4l2capture))) { | |
736 | if (!gst_video_decoder_negotiate (decoder)) { | |
737 | /* FIXME not super nice ? */ | |
738 | if (GST_PAD_IS_FLUSHING (decoder->sinkpad) | |
739 | || GST_PAD_IS_FLUSHING (decoder->srcpad)) { | |
740 | ret = GST_FLOW_FLUSHING; | |
741 | } else { | |
742 | ret = GST_FLOW_NOT_NEGOTIATED; | |
743 | GST_ERROR_OBJECT (decoder, "Failed to setup capture queue"); | |
744 | } | |
745 | GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); | |
746 | goto beach; | |
747 | } | |
748 | } | |
749 | ||
750 | /* just a safety, as introducing mistakes in negotiation seems rather | |
768 | 751 | * easy.*/ |
769 | 752 | g_return_if_fail (GST_V4L2_IS_ACTIVE (self->v4l2capture)); |
770 | 753 | } |
990 | 973 | gst_buffer_unref (codec_data); |
991 | 974 | |
992 | 975 | /* Only wait for source change if the formats supports it */ |
993 | if (self->v4l2output->fmtdesc->flags & V4L2_FMT_FLAG_DYN_RESOLUTION) { | |
976 | if (!GST_V4L2_IS_ACTIVE (self->v4l2capture) && | |
977 | self->v4l2output->fmtdesc->flags & V4L2_FMT_FLAG_DYN_RESOLUTION) { | |
994 | 978 | gst_v4l2_object_unlock_stop (self->v4l2capture); |
995 | 979 | self->wait_for_source_change = TRUE; |
996 | 980 | } |
1383 | 1367 | gint mpegversion = 0; |
1384 | 1368 | gst_structure_get_int (s, "mpegversion", &mpegversion); |
1385 | 1369 | |
1386 | switch (mpegversion) { | |
1387 | /* MPEG 2 decoders supports MPEG 1 format */ | |
1388 | case 1: | |
1389 | case 2: | |
1390 | SET_META ("MPEG2"); | |
1391 | cdata->codec = gst_v4l2_mpeg2_get_codec (); | |
1392 | break; | |
1393 | case 4: | |
1394 | SET_META ("MPEG4"); | |
1395 | cdata->codec = gst_v4l2_mpeg4_get_codec (); | |
1396 | break; | |
1397 | default: | |
1398 | g_warning ("Unsupported MPEG Video version %i", mpegversion); | |
1399 | break; | |
1370 | if (mpegversion == 4) { | |
1371 | SET_META ("MPEG4"); | |
1372 | cdata->codec = gst_v4l2_mpeg4_get_codec (); | |
1373 | } else { | |
1374 | /* MPEG 2 decoders supports MPEG 1 format */ | |
1375 | SET_META ("MPEG2"); | |
1376 | cdata->codec = gst_v4l2_mpeg2_get_codec (); | |
1400 | 1377 | } |
1401 | 1378 | } else if (gst_structure_has_name (s, "video/x-h263")) { |
1402 | 1379 | SET_META ("H263"); |
516 | 516 | return failed; |
517 | 517 | } |
518 | 518 | |
519 | static GstCaps * | |
520 | gst_v4l2_video_enc_sink_getcaps (GstVideoEncoder * encoder, GstCaps * filter) | |
521 | { | |
522 | GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder); | |
523 | GstCaps *probed_caps = NULL; | |
524 | GstCaps *caps; | |
525 | ||
526 | if (self->probed_sinkcaps) | |
527 | probed_caps = gst_caps_ref (self->probed_sinkcaps); | |
528 | ||
529 | caps = gst_video_encoder_proxy_getcaps (encoder, probed_caps, filter); | |
530 | ||
531 | if (probed_caps) | |
532 | gst_caps_unref (probed_caps); | |
533 | ||
534 | GST_DEBUG_OBJECT (self, "Returning sink caps %" GST_PTR_FORMAT, caps); | |
535 | ||
536 | return caps; | |
537 | } | |
538 | ||
519 | 539 | static gboolean |
520 | 540 | gst_v4l2_video_enc_negotiate (GstVideoEncoder * encoder) |
521 | 541 | { |
1005 | 1025 | } |
1006 | 1026 | |
1007 | 1027 | static gboolean |
1008 | gst_v4l2_video_enc_sink_query (GstVideoEncoder * encoder, GstQuery * query) | |
1009 | { | |
1010 | gboolean ret = TRUE; | |
1011 | GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder); | |
1012 | ||
1013 | switch (GST_QUERY_TYPE (query)) { | |
1014 | case GST_QUERY_CAPS:{ | |
1015 | GstCaps *filter, *result = NULL; | |
1016 | GstPad *pad = GST_VIDEO_ENCODER_SINK_PAD (encoder); | |
1017 | ||
1018 | gst_query_parse_caps (query, &filter); | |
1019 | ||
1020 | if (self->probed_sinkcaps) | |
1021 | result = gst_caps_ref (self->probed_sinkcaps); | |
1022 | else | |
1023 | result = gst_pad_get_pad_template_caps (pad); | |
1024 | ||
1025 | if (filter) { | |
1026 | GstCaps *tmp = result; | |
1027 | result = | |
1028 | gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); | |
1029 | gst_caps_unref (tmp); | |
1030 | } | |
1031 | ||
1032 | GST_DEBUG_OBJECT (self, "Returning sink caps %" GST_PTR_FORMAT, result); | |
1033 | ||
1034 | gst_query_set_caps_result (query, result); | |
1035 | gst_caps_unref (result); | |
1036 | break; | |
1037 | } | |
1038 | ||
1039 | default: | |
1040 | ret = GST_VIDEO_ENCODER_CLASS (parent_class)->sink_query (encoder, query); | |
1041 | break; | |
1042 | } | |
1043 | ||
1044 | return ret; | |
1045 | } | |
1046 | ||
1047 | static gboolean | |
1048 | 1028 | gst_v4l2_video_enc_sink_event (GstVideoEncoder * encoder, GstEvent * event) |
1049 | 1029 | { |
1050 | 1030 | GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder); |
1169 | 1149 | video_encoder_class->flush = GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_flush); |
1170 | 1150 | video_encoder_class->set_format = |
1171 | 1151 | GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_set_format); |
1152 | video_encoder_class->getcaps = | |
1153 | GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_sink_getcaps); | |
1172 | 1154 | video_encoder_class->negotiate = |
1173 | 1155 | GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_negotiate); |
1174 | 1156 | video_encoder_class->decide_allocation = |
1175 | 1157 | GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_decide_allocation); |
1176 | 1158 | video_encoder_class->propose_allocation = |
1177 | 1159 | GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_propose_allocation); |
1178 | video_encoder_class->sink_query = | |
1179 | GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_sink_query); | |
1180 | 1160 | video_encoder_class->src_query = |
1181 | 1161 | GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_src_query); |
1182 | 1162 | video_encoder_class->sink_event = |