mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
basevideodecoder: add capture pattern handling
Move typical scan_for_sync() usage into base class, which just calls gst_adapter_masked_scan_uint32().
This commit is contained in:
parent
dbbf1182dc
commit
62a9383527
3 changed files with 41 additions and 52 deletions
|
@ -90,8 +90,6 @@ static gboolean gst_schro_dec_stop (GstBaseVideoDecoder * dec);
|
||||||
static gboolean gst_schro_dec_reset (GstBaseVideoDecoder * dec);
|
static gboolean gst_schro_dec_reset (GstBaseVideoDecoder * dec);
|
||||||
static GstFlowReturn gst_schro_dec_parse_data (GstBaseVideoDecoder *
|
static GstFlowReturn gst_schro_dec_parse_data (GstBaseVideoDecoder *
|
||||||
base_video_decoder, gboolean at_eos);
|
base_video_decoder, gboolean at_eos);
|
||||||
static int gst_schro_dec_scan_for_sync (GstBaseVideoDecoder *
|
|
||||||
base_video_decoder, gboolean at_eos, int offset, int n);
|
|
||||||
static GstFlowReturn gst_schro_dec_handle_frame (GstBaseVideoDecoder * decoder,
|
static GstFlowReturn gst_schro_dec_handle_frame (GstBaseVideoDecoder * decoder,
|
||||||
GstVideoFrame * frame);
|
GstVideoFrame * frame);
|
||||||
static gboolean gst_schro_dec_finish (GstBaseVideoDecoder * base_video_decoder);
|
static gboolean gst_schro_dec_finish (GstBaseVideoDecoder * base_video_decoder);
|
||||||
|
@ -150,11 +148,12 @@ gst_schro_dec_class_init (GstSchroDecClass * klass)
|
||||||
base_video_decoder_class->reset = GST_DEBUG_FUNCPTR (gst_schro_dec_reset);
|
base_video_decoder_class->reset = GST_DEBUG_FUNCPTR (gst_schro_dec_reset);
|
||||||
base_video_decoder_class->parse_data =
|
base_video_decoder_class->parse_data =
|
||||||
GST_DEBUG_FUNCPTR (gst_schro_dec_parse_data);
|
GST_DEBUG_FUNCPTR (gst_schro_dec_parse_data);
|
||||||
base_video_decoder_class->scan_for_sync =
|
|
||||||
GST_DEBUG_FUNCPTR (gst_schro_dec_scan_for_sync);
|
|
||||||
base_video_decoder_class->handle_frame =
|
base_video_decoder_class->handle_frame =
|
||||||
GST_DEBUG_FUNCPTR (gst_schro_dec_handle_frame);
|
GST_DEBUG_FUNCPTR (gst_schro_dec_handle_frame);
|
||||||
base_video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_schro_dec_finish);
|
base_video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_schro_dec_finish);
|
||||||
|
|
||||||
|
gst_base_video_decoder_class_set_capture_pattern (base_video_decoder_class,
|
||||||
|
0xffffffff, 0x42424344);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -536,35 +535,6 @@ gst_schro_dec_parse_data (GstBaseVideoDecoder * base_video_decoder,
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
gst_schro_dec_scan_for_sync (GstBaseVideoDecoder * base_video_decoder,
|
|
||||||
gboolean at_eos, int offset, int n)
|
|
||||||
{
|
|
||||||
GstAdapter *adapter = base_video_decoder->input_adapter;
|
|
||||||
int n_available;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
n_available = gst_adapter_available (adapter) - offset;
|
|
||||||
|
|
||||||
if (n_available < 4) {
|
|
||||||
if (at_eos) {
|
|
||||||
return n_available;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
n = MIN (n, n_available - 3);
|
|
||||||
|
|
||||||
ret = gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x42424344,
|
|
||||||
offset, n);
|
|
||||||
if (ret == -1) {
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_schrodec_send_tags (GstSchroDec * schro_dec)
|
gst_schrodec_send_tags (GstSchroDec * schro_dec)
|
||||||
{
|
{
|
||||||
|
|
|
@ -862,32 +862,36 @@ gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf)
|
||||||
GST_DEBUG ("no sync, scanning");
|
GST_DEBUG ("no sync, scanning");
|
||||||
|
|
||||||
n = gst_adapter_available (base_video_decoder->input_adapter);
|
n = gst_adapter_available (base_video_decoder->input_adapter);
|
||||||
m = klass->scan_for_sync (base_video_decoder, FALSE, 0, n);
|
if (klass->capture_mask != 0) {
|
||||||
|
m = gst_adapter_masked_scan_uint32 (base_video_decoder->input_adapter,
|
||||||
|
klass->capture_mask, klass->capture_pattern, 0, n - 3);
|
||||||
|
} else if (klass->scan_for_sync) {
|
||||||
|
m = klass->scan_for_sync (base_video_decoder, FALSE, 0, n);
|
||||||
|
} else {
|
||||||
|
m = 0;
|
||||||
|
}
|
||||||
if (m == -1) {
|
if (m == -1) {
|
||||||
|
GST_ERROR ("scan returned no sync");
|
||||||
|
gst_adapter_flush (base_video_decoder->input_adapter, n - 3);
|
||||||
|
|
||||||
gst_object_unref (base_video_decoder);
|
gst_object_unref (base_video_decoder);
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
} else {
|
||||||
|
if (m > 0) {
|
||||||
|
if (m >= n) {
|
||||||
|
GST_ERROR ("subclass scanned past end %d >= %d", m, n);
|
||||||
|
}
|
||||||
|
|
||||||
if (m < 0) {
|
gst_adapter_flush (base_video_decoder->input_adapter, m);
|
||||||
g_warning ("subclass returned negative scan %d", m);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m >= n) {
|
if (m < n) {
|
||||||
GST_ERROR ("subclass scanned past end %d >= %d", m, n);
|
GST_DEBUG ("found possible sync after %d bytes (of %d)", m, n);
|
||||||
}
|
|
||||||
|
|
||||||
gst_adapter_flush (base_video_decoder->input_adapter, m);
|
/* this is only "maybe" sync */
|
||||||
|
base_video_decoder->have_sync = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m < n) {
|
|
||||||
GST_DEBUG ("found possible sync after %d bytes (of %d)", m, n);
|
|
||||||
|
|
||||||
/* this is only "maybe" sync */
|
|
||||||
base_video_decoder->have_sync = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!base_video_decoder->have_sync) {
|
|
||||||
gst_object_unref (base_video_decoder);
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1496,3 +1500,13 @@ gst_base_video_decoder_get_max_decode_time (GstBaseVideoDecoder *
|
||||||
|
|
||||||
return deadline;
|
return deadline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_base_video_decoder_class_set_capture_pattern (GstBaseVideoDecoderClass *
|
||||||
|
base_video_decoder_class, guint32 mask, guint32 pattern)
|
||||||
|
{
|
||||||
|
g_return_if_fail (((~mask) & pattern) == 0);
|
||||||
|
|
||||||
|
base_video_decoder_class->capture_mask = mask;
|
||||||
|
base_video_decoder_class->capture_pattern = pattern;
|
||||||
|
}
|
||||||
|
|
|
@ -137,10 +137,15 @@ struct _GstBaseVideoDecoderClass
|
||||||
GstFlowReturn (*shape_output) (GstBaseVideoDecoder *coder, GstVideoFrame *frame);
|
GstFlowReturn (*shape_output) (GstBaseVideoDecoder *coder, GstVideoFrame *frame);
|
||||||
GstCaps *(*get_caps) (GstBaseVideoDecoder *coder);
|
GstCaps *(*get_caps) (GstBaseVideoDecoder *coder);
|
||||||
|
|
||||||
|
guint32 capture_mask;
|
||||||
|
guint32 capture_pattern;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_base_video_decoder_get_type (void);
|
GType gst_base_video_decoder_get_type (void);
|
||||||
|
|
||||||
|
void gst_base_video_decoder_class_set_capture_pattern (GstBaseVideoDecoderClass *klass,
|
||||||
|
guint32 mask, guint32 pattern);
|
||||||
|
|
||||||
int gst_base_video_decoder_get_width (GstBaseVideoDecoder *coder);
|
int gst_base_video_decoder_get_width (GstBaseVideoDecoder *coder);
|
||||||
int gst_base_video_decoder_get_height (GstBaseVideoDecoder *coder);
|
int gst_base_video_decoder_get_height (GstBaseVideoDecoder *coder);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue