static GstFlowReturn gst_jp2k_decimator_decimate_jpc (GstJP2kDecimator * self, GstBuffer * inbuf, GstBuffer ** outbuf_) { GstBuffer *outbuf = NULL; GstFlowReturn ret = GST_FLOW_OK; GstMapInfo info; GstByteReader reader; GstByteWriter writer; MainHeader main_header; if (!gst_buffer_map (inbuf, &info, GST_MAP_READ)) { GST_ELEMENT_ERROR (self, STREAM, WRONG_TYPE, ("Unable to map memory"), (NULL)); gst_buffer_unref (inbuf); return GST_FLOW_ERROR; } gst_byte_reader_init (&reader, info.data, info.size); gst_byte_writer_init_with_size (&writer, gst_buffer_get_size (inbuf), FALSE); /* main header */ memset (&main_header, 0, sizeof (MainHeader)); ret = parse_main_header (self, &reader, &main_header); if (ret != GST_FLOW_OK) goto done; ret = decimate_main_header (self, &main_header); if (ret != GST_FLOW_OK) goto done; ret = write_main_header (self, &writer, &main_header); if (ret != GST_FLOW_OK) goto done; outbuf = gst_byte_writer_reset_and_get_buffer (&writer); gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_METADATA, 0, -1); GST_DEBUG_OBJECT (self, "Decimated buffer from %" G_GSIZE_FORMAT " bytes to %" G_GSIZE_FORMAT " bytes (%.2lf%%)", gst_buffer_get_size (inbuf), gst_buffer_get_size (outbuf), (100 * gst_buffer_get_size (outbuf)) / ((gdouble) gst_buffer_get_size (inbuf))); done: gst_buffer_unmap (inbuf, &info); *outbuf_ = outbuf; reset_main_header (self, &main_header); gst_buffer_unref (inbuf); return ret; }
static GstFlowReturn gst_wavenc_write_tags (GstWavEnc * wavenc) { const GstTagList *user_tags; GstTagList *tags; guint size; GstBuffer *buf; GstByteWriter bw; g_return_val_if_fail (wavenc != NULL, GST_FLOW_OK); user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (wavenc)); if ((!wavenc->tags) && (!user_tags)) { GST_DEBUG_OBJECT (wavenc, "have no tags"); return GST_FLOW_OK; } tags = gst_tag_list_merge (user_tags, wavenc->tags, gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (wavenc))); GST_DEBUG_OBJECT (wavenc, "writing tags"); gst_byte_writer_init_with_size (&bw, 1024, FALSE); /* add LIST INFO chunk */ gst_byte_writer_put_data (&bw, (const guint8 *) "LIST", 4); gst_byte_writer_put_uint32_le (&bw, 0); gst_byte_writer_put_data (&bw, (const guint8 *) "INFO", 4); /* add tags */ gst_tag_list_foreach (tags, gst_wavparse_tags_foreach, &bw); /* sets real size of LIST INFO chunk */ size = gst_byte_writer_get_pos (&bw); gst_byte_writer_set_pos (&bw, 4); gst_byte_writer_put_uint32_le (&bw, size - 8); gst_tag_list_unref (tags); buf = gst_byte_writer_reset_and_get_buffer (&bw); wavenc->meta_length += gst_buffer_get_size (buf); return gst_pad_push (wavenc->srcpad, buf); }
static GstFlowReturn gst_jp2k_decimator_decimate_jpc (GstJP2kDecimator * self, GstBuffer * inbuf, GstBuffer ** outbuf_) { GstBuffer *outbuf = NULL; GstFlowReturn ret = GST_FLOW_OK; GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (inbuf); GstByteWriter writer; MainHeader main_header; gst_byte_writer_init_with_size (&writer, GST_BUFFER_SIZE (inbuf), FALSE); /* main header */ memset (&main_header, 0, sizeof (MainHeader)); ret = parse_main_header (self, &reader, &main_header); if (ret != GST_FLOW_OK) goto done; ret = decimate_main_header (self, &main_header); if (ret != GST_FLOW_OK) goto done; ret = write_main_header (self, &writer, &main_header); if (ret != GST_FLOW_OK) goto done; outbuf = gst_byte_writer_reset_and_get_buffer (&writer); gst_buffer_copy_metadata (outbuf, inbuf, GST_BUFFER_COPY_ALL); GST_DEBUG_OBJECT (self, "Decimated buffer from %u bytes to %u bytes (%.2lf%%)", GST_BUFFER_SIZE (inbuf), GST_BUFFER_SIZE (outbuf), (100 * GST_BUFFER_SIZE (outbuf)) / ((gdouble) GST_BUFFER_SIZE (inbuf))); done: *outbuf_ = outbuf; reset_main_header (self, &main_header); gst_buffer_unref (inbuf); return ret; }
/** * gst_tag_list_to_exif_buffer_with_tiff_header: * @taglist: The taglist * * Formats the tags in taglist into exif structure, a tiff header * is put in the beginning of the buffer. * * Returns: A GstBuffer containing the data * * Since: 0.10.30 */ GstBuffer * gst_tag_list_to_exif_buffer_with_tiff_header (const GstTagList * taglist) { GstBuffer *ifd; GstByteWriter writer; guint size; ifd = gst_tag_list_to_exif_buffer (taglist, G_BYTE_ORDER, 8); if (ifd == NULL) { GST_WARNING ("Failed to create exif buffer"); return NULL; } size = TIFF_HEADER_SIZE + GST_BUFFER_SIZE (ifd); /* TODO what is the correct endianness here? */ gst_byte_writer_init_with_size (&writer, size, FALSE); /* TIFF header */ if (G_BYTE_ORDER == G_LITTLE_ENDIAN) { gst_byte_writer_put_uint16_le (&writer, TIFF_LITTLE_ENDIAN); gst_byte_writer_put_uint16_le (&writer, 42); gst_byte_writer_put_uint32_le (&writer, 8); } else { gst_byte_writer_put_uint16_be (&writer, TIFF_BIG_ENDIAN); gst_byte_writer_put_uint16_be (&writer, 42); gst_byte_writer_put_uint32_be (&writer, 8); } if (!gst_byte_writer_put_data (&writer, GST_BUFFER_DATA (ifd), GST_BUFFER_SIZE (ifd))) { GST_WARNING ("Byte writer size mismatch"); /* reaching here is a programming error because we should have a buffer * large enough */ g_assert_not_reached (); gst_buffer_unref (ifd); gst_byte_writer_reset (&writer); return NULL; } gst_buffer_unref (ifd); return gst_byte_writer_reset_and_get_buffer (&writer); }
static GstFlowReturn gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) { GstH264Parse *h264parse; GstBuffer *buffer; h264parse = GST_H264_PARSE (parse); buffer = frame->buffer; /* periodic SPS/PPS sending */ if (h264parse->interval > 0 || h264parse->push_codec) { GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer); guint64 diff; /* init */ if (!GST_CLOCK_TIME_IS_VALID (h264parse->last_report)) { h264parse->last_report = timestamp; } if (h264parse->idr_pos >= 0) { GST_LOG_OBJECT (h264parse, "IDR nal at offset %d", h264parse->idr_pos); if (timestamp > h264parse->last_report) diff = timestamp - h264parse->last_report; else diff = 0; GST_LOG_OBJECT (h264parse, "now %" GST_TIME_FORMAT ", last SPS/PPS %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp), GST_TIME_ARGS (h264parse->last_report)); GST_DEBUG_OBJECT (h264parse, "interval since last SPS/PPS %" GST_TIME_FORMAT, GST_TIME_ARGS (diff)); if (GST_TIME_AS_SECONDS (diff) >= h264parse->interval || h264parse->push_codec) { GstBuffer *codec_nal; gint i; GstClockTime new_ts; /* avoid overwriting a perfectly fine timestamp */ new_ts = GST_CLOCK_TIME_IS_VALID (timestamp) ? timestamp : h264parse->last_report; if (h264parse->align == GST_H264_PARSE_ALIGN_NAL) { /* send separate config NAL buffers */ GST_DEBUG_OBJECT (h264parse, "- sending SPS/PPS"); for (i = 0; i < MAX_SPS_COUNT; i++) { if ((codec_nal = h264parse->params->sps_nals[i])) { GST_DEBUG_OBJECT (h264parse, "sending SPS nal"); gst_h264_parse_push_codec_buffer (h264parse, codec_nal, timestamp); h264parse->last_report = new_ts; } } for (i = 0; i < MAX_PPS_COUNT; i++) { if ((codec_nal = h264parse->params->pps_nals[i])) { GST_DEBUG_OBJECT (h264parse, "sending PPS nal"); gst_h264_parse_push_codec_buffer (h264parse, codec_nal, timestamp); h264parse->last_report = new_ts; } } } else { /* insert config NALs into AU */ GstByteWriter bw; GstBuffer *new_buf; const gboolean bs = h264parse->format == GST_H264_PARSE_FORMAT_BYTE; gst_byte_writer_init_with_size (&bw, GST_BUFFER_SIZE (buffer), FALSE); gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (buffer), h264parse->idr_pos); GST_DEBUG_OBJECT (h264parse, "- inserting SPS/PPS"); for (i = 0; i < MAX_SPS_COUNT; i++) { if ((codec_nal = h264parse->params->sps_nals[i])) { GST_DEBUG_OBJECT (h264parse, "inserting SPS nal"); gst_byte_writer_put_uint32_be (&bw, bs ? 1 : GST_BUFFER_SIZE (codec_nal)); gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (codec_nal), GST_BUFFER_SIZE (codec_nal)); h264parse->last_report = new_ts; } } for (i = 0; i < MAX_PPS_COUNT; i++) { if ((codec_nal = h264parse->params->pps_nals[i])) { GST_DEBUG_OBJECT (h264parse, "inserting PPS nal"); gst_byte_writer_put_uint32_be (&bw, bs ? 1 : GST_BUFFER_SIZE (codec_nal)); gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (codec_nal), GST_BUFFER_SIZE (codec_nal)); h264parse->last_report = new_ts; } } gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (buffer) + h264parse->idr_pos, GST_BUFFER_SIZE (buffer) - h264parse->idr_pos); /* collect result and push */ new_buf = gst_byte_writer_reset_and_get_buffer (&bw); gst_buffer_copy_metadata (new_buf, buffer, GST_BUFFER_COPY_ALL); gst_buffer_replace (&frame->buffer, new_buf); } } /* we pushed whatever we had */ h264parse->push_codec = FALSE; } } gst_h264_parse_reset_frame (h264parse); return GST_FLOW_OK; }