diff options
author | Sebastien Bacher <seb128@ubuntu.com> | 2020-10-08 21:37:44 +0200 |
---|---|---|
committer | Sebastien Bacher <seb128@ubuntu.com> | 2020-10-08 21:37:44 +0200 |
commit | 245977c8ad426bd475594e9f33b5729678632a69 (patch) | |
tree | eabb76913f8eb17a6c5dc2cbc505214dd4e012cc /src/modules/rtp/rtp-gstreamer.c | |
parent | bb5f82cb41d3d34eb11e13cb19bec99ab276d142 (diff) |
New upstream version 13.99.2
Diffstat (limited to 'src/modules/rtp/rtp-gstreamer.c')
-rw-r--r-- | src/modules/rtp/rtp-gstreamer.c | 84 |
1 files changed, 61 insertions, 23 deletions
diff --git a/src/modules/rtp/rtp-gstreamer.c b/src/modules/rtp/rtp-gstreamer.c index 3ee77cb..0db3309 100644 --- a/src/modules/rtp/rtp-gstreamer.c +++ b/src/modules/rtp/rtp-gstreamer.c @@ -32,6 +32,7 @@ #include <gst/gst.h> #include <gst/app/gstappsrc.h> #include <gst/app/gstappsink.h> +#include <gst/base/gstadapter.h> #include <gst/rtp/gstrtpbuffer.h> #define MAKE_ELEMENT_NAMED(v, e, n) \ @@ -438,36 +439,73 @@ fail: /* Called from I/O thread context */ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, uint32_t *rtp_tstamp, struct timeval *tstamp) { GstSample *sample = NULL; + GstBufferList *buf_list; + GstAdapter *adapter; GstBuffer *buf; GstMapInfo info; - void *data; + uint8_t *data; + uint64_t data_len = 0; if (!process_bus_messages(c)) goto fail; - sample = gst_app_sink_pull_sample(GST_APP_SINK(c->appsink)); - if (!sample) { - pa_log_warn("Could not get any more data"); - goto fail; - } + adapter = gst_adapter_new(); + pa_assert(adapter); - buf = gst_sample_get_buffer(sample); + while (true) { + sample = gst_app_sink_try_pull_sample(GST_APP_SINK(c->appsink), 0); + if (!sample) + break; - if (GST_BUFFER_IS_DISCONT(buf)) - pa_log_info("Discontinuity detected, possibly lost some packets"); + buf = gst_sample_get_buffer(sample); - if (!gst_buffer_map(buf, &info, GST_MAP_READ)) - goto fail; + if (GST_BUFFER_IS_DISCONT(buf)) + pa_log_info("Discontinuity detected, possibly lost some packets"); + + if (!gst_buffer_map(buf, &info, GST_MAP_READ)) { + pa_log_info("Failed to map buffer"); + gst_sample_unref(sample); + goto fail; + } + + data_len += info.size; + /* We need the buffer to be valid longer than the sample, which will + * be valid only for the duration of this loop. + * + * To do this, increase the ref count. Ownership is transferred to the + * adapter in gst_adapter_push. + */ + gst_buffer_ref(buf); + gst_adapter_push(adapter, buf); + gst_buffer_unmap(buf, &info); + + gst_sample_unref(sample); + } + + buf_list = gst_adapter_take_buffer_list(adapter, data_len); + pa_assert(buf_list); - pa_assert(pa_mempool_block_size_max(pool) >= info.size); + pa_assert(pa_mempool_block_size_max(pool) >= data_len); - chunk->memblock = pa_memblock_new(pool, info.size); + chunk->memblock = pa_memblock_new(pool, data_len); chunk->index = 0; - chunk->length = info.size; + chunk->length = data_len; + + data = (uint8_t *) pa_memblock_acquire_chunk(chunk); + + for (int i = 0; i < gst_buffer_list_length(buf_list); i++) { + buf = gst_buffer_list_get(buf_list, i); + + if (!gst_buffer_map(buf, &info, GST_MAP_READ)) { + gst_buffer_list_unref(buf_list); + goto fail; + } + + memcpy(data, info.data, info.size); + data += info.size; + gst_buffer_unmap(buf, &info); + } - data = pa_memblock_acquire_chunk(chunk); - /* TODO: we could probably just provide an allocator and avoid a memcpy */ - memcpy(data, info.data, info.size); pa_memblock_release(chunk->memblock); /* When buffer-mode = none, the buffer PTS is the RTP timestamp, converted @@ -475,17 +513,17 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, uint32_ * wraparound-corrected, and the DTS is the pipeline clock timestamp from * when the buffer was acquired at the source (this is actually the running * time which is why we need to add base time). */ - *rtp_tstamp = gst_util_uint64_scale_int(GST_BUFFER_PTS(buf), c->ss.rate, GST_SECOND) & 0xFFFFFFFFU; - pa_timeval_rtstore(tstamp, (GST_BUFFER_DTS(buf) + gst_element_get_base_time(c->pipeline)) / GST_USECOND, false); + *rtp_tstamp = gst_util_uint64_scale_int(GST_BUFFER_PTS(gst_buffer_list_get(buf_list, 0)), c->ss.rate, GST_SECOND) & 0xFFFFFFFFU; + pa_timeval_rtstore(tstamp, (GST_BUFFER_DTS(gst_buffer_list_get(buf_list, 0)) + gst_element_get_base_time(c->pipeline)) / GST_USECOND, false); - gst_buffer_unmap(buf, &info); - gst_sample_unref(sample); + gst_buffer_list_unref(buf_list); + gst_object_unref(adapter); return 0; fail: - if (sample) - gst_sample_unref(sample); + if (adapter) + gst_object_unref(adapter); if (chunk->memblock) pa_memblock_unref(chunk->memblock); |