EXPORT_C #endif gboolean gst_byte_reader_peek_uint24_le (GstByteReader * reader, guint32 * val) { g_return_val_if_fail (reader != NULL, FALSE); g_return_val_if_fail (val != NULL, FALSE); if (gst_byte_reader_get_remaining (reader) < 3) return FALSE; *val = GST_READ_UINT24_LE (&reader->data[reader->byte]); return TRUE; }
static void input_data_int24_max (const guint8 * _in, gfloat * out, guint len, guint channels, gfloat max_value, guint op, guint nfft) { guint j; for (j = 0; j < len; j++) { #if G_BYTE_ORDER == G_BIG_ENDIAN gint32 v = GST_READ_UINT24_BE (_in); #else gint32 v = GST_READ_UINT24_LE (_in); #endif if (v & 0x00800000) v |= 0xff000000; _in += 3 * channels; out[op] = v / max_value; op = (op + 1) % nfft; } }
static void input_data_mixed_int24_max (const guint8 * _in, double* out, guint len, double max_value, guint op, guint nfft) { guint j; for (j = 0; j < len; j++) { #if G_BYTE_ORDER == G_BIG_ENDIAN gint32 value = GST_READ_UINT24_BE (_in); #else gint32 value = GST_READ_UINT24_LE (_in); #endif if (value & 0x00800000) value |= 0xff000000; out[op] = value / max_value; op = (op + 1) % nfft; _in += 3; } }
static void input_data_mixed_int24_max (const guint8 * _in, gfloat * out, guint len, guint channels, gfloat max_value, guint op, guint nfft) { guint i, j; gfloat v = 0.0; for (j = 0; j < len; j++) { for (i = 0; i < channels; i++) { #if G_BYTE_ORDER == G_BIG_ENDIAN gint32 value = GST_READ_UINT24_BE (_in); #else gint32 value = GST_READ_UINT24_LE (_in); #endif if (value & 0x00800000) value |= 0xff000000; v += value / max_value; _in += 3; } out[op] = v / channels; op = (op + 1) % nfft; } }
EXPORT_C #endif gboolean gst_byte_reader_get_int24_le (GstByteReader * reader, gint32 * val) { guint32 ret; g_return_val_if_fail (reader != NULL, FALSE); g_return_val_if_fail (val != NULL, FALSE); if (gst_byte_reader_get_remaining (reader) < 3) return FALSE; ret = GST_READ_UINT24_LE (&reader->data[reader->byte]); if (ret & 0x00800000) ret |= 0xff000000; reader->byte += 3; *val = ret; return TRUE; }
static GstFlowReturn gst_ivf_parse_handle_frame_data (GstIvfParse * ivf, GstBaseParseFrame * frame, gint * skipsize) { GstBuffer *const buffer = frame->buffer; GstMapInfo map; GstFlowReturn ret = GST_FLOW_OK; GstBuffer *out_buffer; gst_buffer_map (buffer, &map, GST_MAP_READ); if (map.size >= IVF_FILE_HEADER_SIZE) { guint32 frame_size = GST_READ_UINT32_LE (map.data); guint64 frame_pts = GST_READ_UINT64_LE (map.data + 4); GST_LOG_OBJECT (ivf, "Read frame header: size %u, pts %" G_GUINT64_FORMAT, frame_size, frame_pts); if (map.size < IVF_FRAME_HEADER_SIZE + frame_size) { gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (ivf), IVF_FRAME_HEADER_SIZE + frame_size); gst_buffer_unmap (buffer, &map); *skipsize = 0; goto end; } gst_buffer_unmap (buffer, &map); /* Eventually, we would need the buffer memory in a merged state anyway */ out_buffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_META | GST_BUFFER_COPY_MEMORY | GST_BUFFER_COPY_MERGE, IVF_FRAME_HEADER_SIZE, frame_size); if (!out_buffer) { GST_ERROR_OBJECT (ivf, "Failed to copy frame buffer"); ret = GST_FLOW_ERROR; *skipsize = IVF_FRAME_HEADER_SIZE + frame_size; goto end; } gst_buffer_replace (&frame->out_buffer, out_buffer); gst_buffer_unref (out_buffer); /* Detect resolution changes on key frames */ if (gst_buffer_map (frame->out_buffer, &map, GST_MAP_READ)) { guint32 width, height; if (ivf->fourcc == GST_MAKE_FOURCC ('V', 'P', '8', '0')) { guint32 frame_tag; frame_tag = GST_READ_UINT24_LE (map.data); if (!(frame_tag & 0x01) && map.size >= 10) { /* key frame */ GST_DEBUG_OBJECT (ivf, "key frame detected"); width = GST_READ_UINT16_LE (map.data + 6) & 0x3fff; height = GST_READ_UINT16_LE (map.data + 8) & 0x3fff; gst_ivf_parse_set_size (ivf, width, height); } } else if (ivf->fourcc == GST_MAKE_FOURCC ('V', 'P', '9', '0')) { /* Fixme: Add vp9 frame header parsing? */ } else if (ivf->fourcc == GST_MAKE_FOURCC ('A', 'V', '0', '1')) { /* Fixme: Add av1 frame header parsing? */ /* This would allow to parse dynamic resolution changes */ /* implement when gstav1parser is ready */ } gst_buffer_unmap (frame->out_buffer, &map); } if (ivf->fps_n > 0) { GST_BUFFER_TIMESTAMP (out_buffer) = gst_util_uint64_scale_int (GST_SECOND * frame_pts, ivf->fps_d, ivf->fps_n); } gst_ivf_parse_update_src_caps (ivf); ret = gst_base_parse_finish_frame (GST_BASE_PARSE_CAST (ivf), frame, IVF_FRAME_HEADER_SIZE + frame_size); *skipsize = 0; } else { GST_LOG_OBJECT (ivf, "Frame data not yet available."); gst_buffer_unmap (buffer, &map); *skipsize = 0; } end: return ret; }