static GstBuffer * gst_opus_enc_create_id_buffer (gint nchannels, gint n_stereo_streams, gint sample_rate, guint8 channel_mapping_family, const guint8 * channel_mapping) { GstBuffer *buffer; GstByteWriter bw; gboolean hdl = TRUE; g_return_val_if_fail (nchannels > 0 && nchannels < 256, NULL); g_return_val_if_fail (n_stereo_streams >= 0, NULL); g_return_val_if_fail (n_stereo_streams <= nchannels - n_stereo_streams, NULL); gst_byte_writer_init (&bw); /* See http://wiki.xiph.org/OggOpus */ hdl &= gst_byte_writer_put_data (&bw, (const guint8 *) "OpusHead", 8); hdl &= gst_byte_writer_put_uint8 (&bw, 0x01); /* version number */ hdl &= gst_byte_writer_put_uint8 (&bw, nchannels); hdl &= gst_byte_writer_put_uint16_le (&bw, 0); /* pre-skip */ hdl &= gst_byte_writer_put_uint32_le (&bw, sample_rate); hdl &= gst_byte_writer_put_uint16_le (&bw, 0); /* output gain */ hdl &= gst_byte_writer_put_uint8 (&bw, channel_mapping_family); if (channel_mapping_family > 0) { hdl &= gst_byte_writer_put_uint8 (&bw, nchannels - n_stereo_streams); hdl &= gst_byte_writer_put_uint8 (&bw, n_stereo_streams); hdl &= gst_byte_writer_put_data (&bw, channel_mapping, nchannels); } if (!hdl) GST_WARNING ("Error creating header"); buffer = gst_byte_writer_reset_and_get_buffer (&bw); GST_BUFFER_OFFSET (buffer) = 0; GST_BUFFER_OFFSET_END (buffer) = 0; return buffer; }
static GstFlowReturn gst_jif_mux_recombine_image (GstJifMux * self, GstBuffer ** new_buf, GstBuffer * old_buf) { GstBuffer *buf; GstByteWriter *writer; GstFlowReturn fret; GstJifMuxMarker *m; GList *node; guint size = self->priv->scan_size; gboolean writer_status = TRUE; /* iterate list and collect size */ for (node = self->priv->markers; node; node = g_list_next (node)) { m = (GstJifMuxMarker *) node->data; /* some markers like e.g. SOI are empty */ if (m->size) { size += 2 + m->size; } /* 0xff <marker> */ size += 2; } GST_INFO_OBJECT (self, "old size: %u, new size: %u", GST_BUFFER_SIZE (old_buf), size); /* allocate new buffer */ fret = gst_pad_alloc_buffer_and_set_caps (self->priv->srcpad, GST_BUFFER_OFFSET (old_buf), size, GST_PAD_CAPS (self->priv->srcpad), &buf); if (fret != GST_FLOW_OK) goto no_buffer; /* copy buffer metadata */ gst_buffer_copy_metadata (buf, old_buf, GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); /* memcopy markers */ writer = gst_byte_writer_new_with_buffer (buf, TRUE); for (node = self->priv->markers; node && writer_status; node = g_list_next (node)) { m = (GstJifMuxMarker *) node->data; writer_status &= gst_byte_writer_put_uint8 (writer, 0xff); writer_status &= gst_byte_writer_put_uint8 (writer, m->marker); GST_DEBUG_OBJECT (self, "marker = %2x, size = %u", m->marker, m->size + 2); if (m->size) { writer_status &= gst_byte_writer_put_uint16_be (writer, m->size + 2); writer_status &= gst_byte_writer_put_data (writer, m->data, m->size); } if (m->marker == SOS) { GST_DEBUG_OBJECT (self, "scan data, size = %u", self->priv->scan_size); writer_status &= gst_byte_writer_put_data (writer, self->priv->scan_data, self->priv->scan_size); } } gst_byte_writer_free (writer); if (!writer_status) { GST_WARNING_OBJECT (self, "Failed to write to buffer, calculated size " "was probably too short"); g_assert_not_reached (); } *new_buf = buf; return GST_FLOW_OK; no_buffer: GST_WARNING_OBJECT (self, "failed to allocate output buffer, flow_ret = %s", gst_flow_get_name (fret)); return fret; }
static gboolean flx_decode_delta_flc (GstFlxDec * flxdec, GstByteReader * reader, GstByteWriter * writer) { guint16 lines, start_l; g_return_val_if_fail (flxdec != NULL, FALSE); g_return_val_if_fail (flxdec->delta_data != NULL, FALSE); /* use last frame for delta */ if (!gst_byte_writer_put_data (writer, flxdec->delta_data, flxdec->size)) goto error; if (!gst_byte_reader_get_uint16_le (reader, &lines)) goto error; if (lines > flxdec->hdr.height) { GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. too many lines."); return FALSE; } start_l = lines; while (lines) { guint16 opcode; if (!gst_byte_writer_set_pos (writer, flxdec->hdr.width * (start_l - lines))) goto error; /* process opcode(s) */ while (TRUE) { if (!gst_byte_reader_get_uint16_le (reader, &opcode)) goto error; if ((opcode & 0xc000) == 0) break; if ((opcode & 0xc000) == 0xc000) { /* line skip count */ gulong skip = (0x10000 - opcode); if (skip > flxdec->hdr.height) { GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. " "skip line count too big."); return FALSE; } start_l += skip; if (!gst_byte_writer_set_pos (writer, gst_byte_writer_get_pos (writer) + flxdec->hdr.width * skip)) goto error; } else { /* last pixel */ if (!gst_byte_writer_set_pos (writer, gst_byte_writer_get_pos (writer) + flxdec->hdr.width)) goto error; if (!gst_byte_writer_put_uint8 (writer, opcode & 0xff)) goto error; } } /* last opcode is the packet count */ GST_LOG_OBJECT (flxdec, "have %d packets", opcode); while (opcode--) { /* skip count */ guint8 skip; gint8 count; if (!gst_byte_reader_get_uint8 (reader, &skip)) goto error; if (!gst_byte_writer_set_pos (writer, gst_byte_writer_get_pos (writer) + skip)) goto error; /* RLE count */ if (!gst_byte_reader_get_int8 (reader, &count)) goto error; if (count < 0) { guint16 x; /* replicate word run */ count = ABS (count); GST_LOG_OBJECT (flxdec, "have replicate run of size %d at offset %d", count, skip); if (skip + count > flxdec->hdr.width) { GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. " "line too long."); return FALSE; } if (!gst_byte_reader_get_uint16_le (reader, &x)) goto error; while (count--) { if (!gst_byte_writer_put_uint16_le (writer, x)) { goto error; } } } else { GST_LOG_OBJECT (flxdec, "have literal run of size %d at offset %d", count, skip); if (skip + count > flxdec->hdr.width) { GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. " "line too long."); return FALSE; } while (count--) { guint16 x; if (!gst_byte_reader_get_uint16_le (reader, &x)) goto error; if (!gst_byte_writer_put_uint16_le (writer, x)) goto error; } } } lines--; } return TRUE; error: GST_ERROR_OBJECT (flxdec, "Failed to decode FLI packet"); return FALSE; }