basevideodecoder: add documentation

... and remove some more stray unused code and methods.
This commit is contained in:
Mark Nauwelaerts 2011-03-30 09:15:13 +02:00
parent 04f4a583dd
commit f72658435b
2 changed files with 284 additions and 48 deletions

View file

@ -1,5 +1,8 @@
/* GStreamer
* Copyright (C) 2008 David Schleef <ds@schleef.org>
* Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
* Copyright (C) 2011 Nokia Corporation. All rights reserved.
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -17,6 +20,101 @@
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:gstbasevideodecoder
* @short_description: Base class for video decoders
* @see_also: #GstBaseTransform
*
* This base class is for video decoders turning encoded data into raw video
* frames.
*
* GstBaseVideoDecoder and subclass should cooperate as follows.
* <orderedlist>
* <listitem>
* <itemizedlist><title>Configuration</title>
* <listitem><para>
* Initially, GstBaseVideoDecoder calls @start when the decoder element
* is activated, which allows subclass to perform any global setup.
* </para></listitem>
* <listitem><para>
* GstBaseVideoDecoder calls @set_format to inform subclass of caps
* describing input video data that it is about to receive, including
* possibly configuration data.
* While unlikely, it might be called more than once, if changing input
* parameters require reconfiguration.
* </para></listitem>
* <listitem><para>
* GstBaseVideoDecoder calls @stop at end of all processing.
* </para></listitem>
* </itemizedlist>
* </listitem>
* <listitem>
* <itemizedlist>
* <title>Data processing</title>
* <listitem><para>
* Base class gathers input data, and optionally allows subclass
* to parse this into subsequently manageable chunks, typically
* corresponding to and referred to as 'frames'.
* </para></listitem>
* <listitem><para>
* Input frame is provided to subclass' @handle_frame.
* </para></listitem>
* <listitem><para>
* If codec processing results in decoded data, subclass should call
* @gst_base_video_decoder_finish_frame to have decoded data pushed
* downstream.
* </para></listitem>
* </itemizedlist>
* </listitem>
* <listitem>
* <itemizedlist><title>Shutdown phase</title>
* <listitem><para>
* GstBaseVideoDecoder class calls @stop to inform the subclass that data
* parsing will be stopped.
* </para></listitem>
* </itemizedlist>
* </listitem>
* </orderedlist>
*
* Subclass is responsible for providing pad template caps for
* source and sink pads. The pads need to be named "sink" and "src". It also
* needs to set the fixed caps on srcpad, when the format is ensured. This
* is typically when base class calls subclass' @set_format function, though
* it might be delayed until calling @gst_base_video_decoder_finish_frame.
*
* Subclass is also responsible for providing (presentation) timestamps
* (likely based on corresponding input ones). If that is not applicable
* or possible, baseclass provides limited framerate based interpolation.
*
* Similarly, the baseclass provides some limited (legacy) seeking support
* (upon explicit subclass request), as full-fledged support
* should rather be left to upstream demuxer, parser or alike. This simple
* approach caters for seeking and duration reporting using estimated input
* bitrates.
*
* Things that subclass need to take care of:
* <itemizedlist>
* <listitem><para>Provide pad templates</para></listitem>
* <listitem><para>
* Set source pad caps when appropriate
* </para></listitem>
* <listitem><para>
* Configure some baseclass behaviour parameters.
* </para></listitem>
* <listitem><para>
* Optionally parse input data, if it is not considered packetized.
* Parse sync is obtained either by providing baseclass with a
* mask and pattern or a custom @scan_for_sync. When sync is established,
* @parse_data should invoke @gst_base_video_decoder_add_to_frame and
* @gst_base_video_decoder_have_frame as appropriate.
* </para></listitem>
* <listitem><para>
* Accept data in @handle_frame and provide decoded results to
* @gst_base_video_decoder_finish_frame.
* </para></listitem>
* </itemizedlist>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@ -1006,6 +1104,18 @@ gst_base_video_decoder_new_frame (GstBaseVideoDecoder * base_video_decoder)
return frame;
}
/**
* gst_base_video_decoder_finish_frame:
* @base_video_decoder: a #GstBaseVideoDecoder
* @frame: a decoded #GstVideoFrame
*
* @frame should have a valid decoded data buffer, whose metadata fields
* are then appropriately set according to frame data and pushed downstream.
* If no output data is provided, @frame is considered skipped.
* In any case, the frame is considered finished and released.
*
* Returns: a #GstFlowReturn resulting from sending data downstream
*/
GstFlowReturn
gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
GstVideoFrame * frame)
@ -1187,6 +1297,13 @@ done:
return ret;
}
/**
* gst_base_video_decoder_finish_frame:
* @base_video_decoder: a #GstBaseVideoDecoder
* @n_bytes: an encoded #GstVideoFrame
*
* Removes next @n_bytes of input data and adds it to currently parsed frame.
*/
void
gst_base_video_decoder_add_to_frame (GstBaseVideoDecoder * base_video_decoder,
int n_bytes)
@ -1263,7 +1380,15 @@ gst_base_video_decoder_get_field_duration (GstBaseVideoDecoder *
state->fps_n * 2);
}
/**
* gst_base_video_decoder_have_frame:
* @base_video_decoder: a #GstBaseVideoDecoder
*
* Gathers all data collected for currently parsed frame, gathers corresponding
* metadata and passes it along for further processing, i.e. @handle_frame.
*
* Returns: a #GstFlowReturn
*/
GstFlowReturn
gst_base_video_decoder_have_frame (GstBaseVideoDecoder * base_video_decoder)
{
@ -1341,20 +1466,24 @@ gst_base_video_decoder_have_frame_2 (GstBaseVideoDecoder * base_video_decoder)
return ret;
}
/**
* gst_base_video_decoder_get_state:
* @base_video_decoder: a #GstBaseVideoDecoder
*
* Returns: #GstVideoState describing format of video data.
*/
GstVideoState *
gst_base_video_decoder_get_state (GstBaseVideoDecoder * base_video_decoder)
{
return &GST_BASE_VIDEO_CODEC (base_video_decoder)->state;
}
void
gst_base_video_decoder_set_state (GstBaseVideoDecoder * base_video_decoder,
GstVideoState * state)
{
memcpy (&GST_BASE_VIDEO_CODEC (base_video_decoder)->state,
state, sizeof (*state));
}
/**
* gst_base_video_decoder_lost_sync:
* @base_video_decoder: a #GstBaseVideoDecoder
*
* Advances out-of-sync input data by 1 byte and marks it accordingly.
*/
void
gst_base_video_decoder_lost_sync (GstBaseVideoDecoder * base_video_decoder)
{
@ -1369,6 +1498,13 @@ gst_base_video_decoder_lost_sync (GstBaseVideoDecoder * base_video_decoder)
base_video_decoder->have_sync = FALSE;
}
/* FIXME not quite exciting; get rid of this ? */
/**
* gst_base_video_decoder_set_sync_point:
* @base_video_decoder: a #GstBaseVideoDecoder
*
* Marks current frame as a sync point, i.e. keyframe.
*/
void
gst_base_video_decoder_set_sync_point (GstBaseVideoDecoder * base_video_decoder)
{
@ -1378,6 +1514,12 @@ gst_base_video_decoder_set_sync_point (GstBaseVideoDecoder * base_video_decoder)
base_video_decoder->distance_from_sync = 0;
}
/**
* gst_base_video_decoder_get_oldest_frame:
* @base_video_decoder: a #GstBaseVideoDecoder
*
* Returns: oldest pending unfinished #GstVideoFrame.
*/
GstVideoFrame *
gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder *
base_video_decoder)
@ -1391,6 +1533,13 @@ gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder *
return (GstVideoFrame *) (g->data);
}
/**
* gst_base_video_decoder_get_frame:
* @base_video_decoder: a #GstBaseVideoDecoder
* @frame_number: system_frame_number of a frame
*
* Returns: pending unfinished #GstVideoFrame identified by @frame_number.
*/
GstVideoFrame *
gst_base_video_decoder_get_frame (GstBaseVideoDecoder * base_video_decoder,
int frame_number)
@ -1409,6 +1558,13 @@ gst_base_video_decoder_get_frame (GstBaseVideoDecoder * base_video_decoder,
return NULL;
}
/**
* gst_base_video_decoder_set_src_caps:
* @base_video_decoder: a #GstBaseVideoDecoder
*
* Sets src pad caps according to currently configured #GstVideoState.
*
*/
void
gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder)
{
@ -1434,6 +1590,16 @@ gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder)
gst_caps_unref (caps);
}
/**
* gst_base_video_decoder_alloc_src_buffer:
* @base_video_decoder: a #GstBaseVideoDecoder
*
* Helper function that uses gst_pad_alloc_buffer_and_set_caps
* to allocate a buffer to hold a video frame for @base_video_decoder's
* current #GstVideoState.
*
* Returns: allocated buffer
*/
GstBuffer *
gst_base_video_decoder_alloc_src_buffer (GstBaseVideoDecoder *
base_video_decoder)
@ -1464,6 +1630,17 @@ gst_base_video_decoder_alloc_src_buffer (GstBaseVideoDecoder *
return buffer;
}
/**
* gst_base_video_decoder_alloc_src_frame:
* @base_video_decoder: a #GstBaseVideoDecoder
* @frame: a #GstVideoFrame
*
* Helper function that uses gst_pad_alloc_buffer_and_set_caps
* to allocate a buffer to hold a video frame for @base_video_decoder's
* current #GstVideoState.
*
* Returns: result from pad alloc call
*/
GstFlowReturn
gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder *
base_video_decoder, GstVideoFrame * frame)
@ -1490,6 +1667,18 @@ gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder *
return flow_ret;
}
/**
* gst_base_video_decoder_get_max_decode_time:
* @base_video_decoder: a #GstBaseVideoDecoder
* @frame: a #GstVideoFrame
*
* Determines maximum possible decoding time for @frame that will
* allow it to decode and arrive in time (as determined by QoS messages).
* In particular, a negative result means decoding in time is no longer possible
* and should therefore occur as soon/skippy as possible.
*
* Returns: max decoding time.
*/
GstClockTimeDiff
gst_base_video_decoder_get_max_decode_time (GstBaseVideoDecoder *
base_video_decoder, GstVideoFrame * frame)
@ -1511,6 +1700,14 @@ gst_base_video_decoder_get_max_decode_time (GstBaseVideoDecoder *
return deadline;
}
/**
* gst_base_video_decoder_get_oldest_frame:
* @base_video_decoder_class: a #GstBaseVideoDecoderClass
*
* Sets the mask and pattern that will be scanned for to obtain parse sync.
* Note that a non-zero @mask implies that @scan_for_sync will be ignored.
*
*/
void
gst_base_video_decoder_class_set_capture_pattern (GstBaseVideoDecoderClass *
base_video_decoder_class, guint32 mask, guint32 pattern)

View file

@ -1,5 +1,8 @@
/* GStreamer
* Copyright (C) 2008 David Schleef <ds@schleef.org>
* Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
* Copyright (C) 2011 Nokia Corporation. All rights reserved.
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -66,6 +69,11 @@ G_BEGIN_DECLS
typedef struct _GstBaseVideoDecoder GstBaseVideoDecoder;
typedef struct _GstBaseVideoDecoderClass GstBaseVideoDecoderClass;
/**
* GstBaseVideoDecoder:
*
* The opaque #GstBaseVideoDecoder data structure.
*/
struct _GstBaseVideoDecoder
{
GstBaseVideoCodec base_video_codec;
@ -120,58 +128,89 @@ struct _GstBaseVideoDecoder
void *padding[GST_PADDING_LARGE];
};
/**
* GstBaseAudioDecoderClass:
* @start: Optional.
* Called when the element starts processing.
* Allows opening external resources.
* @stop: Optional.
* Called when the element stops processing.
* Allows closing external resources.
* @set_format: Notifies subclass of incoming data format (caps).
* @scan_for_sync: Optional.
* Allows subclass to obtain sync for subsequent parsing
* by custom means (above an beyond scanning for specific
* marker and mask).
* @parse_data: Required for non-packetized input.
* Allows chopping incoming data into manageable units (frames)
* for subsequent decoding.
* @reset: Optional.
* Allows subclass (codec) to perform post-seek semantics reset.
* @handle_frame: Provides input data frame to subclass.
* @finish: Optional.
* Called to request subclass to dispatch any pending remaining
* data (e.g. at EOS).
*
* Subclasses can override any of the available virtual methods or not, as
* needed. At minimum @handle_frame needs to be overridden, and @set_format
* and likely as well. If non-packetized input is supported or expected,
* @parse needs to be overridden as well.
*/
struct _GstBaseVideoDecoderClass
{
GstBaseVideoCodecClass base_video_codec_class;
gboolean (*set_format) (GstBaseVideoDecoder *coder, GstVideoState * state);
gboolean (*start) (GstBaseVideoDecoder *coder);
gboolean (*stop) (GstBaseVideoDecoder *coder);
gboolean (*reset) (GstBaseVideoDecoder *coder);
int (*scan_for_sync) (GstBaseVideoDecoder *decoder, gboolean at_eos,
int offset, int n);
GstFlowReturn (*parse_data) (GstBaseVideoDecoder *decoder, gboolean at_eos);
GstFlowReturn (*finish) (GstBaseVideoDecoder *coder);
GstFlowReturn (*handle_frame) (GstBaseVideoDecoder *coder, GstVideoFrame *frame);
GstFlowReturn (*shape_output) (GstBaseVideoDecoder *coder, GstVideoFrame *frame);
GstCaps *(*get_caps) (GstBaseVideoDecoder *coder);
gboolean (*start) (GstBaseVideoDecoder *coder);
guint32 capture_mask;
guint32 capture_pattern;
gboolean (*stop) (GstBaseVideoDecoder *coder);
int (*scan_for_sync) (GstBaseVideoDecoder *decoder, gboolean at_eos,
int offset, int n);
GstFlowReturn (*parse_data) (GstBaseVideoDecoder *decoder, gboolean at_eos);
gboolean (*set_format) (GstBaseVideoDecoder *coder, GstVideoState * state);
gboolean (*reset) (GstBaseVideoDecoder *coder);
GstFlowReturn (*finish) (GstBaseVideoDecoder *coder);
GstFlowReturn (*handle_frame) (GstBaseVideoDecoder *coder, GstVideoFrame *frame);
/*< private >*/
guint32 capture_mask;
guint32 capture_pattern;
/* FIXME before moving to base */
void *padding[GST_PADDING_LARGE];
void *padding[GST_PADDING_LARGE];
};
GType gst_base_video_decoder_get_type (void);
void gst_base_video_decoder_class_set_capture_pattern (GstBaseVideoDecoderClass *klass,
guint32 mask, guint32 pattern);
void gst_base_video_decoder_class_set_capture_pattern (GstBaseVideoDecoderClass *klass,
guint32 mask, guint32 pattern);
GstVideoFrame *gst_base_video_decoder_get_frame (GstBaseVideoDecoder *coder,
int frame_number);
GstVideoFrame *gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder *coder);
GstVideoFrame *gst_base_video_decoder_get_frame (GstBaseVideoDecoder *coder,
int frame_number);
GstVideoFrame *gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder *coder);
void gst_base_video_decoder_add_to_frame (GstBaseVideoDecoder *base_video_decoder,
int n_bytes);
GstFlowReturn gst_base_video_decoder_finish_frame (GstBaseVideoDecoder *base_video_decoder,
GstVideoFrame *frame);
GstFlowReturn
gst_base_video_decoder_have_frame (GstBaseVideoDecoder *base_video_decoder);
GstVideoState * gst_base_video_decoder_get_state (GstBaseVideoDecoder *base_video_decoder);
void gst_base_video_decoder_set_state (GstBaseVideoDecoder *base_video_decoder,
GstVideoState *state);
void gst_base_video_decoder_lost_sync (GstBaseVideoDecoder *base_video_decoder);
void gst_base_video_decoder_set_sync_point (GstBaseVideoDecoder *base_video_decoder);
void gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder *base_video_decoder);
GstBuffer * gst_base_video_decoder_alloc_src_buffer (GstBaseVideoDecoder *
base_video_decoder);
GstFlowReturn gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder *base_video_decoder,
GstVideoFrame *frame);
void gst_base_video_decoder_add_to_frame (GstBaseVideoDecoder *base_video_decoder,
int n_bytes);
void gst_base_video_decoder_lost_sync (GstBaseVideoDecoder *base_video_decoder);
GstFlowReturn gst_base_video_decoder_have_frame (GstBaseVideoDecoder *base_video_decoder);
void gst_base_video_decoder_set_sync_point (GstBaseVideoDecoder *base_video_decoder);
void gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder *base_video_decoder);
GstBuffer *gst_base_video_decoder_alloc_src_buffer (GstBaseVideoDecoder * base_video_decoder);
GstFlowReturn gst_base_video_decoder_alloc_src_frame (GstBaseVideoDecoder *base_video_decoder,
GstVideoFrame *frame);
GstVideoState *gst_base_video_decoder_get_state (GstBaseVideoDecoder *base_video_decoder);
GstClockTimeDiff gst_base_video_decoder_get_max_decode_time (
GstBaseVideoDecoder *base_video_decoder, GstVideoFrame *frame);
GstBaseVideoDecoder *base_video_decoder,
GstVideoFrame *frame);
GstFlowReturn gst_base_video_decoder_finish_frame (GstBaseVideoDecoder *base_video_decoder,
GstVideoFrame *frame);
GType gst_base_video_decoder_get_type (void);
G_END_DECLS