New upstream version 1.20.1
Sebastian Dröge
2 years ago
0 | === release 1.20.1 === | |
1 | ||
2 | 2022-03-14 11:33:33 +0000 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.20.1 | |
10 | ||
11 | 2022-03-14 11:33:25 +0000 Tim-Philipp Müller <tim@centricular.com> | |
12 | ||
13 | * ChangeLog: | |
14 | Update ChangeLogs for 1.20.1 | |
15 | ||
16 | 2022-02-22 10:13:28 +0100 Guillaume Desmottes <guillaume.desmottes@onestream.live> | |
17 | ||
18 | * gst/rtpmanager/rtpsource.c: | |
19 | rtpsource: fix rtp_source_get_nack_deadlines doc | |
20 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1950> | |
21 | ||
22 | 2022-01-14 23:42:27 -0600 Tim Mooney <Tim.Mooney@ndsu.edu> | |
23 | ||
24 | * sys/v4l2/ext/types-compat.h: | |
25 | v4l2: include <sys/ioccom.h> on Illumos | |
26 | Needed for _IOR/_IORW | |
27 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1947> | |
28 | ||
29 | 2022-03-03 13:47:05 +0800 Hou Qi <qi.hou@nxp.com> | |
30 | ||
31 | * sys/v4l2/gstv4l2bufferpool.c: | |
32 | v4l2bufferpool: Fix race condition between qbuf and pool streamoff | |
33 | There is a chance that pool->buffers[index] sets BUFFER_STATE_QUEUED, but | |
34 | it has not been queued yet which makes pool->buffers[index] still NULL. | |
35 | At this time, if pool_streamff release all buffers with BUFFER_STATE_QUEUED | |
36 | state regardless of whether the buffer is NULL or not, it will cause segfault. | |
37 | To fix this, also check buffer when streamoff release buffer. | |
38 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1948> | |
39 | ||
40 | 2022-03-11 10:32:42 +0100 Jan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com> | |
41 | ||
42 | * gst/deinterlace/tvtime/scalerbob.c: | |
43 | deinterlace: scalerbob: Reduce latency to 0 | |
44 | We only need the current field, just like `linear`. | |
45 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1944> | |
46 | ||
47 | 2022-03-12 17:13:48 +0200 Vivia Nikolaidou <vivia@ahiru.eu> | |
48 | ||
49 | * gst/deinterlace/yadif.c: | |
50 | yadif: Fix CHECK macro for YUY2 format | |
51 | Used to make comb artifacts for videotestsrc pattern=ball for YUY2 | |
52 | format only (not AYUV). | |
53 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1943> | |
54 | ||
55 | 2022-03-10 18:43:45 +0900 Sangchul Lee <sc11.lee@samsung.com> | |
56 | ||
57 | * gst/rtp/gstrtpvp8depay.c: | |
58 | rtpvp8depay: Fix crash when making 'GstRTPPacketLost' custom event | |
59 | This patch fixes a seg.fault in gst_structure_new() with warnings as below. | |
60 | GLib-GObject-WARNING **: | |
61 | ../gobject/gtype.c:4330: type id '0' is invalid | |
62 | GLib-GObject-WARNING **: | |
63 | can't peek value table for type '<invalid>' which is not currently referenced | |
64 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1920> | |
65 | ||
66 | 2022-03-09 12:17:11 +0530 Nirbheek Chauhan <nirbheek@centricular.com> | |
67 | ||
68 | * ext/soup/gstsouploader.c: | |
69 | soup: Load the runtime library, not the development library | |
70 | libsoup-2.4.so / libsoup-3.0.so are symlinks installed by development | |
71 | packages, they are not available at runtime. | |
72 | Also eliminate G_MODULE_SUFFIX since it's not useful for us, and is | |
73 | actually incorrect on macOS anyway. | |
74 | Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1071 | |
75 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1907> | |
76 | ||
77 | 2021-02-08 21:40:19 +0100 Havard Graff <havard@pexip.com> | |
78 | ||
79 | * gst/rtpmanager/gstrtprtxreceive.c: | |
80 | * gst/rtpmanager/gstrtprtxreceive.h: | |
81 | * gst/rtpmanager/gstrtprtxsend.c: | |
82 | * gst/rtpmanager/gstrtprtxsend.h: | |
83 | rtprtx: don't access type-system per buffer | |
84 | When doing only a single stream of audio/video this hardly matters, | |
85 | but when doing many at the same time, the fact that you have to get | |
86 | a hold of the glib global type-system lock every time you process a buffer, | |
87 | means that there is a limit to how many streams you can process in | |
88 | parallel. | |
89 | Luckily the fix is very simple, by doing a cast rather than a full | |
90 | type-check. | |
91 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1890> | |
92 | ||
93 | 2020-02-10 14:37:30 +0100 Havard Graff <havard@pexip.com> | |
94 | ||
95 | * tests/check/elements/rtprtx.c: | |
96 | rtprtx: signed/unsigned and style fixes | |
97 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1888> | |
98 | ||
99 | 2022-03-04 15:36:20 +0100 Jan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com> | |
100 | ||
101 | * gst/deinterlace/gstdeinterlace.c: | |
102 | deinterlace: Prevent race between _set_method and latency query | |
103 | It's possible that the method is being manipulated while downstream | |
104 | queries our latency, leading to crashes. | |
105 | Prevent that from happening. | |
106 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1859> | |
107 | ||
108 | 2022-03-03 23:04:36 +0530 Nirbheek Chauhan <nirbheek@centricular.com> | |
109 | ||
110 | * ext/soup/gstsouploader.c: | |
111 | soup: Fix static build with MSVC | |
112 | ../ext/soup/gstsouploader.c(818): error C4098: '_soup_session_send_async': 'void' function returning a value | |
113 | It's technically a false warning, but that's how MSVC works, so fix | |
114 | it. | |
115 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1846> | |
116 | ||
117 | 2022-03-03 00:37:57 +0530 Nirbheek Chauhan <nirbheek@centricular.com> | |
118 | ||
119 | * ext/soup/meson.build: | |
120 | soup: Fix pkgconfig generation and documentation | |
121 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1846> | |
122 | ||
123 | 2022-03-02 23:22:39 +0530 Nirbheek Chauhan <nirbheek@centricular.com> | |
124 | ||
125 | * ext/soup/meson.build: | |
126 | soup: Fix static build when default_library=both | |
127 | Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1007 | |
128 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1846> | |
129 | ||
130 | 2022-03-02 23:11:09 +0530 Nirbheek Chauhan <nirbheek@centricular.com> | |
131 | ||
132 | * ext/soup/meson.build: | |
133 | soup: Don't error out in static build unless option is enabled | |
134 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1846> | |
135 | ||
136 | 2022-02-27 15:45:01 +0100 Philippe Normand <philn@igalia.com> | |
137 | ||
138 | * ext/soup/gstsouploader.c: | |
139 | soup: Lookup libsoup dylib files on Apple platforms | |
140 | Fixes #1007 | |
141 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1846> | |
142 | ||
143 | 2022-03-01 20:59:30 +0200 Sebastian Dröge <sebastian@centricular.com> | |
144 | ||
145 | * gst/matroska/matroska-mux.c: | |
146 | matroska-mux: Handle pixel-aspect-ratio caps field correctly when checking caps equality | |
147 | Not having this field is equivalent with it being 1/1 so consider | |
148 | it like that. The generic caps functions are not aware of these | |
149 | semantics and would consider the caps different, causing a negotiation | |
150 | failure when caps are changing from caps with to caps without or the | |
151 | other way around. | |
152 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1833> | |
153 | ||
154 | 2022-03-01 20:56:43 +0200 Sebastian Dröge <sebastian@centricular.com> | |
155 | ||
156 | * gst/matroska/matroska-mux.c: | |
157 | matroska-mux: Handle multiview-mode/flags caps fields correctly when checking caps equality | |
158 | Not having these fields is equivalent with them being mono/0 so consider | |
159 | them like that. The generic caps functions are not aware of these | |
160 | semantics and would consider the caps different, causing a negotiation | |
161 | failure when caps are changing from caps with to caps without or the | |
162 | other way around. | |
163 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1833> | |
164 | ||
165 | 2022-02-23 11:10:11 +0100 Sebastian Fricke <sebastian.fricke@collabora.com> | |
166 | ||
167 | * README.md: | |
168 | Maintain build instructions at a single location | |
169 | Do not maintain similar build instructions within each gst-plugins-* | |
170 | subproject and the subproject/gstreamer subproject. Use the build | |
171 | instructions from the mono-repository and link to them via hyperlink. | |
172 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1829> | |
173 | ||
174 | 2022-03-01 00:12:56 +0200 Vivia Nikolaidou <vivia@ahiru.eu> | |
175 | ||
176 | * gst/deinterlace/x86/yadif.asm: | |
177 | yadif.asm: Fix improper usage of LOAD macro | |
178 | LOAD macro relies in m7 being zero for interleaving purposes. Using LOAD | |
179 | on the m7 register makes it interleave with its new content instead of | |
180 | with 0. | |
181 | The effect of this bug was bobbing on some static lines that appeared | |
182 | over fast-moving content. | |
183 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1823> | |
184 | ||
185 | 2022-03-01 00:12:33 +0200 Vivia Nikolaidou <vivia@ahiru.eu> | |
186 | ||
187 | * gst/deinterlace/x86/yadif.asm: | |
188 | yadif.asm: Typo fixes in comments | |
189 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1823> | |
190 | ||
191 | 2022-02-28 20:39:11 +0200 Vivia Nikolaidou <vivia@ahiru.eu> | |
192 | ||
193 | * gst/deinterlace/yadif.c: | |
194 | yadif: Fix bug in C implementation of CHECK | |
195 | It was different compared to the corresponding part in both ffmpeg and | |
196 | the asm implementation. Fixing this makes videotestsrc pattern=spokes | |
197 | not jump at all when not using the asm optimisations. | |
198 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1823> | |
199 | ||
200 | 2021-12-06 12:49:18 -0500 Joseph Donofry <rubberduckie3554@gmail.com> | |
201 | ||
202 | * sys/osxaudio/gstosxaudiodeviceprovider.c: | |
203 | osxaudiosrc: Support a device as both input and output | |
204 | osxaudiodeviceprovider now probes devices more than once to determine | |
205 | if the device can function as both an input AND and output device. | |
206 | Previously, if the device provider detected that a device had any output | |
207 | capabilities, it was treated solely as an Audio/Sink. This causes issues | |
208 | that have both input and output capabilities (for example, USB interfaces | |
209 | for professional audio have both input and output channels). Such devices | |
210 | are now listed as both an Audio/Sink as well as an Audio/Source. | |
211 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1809> | |
212 | ||
213 | 2022-02-24 20:28:23 +0530 Sanchayan Maity <sanchayan@asymptotic.io> | |
214 | ||
215 | * docs/gst_plugins_cache.json: | |
216 | * gst/rtp/gstrtpldacpay.c: | |
217 | * gst/rtp/gstrtpldacpay.h: | |
218 | rtp: ldac: Set frame count information in payload | |
219 | The RTP payload seems to be required as it carries the frame count | |
220 | information. Also, gst_rtp_base_payload_allocate_output_buffer had | |
221 | the second argument incorrect. | |
222 | Strangely some devices like Shanling MP4 and Sony XM3 would still | |
223 | work without this while some like the Sony XM4 do not. | |
224 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1804> | |
225 | ||
226 | 2022-02-25 12:44:26 +0100 Jan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com> | |
227 | ||
228 | * gst/deinterlace/tvtime/greedyh.c: | |
229 | deinterlace: greedyh: Stop adding 2 to cur_field_idx | |
230 | Just a simplification. | |
231 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1799> | |
232 | ||
233 | 2022-02-24 17:36:40 +0100 Jan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com> | |
234 | ||
235 | * gst/deinterlace/tvtime/greedyh.c: | |
236 | deinterlace: greedyh: Use _plane in _packed, fix planar formats | |
237 | This greatly reduces code duplication. It also exposed the cause for | |
238 | planar formats not being properly deinterlaced: | |
239 | The planar path was missing the initial offset adjustment that the | |
240 | packed path did to `L2` and `L2P` in the case of an even field, which | |
241 | caused it to select the wrong weave lines every other field. | |
242 | Add those offsets in `_plane`. | |
243 | Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1047 | |
244 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1799> | |
245 | ||
246 | 2022-02-25 12:39:31 +0100 Jan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com> | |
247 | ||
248 | * gst/deinterlace/tvtime/greedyh.c: | |
249 | deinterlace: greedyh: Rename _planar_plane to _plane | |
250 | As well as `i` to `plane`. | |
251 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1799> | |
252 | ||
253 | 2022-02-25 12:36:17 +0100 Jan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com> | |
254 | ||
255 | * gst/deinterlace/tvtime/greedyh.c: | |
256 | deinterlace: greedyh: Move code from _planar into _planar_plane | |
257 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1799> | |
258 | ||
259 | 2022-02-25 12:30:21 +0100 Jan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com> | |
260 | ||
261 | * gst/deinterlace/tvtime/greedyh.c: | |
262 | deinterlace: greedyh: Move _planar_plane upwards | |
263 | In preparation of refactoring. No functional change. | |
264 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1799> | |
265 | ||
266 | 2022-02-18 15:23:13 +0530 Nirbheek Chauhan <nirbheek@centricular.com> | |
267 | ||
268 | * gst/matroska/matroska-demux.c: | |
269 | matroska-demux: Emit a warning when no codec data found | |
270 | It is bad if an mkv file does not have codec data for the ProRes | |
271 | variant, so we should emit a warning. ffmpeg does the same thing. | |
272 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1766> | |
273 | ||
274 | 2022-02-21 13:27:06 +1100 Matthew Waters <matthew@centricular.com> | |
275 | ||
276 | * gst/rtp/gstrtpulpfecenc.c: | |
277 | ulpfecenc: slightly safer dispose impl | |
278 | Technically dispose can be called more than once (even if gstelement is | |
279 | not actually set up to do that) so need to protect against that. | |
280 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1767> | |
281 | ||
282 | 2022-02-21 13:24:07 +1100 Matthew Waters <matthew@centricular.com> | |
283 | ||
284 | * gst/rtp/gstrtpulpfecenc.c: | |
285 | ulpfecenc: fix unmatched free() call | |
286 | One must always match a g_slice_new with a g_slice_free and a g_new with | |
287 | a g_free. This was not the case for the internal ctx struct. | |
288 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1767> | |
289 | ||
290 | 2021-11-09 17:37:24 +1100 Matthew Waters <matthew@centricular.com> | |
291 | ||
292 | * gst/rtp/gstrtpulpfecenc.c: | |
293 | rtpulpfecenc: add some debug logging | |
294 | Like, what configuration we are using or whether a fec packet is | |
295 | generated. | |
296 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1767> | |
297 | ||
298 | 2022-02-02 12:49:29 +0100 Rouven Czerwinski <rouven@czerwinskis.de> | |
299 | ||
300 | * sys/v4l2/gstv4l2tuner.c: | |
301 | gstv4l2tuner: return NULL if no norm set | |
302 | If the video4linux device supports norms but has no norm set, norm is | |
303 | returned as an uninitialized variable after the ioctl call, leading to | |
304 | gst_v4l2_tuner_get_norm_by_std_id() returning a random norm from the | |
305 | supported norms. Catch this case and instead return NULL to indicate | |
306 | that no norm is setup. | |
307 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1758> | |
308 | ||
309 | 2022-02-17 17:36:22 +0100 Sebastian Wick <sebastian.wick@redhat.com> | |
310 | ||
311 | * gst/matroska/matroska-demux.c: | |
312 | matroska: default prores fourcc apcn | |
313 | If there is no codec private data for prores it should default to Apple | |
314 | ProRes 422 Standard Definition (apcn). Can be tested with | |
315 | strobe_scientist.mkv from | |
316 | https://developers.google.com/media/vp9/hdr-encoding | |
317 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1753> | |
318 | ||
319 | 2021-04-08 12:18:09 +0300 Sebastian Dröge <sebastian@centricular.com> | |
320 | ||
321 | * gst/isomp4/gstqtmux.c: | |
322 | qtmux: Don't post an error message if pushing a sample failed with FLUSHING | |
323 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1732> | |
324 | ||
325 | 2022-02-11 23:55:57 +0100 Marek Vasut <marex@denx.de> | |
326 | ||
327 | * ext/jpeg/gstjpegdec.c: | |
328 | jpegdec: Pull row_stride from GST_VIDEO_FRAME_PLANE_STRIDE() | |
329 | The libjpeg-turbo internal state might not be correctly initialized for | |
330 | the first frame in a stream, pull the frame stride from gstreamer frame | |
331 | metadata instead, which is correct even for the first frame, and which | |
332 | makes this code consistent with the surrounding lines. | |
333 | Fixes: e6d83d8f96 ("jpegdec: Support libjpeg-turbo colorspace conversion") | |
334 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1716> | |
335 | ||
336 | 2022-02-11 23:44:24 +0100 Marek Vasut <marex@denx.de> | |
337 | ||
338 | * ext/jpeg/gstjpegdec.c: | |
339 | jpegdec: Call gst_jpeg_turbo_parse_ext_fmt_convert() before jpeg_start_decompress() | |
340 | It is imperative that the libjpeg-turbo state is properly initialized | |
341 | before jpeg_start_decompress() is called. Make sure cinfo.out_color_space | |
342 | and cinfo.raw_data_out are set to their final values matching their peer | |
343 | caps before calling jpeg_start_decompress(). | |
344 | Fixes: e6d83d8f96 ("jpegdec: Support libjpeg-turbo colorspace conversion") | |
345 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1716> | |
346 | ||
347 | 2022-02-11 23:44:20 +0100 Marek Vasut <marex@denx.de> | |
348 | ||
349 | * ext/jpeg/gstjpegdec.c: | |
350 | jpegdec: Factor out gst_jpeg_turbo_parse_ext_fmt_convert() | |
351 | Pull out peer caps checking code into gst_jpeg_turbo_parse_ext_fmt_convert(). | |
352 | This code is used by libjpeg-turbo extras to determine whether peer is capable | |
353 | of handling buffers into which libjpeg-turbo can directly decode data. This | |
354 | kind of check must be performed before jpeg_start_decompress() is called in | |
355 | gst_jpeg_dec_prepare_decode() as well as in gst_jpeg_dec_negotiate(), hence | |
356 | the common code. | |
357 | This commit does modify the code a little to make it easier to call from both | |
358 | call sites without much duplication, hence the extra `if (*clrspc)` test. | |
359 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1716> | |
360 | ||
361 | 2022-02-11 23:29:27 +0100 Marek Vasut <marex@denx.de> | |
362 | ||
363 | * ext/jpeg/gstjpegdec.c: | |
364 | Revert "jpegdec: only allow conversions from RGB" | |
365 | This reverts commit 2aa2477208c029b0e1b8232d69f4f99a3bf1d473. | |
366 | The commit is completely wrong, libjpeg-turbo is perfectly capable | |
367 | of decoding I420 (YUV) to RGB. The test case provided alongside the | |
368 | aforementioned commit passes without this revert because it decodes | |
369 | image of JCS_YCrCb color space, so the new `if (clrspc == JCS_RGB)` | |
370 | condition is false on that image, and the libjpeg-turbo decoding | |
371 | does not get used. The real bug is hidden by that commit. | |
372 | The real problem is in the call order of gst_jpeg_dec_prepare_decode() | |
373 | and gst_jpeg_dec_negotiate(). The gst_jpeg_dec_prepare_decode() calls | |
374 | jpeg_start_decompress() which sets up internal state of the libjpeg, | |
375 | however, neither cinfo.out_color_space nor cinfo.raw_data_out are | |
376 | set correctly yet. Those two are set up in gst_jpeg_dec_negotiate() | |
377 | which is called a bit later. Therefore, the real fix is the set up | |
378 | cinfo.out_color_space and cinfo.raw_data_out before calling | |
379 | jpeg_start_decompress(). This is however a separate patch. | |
380 | Fixes: 2aa2477208 ("jpegdec: only allow conversions from RGB") | |
381 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1716> | |
382 | ||
383 | 2022-02-11 21:35:54 +0100 Heiko Becker <heirecka@exherbo.org> | |
384 | ||
385 | * ext/lame/meson.build: | |
386 | meson: Don't build lame plugin with -Dlame=disabled | |
387 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1720> | |
388 | ||
389 | 2022-02-01 14:28:24 +0100 Bastien Nocera <hadess@hadess.net> | |
390 | ||
391 | * ext/gtk/gtkgstglwidget.c: | |
392 | gtk: Fix rotation not being applied when paused | |
393 | The video wouldn't be redrawn immediately when a rotation was applied | |
394 | but the pipeline was paused, as no new buffers were scheduled to be | |
395 | displayed. | |
396 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1710> | |
397 | ||
398 | 2022-02-01 14:26:02 +0100 Bastien Nocera <hadess@hadess.net> | |
399 | ||
400 | * ext/gtk/gtkgstbasewidget.c: | |
401 | * ext/gtk/gtkgstbasewidget.h: | |
402 | gtk: Add a way to queue redrawing the base GTK widget | |
403 | This will be used to request a redraw of the GTK widget should the | |
404 | display be changed using properties not directly handled by the base GTK | |
405 | widget, but by one of its descendants. | |
406 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1710> | |
407 | ||
408 | 2022-02-07 16:17:28 +0000 Tim-Philipp Müller <tim@centricular.com> | |
409 | ||
410 | * docs/gst_plugins_cache.json: | |
411 | * meson.build: | |
412 | Back to development | |
413 | ||
0 | 414 | === release 1.20.0 === |
1 | 415 | |
2 | 416 | 2022-02-03 19:53:25 +0000 Tim-Philipp Müller <tim@centricular.com> |
3 | 417 | |
418 | * ChangeLog: | |
4 | 419 | * NEWS: |
5 | 420 | * README: |
6 | 421 | * RELEASE: |
0 | 0 | GStreamer 1.20 Release Notes |
1 | 1 | |
2 | GStreamer 1.20.0 was released on 3 February 2022. | |
2 | GStreamer 1.20.0 was originally released on 3 February 2022. | |
3 | ||
4 | The latest bug-fix release in the 1.20 series is 1.20.1 and was released | |
5 | on 14 March 2022. | |
3 | 6 | |
4 | 7 | See https://gstreamer.freedesktop.org/releases/1.20/ for the latest |
5 | 8 | version of this document. |
6 | 9 | |
7 | Last updated: Wednesday 2 February 2022, 23:30 UTC (log) | |
10 | Last updated: Monday 14 March 2022, 00:30 UTC (log) | |
8 | 11 | |
9 | 12 | Introduction |
10 | 13 | |
1875 | 1878 | |
1876 | 1879 | 1.20.0 was released on 3 February 2022. |
1877 | 1880 | |
1881 | 1.20.1 | |
1882 | ||
1883 | The first 1.20 bug-fix release (1.20.1) was released on 14 March 2022. | |
1884 | ||
1885 | This release only contains bugfixes and it should be safe to update from | |
1886 | 1.20.0. | |
1887 | ||
1888 | Highlighted bugfixes in 1.20.1 | |
1889 | ||
1890 | - deinterlace: various bug fixes for yadif and greedy methods | |
1891 | - gtk video sink: Fix rotation not being applied when paused | |
1892 | - gst-play-1.0: Fix trick-mode handling in keyboard shortcut | |
1893 | - jpegdec: fix RGB conversion handling | |
1894 | - matroskademux: improved ProRes video handling | |
1895 | - matroskamux: Handle multiview-mode/flags/pixel-aspect-ratio caps | |
1896 | fields correctly when checking caps equality on input caps changes | |
1897 | - videoaggregator fixes (negative rate handling, current position | |
1898 | rounding) | |
1899 | - soup http plugin: Lookup libsoup dylib files on Apple platforms & | |
1900 | fix Cerbero static build on Android and iOS | |
1901 | - Support build against libfreeaptx in openaptx plugin | |
1902 | - Fix linking issues on Illumos distros | |
1903 | - GstPlay: Fix new error + warning parsing API (was unusuable before) | |
1904 | - mpegtsmux: VBR muxing fixes | |
1905 | - nvdecoder: Various fixes for 4:4:4 and high-bitdepth decoding | |
1906 | - Support build against libfreeaptx in openaptx plugin | |
1907 | - webrtc: Various fixes to the webrtc-sendrecv python example | |
1908 | - macOS: support a relocatable GStreamer.framework on macOS (see below | |
1909 | for details) | |
1910 | - macOS: fix applemedia plugin failing to load on ARM64 macOS | |
1911 | - windows: ship wavpack library | |
1912 | - gst-python: Fix build with Python 3.11 | |
1913 | - various bug fixes, memory leak fixes, and other stability and | |
1914 | reliability improvements | |
1915 | ||
1916 | gstreamer | |
1917 | ||
1918 | - plugin loader: show the reason when spawning of gst-plugin-scanner | |
1919 | fails | |
1920 | - registry, plugin loading: fix dynamic relocation if | |
1921 | GST_PLUGIN_SUBDIR (libdir) is not a single subdirectory; improve | |
1922 | GST_PLUGIN_SUBDIR handling | |
1923 | - context: fix transfer annotation on gst_context_writable_structure() | |
1924 | for bindings | |
1925 | - baseparse: Don’t truncate the duration to milliseconds in | |
1926 | gst_base_parse_convert_default() | |
1927 | - bufferpool: Deactivate pool and get rid of references to other | |
1928 | objects from dispose instead of finalize | |
1929 | ||
1930 | gst-plugins-base | |
1931 | ||
1932 | - typefindfunctions: Fix WebVTT format detection for very short files | |
1933 | - gldisplay: Reorder GST_GL_WINDOW check for egl-device | |
1934 | - rtpbasepayload: Copy all buffer metadata instead of just GstMetas | |
1935 | for the input meta buffer | |
1936 | - codec-utils: Avoid out-of-bounds error | |
1937 | - navigation: Fix Since markers for mouse scroll events | |
1938 | - videoaggregator: Fix for unhandled negative rate | |
1939 | - videoaggregator: Use floor() to calculate current position | |
1940 | - video-color: Fix for missing clipping in PQ EOTF function | |
1941 | - gst-play-1.0: Fix trick-mode handling in keyboard shortcut | |
1942 | - audiovisualizer: shader: Fix out of bound write | |
1943 | ||
1944 | gst-plugins-good | |
1945 | ||
1946 | - deinterlace: various bug fixes for yadif method | |
1947 | - deinterlace: Refactor greedyh and fix planar formats | |
1948 | - deinterlace: Prevent race between method configuration and latency | |
1949 | query | |
1950 | - gtk video sink: Fix rotation not being applied when paused | |
1951 | - jpegdec: fix RGB conversion handling | |
1952 | - matroskademux: improved ProRes video handling | |
1953 | - matroskamux: Handle multiview-mode/flags/pixel-aspect-ratio caps | |
1954 | fields correctly when checking caps equality on input caps changes | |
1955 | - rtprtx: don’t access type-system per buffer (performance | |
1956 | optimisation); code cleanups | |
1957 | - rtpulpfecenc: fix unmatched g_slice_free() | |
1958 | - rtpvp8depay: fix crash when making GstRTPPacketLost custom event | |
1959 | - qtmux: Don’t post an error message if pushing a sample failed with | |
1960 | FLUSHING (e.g. on pipeline shutdown) | |
1961 | - soup: Lookup libsoup dylib files on Apple platforms & fix Cerbero | |
1962 | static build on Android and iOS | |
1963 | - souphttpsrc: element not present on iOS after 1.20.0 update | |
1964 | - v4l2tuner: return NULL if no norm set | |
1965 | - v4l2bufferpool: Fix race condition between qbuf and pool streamoff | |
1966 | - meson: Don’t build lame plugin with -Dlame=disabled | |
1967 | ||
1968 | gst-plugins-bad | |
1969 | ||
1970 | - GstPlay: Fix new error + warning parsing API (was unusuable before) | |
1971 | - av1parse: let the parser continue on verbose OBUs | |
1972 | - d3d11converter: Fix RGB to GRAY conversion, broken debug messages, | |
1973 | and add missing GRAY conversion | |
1974 | - gs: look for google_cloud_cpp_storage.pc | |
1975 | - ipcpipeline: fix crash and error on windows with SOCKET or _pipe() | |
1976 | - ivfparse: Don’t set zero resolution on caps | |
1977 | - mpegtsdemux: Handle PES headers bigger than a mpeg-ts packet; fix | |
1978 | locking in error code path; handle more program updates | |
1979 | - mpegtsmux: Start last_ts with GST_CLOCK_TIME_NONE to fix VBR muxing | |
1980 | behaviour | |
1981 | - mpegtsmux: Thread safety fixes: lock mux->tsmux, the programs hash | |
1982 | table, and pad streams | |
1983 | - mpegtsmux: Skip empty buffers | |
1984 | - osxaudiodeviceprovider: Add initial support for duplex devices on | |
1985 | OSX | |
1986 | - rtpldacpay: Fix missing payload information | |
1987 | - sdpdemux: add media attributes to caps, fixes ptp clock handling | |
1988 | - mfaudioenc: Handle empty IMFMediaBuffer | |
1989 | - nvdecoder: Various fixes for 4:4:4 and high-bitdepth decoding | |
1990 | - nvenc: Fix deadlock because of too strict buffer pool size | |
1991 | - va: fix library build issues, caps leaks in the vpp transform | |
1992 | function, and add vaav1dec to documentation | |
1993 | - v4l2codecs: vp9: Minor fixes | |
1994 | - v4l2codecs: h264: Correct scaling matrix ABI check | |
1995 | - dtlstransport: Notify ICE transport property changes | |
1996 | - webrtc: Various fixes to the webrtc-sendrecv python example | |
1997 | - webrtc-ice: Fix memory leaks in gst_webrtc_ice_add_candidate() | |
1998 | - Support build against libfreeaptx in openaptx plugin | |
1999 | - Fix linking issues on Illumos distros | |
2000 | ||
2001 | gst-plugins-ugly | |
2002 | ||
2003 | - x264enc: fix plugin long-name and description | |
2004 | ||
2005 | gst-libav | |
2006 | ||
2007 | - No changes | |
2008 | ||
2009 | gst-rtsp-server | |
2010 | ||
2011 | - Fix race in rtsp-client when tunneling over HTTP | |
2012 | ||
2013 | gstreamer-vaapi | |
2014 | ||
2015 | - No changes | |
2016 | ||
2017 | gstreamer-sharp | |
2018 | ||
2019 | - No changes | |
2020 | ||
2021 | gst-omx | |
2022 | ||
2023 | - No changes | |
2024 | ||
2025 | gst-python | |
2026 | ||
2027 | - Fix build with Python 3.11 | |
2028 | ||
2029 | gst-editing-services | |
2030 | ||
2031 | - Update validate test scenarios for videoaggregator rounding | |
2032 | behaviour change | |
2033 | ||
2034 | gst-integration-testsuites | |
2035 | ||
2036 | - Update validate test scenarios for videoaggregator rounding | |
2037 | behaviour change | |
2038 | ||
2039 | Development build environment | |
2040 | ||
2041 | - gst-env: various clean-ups and documentation improvements | |
2042 | ||
2043 | Cerbero build tool and packaging changes in 1.20.1 | |
2044 | ||
2045 | - Fix nasm version check | |
2046 | - Disable certificate checking on RHEL/CentOS 7 | |
2047 | - packages: Ship wavpack.dll for Windows | |
2048 | - osx/universal: make the library name relocatable | |
2049 | - macOS: In order to support a relocatable GStreamer.framework on | |
2050 | macOS, an application may now need to add an rpath entry to the | |
2051 | location of the GStreamer.framework (which could be bundled with the | |
2052 | application itself). Some build systems will do this for you by | |
2053 | default. | |
2054 | - Disable MoltenVK on macOS arm64 to fix applemedia plugin loading | |
2055 | - Fix applemedia plugin failing to load on ARM64 macOS | |
2056 | ||
2057 | Contributors to 1.20.1 | |
2058 | ||
2059 | Bastien Nocera, Branko Subasic, David Svensson Fors, Dmitry Osipenko, | |
2060 | Edward Hervey, Guillaume Desmottes, Havard Graff, Heiko Becker, He | |
2061 | Junyan, Igor V. Kovalenko, Jan Alexander Steffens (heftig), Jan Schmidt, | |
2062 | jinsl00000, Joseph Donofry, Jose Quaresma, Marek Vasut, Matthew Waters, | |
2063 | Mengkejiergeli Ba, Nicolas Dufresne, Nirbheek Chauhan, Philippe Normand, | |
2064 | Qi Hou, Rouven Czerwinski, Ruben Gonzalez, Sanchayan Maity, Sangchul | |
2065 | Lee, Sebastian Dröge, Sebastian Fricke, Sebastian Groß, Sebastian | |
2066 | Mueller, Sebastian Wick, Seungha Yang, Stéphane Cerveau, Thibault | |
2067 | Saunier, Tim Mooney, Tim-Philipp Müller, Víctor Manuel Jáquez Leal, | |
2068 | Vivia Nikolaidou, Zebediah Figura, | |
2069 | ||
2070 | … and many others who have contributed bug reports, translations, sent | |
2071 | suggestions or helped testing. Thank you all! | |
2072 | ||
2073 | List of merge requests and issues fixed in 1.20.1 | |
2074 | ||
2075 | - List of Merge Requests applied in 1.20.1 | |
2076 | - List of Issues fixed in 1.20.1 | |
2077 | ||
1878 | 2078 | Schedule for 1.22 |
1879 | 2079 | |
1880 | 2080 | Our next major feature release will be 1.22, and 1.21 will be the |
0 | GStreamer 1.20.x stable series | |
1 | ||
2 | WHAT IT IS | |
3 | ---------- | |
4 | ||
5 | This is GStreamer, a framework for streaming media. | |
6 | ||
7 | WHERE TO START | |
8 | -------------- | |
9 | ||
10 | We have a website at | |
11 | ||
12 | https://gstreamer.freedesktop.org | |
13 | ||
14 | Our documentation, including tutorials, API reference and FAQ can be found at | |
15 | ||
16 | https://gstreamer.freedesktop.org/documentation/ | |
17 | ||
18 | You can subscribe to our mailing lists: | |
19 | ||
20 | https://lists.freedesktop.org/mailman/listinfo/gstreamer-announce | |
21 | ||
22 | https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel | |
23 | ||
24 | We track bugs, feature requests and merge requests (patches) in GitLab at | |
25 | ||
26 | https://gitlab.freedesktop.org/gstreamer/ | |
27 | ||
28 | You can join us on IRC - #gstreamer on irc.oftc.net | |
29 | ||
30 | GStreamer 1.0 series | |
31 | -------------------- | |
32 | ||
33 | Starring | |
34 | ||
35 | GSTREAMER | |
36 | ||
37 | The core around which all other modules revolve. Base functionality and | |
38 | libraries, some essential elements, documentation, and testing. | |
39 | ||
40 | BASE | |
41 | ||
42 | A well-groomed and well-maintained collection of GStreamer plug-ins and | |
43 | elements, spanning the range of possible types of elements one would want | |
44 | to write for GStreamer. | |
45 | ||
46 | And introducing, for the first time ever, on the development screen ... | |
47 | ||
48 | THE GOOD | |
49 | ||
50 | --- "Such ingratitude. After all the times I've saved your life." | |
51 | ||
52 | A collection of plug-ins you'd want to have right next to you on the | |
53 | battlefield. Shooting sharp and making no mistakes, these plug-ins have it | |
54 | all: good looks, good code, and good licensing. Documented and dressed up | |
55 | in tests. If you're looking for a role model to base your own plug-in on, | |
56 | here it is. | |
57 | ||
58 | If you find a plot hole or a badly lip-synced line of code in them, | |
59 | let us know - it is a matter of honour for us to ensure Blondie doesn't look | |
60 | like he's been walking 100 miles through the desert without water. | |
61 | ||
62 | THE UGLY | |
63 | ||
64 | --- "When you have to shoot, shoot. Don't talk." | |
65 | ||
66 | There are times when the world needs a color between black and white. | |
67 | Quality code to match the good's, but two-timing, backstabbing and ready to | |
68 | sell your freedom down the river. These plug-ins might have a patent noose | |
69 | around their neck, or a lock-up license, or any other problem that makes you | |
70 | think twice about shipping them. | |
71 | ||
72 | We don't call them ugly because we like them less. Does a mother love her | |
73 | son less because he's not as pretty as the other ones ? No - she commends | |
74 | him on his great personality. These plug-ins are the life of the party. | |
75 | And we'll still step in and set them straight if you report any unacceptable | |
76 | behaviour - because there are two kinds of people in the world, my friend: | |
77 | those with a rope around their neck and the people who do the cutting. | |
78 | ||
79 | THE BAD | |
80 | ||
81 | --- "That an accusation?" | |
82 | ||
83 | No perfectly groomed moustache or any amount of fine clothing is going to | |
84 | cover up the truth - these plug-ins are Bad with a capital B. | |
85 | They look fine on the outside, and might even appear to get the job done, but | |
86 | at the end of the day they're a black sheep. Without a golden-haired angel | |
87 | to watch over them, they'll probably land in an unmarked grave at the final | |
88 | showdown. | |
89 | ||
90 | Don't bug us about their quality - exercise your Free Software rights, | |
91 | patch up the offender and send us the patch on the fastest steed you can | |
92 | steal from the Confederates. Because you see, in this world, there's two | |
93 | kinds of people, my friend: those with loaded guns and those who dig. | |
94 | You dig. | |
95 | ||
96 | The Lowdown | |
97 | ----------- | |
98 | ||
99 | --- "I've never seen so many plug-ins wasted so badly." | |
100 | ||
101 | GStreamer Plug-ins has grown so big that it's hard to separate the wheat from | |
102 | the chaff. Also, distributors have brought up issues about the legal status | |
103 | of some of the plug-ins we ship. To remedy this, we've divided the previous | |
104 | set of available plug-ins into four modules: | |
105 | ||
106 | - gst-plugins-base: a small and fixed set of plug-ins, covering a wide range | |
107 | of possible types of elements; these are continuously kept up-to-date | |
108 | with any core changes during the development series. | |
109 | ||
110 | - We believe distributors can safely ship these plug-ins. | |
111 | - People writing elements should base their code on these elements. | |
112 | - These elements come with examples, documentation, and regression tests. | |
113 | ||
114 | - gst-plugins-good: a set of plug-ins that we consider to have good quality | |
115 | code, correct functionality, our preferred license (LGPL for the plug-in | |
116 | code, LGPL or LGPL-compatible for the supporting library). | |
117 | ||
118 | - We believe distributors can safely ship these plug-ins. | |
119 | - People writing elements should base their code on these elements. | |
120 | ||
121 | - gst-plugins-ugly: a set of plug-ins that have good quality and correct | |
122 | functionality, but distributing them might pose problems. The license | |
123 | on either the plug-ins or the supporting libraries might not be how we'd | |
124 | like. The code might be widely known to present patent problems. | |
125 | ||
126 | - Distributors should check if they want/can ship these plug-ins. | |
127 | - People writing elements should base their code on these elements. | |
128 | ||
129 | - gst-plugins-bad: a set of plug-ins that aren't up to par compared to the | |
130 | rest. They might be close to being good quality, but they're missing | |
131 | something - be it a good code review, some documentation, a set of tests, | |
132 | a real live maintainer, or some actual wide use. | |
133 | If the blanks are filled in they might be upgraded to become part of | |
134 | either gst-plugins-good or gst-plugins-ugly, depending on the other factors. | |
135 | ||
136 | - If the plug-ins break, you can't complain - instead, you can fix the | |
137 | problem and send us a patch, or bribe someone into fixing them for you. | |
138 | - New contributors can start here for things to work on. | |
139 | ||
140 | PLATFORMS | |
141 | --------- | |
142 | ||
143 | - Linux is of course fully supported | |
144 | - FreeBSD is reported to work; other BSDs should work too; same for Solaris | |
145 | - MacOS works, binary 1.x packages can be built using the cerbero build tool | |
146 | - Windows works; binary 1.x packages can be built using the cerbero build tool | |
147 | - MSys/MinGW builds | |
148 | - Microsoft Visual Studio builds are also available and supported | |
149 | - Android works, binary 1.x packages can be built using the cerbero build tool | |
150 | - iOS works | |
151 | ||
152 | INSTALLING FROM PACKAGES | |
153 | ------------------------ | |
154 | ||
155 | You should always prefer installing from packages first. GStreamer is | |
156 | well-maintained for a number of distributions, including Fedora, Debian, | |
157 | Ubuntu, Mandrake, Arch Linux, Gentoo, ... | |
158 | ||
159 | Only in cases where you: | |
160 | ||
161 | - want to hack on GStreamer | |
162 | - want to verify that a bug has been fixed | |
163 | - do not have a sane distribution | |
164 | ||
165 | should you choose to build from source tarballs or git. | |
166 | ||
167 | Find more information about the various packages at | |
168 | ||
169 | https://gstreamer.freedesktop.org/download/ | |
170 | ||
171 | COMPILING FROM SOURCE TARBALLS | |
172 | ------------------------------ | |
173 | ||
174 | - again, make sure that you really need to install from source! | |
175 | If GStreamer is one of your first projects ever that you build from source, | |
176 | consider taking on an easier project. | |
177 | ||
178 | - you need a recent version of Meson installed, see | |
179 | ||
180 | http://mesonbuild.com/Getting-meson.html | |
181 | ||
182 | and | |
183 | ||
184 | https://gitlab.freedesktop.org/gstreamer/gst-build/blob/master/README.md | |
185 | ||
186 | - run | |
187 | ||
188 | meson build | |
189 | ninja -C build | |
190 | ||
191 | to build GStreamer. | |
192 | ||
193 | - if you want to install it (not required, but what you usually want to do), run | |
194 | ||
195 | ninja -C build install | |
196 | ||
197 | - try out a simple test: | |
198 | gst-launch-1.0 -v fakesrc num_buffers=5 ! fakesink | |
199 | (If you didn't install GStreamer, run `./build/tools/gst-launch-1.0`) | |
200 | ||
201 | If it outputs a bunch of messages from fakesrc and fakesink, everything is | |
202 | ok. | |
203 | ||
204 | If it did not work, keep in mind that you might need to adjust the | |
205 | PATH and/or LD_LIBRARY_PATH environment variables to make the system | |
206 | find GStreamer in the prefix where you installed (by default that is /usr/local). | |
207 | ||
208 | - After this, you're ready to install gst-plugins, which will provide the | |
209 | functionality you're probably looking for by now, so go on and read | |
210 | that README. | |
211 | ||
212 | COMPILING FROM GIT | |
213 | ------------------ | |
214 | ||
215 | You can build an uninstalled GStreamer from git for development or testing | |
216 | purposes without affecting your system installation. | |
217 | ||
218 | Get started with: | |
219 | ||
220 | git clone https://gitlab.freedesktop.org/gstreamer/gst-build | |
221 | meson build | |
222 | ninja -C build | |
223 | ninja -C build uninstalled | |
224 | ||
225 | For more information, see the `gst-build` module and its documentation: | |
226 | ||
227 | https://gitlab.freedesktop.org/gstreamer/gst-build/blob/master/README.md | |
228 | ||
229 | ||
230 | PLUG-IN DEPENDENCIES AND LICENSES | |
231 | --------------------------------- | |
232 | ||
233 | GStreamer is developed under the terms of the LGPL (see COPYING file for | |
234 | details). Some of our plug-ins however rely on libraries which are available | |
235 | under other licenses. This means that if you are distributing an application | |
236 | which has a non-GPL compatible license (for instance a closed-source | |
237 | application) with GStreamer, you have to make sure not to distribute GPL-linked | |
238 | plug-ins. | |
239 | ||
240 | When using GPL-linked plug-ins, GStreamer is for all practical reasons | |
241 | under the GPL itself. | |
242 | ||
243 | HISTORY | |
244 | ------- | |
245 | ||
246 | The fundamental design comes from the video pipeline at Oregon Graduate | |
247 | Institute, as well as some ideas from DirectMedia. It's based on plug-ins that | |
248 | will provide the various codec and other functionality. The interface | |
249 | hopefully is generic enough for various companies (ahem, Apple) to release | |
250 | binary codecs for Linux, until such time as they get a clue and release the | |
251 | source. |
0 | GStreamer 1.20.x stable series | |
1 | ||
2 | WHAT IT IS | |
3 | ---------- | |
4 | ||
5 | This is GStreamer, a framework for streaming media. | |
6 | ||
7 | WHERE TO START | |
8 | -------------- | |
9 | ||
10 | We have a website at | |
11 | ||
12 | https://gstreamer.freedesktop.org | |
13 | ||
14 | Our documentation, including tutorials, API reference and FAQ can be found at | |
15 | ||
16 | https://gstreamer.freedesktop.org/documentation/ | |
17 | ||
18 | You can subscribe to our mailing lists: | |
19 | ||
20 | https://lists.freedesktop.org/mailman/listinfo/gstreamer-announce | |
21 | ||
22 | https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel | |
23 | ||
24 | We track bugs, feature requests and merge requests (patches) in GitLab at | |
25 | ||
26 | https://gitlab.freedesktop.org/gstreamer/ | |
27 | ||
28 | You can join us on IRC - #gstreamer on irc.oftc.net | |
29 | ||
30 | GStreamer 1.0 series | |
31 | -------------------- | |
32 | ||
33 | Starring | |
34 | ||
35 | GSTREAMER | |
36 | ||
37 | The core around which all other modules revolve. Base functionality and | |
38 | libraries, some essential elements, documentation, and testing. | |
39 | ||
40 | BASE | |
41 | ||
42 | A well-groomed and well-maintained collection of GStreamer plug-ins and | |
43 | elements, spanning the range of possible types of elements one would want | |
44 | to write for GStreamer. | |
45 | ||
46 | And introducing, for the first time ever, on the development screen ... | |
47 | ||
48 | THE GOOD | |
49 | ||
50 | --- "Such ingratitude. After all the times I've saved your life." | |
51 | ||
52 | A collection of plug-ins you'd want to have right next to you on the | |
53 | battlefield. Shooting sharp and making no mistakes, these plug-ins have it | |
54 | all: good looks, good code, and good licensing. Documented and dressed up | |
55 | in tests. If you're looking for a role model to base your own plug-in on, | |
56 | here it is. | |
57 | ||
58 | If you find a plot hole or a badly lip-synced line of code in them, | |
59 | let us know - it is a matter of honour for us to ensure Blondie doesn't look | |
60 | like he's been walking 100 miles through the desert without water. | |
61 | ||
62 | THE UGLY | |
63 | ||
64 | --- "When you have to shoot, shoot. Don't talk." | |
65 | ||
66 | There are times when the world needs a color between black and white. | |
67 | Quality code to match the good's, but two-timing, backstabbing and ready to | |
68 | sell your freedom down the river. These plug-ins might have a patent noose | |
69 | around their neck, or a lock-up license, or any other problem that makes you | |
70 | think twice about shipping them. | |
71 | ||
72 | We don't call them ugly because we like them less. Does a mother love her | |
73 | son less because he's not as pretty as the other ones ? No - she commends | |
74 | him on his great personality. These plug-ins are the life of the party. | |
75 | And we'll still step in and set them straight if you report any unacceptable | |
76 | behaviour - because there are two kinds of people in the world, my friend: | |
77 | those with a rope around their neck and the people who do the cutting. | |
78 | ||
79 | THE BAD | |
80 | ||
81 | --- "That an accusation?" | |
82 | ||
83 | No perfectly groomed moustache or any amount of fine clothing is going to | |
84 | cover up the truth - these plug-ins are Bad with a capital B. | |
85 | They look fine on the outside, and might even appear to get the job done, but | |
86 | at the end of the day they're a black sheep. Without a golden-haired angel | |
87 | to watch over them, they'll probably land in an unmarked grave at the final | |
88 | showdown. | |
89 | ||
90 | Don't bug us about their quality - exercise your Free Software rights, | |
91 | patch up the offender and send us the patch on the fastest steed you can | |
92 | steal from the Confederates. Because you see, in this world, there's two | |
93 | kinds of people, my friend: those with loaded guns and those who dig. | |
94 | You dig. | |
95 | ||
96 | The Lowdown | |
97 | ----------- | |
98 | ||
99 | --- "I've never seen so many plug-ins wasted so badly." | |
100 | ||
101 | GStreamer Plug-ins has grown so big that it's hard to separate the wheat from | |
102 | the chaff. Also, distributors have brought up issues about the legal status | |
103 | of some of the plug-ins we ship. To remedy this, we've divided the previous | |
104 | set of available plug-ins into four modules: | |
105 | ||
106 | - gst-plugins-base: a small and fixed set of plug-ins, covering a wide range | |
107 | of possible types of elements; these are continuously kept up-to-date | |
108 | with any core changes during the development series. | |
109 | ||
110 | - We believe distributors can safely ship these plug-ins. | |
111 | - People writing elements should base their code on these elements. | |
112 | - These elements come with examples, documentation, and regression tests. | |
113 | ||
114 | - gst-plugins-good: a set of plug-ins that we consider to have good quality | |
115 | code, correct functionality, our preferred license (LGPL for the plug-in | |
116 | code, LGPL or LGPL-compatible for the supporting library). | |
117 | ||
118 | - We believe distributors can safely ship these plug-ins. | |
119 | - People writing elements should base their code on these elements. | |
120 | ||
121 | - gst-plugins-ugly: a set of plug-ins that have good quality and correct | |
122 | functionality, but distributing them might pose problems. The license | |
123 | on either the plug-ins or the supporting libraries might not be how we'd | |
124 | like. The code might be widely known to present patent problems. | |
125 | ||
126 | - Distributors should check if they want/can ship these plug-ins. | |
127 | - People writing elements should base their code on these elements. | |
128 | ||
129 | - gst-plugins-bad: a set of plug-ins that aren't up to par compared to the | |
130 | rest. They might be close to being good quality, but they're missing | |
131 | something - be it a good code review, some documentation, a set of tests, | |
132 | a real live maintainer, or some actual wide use. | |
133 | If the blanks are filled in they might be upgraded to become part of | |
134 | either gst-plugins-good or gst-plugins-ugly, depending on the other factors. | |
135 | ||
136 | - If the plug-ins break, you can't complain - instead, you can fix the | |
137 | problem and send us a patch, or bribe someone into fixing them for you. | |
138 | - New contributors can start here for things to work on. | |
139 | ||
140 | PLATFORMS | |
141 | --------- | |
142 | ||
143 | - Linux is of course fully supported | |
144 | - FreeBSD is reported to work; other BSDs should work too; same for Solaris | |
145 | - MacOS works, binary 1.x packages can be built using the cerbero build tool | |
146 | - Windows works; binary 1.x packages can be built using the cerbero build tool | |
147 | - MSys/MinGW builds | |
148 | - Microsoft Visual Studio builds are also available and supported | |
149 | - Android works, binary 1.x packages can be built using the cerbero build tool | |
150 | - iOS works | |
151 | ||
152 | INSTALLING FROM PACKAGES | |
153 | ------------------------ | |
154 | ||
155 | You should always prefer installing from packages first. GStreamer is | |
156 | well-maintained for a number of distributions, including Fedora, Debian, | |
157 | Ubuntu, Mandrake, Arch Linux, Gentoo, ... | |
158 | ||
159 | Only in cases where you: | |
160 | ||
161 | - want to hack on GStreamer | |
162 | - want to verify that a bug has been fixed | |
163 | - do not have a sane distribution | |
164 | ||
165 | should you choose to build from source tarballs or git. | |
166 | ||
167 | Find more information about the various packages at | |
168 | ||
169 | https://gstreamer.freedesktop.org/download/ | |
170 | ||
171 | For in-depth instructions about building GStreamer visit: | |
172 | [getting-started](https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/README.md#getting-started). | |
173 | ||
174 | PLUG-IN DEPENDENCIES AND LICENSES | |
175 | --------------------------------- | |
176 | ||
177 | GStreamer is developed under the terms of the LGPL (see COPYING file for | |
178 | details). Some of our plug-ins however rely on libraries which are available | |
179 | under other licenses. This means that if you are distributing an application | |
180 | which has a non-GPL compatible license (for instance a closed-source | |
181 | application) with GStreamer, you have to make sure not to distribute GPL-linked | |
182 | plug-ins. | |
183 | ||
184 | When using GPL-linked plug-ins, GStreamer is for all practical reasons | |
185 | under the GPL itself. | |
186 | ||
187 | HISTORY | |
188 | ------- | |
189 | ||
190 | The fundamental design comes from the video pipeline at Oregon Graduate | |
191 | Institute, as well as some ideas from DirectMedia. It's based on plug-ins that | |
192 | will provide the various codec and other functionality. The interface | |
193 | hopefully is generic enough for various companies (ahem, Apple) to release | |
194 | binary codecs for Linux, until such time as they get a clue and release the | |
195 | source. |
0 | This is GStreamer gst-plugins-good 1.20.0. | |
0 | This is GStreamer gst-plugins-good 1.20.1. | |
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! |
6606 | 6606 | "construct": false, |
6607 | 6607 | "construct-only": false, |
6608 | 6608 | "controllable": false, |
6609 | "default": "GStreamer 1.20.0 FLV muxer", | |
6609 | "default": "GStreamer 1.20.1 FLV muxer", | |
6610 | 6610 | "mutable": "null", |
6611 | 6611 | "readable": true, |
6612 | 6612 | "type": "gchararray", |
6618 | 6618 | "construct": false, |
6619 | 6619 | "construct-only": false, |
6620 | 6620 | "controllable": false, |
6621 | "default": "GStreamer 1.20.0 FLV muxer", | |
6621 | "default": "GStreamer 1.20.1 FLV muxer", | |
6622 | 6622 | "mutable": "null", |
6623 | 6623 | "readable": true, |
6624 | 6624 | "type": "gchararray", |
14677 | 14677 | "long-name": "RTP packet payloader", |
14678 | 14678 | "pad-templates": { |
14679 | 14679 | "sink": { |
14680 | "caps": "audio/x-ldac:\n channels: [ 1, 2 ]\n rate: { (int)44100, (int)48000, (int)88200, (int)96000 }\n", | |
14680 | "caps": "audio/x-ldac:\n channels: [ 1, 2 ]\n eqmid: { (int)0, (int)1, (int)2 }\n rate: { (int)44100, (int)48000, (int)88200, (int)96000 }\n", | |
14681 | 14681 | "direction": "sink", |
14682 | 14682 | "presence": "always" |
14683 | 14683 | }, |
20477 | 20477 | "construct": false, |
20478 | 20478 | "construct-only": false, |
20479 | 20479 | "controllable": false, |
20480 | "default": "GStreamer/1.20.0", | |
20480 | "default": "GStreamer/1.20.1", | |
20481 | 20481 | "mutable": "null", |
20482 | 20482 | "readable": true, |
20483 | 20483 | "type": "gchararray", |
22434 | 22434 | "construct": false, |
22435 | 22435 | "construct-only": false, |
22436 | 22436 | "controllable": false, |
22437 | "default": "GStreamer souphttpsrc 1.20.0 ", | |
22437 | "default": "GStreamer souphttpsrc 1.20.1 ", | |
22438 | 22438 | "mutable": "null", |
22439 | 22439 | "readable": true, |
22440 | 22440 | "type": "gchararray", |
592 | 592 | |
593 | 593 | GTK_GST_BASE_WIDGET_UNLOCK (widget); |
594 | 594 | } |
595 | ||
596 | void | |
597 | gtk_gst_base_widget_queue_draw (GtkGstBaseWidget * widget) | |
598 | { | |
599 | /* As we have no type, this is better then no check */ | |
600 | g_return_if_fail (GTK_IS_WIDGET (widget)); | |
601 | ||
602 | GTK_GST_BASE_WIDGET_LOCK (widget); | |
603 | ||
604 | if (!widget->draw_id) { | |
605 | widget->draw_id = g_idle_add_full (G_PRIORITY_DEFAULT, | |
606 | (GSourceFunc) _queue_draw, widget, NULL); | |
607 | } | |
608 | ||
609 | GTK_GST_BASE_WIDGET_UNLOCK (widget); | |
610 | } |
90 | 90 | /* API */ |
91 | 91 | gboolean gtk_gst_base_widget_set_format (GtkGstBaseWidget * widget, GstVideoInfo * v_info); |
92 | 92 | void gtk_gst_base_widget_set_buffer (GtkGstBaseWidget * widget, GstBuffer * buffer); |
93 | void gtk_gst_base_widget_queue_draw (GtkGstBaseWidget * widget); | |
93 | 94 | void gtk_gst_base_widget_set_element (GtkGstBaseWidget * widget, GstElement * element); |
94 | 95 | void gtk_gst_base_widget_display_size_to_stream_size (GtkGstBaseWidget * base_widget, |
95 | 96 | gdouble x, gdouble y, |
751 | 751 | priv->current_rotate_method = method; |
752 | 752 | } |
753 | 753 | GTK_GST_BASE_WIDGET_UNLOCK (gst_widget); |
754 | ||
755 | gtk_gst_base_widget_queue_draw (GTK_GST_BASE_WIDGET (gst_widget)); | |
754 | 756 | } |
755 | 757 | |
756 | 758 | GstVideoOrientationMethod |
914 | 914 | |
915 | 915 | #ifdef JCS_EXTENSIONS |
916 | 916 | if (dec->format_convert) { |
917 | gint row_stride = dec->cinfo.output_width * dec->cinfo.output_components; | |
917 | gint row_stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0); | |
918 | 918 | guchar *bufbase = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); |
919 | 919 | |
920 | 920 | if (num_fields == 2) { |
1007 | 1007 | return 0; |
1008 | 1008 | } |
1009 | 1009 | } |
1010 | ||
1011 | static void | |
1012 | gst_jpeg_turbo_parse_ext_fmt_convert (GstJpegDec * dec, gint * clrspc) | |
1013 | { | |
1014 | GstCaps *peer_caps, *dec_caps; | |
1015 | ||
1016 | dec_caps = gst_static_caps_get (&gst_jpeg_dec_src_pad_template.static_caps); | |
1017 | peer_caps = | |
1018 | gst_pad_peer_query_caps (GST_VIDEO_DECODER_SRC_PAD (dec), dec_caps); | |
1019 | gst_caps_unref (dec_caps); | |
1020 | ||
1021 | GST_DEBUG ("Received caps from peer: %" GST_PTR_FORMAT, peer_caps); | |
1022 | dec->format_convert = FALSE; | |
1023 | if (!gst_caps_is_empty (peer_caps)) { | |
1024 | GstStructure *peerstruct; | |
1025 | const gchar *peerformat; | |
1026 | GstVideoFormat peerfmt; | |
1027 | ||
1028 | if (!gst_caps_is_fixed (peer_caps)) | |
1029 | peer_caps = gst_caps_fixate (peer_caps); | |
1030 | ||
1031 | peerstruct = gst_caps_get_structure (peer_caps, 0); | |
1032 | peerformat = gst_structure_get_string (peerstruct, "format"); | |
1033 | peerfmt = gst_video_format_from_string (peerformat); | |
1034 | ||
1035 | switch (peerfmt) { | |
1036 | case GST_VIDEO_FORMAT_RGB: | |
1037 | case GST_VIDEO_FORMAT_RGBx: | |
1038 | case GST_VIDEO_FORMAT_xRGB: | |
1039 | case GST_VIDEO_FORMAT_RGBA: | |
1040 | case GST_VIDEO_FORMAT_ARGB: | |
1041 | case GST_VIDEO_FORMAT_BGR: | |
1042 | case GST_VIDEO_FORMAT_BGRx: | |
1043 | case GST_VIDEO_FORMAT_xBGR: | |
1044 | case GST_VIDEO_FORMAT_BGRA: | |
1045 | case GST_VIDEO_FORMAT_ABGR: | |
1046 | if (clrspc) | |
1047 | *clrspc = JCS_RGB; | |
1048 | dec->format = peerfmt; | |
1049 | dec->format_convert = TRUE; | |
1050 | dec->libjpeg_ext_format = gst_fmt_to_jpeg_turbo_ext_fmt (peerfmt); | |
1051 | break; | |
1052 | default: | |
1053 | break; | |
1054 | } | |
1055 | } | |
1056 | gst_caps_unref (peer_caps); | |
1057 | GST_DEBUG_OBJECT (dec, "format_convert=%d", dec->format_convert); | |
1058 | } | |
1010 | 1059 | #endif |
1011 | 1060 | |
1012 | 1061 | static void |
1016 | 1065 | GstVideoCodecState *outstate; |
1017 | 1066 | GstVideoInfo *info; |
1018 | 1067 | GstVideoFormat format; |
1019 | GstCaps *peer_caps, *dec_caps; | |
1020 | 1068 | |
1021 | 1069 | #ifdef JCS_EXTENSIONS |
1022 | 1070 | if (dec->format_convert) { |
1051 | 1099 | gst_video_codec_state_unref (outstate); |
1052 | 1100 | } |
1053 | 1101 | #ifdef JCS_EXTENSIONS |
1054 | dec_caps = gst_static_caps_get (&gst_jpeg_dec_src_pad_template.static_caps); | |
1055 | peer_caps = | |
1056 | gst_pad_peer_query_caps (GST_VIDEO_DECODER_SRC_PAD (dec), dec_caps); | |
1057 | gst_caps_unref (dec_caps); | |
1058 | ||
1059 | GST_DEBUG ("Received caps from peer: %" GST_PTR_FORMAT, peer_caps); | |
1060 | dec->format_convert = FALSE; | |
1061 | if (!gst_caps_is_empty (peer_caps)) { | |
1062 | GstStructure *peerstruct; | |
1063 | const gchar *peerformat; | |
1064 | GstVideoFormat peerfmt; | |
1065 | ||
1066 | if (!gst_caps_is_fixed (peer_caps)) | |
1067 | peer_caps = gst_caps_fixate (peer_caps); | |
1068 | ||
1069 | peerstruct = gst_caps_get_structure (peer_caps, 0); | |
1070 | peerformat = gst_structure_get_string (peerstruct, "format"); | |
1071 | peerfmt = gst_video_format_from_string (peerformat); | |
1072 | ||
1073 | /* libjpeg-turbo only supports some colorspace conversions, see | |
1074 | * https://raw.githubusercontent.com/libjpeg-turbo/libjpeg-turbo/main/libjpeg.txt */ | |
1075 | switch (peerfmt) { | |
1076 | case GST_VIDEO_FORMAT_RGBx: | |
1077 | case GST_VIDEO_FORMAT_xRGB: | |
1078 | case GST_VIDEO_FORMAT_RGBA: | |
1079 | case GST_VIDEO_FORMAT_ARGB: | |
1080 | case GST_VIDEO_FORMAT_BGR: | |
1081 | case GST_VIDEO_FORMAT_BGRx: | |
1082 | case GST_VIDEO_FORMAT_xBGR: | |
1083 | case GST_VIDEO_FORMAT_BGRA: | |
1084 | case GST_VIDEO_FORMAT_ABGR: | |
1085 | if (clrspc == JCS_RGB) { | |
1086 | /* RGB -> other RGB formats */ | |
1087 | format = peerfmt; | |
1088 | dec->format_convert = TRUE; | |
1089 | dec->libjpeg_ext_format = gst_fmt_to_jpeg_turbo_ext_fmt (peerfmt); | |
1090 | } | |
1091 | break; | |
1092 | /* TODO: implement conversion from/to other supported colorspaces */ | |
1093 | default: | |
1094 | break; | |
1095 | } | |
1096 | } | |
1097 | dec->format = format; | |
1098 | gst_caps_unref (peer_caps); | |
1099 | GST_DEBUG_OBJECT (dec, "format_convert=%d", dec->format_convert); | |
1102 | /* Determine if libjpeg-turbo direct format conversion can be used | |
1103 | * with current caps and if so, adjust $dec to enable it and $clrspc | |
1104 | * accordingly. */ | |
1105 | gst_jpeg_turbo_parse_ext_fmt_convert (dec, &clrspc); | |
1100 | 1106 | #endif |
1101 | 1107 | |
1102 | 1108 | outstate = |
1182 | 1188 | dec->cinfo.do_block_smoothing = FALSE; |
1183 | 1189 | dec->cinfo.dct_method = dec->idct_method; |
1184 | 1190 | #ifdef JCS_EXTENSIONS |
1191 | gst_jpeg_turbo_parse_ext_fmt_convert (dec, NULL); | |
1185 | 1192 | if (dec->format_convert) { |
1186 | 1193 | dec->cinfo.out_color_space = dec->libjpeg_ext_format; |
1187 | 1194 | dec->cinfo.raw_data_out = FALSE; |
0 | lame_dep = dependency('', required: false) | |
0 | 1 | lame_option = get_option('lame') |
2 | ||
3 | if lame_option.disabled() | |
4 | subdir_done() | |
5 | endif | |
1 | 6 | |
2 | 7 | lame_extra_c_args = [] |
3 | 8 | lame_dep = cc.find_library('mp3lame', required: false) |
32 | 32 | GST_DEBUG_CATEGORY_EXTERN (gst_soup_debug); |
33 | 33 | #define GST_CAT_DEFAULT gst_soup_debug |
34 | 34 | |
35 | /* G_OS_WIN32 is handled separately below */ | |
36 | #ifdef __APPLE__ | |
37 | #define LIBSOUP_3_SONAME "libsoup-3.0.0.dylib" | |
38 | #define LIBSOUP_2_SONAME "libsoup-2.4.1.dylib" | |
39 | #else | |
35 | 40 | #define LIBSOUP_3_SONAME "libsoup-3.0.so.0" |
36 | 41 | #define LIBSOUP_2_SONAME "libsoup-2.4.so.1" |
42 | #endif | |
43 | ||
37 | 44 | |
38 | 45 | #define LOAD_SYMBOL(name) G_STMT_START { \ |
39 | 46 | if (!g_module_symbol (module, G_STRINGIFY (name), (gpointer *) &G_PASTE (vtable->_, name))) { \ |
807 | 814 | { |
808 | 815 | #ifdef STATIC_SOUP |
809 | 816 | #if STATIC_SOUP == 2 |
810 | return soup_session_send_async (session, msg, cancellable, | |
817 | soup_session_send_async (session, msg, cancellable, callback, user_data); | |
818 | #else | |
819 | soup_session_send_async (session, msg, G_PRIORITY_DEFAULT, cancellable, | |
811 | 820 | callback, user_data); |
812 | #else | |
813 | return soup_session_send_async (session, msg, G_PRIORITY_DEFAULT, | |
814 | cancellable, callback, user_data); | |
815 | 821 | #endif |
816 | 822 | #else |
817 | 823 | if (gst_soup_vtable.lib_version == 3) { |
16 | 16 | |
17 | 17 | libdl_dep = cc.find_library('dl', required: false) |
18 | 18 | |
19 | extra_args = [] | |
20 | extra_deps = [] | |
21 | if get_option('default_library') == 'static' | |
19 | static_args = [] | |
20 | static_deps = [] | |
21 | default_library = get_option('default_library') | |
22 | if default_library in ['static', 'both'] | |
22 | 23 | libsoup2_dep = dependency('libsoup-2.4', version : '>=2.48', |
23 | 24 | required : false, fallback : ['libsoup', 'libsoup_dep'], |
24 | 25 | default_options: ['sysprof=disabled']) |
25 | 26 | libsoup3_dep = dependency('libsoup-3.0', required : false, |
26 | 27 | fallback : ['libsoup3', 'libsoup_dep']) |
27 | 28 | if not libsoup2_dep.found() and not libsoup3_dep.found() |
28 | error('Either libsoup2 or libsoup3 is needed') | |
29 | if soup_opt.enabled() | |
30 | error('Either libsoup2 or libsoup3 is needed') | |
31 | endif | |
29 | 32 | subdir_done() |
30 | 33 | endif |
31 | 34 | if libsoup3_dep.found() |
32 | extra_deps += libsoup3_dep | |
33 | extra_args += '-DSTATIC_SOUP=3' | |
35 | static_deps += libsoup3_dep | |
36 | static_args += '-DSTATIC_SOUP=3' | |
34 | 37 | elif libsoup2_dep.found() |
35 | extra_deps += libsoup2_dep | |
36 | extra_args += '-DSTATIC_SOUP=2' | |
38 | static_deps += libsoup2_dep | |
39 | static_args += '-DSTATIC_SOUP=2' | |
37 | 40 | endif |
38 | 41 | endif |
39 | 42 | |
40 | gstsouphttpsrc = library('gstsoup', | |
41 | soup_sources, | |
42 | c_args : gst_plugins_good_args + extra_args, | |
43 | link_args : noseh_link_args, | |
44 | include_directories : [configinc, libsinc], | |
45 | dependencies : [gst_dep, gstbase_dep, gsttag_dep, gmodule_dep, gobject_dep, gio_dep, libdl_dep] + extra_deps, | |
46 | install : true, | |
47 | install_dir : plugins_install_dir, | |
48 | ) | |
49 | pkgconfig.generate(gstsouphttpsrc, install_dir : plugins_pkgconfig_install_dir) | |
50 | plugins += [gstsouphttpsrc] | |
43 | soup_library_kwargs = { | |
44 | 'sources' : soup_sources, | |
45 | 'link_args' : noseh_link_args, | |
46 | 'include_directories' : [configinc, libsinc], | |
47 | 'install' : true, | |
48 | 'install_dir' : plugins_install_dir, | |
49 | } | |
50 | soup_library_deps = [gst_dep, gstbase_dep, gsttag_dep, gmodule_dep, gobject_dep, gio_dep, libdl_dep] | |
51 | soup_library_c_args = gst_plugins_good_args | |
52 | ||
53 | if default_library in ['shared', 'both'] | |
54 | gstsouphttpsrc_shared = shared_library('gstsoup', | |
55 | c_args : soup_library_c_args, | |
56 | dependencies : soup_library_deps, | |
57 | kwargs: soup_library_kwargs, | |
58 | ) | |
59 | endif | |
60 | ||
61 | if default_library in ['static', 'both'] | |
62 | gstsouphttpsrc_static = static_library('gstsoup', | |
63 | c_args : soup_library_c_args + static_args, | |
64 | dependencies : soup_library_deps + static_deps, | |
65 | kwargs: soup_library_kwargs, | |
66 | ) | |
67 | endif | |
68 | ||
69 | # Use the static library to generate the .pc file if it's available. The shared | |
70 | # library .pc file does not have a Requires: on libsoup-2.4, and we use plugin | |
71 | # .pc files to generate dependencies for linking plugins statically. | |
72 | if default_library == 'shared' | |
73 | pkgconfig.generate(gstsouphttpsrc_shared, install_dir : plugins_pkgconfig_install_dir) | |
74 | else | |
75 | pkgconfig.generate(gstsouphttpsrc_static, install_dir : plugins_pkgconfig_install_dir) | |
76 | endif | |
77 | ||
78 | # Add the shared library to the plugins list if available. We pass this list of | |
79 | # plugins to hotdoc to generate the plugins cache, which introspects the plugin | |
80 | # by loading it. We need the shared plugin for that. | |
81 | if default_library == 'static' | |
82 | plugins += [gstsouphttpsrc_static] | |
83 | else | |
84 | plugins += [gstsouphttpsrc_shared] | |
85 | endif |
411 | 411 | gst_child_proxy_child_removed (GST_OBJECT (self), |
412 | 412 | GST_OBJECT (self->method)); |
413 | 413 | #endif |
414 | ||
415 | GST_OBJECT_LOCK (self); | |
414 | 416 | gst_object_unparent (GST_OBJECT (self->method)); |
415 | 417 | self->method = NULL; |
418 | GST_OBJECT_UNLOCK (self); | |
416 | 419 | } |
417 | 420 | |
418 | 421 | method_type = |
442 | 445 | g_assert (method_type != G_TYPE_INVALID); |
443 | 446 | } |
444 | 447 | |
448 | self->method_id = method; | |
449 | ||
450 | GST_OBJECT_LOCK (self); | |
445 | 451 | self->method = g_object_new (method_type, "name", "method", NULL); |
446 | self->method_id = method; | |
447 | ||
448 | 452 | gst_object_set_parent (GST_OBJECT (self->method), GST_OBJECT (self)); |
453 | GST_OBJECT_UNLOCK (self); | |
454 | ||
449 | 455 | #if 0 |
450 | 456 | gst_child_proxy_child_added (GST_OBJECT (self), GST_OBJECT (self->method)); |
451 | 457 | #endif |
3282 | 3288 | gint fields_required = 0; |
3283 | 3289 | gint method_latency = 0; |
3284 | 3290 | |
3291 | GST_OBJECT_LOCK (self); | |
3285 | 3292 | if (self->method) { |
3286 | 3293 | fields_required = |
3287 | 3294 | gst_deinterlace_method_get_fields_required (self->method); |
3288 | 3295 | method_latency = |
3289 | 3296 | gst_deinterlace_method_get_latency (self->method); |
3290 | 3297 | } |
3298 | GST_OBJECT_UNLOCK (self); | |
3291 | 3299 | |
3292 | 3300 | gst_query_parse_latency (query, &live, &min, &max); |
3293 | 3301 |
716 | 716 | #endif |
717 | 717 | |
718 | 718 | static void |
719 | deinterlace_frame_di_greedyh_packed (GstDeinterlaceMethod * method, | |
719 | deinterlace_frame_di_greedyh_plane (GstDeinterlaceMethodGreedyH * self, | |
720 | 720 | const GstDeinterlaceField * history, guint history_count, |
721 | GstVideoFrame * outframe, int cur_field_idx) | |
722 | { | |
723 | GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (method); | |
724 | GstDeinterlaceMethodGreedyHClass *klass = | |
725 | GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS (self); | |
726 | gint InfoIsOdd = 0; | |
727 | gint Line; | |
728 | gint RowStride = GST_VIDEO_FRAME_COMP_STRIDE (outframe, 0); | |
729 | gint FieldHeight = GST_VIDEO_FRAME_HEIGHT (outframe) / 2; | |
721 | GstVideoFrame * outframe, int cur_field_idx, int plane, | |
722 | ScanlineFunction scanline) | |
723 | { | |
724 | guint8 *Dest = GST_VIDEO_FRAME_COMP_DATA (outframe, plane); | |
725 | gint RowStride = GST_VIDEO_FRAME_COMP_STRIDE (outframe, plane); | |
726 | gint FieldHeight = GST_VIDEO_FRAME_COMP_HEIGHT (outframe, plane) / 2; | |
730 | 727 | gint Pitch = RowStride * 2; |
731 | 728 | const guint8 *L1; // ptr to Line1, of 3 |
732 | 729 | const guint8 *L2; // ptr to Line2, the weave line |
733 | 730 | const guint8 *L3; // ptr to Line3 |
734 | 731 | const guint8 *L2P; // ptr to prev Line2 |
735 | guint8 *Dest = GST_VIDEO_FRAME_COMP_DATA (outframe, 0); | |
732 | gint InfoIsOdd; | |
733 | gint Line; | |
734 | ||
735 | L1 = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx].frame, plane); | |
736 | if (history[cur_field_idx].flags & PICTURE_INTERLACED_BOTTOM) | |
737 | L1 += RowStride; | |
738 | ||
739 | L2 = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx + 1].frame, plane); | |
740 | if (history[cur_field_idx + 1].flags & PICTURE_INTERLACED_BOTTOM) | |
741 | L2 += RowStride; | |
742 | ||
743 | L3 = L1 + Pitch; | |
744 | L2P = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - 1].frame, plane); | |
745 | if (history[cur_field_idx - 1].flags & PICTURE_INTERLACED_BOTTOM) | |
746 | L2P += RowStride; | |
747 | ||
748 | // copy first even line no matter what, and the first odd line if we're | |
749 | // processing an EVEN field. (note diff from other deint rtns.) | |
750 | ||
751 | InfoIsOdd = (history[cur_field_idx + 1].flags == PICTURE_INTERLACED_BOTTOM); | |
752 | if (InfoIsOdd) { | |
753 | // copy first even line | |
754 | memcpy (Dest, L1, RowStride); | |
755 | Dest += RowStride; | |
756 | } else { | |
757 | // copy first even line | |
758 | memcpy (Dest, L1, RowStride); | |
759 | Dest += RowStride; | |
760 | // then first odd line | |
761 | memcpy (Dest, L1, RowStride); | |
762 | Dest += RowStride; | |
763 | ||
764 | L2 += Pitch; | |
765 | L2P += Pitch; | |
766 | } | |
767 | ||
768 | for (Line = 0; Line < (FieldHeight - 1); ++Line) { | |
769 | scanline (self, L1, L2, L3, L2P, Dest, RowStride); | |
770 | Dest += RowStride; | |
771 | memcpy (Dest, L3, RowStride); | |
772 | Dest += RowStride; | |
773 | ||
774 | L1 += Pitch; | |
775 | L2 += Pitch; | |
776 | L3 += Pitch; | |
777 | L2P += Pitch; | |
778 | } | |
779 | ||
780 | if (InfoIsOdd) { | |
781 | memcpy (Dest, L2, RowStride); | |
782 | } | |
783 | } | |
784 | ||
785 | static void | |
786 | deinterlace_frame_di_greedyh_packed (GstDeinterlaceMethod * method, | |
787 | const GstDeinterlaceField * history, guint history_count, | |
788 | GstVideoFrame * outframe, int cur_field_idx) | |
789 | { | |
790 | GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (method); | |
791 | GstDeinterlaceMethodGreedyHClass *klass = | |
792 | GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS (self); | |
736 | 793 | ScanlineFunction scanline; |
737 | 794 | |
738 | 795 | if (cur_field_idx + 2 > history_count || cur_field_idx < 1) { |
748 | 805 | g_object_unref (backup_method); |
749 | 806 | return; |
750 | 807 | } |
751 | ||
752 | cur_field_idx += 2; | |
753 | 808 | |
754 | 809 | switch (GST_VIDEO_INFO_FORMAT (method->vinfo)) { |
755 | 810 | case GST_VIDEO_FORMAT_YUY2: |
767 | 822 | return; |
768 | 823 | } |
769 | 824 | |
770 | // copy first even line no matter what, and the first odd line if we're | |
771 | // processing an EVEN field. (note diff from other deint rtns.) | |
772 | ||
773 | if (history[cur_field_idx - 1].flags == PICTURE_INTERLACED_BOTTOM) { | |
774 | InfoIsOdd = 1; | |
775 | ||
776 | L1 = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - 2].frame, 0); | |
777 | if (history[cur_field_idx - 2].flags & PICTURE_INTERLACED_BOTTOM) | |
778 | L1 += RowStride; | |
779 | ||
780 | L2 = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - 1].frame, 0); | |
781 | if (history[cur_field_idx - 1].flags & PICTURE_INTERLACED_BOTTOM) | |
782 | L2 += RowStride; | |
783 | ||
784 | L3 = L1 + Pitch; | |
785 | L2P = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - 3].frame, 0); | |
786 | if (history[cur_field_idx - 3].flags & PICTURE_INTERLACED_BOTTOM) | |
787 | L2P += RowStride; | |
788 | ||
789 | // copy first even line | |
790 | memcpy (Dest, L1, RowStride); | |
791 | Dest += RowStride; | |
792 | } else { | |
793 | InfoIsOdd = 0; | |
794 | L1 = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - 2].frame, 0); | |
795 | if (history[cur_field_idx - 2].flags & PICTURE_INTERLACED_BOTTOM) | |
796 | L1 += RowStride; | |
797 | ||
798 | L2 = (guint8 *) GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - | |
799 | 1].frame, 0) + Pitch; | |
800 | if (history[cur_field_idx - 1].flags & PICTURE_INTERLACED_BOTTOM) | |
801 | L2 += RowStride; | |
802 | ||
803 | L3 = L1 + Pitch; | |
804 | L2P = | |
805 | (guint8 *) GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - 3].frame, | |
806 | 0) + Pitch; | |
807 | if (history[cur_field_idx - 3].flags & PICTURE_INTERLACED_BOTTOM) | |
808 | L2P += RowStride; | |
809 | ||
810 | // copy first even line | |
811 | memcpy (Dest, L1, RowStride); | |
812 | Dest += RowStride; | |
813 | // then first odd line | |
814 | memcpy (Dest, L1, RowStride); | |
815 | Dest += RowStride; | |
816 | } | |
817 | ||
818 | for (Line = 0; Line < (FieldHeight - 1); ++Line) { | |
819 | scanline (self, L1, L2, L3, L2P, Dest, RowStride); | |
820 | Dest += RowStride; | |
821 | memcpy (Dest, L3, RowStride); | |
822 | Dest += RowStride; | |
823 | ||
824 | L1 += Pitch; | |
825 | L2 += Pitch; | |
826 | L3 += Pitch; | |
827 | L2P += Pitch; | |
828 | } | |
829 | ||
830 | if (InfoIsOdd) { | |
831 | memcpy (Dest, L2, RowStride); | |
832 | } | |
833 | } | |
834 | ||
835 | static void | |
836 | deinterlace_frame_di_greedyh_planar_plane (GstDeinterlaceMethodGreedyH * self, | |
837 | const guint8 * L1, const guint8 * L2, const guint8 * L3, const guint8 * L2P, | |
838 | guint8 * Dest, gint RowStride, gint FieldHeight, gint Pitch, gint InfoIsOdd, | |
839 | ScanlineFunction scanline) | |
840 | { | |
841 | gint Line; | |
842 | ||
843 | // copy first even line no matter what, and the first odd line if we're | |
844 | // processing an EVEN field. (note diff from other deint rtns.) | |
845 | ||
846 | if (InfoIsOdd) { | |
847 | // copy first even line | |
848 | memcpy (Dest, L1, RowStride); | |
849 | Dest += RowStride; | |
850 | } else { | |
851 | // copy first even line | |
852 | memcpy (Dest, L1, RowStride); | |
853 | Dest += RowStride; | |
854 | // then first odd line | |
855 | memcpy (Dest, L1, RowStride); | |
856 | Dest += RowStride; | |
857 | } | |
858 | ||
859 | for (Line = 0; Line < (FieldHeight - 1); ++Line) { | |
860 | scanline (self, L1, L2, L3, L2P, Dest, RowStride); | |
861 | Dest += RowStride; | |
862 | memcpy (Dest, L3, RowStride); | |
863 | Dest += RowStride; | |
864 | ||
865 | L1 += Pitch; | |
866 | L2 += Pitch; | |
867 | L3 += Pitch; | |
868 | L2P += Pitch; | |
869 | } | |
870 | ||
871 | if (InfoIsOdd) { | |
872 | memcpy (Dest, L2, RowStride); | |
873 | } | |
825 | deinterlace_frame_di_greedyh_plane (self, history, history_count, outframe, | |
826 | cur_field_idx, 0, scanline); | |
874 | 827 | } |
875 | 828 | |
876 | 829 | static void |
881 | 834 | GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (method); |
882 | 835 | GstDeinterlaceMethodGreedyHClass *klass = |
883 | 836 | GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS (self); |
884 | gint InfoIsOdd; | |
885 | gint RowStride; | |
886 | gint FieldHeight; | |
887 | gint Pitch; | |
888 | const guint8 *L1; // ptr to Line1, of 3 | |
889 | const guint8 *L2; // ptr to Line2, the weave line | |
890 | const guint8 *L3; // ptr to Line3 | |
891 | const guint8 *L2P; // ptr to prev Line2 | |
892 | guint8 *Dest; | |
893 | gint i; | |
894 | ScanlineFunction scanline; | |
895 | 837 | |
896 | 838 | if (cur_field_idx + 2 > history_count || cur_field_idx < 1) { |
897 | 839 | GstDeinterlaceMethod *backup_method; |
907 | 849 | return; |
908 | 850 | } |
909 | 851 | |
910 | cur_field_idx += 2; | |
911 | ||
912 | for (i = 0; i < 3; i++) { | |
913 | InfoIsOdd = (history[cur_field_idx - 1].flags == PICTURE_INTERLACED_BOTTOM); | |
914 | RowStride = GST_VIDEO_FRAME_COMP_STRIDE (outframe, i); | |
915 | FieldHeight = GST_VIDEO_FRAME_COMP_HEIGHT (outframe, i) / 2; | |
916 | Pitch = RowStride * 2; | |
917 | ||
918 | if (i == 0) | |
919 | scanline = klass->scanline_planar_y; | |
920 | else | |
921 | scanline = klass->scanline_planar_uv; | |
922 | ||
923 | Dest = GST_VIDEO_FRAME_COMP_DATA (outframe, i); | |
924 | ||
925 | L1 = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - 2].frame, i); | |
926 | if (history[cur_field_idx - 2].flags & PICTURE_INTERLACED_BOTTOM) | |
927 | L1 += RowStride; | |
928 | ||
929 | L2 = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - 1].frame, i); | |
930 | if (history[cur_field_idx - 1].flags & PICTURE_INTERLACED_BOTTOM) | |
931 | L2 += RowStride; | |
932 | ||
933 | L3 = L1 + Pitch; | |
934 | L2P = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - 3].frame, i); | |
935 | if (history[cur_field_idx - 3].flags & PICTURE_INTERLACED_BOTTOM) | |
936 | L2P += RowStride; | |
937 | ||
938 | deinterlace_frame_di_greedyh_planar_plane (self, L1, L2, L3, L2P, Dest, | |
939 | RowStride, FieldHeight, Pitch, InfoIsOdd, scanline); | |
940 | } | |
852 | deinterlace_frame_di_greedyh_plane (self, history, history_count, outframe, | |
853 | cur_field_idx, 0, klass->scanline_planar_y); | |
854 | deinterlace_frame_di_greedyh_plane (self, history, history_count, outframe, | |
855 | cur_field_idx, 1, klass->scanline_planar_uv); | |
856 | deinterlace_frame_di_greedyh_plane (self, history, history_count, outframe, | |
857 | cur_field_idx, 2, klass->scanline_planar_uv); | |
941 | 858 | } |
942 | 859 | |
943 | 860 | G_DEFINE_TYPE (GstDeinterlaceMethodGreedyH, gst_deinterlace_method_greedy_h, |
76 | 76 | GstDeinterlaceSimpleMethodClass *dism_class = |
77 | 77 | (GstDeinterlaceSimpleMethodClass *) klass; |
78 | 78 | |
79 | dim_class->fields_required = 2; | |
79 | dim_class->fields_required = 1; | |
80 | 80 | dim_class->name = "Double lines"; |
81 | 81 | dim_class->nick = "scalerbob"; |
82 | dim_class->latency = 1; | |
82 | dim_class->latency = 0; | |
83 | 83 | |
84 | 84 | dism_class->interpolate_scanline_ayuv = |
85 | 85 | deinterlace_scanline_scaler_bob_packed; |
58 | 58 | mova m4, m2 |
59 | 59 | ; m5 = t0[x+1+j] |
60 | 60 | mova m5, m2 |
61 | ; m4 = xor(t0[x+1+j], b0[x+1-j] | |
61 | ; m4 = xor(t0[x+1+j], b0[x+1-j]) | |
62 | 62 | pxor m4, m3 |
63 | 63 | pavgb m5, m3 |
64 | 64 | ; round down to 0 |
81 | 81 | pmaxub m2, m3 |
82 | 82 | ; m3 = FFABS(t0[x+1+j] - b0[x+1-j]); |
83 | 83 | mova m3, m2 |
84 | ; m4 = FFABS(FFABS(t0[x+1+j] - b0[x+1-j]); | |
84 | ; m4 = FFABS(t0[x+1+j] - b0[x+1-j]); | |
85 | 85 | mova m4, m2 |
86 | 86 | ; m3 = FFABS(t0[x+j] - b0[x-j]) |
87 | 87 | psrldq m3, 1 |
159 | 159 | psraw m3, 1 |
160 | 160 | ; rsp + 0 = d |
161 | 161 | mova [rsp+ 0], m3 |
162 | ; rsp + 16 = bzeroq | |
163 | mova [rsp+16], m1 | |
162 | 164 | ; m2 = m1 - mp |
163 | 165 | psubw m2, m4 |
164 | 166 | ; m2 = temporal_diff0 (m4 is temporary) |
194 | 196 | psrlw m3, 1 |
195 | 197 | ; m2 = diff (for real) |
196 | 198 | pmaxsw m2, m3 |
197 | ; rsp + 16 = diff | |
198 | mova [rsp+16], m2 | |
199 | ; rsp + 32 = diff | |
200 | mova [rsp+32], m2 | |
199 | 201 | |
200 | 202 | ; m1 = e + c |
201 | 203 | paddw m1, m0 |
250 | 252 | ; now m0 = spatial_score, m1 = spatial_pred |
251 | 253 | |
252 | 254 | ; m6 = diff |
253 | mova m6, [rsp+16] | |
255 | mova m6, [rsp+32] | |
254 | 256 | %endmacro |
255 | 257 | |
256 | 258 | %macro FILTER_TAIL 0 |
310 | 312 | ; m5 = d |
311 | 313 | mova m5, [rsp] |
312 | 314 | ; m7 = e |
313 | LOAD m7, [bzeroq] | |
315 | mova m7, [rsp+16] | |
314 | 316 | ; m2 = b - c |
315 | 317 | psubw m2, m4 |
316 | 318 | ; m3 = f - e |
189 | 189 | #define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) |
190 | 190 | #define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) |
191 | 191 | |
192 | #define CHECK(j1, j2, j3)\ | |
193 | { int score = FFABS(stzero[x - j1] - sbzero[x - j2])\ | |
194 | + FFABS(stzero[x + j3] - sbzero[x - j3])\ | |
195 | + FFABS(stzero[x + j1] - sbzero[x + j2]);\ | |
192 | ||
193 | #define CHECK(j)\ | |
194 | { int score = FFABS(stzero[x - colors2 + j] - sbzero[x - colors2 - j])\ | |
195 | + FFABS(stzero[x + j] - sbzero[x - j])\ | |
196 | + FFABS(stzero[x + colors2 + j] - sbzero[x + colors2 - j]);\ | |
196 | 197 | if (score < spatial_score) {\ |
197 | 198 | spatial_score= score;\ |
198 | spatial_pred= (stzero[x + j3] + sbzero[x - j3])>>1;\ | |
199 | spatial_pred= (stzero[x + j] + sbzero[x - j])>>1;\ | |
199 | 200 | |
200 | 201 | /* The is_not_edge argument here controls when the code will enter a branch |
201 | 202 | * which reads up to and including x-3 and x+3. */ |
218 | 219 | if (is_not_edge) {\ |
219 | 220 | int spatial_score = FFABS(stzero[x-colors2] - sbzero[x-colors2]) + FFABS(c-e) \ |
220 | 221 | + FFABS(stzero[x+colors2] - sbzero[x+colors2]); \ |
221 | int twice_colors2 = colors2 << 1; \ | |
222 | int minus_colors2 = -colors2; \ | |
223 | int thrice_colors2 = colors2 * 3; \ | |
224 | int minus2_colors2 = colors2 * -2; \ | |
225 | CHECK(0, twice_colors2, minus_colors2) \ | |
226 | CHECK(-colors2, thrice_colors2, minus2_colors2) }} }} \ | |
227 | CHECK(twice_colors2, 0, colors2) \ | |
228 | CHECK(thrice_colors2, minus_colors2, twice_colors2) }} }} \ | |
222 | CHECK(-1 * colors2) CHECK(-2 * colors2) }} }} \ | |
223 | CHECK(colors2) CHECK(2 * colors2) }} }} \ | |
229 | 224 | }\ |
230 | 225 | \ |
231 | 226 | if (!(mode&2)) { \ |
5411 | 5411 | } |
5412 | 5412 | sample_error: |
5413 | 5413 | { |
5414 | GST_ELEMENT_ERROR (qtmux, STREAM, MUX, (NULL), ("Failed to push sample.")); | |
5414 | /* Only post an error message for actual errors that are not flushing */ | |
5415 | if (pad->flow_status < GST_FLOW_OK && pad->flow_status != GST_FLOW_FLUSHING) | |
5416 | GST_ELEMENT_ERROR (qtmux, STREAM, MUX, (NULL), | |
5417 | ("Failed to push sample.")); | |
5415 | 5418 | return pad->flow_status; |
5416 | 5419 | } |
5417 | 5420 | } |
6642 | 6642 | } |
6643 | 6643 | *codec_name = g_strdup_printf ("FFMpeg v1"); |
6644 | 6644 | } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) { |
6645 | guint32 fourcc; | |
6645 | guint32 fourcc = 0; | |
6646 | 6646 | const gchar *variant, *variant_descr = ""; |
6647 | 6647 | |
6648 | 6648 | /* Expect a fourcc in the codec private data */ |
6649 | if (!data || size < 4) { | |
6650 | GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size); | |
6651 | return NULL; | |
6652 | } | |
6653 | ||
6654 | fourcc = GST_STR_FOURCC (data); | |
6649 | if (data && size >= 4) { | |
6650 | fourcc = GST_STR_FOURCC (data); | |
6651 | } else { | |
6652 | GST_WARNING ("No ProRes codec data found, picking 'standard 422 SD'"); | |
6653 | } | |
6654 | ||
6655 | 6655 | switch (fourcc) { |
6656 | 6656 | case GST_MAKE_FOURCC ('a', 'p', 'c', 's'): |
6657 | 6657 | variant_descr = " 4:2:2 LT"; |
1007 | 1007 | return FALSE; |
1008 | 1008 | else if (field_id == g_quark_from_static_string ("bit-depth-luma")) |
1009 | 1009 | return FALSE; |
1010 | ||
1011 | /* Remove pixel-aspect-ratio field if it contains 1/1 as that's considered | |
1012 | * equivalent to not having the field but are not considered equivalent | |
1013 | * by the generic caps functions | |
1014 | */ | |
1015 | if (field_id == g_quark_from_static_string ("pixel-aspect-ratio")) { | |
1016 | gint par_n = gst_value_get_fraction_numerator (value); | |
1017 | gint par_d = gst_value_get_fraction_denominator (value); | |
1018 | ||
1019 | if (par_n == 1 && par_d == 1) | |
1020 | return FALSE; | |
1021 | } | |
1022 | ||
1023 | /* Remove multiview-mode=mono and multiview-flags=0 fields as those are | |
1024 | * equivalent with not having the fields but are not considered equivalent | |
1025 | * by the generic caps functions. | |
1026 | */ | |
1027 | if (field_id == g_quark_from_static_string ("multiview-mode")) { | |
1028 | const gchar *s = g_value_get_string (value); | |
1029 | ||
1030 | if (g_strcmp0 (s, "mono") == 0) | |
1031 | return FALSE; | |
1032 | } | |
1033 | ||
1034 | if (field_id == g_quark_from_static_string ("multiview-flags")) { | |
1035 | guint multiview_flags = gst_value_get_flagset_flags (value); | |
1036 | ||
1037 | if (multiview_flags == 0) | |
1038 | return FALSE; | |
1039 | } | |
1010 | 1040 | } |
1011 | 1041 | |
1012 | 1042 | return TRUE; |
1013 | 1043 | } |
1014 | 1044 | |
1015 | 1045 | static gboolean |
1016 | check_new_caps (GstCaps * old_caps, GstCaps * new_caps) | |
1046 | check_new_caps (GstMatroskaTrackVideoContext * videocontext, GstCaps * old_caps, | |
1047 | GstCaps * new_caps) | |
1017 | 1048 | { |
1018 | 1049 | GstStructure *old_s, *new_s; |
1019 | 1050 | gboolean ret; |
1065 | 1096 | |
1066 | 1097 | mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad)); |
1067 | 1098 | |
1068 | if ((old_caps = gst_pad_get_current_caps (pad))) { | |
1069 | if (mux->state >= GST_MATROSKA_MUX_STATE_HEADER | |
1070 | && !check_new_caps (old_caps, caps)) { | |
1071 | GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL), | |
1072 | ("Caps changes are not supported by Matroska\nCurrent: `%" | |
1073 | GST_PTR_FORMAT "`\nNew: `%" GST_PTR_FORMAT "`", old_caps, caps)); | |
1074 | gst_caps_unref (old_caps); | |
1075 | goto refuse_caps; | |
1076 | } | |
1077 | gst_caps_unref (old_caps); | |
1078 | } else if (mux->state >= GST_MATROSKA_MUX_STATE_HEADER) { | |
1079 | GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL), | |
1080 | ("Caps on pad %" GST_PTR_FORMAT | |
1081 | " arrived late. Headers were already written", pad)); | |
1082 | goto refuse_caps; | |
1083 | } | |
1084 | ||
1085 | 1099 | /* find context */ |
1086 | 1100 | collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad); |
1087 | 1101 | g_assert (collect_pad); |
1089 | 1103 | g_assert (context); |
1090 | 1104 | g_assert (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO); |
1091 | 1105 | videocontext = (GstMatroskaTrackVideoContext *) context; |
1106 | ||
1107 | if ((old_caps = gst_pad_get_current_caps (pad))) { | |
1108 | if (mux->state >= GST_MATROSKA_MUX_STATE_HEADER | |
1109 | && !check_new_caps (videocontext, old_caps, caps)) { | |
1110 | GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL), | |
1111 | ("Caps changes are not supported by Matroska\nCurrent: `%" | |
1112 | GST_PTR_FORMAT "`\nNew: `%" GST_PTR_FORMAT "`", old_caps, caps)); | |
1113 | gst_caps_unref (old_caps); | |
1114 | goto refuse_caps; | |
1115 | } | |
1116 | gst_caps_unref (old_caps); | |
1117 | } else if (mux->state >= GST_MATROSKA_MUX_STATE_HEADER) { | |
1118 | GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL), | |
1119 | ("Caps on pad %" GST_PTR_FORMAT | |
1120 | " arrived late. Headers were already written", pad)); | |
1121 | goto refuse_caps; | |
1122 | } | |
1092 | 1123 | |
1093 | 1124 | /* gst -> matroska ID'ing */ |
1094 | 1125 | structure = gst_caps_get_structure (caps, 0); |
47 | 47 | #include "gstrtpldacpay.h" |
48 | 48 | #include "gstrtputils.h" |
49 | 49 | |
50 | #define GST_RTP_HEADER_LENGTH 12 | |
50 | #define GST_RTP_LDAC_PAYLOAD_HEADER_SIZE 1 | |
51 | 51 | /* MTU size required for LDAC A2DP streaming */ |
52 | 52 | #define GST_LDAC_MTU_REQUIRED 679 |
53 | 53 | |
63 | 63 | GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, |
64 | 64 | GST_STATIC_CAPS ("audio/x-ldac, " |
65 | 65 | "channels = (int) [ 1, 2 ], " |
66 | "eqmid = (int) { 0, 1, 2 }, " | |
66 | 67 | "rate = (int) { 44100, 48000, 88200, 96000 }") |
67 | 68 | ); |
68 | 69 | |
80 | 81 | static GstFlowReturn gst_rtp_ldac_pay_handle_buffer (GstRTPBasePayload * |
81 | 82 | payload, GstBuffer * buffer); |
82 | 83 | |
84 | /** | |
85 | * gst_rtp_ldac_pay_get_num_frames | |
86 | * @eqmid: Encode Quality Mode Index | |
87 | * @channels: Number of channels | |
88 | * | |
89 | * Returns: Number of LDAC frames per packet. | |
90 | */ | |
91 | static guint8 | |
92 | gst_rtp_ldac_pay_get_num_frames (gint eqmid, gint channels) | |
93 | { | |
94 | g_assert (channels == 1 || channels == 2); | |
95 | ||
96 | switch (eqmid) { | |
97 | /* Encode setting for High Quality */ | |
98 | case 0: | |
99 | return 4 / channels; | |
100 | /* Encode setting for Standard Quality */ | |
101 | case 1: | |
102 | return 6 / channels; | |
103 | /* Encode setting for Mobile use Quality */ | |
104 | case 2: | |
105 | return 12 / channels; | |
106 | default: | |
107 | break; | |
108 | } | |
109 | ||
110 | g_assert_not_reached (); | |
111 | ||
112 | /* If assertion gets compiled out */ | |
113 | return 6 / channels; | |
114 | } | |
115 | ||
83 | 116 | static void |
84 | 117 | gst_rtp_ldac_pay_class_init (GstRtpLdacPayClass * klass) |
85 | 118 | { |
114 | 147 | { |
115 | 148 | GstRtpLdacPay *ldacpay = GST_RTP_LDAC_PAY (payload); |
116 | 149 | GstStructure *structure; |
117 | gint rate; | |
150 | gint channels, eqmid, rate; | |
118 | 151 | |
119 | 152 | if (GST_RTP_BASE_PAYLOAD_MTU (ldacpay) < GST_LDAC_MTU_REQUIRED) { |
120 | 153 | GST_ERROR_OBJECT (ldacpay, "Invalid MTU %d, should be >= %d", |
127 | 160 | GST_ERROR_OBJECT (ldacpay, "Failed to get audio rate from caps"); |
128 | 161 | return FALSE; |
129 | 162 | } |
163 | ||
164 | if (!gst_structure_get_int (structure, "channels", &channels)) { | |
165 | GST_ERROR_OBJECT (ldacpay, "Failed to get audio rate from caps"); | |
166 | return FALSE; | |
167 | } | |
168 | ||
169 | if (!gst_structure_get_int (structure, "eqmid", &eqmid)) { | |
170 | GST_ERROR_OBJECT (ldacpay, "Failed to get eqmid from caps"); | |
171 | return FALSE; | |
172 | } | |
173 | ||
174 | ldacpay->frame_count = gst_rtp_ldac_pay_get_num_frames (eqmid, channels); | |
130 | 175 | |
131 | 176 | gst_rtp_base_payload_set_options (payload, "audio", TRUE, "X-GST-LDAC", rate); |
132 | 177 | |
144 | 189 | static GstFlowReturn |
145 | 190 | gst_rtp_ldac_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer) |
146 | 191 | { |
192 | GstRTPBuffer rtp = GST_RTP_BUFFER_INIT; | |
147 | 193 | GstRtpLdacPay *ldacpay = GST_RTP_LDAC_PAY (payload); |
148 | 194 | GstBuffer *outbuf; |
149 | 195 | GstClockTime outbuf_frame_duration, outbuf_pts; |
196 | guint8 *payload_data; | |
150 | 197 | gsize buf_sz; |
151 | 198 | |
152 | 199 | outbuf = |
153 | 200 | gst_rtp_base_payload_allocate_output_buffer (GST_RTP_BASE_PAYLOAD |
154 | (ldacpay), GST_RTP_HEADER_LENGTH, 0, 0); | |
201 | (ldacpay), GST_RTP_LDAC_PAYLOAD_HEADER_SIZE, 0, 0); | |
202 | ||
203 | /* Get payload */ | |
204 | gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp); | |
205 | ||
206 | /* Write header and copy data into payload */ | |
207 | payload_data = gst_rtp_buffer_get_payload (&rtp); | |
208 | /* Upper 3 fragment bits not used, ref A2DP v13, 4.3.4 */ | |
209 | payload_data[0] = ldacpay->frame_count & 0x0f; | |
210 | ||
211 | gst_rtp_buffer_unmap (&rtp); | |
155 | 212 | |
156 | 213 | outbuf_pts = GST_BUFFER_PTS (buffer); |
157 | 214 | outbuf_frame_duration = GST_BUFFER_DURATION (buffer); |
41 | 41 | |
42 | 42 | struct _GstRtpLdacPay { |
43 | 43 | GstRTPBasePayload base; |
44 | guint8 frame_count; | |
44 | 45 | }; |
45 | 46 | |
46 | 47 | struct _GstRtpLdacPayClass { |
131 | 131 | ((GstRtpUlpFecEncStreamCtx *)ctx)->info_arr, \ |
132 | 132 | RtpUlpFecMapInfo, \ |
133 | 133 | GPOINTER_TO_UINT(data))) |
134 | ||
135 | static void | |
136 | dump_stream_ctx_settings (GstRtpUlpFecEncStreamCtx * ctx) | |
137 | { | |
138 | GST_DEBUG_OBJECT (ctx->parent, "rtpulpfec settings for ssrc 0x%x, pt %u, " | |
139 | "percentage %u, percentage important %u, multipacket %u, mux_seq %u", | |
140 | ctx->ssrc, ctx->pt, ctx->percentage, ctx->percentage_important, | |
141 | ctx->multipacket, ctx->mux_seq); | |
142 | }; | |
134 | 143 | |
135 | 144 | static void |
136 | 145 | gst_rtp_ulpfec_enc_stream_ctx_start (GstRtpUlpFecEncStreamCtx * ctx, |
337 | 346 | guint fec_packets_num = |
338 | 347 | gst_rtp_ulpfec_enc_stream_ctx_get_fec_packets_num (ctx); |
339 | 348 | |
349 | GST_LOG_OBJECT (ctx->parent, "ctx %p have %u fec packets to push", ctx, | |
350 | fec_packets_num); | |
340 | 351 | if (fec_packets_num) { |
341 | 352 | guint fec_packets_pushed = 0; |
342 | 353 | GstBuffer *latest_packet = ctx->packets_buf.head->data; |
376 | 387 | gst_rtp_buffer_unmap (&rtp); |
377 | 388 | } |
378 | 389 | |
390 | GST_LOG_OBJECT (ctx->parent, "ctx %p pushing generated fec buffer %" | |
391 | GST_PTR_FORMAT, ctx, fec); | |
379 | 392 | ret = gst_pad_push (ctx->srcpad, fec); |
380 | 393 | if (GST_FLOW_OK == ret) |
381 | 394 | ++fec_packets_pushed; |
409 | 422 | |
410 | 423 | *dst_empty_packet_buffer = gst_rtp_buffer_get_marker (rtp); |
411 | 424 | *dst_push_fec = *dst_empty_packet_buffer; |
425 | ||
426 | GST_TRACE ("ctx %p pushing fec %u", ctx, *dst_push_fec); | |
412 | 427 | } else { |
413 | 428 | gboolean push_fec; |
414 | 429 | |
422 | 437 | |
423 | 438 | *dst_push_fec = push_fec; |
424 | 439 | *dst_empty_packet_buffer = FALSE; |
440 | ||
441 | GST_TRACE ("ctx %p pushing fec %u", ctx, *dst_push_fec); | |
425 | 442 | } |
426 | 443 | } |
427 | 444 | |
448 | 465 | */ |
449 | 466 | ctx->budget_inc_important = percentage > percentage_important ? |
450 | 467 | ctx->budget_inc : percentage_important / 100.; |
468 | ||
469 | dump_stream_ctx_settings (ctx); | |
451 | 470 | } |
452 | 471 | |
453 | 472 | static GstRtpUlpFecEncStreamCtx * |
488 | 507 | g_assert (0 == ctx->info_arr->len); |
489 | 508 | g_array_free (ctx->info_arr, TRUE); |
490 | 509 | g_array_free (ctx->scratch_buf, TRUE); |
491 | g_slice_free1 (sizeof (GstRtpUlpFecEncStreamCtx), ctx); | |
510 | g_free (ctx); | |
492 | 511 | } |
493 | 512 | |
494 | 513 | static GstFlowReturn |
733 | 752 | { |
734 | 753 | GstRtpUlpFecEnc *fec = GST_RTP_ULPFEC_ENC (obj); |
735 | 754 | |
736 | g_hash_table_destroy (fec->ssrc_to_ctx); | |
755 | if (fec->ssrc_to_ctx) | |
756 | g_hash_table_destroy (fec->ssrc_to_ctx); | |
757 | fec->ssrc_to_ctx = NULL; | |
737 | 758 | |
738 | 759 | G_OBJECT_CLASS (gst_rtp_ulpfec_enc_parent_class)->dispose (obj); |
739 | 760 | } |
230 | 230 | event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, |
231 | 231 | gst_structure_new ("GstRTPPacketLost", |
232 | 232 | "timestamp", G_TYPE_UINT64, timestamp, |
233 | "duration", G_TYPE_UINT64, 0, NULL)); | |
233 | "duration", G_TYPE_UINT64, G_GUINT64_CONSTANT (0), NULL)); | |
234 | 234 | |
235 | 235 | GST_DEBUG_OBJECT (self, "Pushing lost event " |
236 | 236 | "(picids 0x%x 0x%x, reason \"%s\"): %" GST_PTR_FORMAT, |
257 | 257 | static void |
258 | 258 | gst_rtp_rtx_receive_finalize (GObject * object) |
259 | 259 | { |
260 | GstRtpRtxReceive *rtx = GST_RTP_RTX_RECEIVE (object); | |
260 | GstRtpRtxReceive *rtx = GST_RTP_RTX_RECEIVE_CAST (object); | |
261 | 261 | |
262 | 262 | g_hash_table_unref (rtx->ssrc2_ssrc1_map); |
263 | 263 | g_hash_table_unref (rtx->seqnum_ssrc1_map); |
325 | 325 | gst_rtp_rtx_receive_src_event (GstPad * pad, GstObject * parent, |
326 | 326 | GstEvent * event) |
327 | 327 | { |
328 | GstRtpRtxReceive *rtx = GST_RTP_RTX_RECEIVE (parent); | |
328 | GstRtpRtxReceive *rtx = GST_RTP_RTX_RECEIVE_CAST (parent); | |
329 | 329 | gboolean res; |
330 | 330 | |
331 | 331 | switch (GST_EVENT_TYPE (event)) { |
514 | 514 | static GstFlowReturn |
515 | 515 | gst_rtp_rtx_receive_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) |
516 | 516 | { |
517 | GstRtpRtxReceive *rtx = GST_RTP_RTX_RECEIVE (parent); | |
517 | GstRtpRtxReceive *rtx = GST_RTP_RTX_RECEIVE_CAST (parent); | |
518 | 518 | GstRTPBuffer rtp = GST_RTP_BUFFER_INIT; |
519 | 519 | GstFlowReturn ret = GST_FLOW_OK; |
520 | 520 | GstBuffer *new_buffer = NULL; |
691 | 691 | gst_rtp_rtx_receive_get_property (GObject * object, |
692 | 692 | guint prop_id, GValue * value, GParamSpec * pspec) |
693 | 693 | { |
694 | GstRtpRtxReceive *rtx = GST_RTP_RTX_RECEIVE (object); | |
694 | GstRtpRtxReceive *rtx = GST_RTP_RTX_RECEIVE_CAST (object); | |
695 | 695 | |
696 | 696 | switch (prop_id) { |
697 | 697 | case PROP_PAYLOAD_TYPE_MAP: |
741 | 741 | gst_rtp_rtx_receive_set_property (GObject * object, |
742 | 742 | guint prop_id, const GValue * value, GParamSpec * pspec) |
743 | 743 | { |
744 | GstRtpRtxReceive *rtx = GST_RTP_RTX_RECEIVE (object); | |
744 | GstRtpRtxReceive *rtx = GST_RTP_RTX_RECEIVE_CAST (object); | |
745 | 745 | |
746 | 746 | switch (prop_id) { |
747 | 747 | case PROP_PAYLOAD_TYPE_MAP: |
767 | 767 | GstStateChangeReturn ret; |
768 | 768 | GstRtpRtxReceive *rtx; |
769 | 769 | |
770 | rtx = GST_RTP_RTX_RECEIVE (element); | |
770 | rtx = GST_RTP_RTX_RECEIVE_CAST (element); | |
771 | 771 | |
772 | 772 | switch (transition) { |
773 | 773 | default: |
27 | 27 | #include <gst/rtp/gstrtpbuffer.h> |
28 | 28 | |
29 | 29 | G_BEGIN_DECLS |
30 | typedef struct _GstRtpRtxReceive GstRtpRtxReceive; | |
31 | typedef struct _GstRtpRtxReceiveClass GstRtpRtxReceiveClass; | |
32 | ||
30 | 33 | #define GST_TYPE_RTP_RTX_RECEIVE (gst_rtp_rtx_receive_get_type()) |
31 | 34 | #define GST_RTP_RTX_RECEIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_RTX_RECEIVE, GstRtpRtxReceive)) |
32 | 35 | #define GST_RTP_RTX_RECEIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_RTX_RECEIVE, GstRtpRtxReceiveClass)) |
33 | 36 | #define GST_RTP_RTX_RECEIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTP_RTX_RECEIVE, GstRtpRtxReceiveClass)) |
34 | 37 | #define GST_IS_RTP_RTX_RECEIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_RTX_RECEIVE)) |
35 | 38 | #define GST_IS_RTP_RTX_RECEIVE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_RTX_RECEIVE)) |
36 | typedef struct _GstRtpRtxReceive GstRtpRtxReceive; | |
37 | typedef struct _GstRtpRtxReceiveClass GstRtpRtxReceiveClass; | |
39 | #define GST_RTP_RTX_RECEIVE_CAST(obj) ((GstRtpRtxReceive *)(obj)) | |
38 | 40 | |
39 | 41 | struct _GstRtpRtxReceive |
40 | 42 | { |
228 | 228 | static void |
229 | 229 | gst_rtp_rtx_send_finalize (GObject * object) |
230 | 230 | { |
231 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND (object); | |
231 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND_CAST (object); | |
232 | 232 | |
233 | 233 | g_hash_table_unref (rtx->ssrc_data); |
234 | 234 | g_hash_table_unref (rtx->rtx_ssrcs); |
463 | 463 | static gboolean |
464 | 464 | gst_rtp_rtx_send_src_event (GstPad * pad, GstObject * parent, GstEvent * event) |
465 | 465 | { |
466 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND (parent); | |
466 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND_CAST (parent); | |
467 | 467 | gboolean res; |
468 | 468 | |
469 | 469 | switch (GST_EVENT_TYPE (event)) { |
603 | 603 | static gboolean |
604 | 604 | gst_rtp_rtx_send_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) |
605 | 605 | { |
606 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND (parent); | |
606 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND_CAST (parent); | |
607 | 607 | |
608 | 608 | switch (GST_EVENT_TYPE (event)) { |
609 | 609 | case GST_EVENT_FLUSH_START: |
767 | 767 | static GstFlowReturn |
768 | 768 | gst_rtp_rtx_send_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) |
769 | 769 | { |
770 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND (parent); | |
770 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND_CAST (parent); | |
771 | 771 | GstFlowReturn ret; |
772 | 772 | |
773 | 773 | GST_OBJECT_LOCK (rtx); |
789 | 789 | gst_rtp_rtx_send_chain_list (GstPad * pad, GstObject * parent, |
790 | 790 | GstBufferList * list) |
791 | 791 | { |
792 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND (parent); | |
792 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND_CAST (parent); | |
793 | 793 | GstFlowReturn ret; |
794 | 794 | |
795 | 795 | GST_OBJECT_LOCK (rtx); |
840 | 840 | gst_rtp_rtx_send_activate_mode (GstPad * pad, GstObject * parent, |
841 | 841 | GstPadMode mode, gboolean active) |
842 | 842 | { |
843 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND (parent); | |
843 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND_CAST (parent); | |
844 | 844 | gboolean ret = FALSE; |
845 | 845 | |
846 | 846 | switch (mode) { |
865 | 865 | gst_rtp_rtx_send_get_property (GObject * object, |
866 | 866 | guint prop_id, GValue * value, GParamSpec * pspec) |
867 | 867 | { |
868 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND (object); | |
868 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND_CAST (object); | |
869 | 869 | |
870 | 870 | switch (prop_id) { |
871 | 871 | case PROP_PAYLOAD_TYPE_MAP: |
924 | 924 | gst_rtp_rtx_send_set_property (GObject * object, |
925 | 925 | guint prop_id, const GValue * value, GParamSpec * pspec) |
926 | 926 | { |
927 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND (object); | |
927 | GstRtpRtxSend *rtx = GST_RTP_RTX_SEND_CAST (object); | |
928 | 928 | |
929 | 929 | switch (prop_id) { |
930 | 930 | case PROP_SSRC_MAP: |
976 | 976 | GstStateChangeReturn ret; |
977 | 977 | GstRtpRtxSend *rtx; |
978 | 978 | |
979 | rtx = GST_RTP_RTX_SEND (element); | |
979 | rtx = GST_RTP_RTX_SEND_CAST (element); | |
980 | 980 | |
981 | 981 | switch (transition) { |
982 | 982 | default: |
28 | 28 | #include <gst/base/gstdataqueue.h> |
29 | 29 | |
30 | 30 | G_BEGIN_DECLS |
31 | ||
32 | typedef struct _GstRtpRtxSend GstRtpRtxSend; | |
33 | typedef struct _GstRtpRtxSendClass GstRtpRtxSendClass; | |
34 | ||
31 | 35 | #define GST_TYPE_RTP_RTX_SEND (gst_rtp_rtx_send_get_type()) |
32 | 36 | #define GST_RTP_RTX_SEND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_RTX_SEND, GstRtpRtxSend)) |
33 | 37 | #define GST_RTP_RTX_SEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_RTX_SEND, GstRtpRtxSendClass)) |
34 | 38 | #define GST_RTP_RTX_SEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTP_RTX_SEND, GstRtpRtxSendClass)) |
35 | 39 | #define GST_IS_RTP_RTX_SEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_RTX_SEND)) |
36 | 40 | #define GST_IS_RTP_RTX_SEND_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_RTX_SEND)) |
37 | typedef struct _GstRtpRtxSend GstRtpRtxSend; | |
38 | typedef struct _GstRtpRtxSendClass GstRtpRtxSendClass; | |
41 | #define GST_RTP_RTX_SEND_CAST(obj) ((GstRtpRtxSend *)(obj)) | |
39 | 42 | |
40 | 43 | struct _GstRtpRtxSend |
41 | 44 | { |
2032 | 2032 | } |
2033 | 2033 | |
2034 | 2034 | /** |
2035 | * rtp_source_get_nacks: | |
2035 | * rtp_source_get_nack_deadlines: | |
2036 | 2036 | * @src: The #RTPSource |
2037 | 2037 | * @n_nacks: result number of nacks |
2038 | 2038 | * |
33 | 33 | |
34 | 34 | <release> |
35 | 35 | <Version> |
36 | <revision>1.20.1</revision> | |
37 | <branch>1.20</branch> | |
38 | <name></name> | |
39 | <created>2022-03-14</created> | |
40 | <file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-1.20.1.tar.xz" /> | |
41 | </Version> | |
42 | </release> | |
43 | ||
44 | <release> | |
45 | <Version> | |
36 | 46 | <revision>1.20.0</revision> |
37 | 47 | <branch>main</branch> |
38 | 48 | <name></name> |
0 | 0 | project('gst-plugins-good', 'c', |
1 | version : '1.20.0', | |
1 | version : '1.20.1', | |
2 | 2 | meson_version : '>= 0.59', |
3 | 3 | default_options : [ 'warning_level=1', |
4 | 4 | 'buildtype=debugoptimized' ]) |
7 | 7 | msgstr "" |
8 | 8 | "Project-Id-Version: gst-plugins-good-1.0\n" |
9 | 9 | "Report-Msgid-Bugs-To: \n" |
10 | "POT-Creation-Date: 2022-02-03 19:54+0000\n" | |
10 | "POT-Creation-Date: 2022-03-14 11:37+0000\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" |
20 | 20 | msgid "Jack server not found" |
21 | 21 | msgstr "" |
22 | 22 | |
23 | #: ext/jpeg/gstjpegdec.c:974 ext/jpeg/gstjpegdec.c:1239 | |
24 | #: ext/jpeg/gstjpegdec.c:1248 ext/jpeg/gstjpegdec.c:1258 | |
25 | #: ext/jpeg/gstjpegdec.c:1267 ext/jpeg/gstjpegdec.c:1551 | |
26 | #: ext/jpeg/gstjpegdec.c:1579 | |
23 | #: ext/jpeg/gstjpegdec.c:974 ext/jpeg/gstjpegdec.c:1246 | |
24 | #: ext/jpeg/gstjpegdec.c:1255 ext/jpeg/gstjpegdec.c:1265 | |
25 | #: ext/jpeg/gstjpegdec.c:1274 ext/jpeg/gstjpegdec.c:1558 | |
26 | #: ext/jpeg/gstjpegdec.c:1586 | |
27 | 27 | msgid "Failed to decode JPEG image" |
28 | 28 | msgstr "" |
29 | 29 | |
30 | #: ext/jpeg/gstjpegdec.c:1539 | |
30 | #: ext/jpeg/gstjpegdec.c:1546 | |
31 | 31 | msgid "Failed to read memory" |
32 | 32 | msgstr "" |
33 | 33 |
149 | 149 | |
150 | 150 | status = AudioObjectGetPropertyDataSize (device_id, |
151 | 151 | &streamsAddress, 0, NULL, &propertySize); |
152 | ||
152 | 153 | if (status != noErr) { |
154 | GST_WARNING ("failed getting device property: %d", (int) status); | |
153 | 155 | return FALSE; |
154 | 156 | } |
155 | 157 | if (propertySize == 0) { |
158 | GST_DEBUG ("property size was 0; device has no output channels"); | |
159 | return FALSE; | |
160 | } | |
161 | ||
162 | return TRUE; | |
163 | } | |
164 | ||
165 | static inline gboolean | |
166 | _audio_device_has_input (AudioDeviceID device_id) | |
167 | { | |
168 | OSStatus status = noErr; | |
169 | UInt32 propertySize; | |
170 | ||
171 | AudioObjectPropertyAddress streamsAddress = { | |
172 | kAudioDevicePropertyStreams, | |
173 | kAudioDevicePropertyScopeInput, | |
174 | kAudioObjectPropertyElementMaster | |
175 | }; | |
176 | ||
177 | status = AudioObjectGetPropertyDataSize (device_id, | |
178 | &streamsAddress, 0, NULL, &propertySize); | |
179 | ||
180 | if (status != noErr) { | |
181 | GST_WARNING ("failed getting device property: %d", (int) status); | |
182 | return FALSE; | |
183 | } | |
184 | if (propertySize == 0) { | |
185 | GST_DEBUG ("property size was 0; device has no input channels"); | |
156 | 186 | return FALSE; |
157 | 187 | } |
158 | 188 | |
196 | 226 | return devices; |
197 | 227 | } |
198 | 228 | |
199 | static GList * | |
200 | gst_osx_audio_device_provider_probe (GstDeviceProvider * provider) | |
201 | { | |
202 | GstOsxAudioDeviceProvider *self = GST_OSX_AUDIO_DEVICE_PROVIDER (provider); | |
203 | GList *devices = NULL; | |
229 | static void | |
230 | gst_osx_audio_device_provider_probe_internal (GstOsxAudioDeviceProvider * self, | |
231 | gboolean is_src, AudioDeviceID * osx_devices, gint ndevices, | |
232 | GList ** devices) | |
233 | { | |
234 | ||
235 | gint i = 0; | |
236 | GstOsxAudioDeviceType type = GST_OSX_AUDIO_DEVICE_TYPE_INVALID; | |
204 | 237 | GstOsxAudioDevice *device = NULL; |
205 | AudioDeviceID *osx_devices = NULL; | |
206 | gint i, ndevices = 0; | |
207 | ||
208 | osx_devices = _audio_system_get_devices (&ndevices); | |
209 | ||
210 | if (ndevices < 1) { | |
211 | GST_WARNING ("no audio output devices found"); | |
212 | goto done; | |
213 | } | |
214 | ||
215 | GST_INFO ("found %d audio device(s)", ndevices); | |
238 | ||
239 | if (is_src) { | |
240 | type = GST_OSX_AUDIO_DEVICE_TYPE_SOURCE; | |
241 | } else { | |
242 | type = GST_OSX_AUDIO_DEVICE_TYPE_SINK; | |
243 | } | |
216 | 244 | |
217 | 245 | for (i = 0; i < ndevices; i++) { |
218 | 246 | gchar *device_name; |
219 | GstOsxAudioDeviceType type = GST_OSX_AUDIO_DEVICE_TYPE_INVALID; | |
220 | 247 | |
221 | 248 | if ((device_name = _audio_device_get_name (osx_devices[i], FALSE))) { |
222 | if (!_audio_device_has_output (osx_devices[i])) { | |
223 | GST_DEBUG ("Input Device ID: %u Name: %s", | |
224 | (unsigned) osx_devices[i], device_name); | |
225 | type = GST_OSX_AUDIO_DEVICE_TYPE_SOURCE; | |
226 | ||
227 | } else { | |
228 | GST_DEBUG ("Output Device ID: %u Name: %s", | |
229 | (unsigned) osx_devices[i], device_name); | |
230 | type = GST_OSX_AUDIO_DEVICE_TYPE_SINK; | |
249 | gboolean has_output = _audio_device_has_output (osx_devices[i]); | |
250 | gboolean has_input = _audio_device_has_input (osx_devices[i]); | |
251 | ||
252 | if (is_src && !has_input) { | |
253 | goto cleanup; | |
254 | } else if (!is_src && !has_output) { | |
255 | goto cleanup; | |
231 | 256 | } |
232 | 257 | |
233 | 258 | device = |
234 | 259 | gst_osx_audio_device_provider_probe_device (self, osx_devices[i], |
235 | 260 | device_name, type); |
236 | 261 | if (device) { |
262 | if (is_src) { | |
263 | GST_DEBUG ("Input Device ID: %u Name: %s", | |
264 | (unsigned) osx_devices[i], device_name); | |
265 | } else { | |
266 | GST_DEBUG ("Output Device ID: %u Name: %s", | |
267 | (unsigned) osx_devices[i], device_name); | |
268 | } | |
237 | 269 | gst_object_ref_sink (device); |
238 | devices = g_list_prepend (devices, device); | |
270 | *devices = g_list_prepend (*devices, device); | |
239 | 271 | } |
240 | 272 | |
273 | cleanup: | |
241 | 274 | g_free (device_name); |
242 | 275 | } |
243 | 276 | } |
277 | } | |
278 | ||
279 | static GList * | |
280 | gst_osx_audio_device_provider_probe (GstDeviceProvider * provider) | |
281 | { | |
282 | GstOsxAudioDeviceProvider *self = GST_OSX_AUDIO_DEVICE_PROVIDER (provider); | |
283 | GList *devices = NULL; | |
284 | AudioDeviceID *osx_devices = NULL; | |
285 | gint ndevices = 0; | |
286 | ||
287 | osx_devices = _audio_system_get_devices (&ndevices); | |
288 | ||
289 | if (ndevices < 1) { | |
290 | GST_WARNING ("no audio output devices found"); | |
291 | goto done; | |
292 | } | |
293 | ||
294 | GST_INFO ("found %d audio device(s)", ndevices); | |
295 | ||
296 | gst_osx_audio_device_provider_probe_internal (self, TRUE, osx_devices, | |
297 | ndevices, &devices); | |
298 | gst_osx_audio_device_provider_probe_internal (self, FALSE, osx_devices, | |
299 | ndevices, &devices); | |
244 | 300 | |
245 | 301 | done: |
246 | 302 | g_free (osx_devices); |
39 | 39 | # endif |
40 | 40 | #endif |
41 | 41 | |
42 | #if defined(__sun) | |
43 | /* for _IOR/_IORW on Illumos distros */ | |
44 | #include <sys/ioccom.h> | |
45 | #endif | |
46 | ||
42 | 47 | #ifndef __bitwise |
43 | 48 | # ifdef __CHECK_ENDIAN__ |
44 | 49 | # define __bitwise __bitwise__ |
743 | 743 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
744 | 744 | gint old_buffer_state = |
745 | 745 | g_atomic_int_and (&pool->buffer_state[i], ~BUFFER_STATE_QUEUED); |
746 | if (old_buffer_state & BUFFER_STATE_QUEUED) { | |
746 | if ((old_buffer_state & BUFFER_STATE_QUEUED) && pool->buffers[i]) { | |
747 | 747 | GstBuffer *buffer = pool->buffers[i]; |
748 | 748 | GstBufferPool *bpool = GST_BUFFER_POOL (pool); |
749 | 749 |
180 | 180 | /* assert that we're opened and that we're using a known item */ |
181 | 181 | g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), NULL); |
182 | 182 | |
183 | gst_v4l2_get_norm (v4l2object, &norm); | |
183 | if (!gst_v4l2_get_norm (v4l2object, &norm)) | |
184 | return NULL; | |
184 | 185 | |
185 | 186 | return gst_v4l2_tuner_get_norm_by_std_id (v4l2object, norm); |
186 | 187 | } |
137 | 137 | GstBuffer *inbufs[5]; |
138 | 138 | GstHarness *hrecv = gst_harness_new ("rtprtxreceive"); |
139 | 139 | GstHarness *hsend = gst_harness_new ("rtprtxsend"); |
140 | gint i; | |
140 | guint i; | |
141 | 141 | |
142 | 142 | pt_map = gst_structure_new ("application/x-rtp-pt-map", |
143 | 143 | "96", G_TYPE_UINT, rtx_pt, NULL); |
154 | 154 | "encoding-name = (string)RAW"); |
155 | 155 | |
156 | 156 | /* Push 'packets_num' packets through rtxsend to rtxreceive */ |
157 | for (i = 0; i < packets_num; ++i) { | |
157 | for (i = 0; i < packets_num; i++) { | |
158 | 158 | inbufs[i] = create_rtp_buffer (master_ssrc, master_pt, 100 + i); |
159 | 159 | gst_harness_push (hsend, gst_buffer_ref (inbufs[i])); |
160 | 160 | gst_harness_push (hrecv, gst_harness_pull (hsend)); |
169 | 169 | Push RTX packets from rtxsend to rtxreceive and |
170 | 170 | check that the packet produced out of RTX packet is the same |
171 | 171 | as an original packet */ |
172 | for (i = 0; i < packets_num; ++i) { | |
172 | for (i = 0; i < packets_num; i++) { | |
173 | 173 | GstBuffer *outbuf; |
174 | 174 | gst_harness_push_upstream_event (hrecv, |
175 | 175 | create_rtx_event (master_ssrc, master_pt, 100 + i)); |
221 | 221 | GstStructure *pt_map; |
222 | 222 | GstHarness *hrecv = gst_harness_new ("rtprtxreceive"); |
223 | 223 | GstHarness *hsend = gst_harness_new ("rtprtxsend"); |
224 | gint drop_nth_packet, i; | |
224 | guint drop_nth_packet, i; | |
225 | 225 | |
226 | 226 | pt_map = gst_structure_new ("application/x-rtp-pt-map", |
227 | 227 | "96", G_TYPE_UINT, rtx_pt, NULL); |
245 | 245 | /* Push 'packets_num' packets through rtxsend to rtxreceive losing every |
246 | 246 | 'drop_every_n_packets' packet. When we loose the packet we send RTX event |
247 | 247 | through rtxreceive to rtxsend, and verify the packet was retransmitted */ |
248 | for (drop_nth_packet = 2; drop_nth_packet < 10; ++drop_nth_packet) { | |
249 | for (i = 0; i < packets_num; ++i, ++seqnum) { | |
248 | for (drop_nth_packet = 2; drop_nth_packet < 10; drop_nth_packet++) { | |
249 | for (i = 0; i < packets_num; i++, seqnum++) { | |
250 | 250 | GstBuffer *outbuf; |
251 | 251 | GstBuffer *inbuf = create_rtp_buffer (master_ssrc, master_pt, seqnum); |
252 | 252 | gboolean drop_this_packet = ((i + 1) % drop_nth_packet) == 0; |
262 | 262 | gst_harness_pull_upstream_event (hrecv)); |
263 | 263 | /* Pushing RTX packet to rtxreceive */ |
264 | 264 | gst_harness_push (hrecv, gst_harness_pull (hsend)); |
265 | ++expected_rtx_packets; | |
265 | expected_rtx_packets++; | |
266 | 266 | } else { |
267 | 267 | gst_harness_push (hrecv, gst_harness_pull (hsend)); |
268 | 268 | } |
327 | 327 | { |
328 | 328 | GstStructure *recv_pt_map = |
329 | 329 | gst_structure_new_empty ("application/x-rtp-pt-map"); |
330 | gint i; | |
331 | ||
332 | for (i = 0; i < senders_num; ++i) { | |
330 | guint i; | |
331 | ||
332 | for (i = 0; i < senders_num; i++) { | |
333 | 333 | gchar *master_pt_str; |
334 | 334 | gchar *master_caps_str; |
335 | 335 | GstStructure *send_pt_map; |
368 | 368 | check_rtxsenders_stats_and_teardown (RtxSender * senders, guint senders_num) |
369 | 369 | { |
370 | 370 | guint total_pakets_num = 0; |
371 | gint i; | |
372 | ||
373 | for (i = 0; i < senders_num; ++i) { | |
371 | guint i; | |
372 | ||
373 | for (i = 0; i < senders_num; i++) { | |
374 | 374 | guint rtx_requests; |
375 | 375 | guint rtx_packets; |
376 | 376 | g_object_get (G_OBJECT (senders[i].h->element), |
394 | 394 | RtxSender senders[5]; |
395 | 395 | GstStructure *pt_map; |
396 | 396 | GstHarness *hrecv = gst_harness_new ("rtprtxreceive"); |
397 | gint drop_nth_packet, i, j; | |
397 | guint drop_nth_packet, i, j; | |
398 | 398 | |
399 | 399 | pt_map = create_rtxsenders (senders, 5); |
400 | 400 | g_object_set (hrecv->element, "payload-type-map", pt_map, NULL); |
415 | 415 | We need to make sure that all other senders will ignore the RTX event they |
416 | 416 | can't act upon. |
417 | 417 | */ |
418 | for (drop_nth_packet = 2; drop_nth_packet < 5; ++drop_nth_packet) { | |
419 | for (i = 0; i < total_pakets_num; ++i) { | |
418 | for (drop_nth_packet = 2; drop_nth_packet < 5; drop_nth_packet++) { | |
419 | for (i = 0; i < total_pakets_num; i++) { | |
420 | 420 | RtxSender *sender = &senders[i % senders_num]; |
421 | 421 | gboolean drop_this_packet = ((i + 1) % drop_nth_packet) == 0; |
422 | 422 | GstBuffer *outbuf, *inbuf; |
437 | 437 | rtxevent = gst_harness_pull_upstream_event (hrecv); |
438 | 438 | |
439 | 439 | /* ... to all the senders */ |
440 | for (j = 0; j < senders_num; ++j) | |
440 | for (j = 0; j < senders_num; j++) | |
441 | 441 | gst_harness_push_upstream_event (senders[j].h, |
442 | 442 | gst_event_ref (rtxevent)); |
443 | 443 | gst_event_unref (rtxevent); |
444 | 444 | |
445 | 445 | /* Pushing RTX packet to rtxreceive */ |
446 | 446 | gst_harness_push (hrecv, gst_harness_pull (sender->h)); |
447 | ++sender->expected_rtx_packets; | |
448 | ++total_dropped_packets; | |
447 | sender->expected_rtx_packets++; | |
448 | total_dropped_packets++; | |
449 | 449 | } else { |
450 | 450 | gst_harness_push (hrecv, gst_harness_pull (sender->h)); |
451 | 451 | } |
462 | 462 | We should not have any packets in the harness queue by this point. It |
463 | 463 | means our senders didn't produce the packets for the unknown RTX event. |
464 | 464 | */ |
465 | for (j = 0; j < senders_num; ++j) | |
465 | for (j = 0; j < senders_num; j++) | |
466 | 466 | fail_unless_equals_int (gst_harness_buffers_in_queue (senders[j].h), 0); |
467 | 467 | |
468 | ++sender->seqnum; | |
468 | sender->seqnum++; | |
469 | 469 | } |
470 | 470 | } |
471 | 471 | |
604 | 604 | * Note that rtprtxqueue sends retransmissions in chain(), just before |
605 | 605 | * pushing out the chained buffer, a differentiation from rtprtxsend above |
606 | 606 | */ |
607 | for (i = 0; i < num_buffers; ++i, timestamp += timestamp_delta) { | |
607 | for (i = 0; i < num_buffers; i++, timestamp += timestamp_delta) { | |
608 | 608 | /* Request to retransmit all the previous ones */ |
609 | for (j = 0; j < i; ++j) { | |
609 | for (j = 0; j < i; j++) { | |
610 | 610 | guint rtx_seqnum = 0x100 + j; |
611 | 611 | gst_harness_push_upstream_event (h, |
612 | 612 | create_rtx_event (ssrc, pt, rtx_seqnum)); |
618 | 618 | gst_harness_push (h, buf); |
619 | 619 | |
620 | 620 | /* Pull the ones supposed to be retransmitted */ |
621 | for (j = 0; j < i; ++j) { | |
621 | for (j = 0; j < i; j++) { | |
622 | 622 | guint rtx_seqnum = 0x100 + j; |
623 | 623 | if (j >= i - half_buffers) |
624 | 624 | pull_and_verify (h, FALSE, ssrc, pt, rtx_seqnum); |