From: Jan Alexander Steffens (heftig) Date: Mon, 16 Oct 2023 22:57:56 +0000 (+0200) Subject: tsmux: Simplify tsmux_section_write_packet X-Git-Tag: 1.22.7~28 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=77429e4096ef89eca804459aee9ca39d221ff256;p=platform%2Fupstream%2Fgstreamer.git tsmux: Simplify tsmux_section_write_packet - Don't try to make the parameters match `GHFunc`. Use a dedicated callback for `g_hash_table_foreach`. - Don't try to be clever with buffer memories. We're allocating a full packet anyway, might as well memcpy and save on a lot of complexity. Part-of: --- diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c index 52849d4..6ab7170 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c @@ -1147,132 +1147,80 @@ tsmux_write_ts_header (TsMux * mux, guint8 * buf, TsMuxPacketInfo * pi, return TRUE; } -/* The unused_arg is needed for g_hash_table_foreach() */ static gboolean -tsmux_section_write_packet (gpointer unused_arg, - TsMuxSection * section, TsMux * mux) +tsmux_section_write_packet (TsMux * mux, TsMuxSection * section) { - GstBuffer *section_buffer; - GstBuffer *packet_buffer = NULL; - GstMemory *mem; - guint8 *packet; guint8 *data; - gsize data_size = 0; - gsize payload_written; - guint len = 0, offset = 0, payload_len = 0; - guint extra_alloc_bytes = 0; + gsize data_size; + guint payload_written = 0; + gboolean ret = FALSE; g_return_val_if_fail (section != NULL, FALSE); g_return_val_if_fail (mux != NULL, FALSE); - /* Mark the start of new PES unit */ - section->pi.packet_start_unit_indicator = TRUE; - data = gst_mpegts_section_packetize (section->section, &data_size); - if (!data) { - TS_DEBUG ("Could not packetize section"); + GST_WARNING ("Could not packetize section"); return FALSE; } + /* Mark the start of new PES unit */ + section->pi.packet_start_unit_indicator = TRUE; + /* Mark payload data size */ section->pi.stream_avail = data_size; - payload_written = 0; - - /* Wrap section data in a buffer without free function. - The data will be freed when the GstMpegtsSection is destroyed. */ - section_buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, - data, data_size, 0, data_size, NULL, NULL); - - TS_DEBUG ("Section buffer with size %" G_GSIZE_FORMAT " created", - gst_buffer_get_size (section_buffer)); while (section->pi.stream_avail > 0) { + GstBuffer *buf; + GstMapInfo map; + guint len, offset; - packet = g_malloc (TSMUX_PACKET_LENGTH); + if (!tsmux_get_buffer (mux, &buf)) + goto done; - if (section->pi.packet_start_unit_indicator) { - /* Wee need room for a pointer byte */ - section->pi.stream_avail++; + if (!gst_buffer_map (buf, &map, GST_MAP_WRITE)) { + gst_buffer_unref (buf); + goto done; + } - if (!tsmux_write_ts_header (mux, packet, §ion->pi, - section->pi.stream_avail, &len, &offset)) - goto fail; + if (section->pi.packet_start_unit_indicator) { + /* We need room for a pointer byte */ + if (!tsmux_write_ts_header (mux, map.data, §ion->pi, + section->pi.stream_avail + 1, &len, &offset)) { + gst_buffer_unmap (buf, &map); + gst_buffer_unref (buf); + goto done; + } /* Write the pointer byte */ - packet[offset++] = 0x00; - payload_len = len - 1; - - } else { - if (!tsmux_write_ts_header (mux, packet, §ion->pi, - section->pi.stream_avail, &len, &offset)) - goto fail; - payload_len = len; + map.data[offset++] = 0x00; + len--; + } else if (!tsmux_write_ts_header (mux, map.data, §ion->pi, + section->pi.stream_avail, &len, &offset)) { + gst_buffer_unmap (buf, &map); + gst_buffer_unref (buf); + goto done; } - /* Wrap the TS header and adaption field in a GstMemory */ - mem = gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, - packet, TSMUX_PACKET_LENGTH, 0, offset, packet, g_free); - - TS_DEBUG ("Creating packet buffer at offset " - "%" G_GSIZE_FORMAT " with length %u", payload_written, payload_len); - - /* If in M2TS mode, we will need to resize to 4 bytes after the end - of the buffer. For performance reasons, we will now try to include - 4 extra bytes from the source buffer, then resize down, to avoid - having an extra 4 byte GstMemory appended. If the source buffer - does not have enough data for this, a new GstMemory will be used */ - if (gst_buffer_get_size (section_buffer) - (payload_written + - payload_len) >= 4) { - /* enough space */ - extra_alloc_bytes = 4; - } else { - extra_alloc_bytes = 0; - } - packet_buffer = gst_buffer_copy_region (section_buffer, GST_BUFFER_COPY_ALL, - payload_written, payload_len + extra_alloc_bytes); - - /* Prepend the header to the section data */ - gst_buffer_prepend_memory (packet_buffer, mem); - - /* add an extra 4 bytes if it could not be reserved already */ - if (extra_alloc_bytes == 4) { - /* we allocated those already, resize */ - gst_buffer_set_size (packet_buffer, - gst_buffer_get_size (packet_buffer) - extra_alloc_bytes); - } else { - void *ptr = g_malloc (4); - GstMemory *extra = - gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, ptr, 4, 0, 0, ptr, - g_free); - gst_buffer_append_memory (packet_buffer, extra); - } + GST_DEBUG ("Creating section packet for offset %u with length %u; %u bytes" + " remaining", payload_written, len, section->pi.stream_avail - len); - TS_DEBUG ("Writing %d bytes to section. %d bytes remaining", - len, section->pi.stream_avail - len); + memcpy (map.data + offset, data + payload_written, len); + gst_buffer_unmap (buf, &map); /* Push the packet without PCR */ - if (G_UNLIKELY (!tsmux_packet_out (mux, packet_buffer, -1))) { - /* Buffer given away */ - packet_buffer = NULL; - goto fail; - } + if (G_UNLIKELY (!tsmux_packet_out (mux, buf, -1))) + goto done; - packet_buffer = NULL; section->pi.stream_avail -= len; - payload_written += payload_len; + payload_written += len; section->pi.packet_start_unit_indicator = FALSE; } - gst_buffer_unref (section_buffer); - - return TRUE; + ret = TRUE; -fail: - g_free (packet); - if (section_buffer) - gst_buffer_unref (section_buffer); - return FALSE; +done: + return ret; } /** @@ -1301,22 +1249,29 @@ tsmux_send_section (TsMux * mux, GstMpegtsSection * section) tsmux_section.section = section; tsmux_section.pi.pid = section->pid; - ret = tsmux_section_write_packet (NULL, &tsmux_section, mux); + ret = tsmux_section_write_packet (mux, &tsmux_section); gst_mpegts_section_unref (section); return ret; } +static void +tsmux_write_si_foreach (gpointer key, gpointer value, gpointer user_data) +{ + GstMpegtsSectionType section_type = GPOINTER_TO_INT (key); + TsMuxSection *section = value; + TsMux *mux = user_data; + + if (!tsmux_section_write_packet (mux, section)) + GST_WARNING ("Failed to send SI section (type %d)", section_type); +} + static gboolean tsmux_write_si (TsMux * mux) { - g_hash_table_foreach (mux->si_sections, - (GHFunc) tsmux_section_write_packet, mux); - + g_hash_table_foreach (mux->si_sections, tsmux_write_si_foreach, mux); mux->si_changed = FALSE; - return TRUE; - } static void @@ -1753,7 +1708,7 @@ tsmux_write_pat (TsMux * mux) mux->pat_changed = FALSE; } - return tsmux_section_write_packet (NULL, &mux->pat, mux); + return tsmux_section_write_packet (mux, &mux->pat); } static gboolean @@ -1853,7 +1808,7 @@ tsmux_write_pmt (TsMux * mux, TsMuxProgram * program) program->pmt.section->version_number = program->pmt_version++; } - return tsmux_section_write_packet (NULL, &program->pmt, mux); + return tsmux_section_write_packet (mux, &program->pmt); } static gboolean @@ -1861,7 +1816,7 @@ tsmux_write_scte_null (TsMux * mux, TsMuxProgram * program) { /* SCTE-35 NULL section is created when PID is set */ GST_LOG ("Writing SCTE NULL packet"); - return tsmux_section_write_packet (NULL, program->scte35_null_section, mux); + return tsmux_section_write_packet (mux, program->scte35_null_section); } void