#include <string>
#include <alloca.h>
+#include <vector>
#include "trackrenderer/core/caps_recipes.h"
#include "trackrenderer/core/pipeline.hpp"
}
GstBufferList *
-ParseStreamHeaders (guchar* codec_data, gsize codec_data_size) {
- GstBufferList *list = NULL;
- guchar *p = codec_data;
- guint i, offset, num_packets;
- guint *length, last;
-
- if (codec_data == NULL || codec_data_size == 0)
- goto error;
-
- /* start of the stream and vorbis audio or theora video, need to
- * send the codec_priv data as first three packets */
- num_packets = p[0] + 1;
- TRACKRENDERER_INFO("%u stream headers, total length=%" G_GSIZE_FORMAT " bytes",
- num_packets, codec_data_size);
-
- length = (guint *)g_alloca(num_packets * sizeof(guint));
- last = 0;
- offset = 1;
-
- /* first packets, read length values */
- for (i = 0; i < num_packets - 1; i++) {
- length[i] = 0;
- while (offset < (guint)codec_data_size) {
- length[i] += p[offset];
- if (p[offset++] != 0xff)
- break;
- }
- last += length[i];
+ParseStreamHeaders (char* codec_data, size_t codec_data_size) {
+ char *p = codec_data;
+ size_t offset = 1;
+ size_t last = 0;
+ std::vector<size_t> packetLength;
+
+ if (!codec_data || codec_data_size == 0) {
+ TRACKRENDERER_ERROR("codec_data is null or size 0");
+ return nullptr;
}
- if (offset + last > codec_data_size)
- goto error;
- /* last packet is the remaining size */
- length[i] = codec_data_size - offset - last;
+ size_t numPackets = p[0] + 1;
+ TRACKRENDERER_INFO("%zu stream headers, total length=%zu bytes",
+ numPackets, codec_data_size);
- list = gst_buffer_list_new();
+ for (size_t i = 0; i < numPackets - 1; i++) {
+ size_t length = 0;
+ while (offset < codec_data_size) {
+ length += p[offset];
+ if (p[offset++] == 0xff)
+ continue;
- for (i = 0; i < num_packets; i++) {
- GstBuffer *hdr;
- TRACKRENDERER_INFO ("buffer %d: %u bytes", i, (guint)length[i]);
- if (offset + length[i] > codec_data_size)
- goto error;
+ packetLength.push_back(length);
+ break;
+ }
+ last += length;
+ }
- hdr = gst_buffer_new_wrapped(g_memdup2(p + offset, length[i]), length[i]);
- gst_buffer_list_add(list, hdr);
- offset += length[i];
+ if (offset + last > codec_data_size) {
+ TRACKRENDERER_ERROR("Over the codec data size");
+ return nullptr;
}
- return list;
-
- /* ERRORS */
- error:
- {
- TRACKRENDERER_ERROR("error occurs");
- if (list != NULL)
- gst_buffer_list_unref(list);
- return NULL;
+
+ packetLength.push_back(codec_data_size - offset - last);
+
+ GstBufferList* bufferList = gst_buffer_list_new();
+
+ for (auto& len : packetLength) {
+ TRACKRENDERER_INFO ("buffer : %zu bytes", len);
+ if (offset + len > codec_data_size) {
+ TRACKRENDERER_ERROR("Over the codec data size");
+ gst_buffer_list_unref(bufferList);
+ return nullptr;
+ }
+
+ gst_buffer_list_add(bufferList, gst_buffer_new_memdup(p + offset, len));
+ offset += len;
}
+
+ return bufferList;
}
static GValue
MakeGstBufferWithCodecData(track.codec_data, track.codec_data_len);
if (codec_data == nullptr) return;
if (track.mimetype.find("audio/x-vorbis") != std::string::npos) {
- GValue streamheader =
- MakeStreamHeaders(ParseStreamHeaders((guchar*)track.codec_data.get(), track.codec_data_len));
+ GValue streamheader = MakeStreamHeaders(
+ ParseStreamHeaders(track.codec_data.get(), static_cast<size_t>(track.codec_data_len)));
caps.SetArray("streamheader", streamheader);
} else {
caps.SetValue("codec_data", GST_TYPE_BUFFER, codec_data);