gstreamer/sys/androidmedia/gstamcvideodec.h
Matthew Waters f2ca0eaf27 amcviddec: output external-oes textures
This provides a performance and power usage improvement by removing
the texture copy from an OES texture to 2D texture.

The flow is as follows
1. Generate the output buffer with the required sync meta with the incrementing
   push counter and OES GL memory
1.1 release_output_buffer (buf, render=true) and push downstream
2. Downstream waits for on the sync meta (timed wait) or drops the frame (no wait)
2.1 Timed wait for the frame number to reach the number of frame callbacks fired
2.2 Unconditionally update the image when the wait completes (success or fail).
    Sets the affine transformation matrix meta on the buffer.
3. Downstream renders as usual.

At *some* point through this the on_frame_callback may or may not fire.  If it
does fire, we can finish waiting early and render. Otherwise we have to
wait for a timeout to occur which may cause more buffers to be pused into the
internal GL queue which siginificantly decreases the chances of the
on_frame_callback to fire again.  This is because the frame callback only occurs
when the internal GL queue changes state from empty to non-empty.

Because there is no way to reliably correlate between the number of buffers
pushed and the number of frame callbacks received, there are a number of
workarounds in place.
1. We self-increment the ready counter when it falls behind the push counter
2. Time based waits as the frame callback may not be fired for a certain frame.
3. It is assumed that the device can render at speed or performs some QoS of
   the interal GL queue (which may not match the GStreamer QoS).

It holds that we call SurfaceTexture::updateTexImage for each buffer pushed
downstream however there's no guarentee that updateTexImage will result in
the exact next frame (it could skip or duplicate) so synchronization is not
guaranteed to be accurate although it seems to be close enough to be unable
to discern visually.  This has not changed from before this patch.  The current
requirement for synchronization is that updateTexImage is called at the point in
time when the buffers is to be rendered.

https://bugzilla.gnome.org/show_bug.cgi?id=757285
2015-11-17 15:27:26 +11:00

126 lines
3.3 KiB
C

/*
* Copyright (C) 2012, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_AMC_VIDEO_DEC_H__
#define __GST_AMC_VIDEO_DEC_H__
#include <gst/gst.h>
#include <gst/gl/gl.h>
#include <gst/video/gstvideodecoder.h>
#include "gstamc.h"
#include "gstamcsurface.h"
G_BEGIN_DECLS
#define GST_TYPE_AMC_VIDEO_DEC \
(gst_amc_video_dec_get_type())
#define GST_AMC_VIDEO_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AMC_VIDEO_DEC,GstAmcVideoDec))
#define GST_AMC_VIDEO_DEC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AMC_VIDEO_DEC,GstAmcVideoDecClass))
#define GST_AMC_VIDEO_DEC_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_AMC_VIDEO_DEC,GstAmcVideoDecClass))
#define GST_IS_AMC_VIDEO_DEC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AMC_VIDEO_DEC))
#define GST_IS_AMC_VIDEO_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AMC_VIDEO_DEC))
typedef struct _GstAmcVideoDec GstAmcVideoDec;
typedef struct _GstAmcVideoDecClass GstAmcVideoDecClass;
typedef enum _GstAmcCodecConfig GstAmcCodecConfig;
enum _GstAmcCodecConfig
{
AMC_CODEC_CONFIG_NONE,
AMC_CODEC_CONFIG_WITH_SURFACE,
AMC_CODEC_CONFIG_WITHOUT_SURFACE,
};
struct _GstAmcVideoDec
{
GstVideoDecoder parent;
/* < private > */
GstAmcCodec *codec;
GstAmcCodecConfig codec_config;
GstVideoCodecState *input_state;
gboolean input_state_changed;
/* Output format of the codec */
GstVideoFormat format;
GstAmcColorFormatInfo color_format_info;
/* Output dimensions */
guint width;
guint height;
guint8 *codec_data;
gsize codec_data_size;
/* TRUE if the component is configured and saw
* the first buffer */
gboolean started;
gboolean flushing;
GstClockTime last_upstream_ts;
/* Draining state */
GMutex drain_lock;
GCond drain_cond;
/* TRUE if EOS buffers shouldn't be forwarded */
gboolean draining;
/* TRUE if the component is drained currently */
gboolean drained;
GstAmcSurface *surface;
GstGLDisplay *gl_display;
GstGLContext *gl_context;
GstGLContext *other_gl_context;
gboolean downstream_supports_gl;
GstFlowReturn downstream_flow_ret;
gboolean gl_mem_attached;
GstGLMemory *oes_mem;
GError *gl_error;
GMutex gl_lock;
GCond gl_cond;
guint gl_last_rendered_frame;
guint gl_pushed_frame_count; /* n buffers pushed */
guint gl_ready_frame_count; /* n buffers ready for GL access */
guint gl_rendered_frame_count; /* n buffers rendered */
GQueue *gl_queue;
};
struct _GstAmcVideoDecClass
{
GstVideoDecoderClass parent_class;
const GstAmcCodecInfo *codec_info;
};
GType gst_amc_video_dec_get_type (void);
G_END_DECLS
#endif /* __GST_AMC_VIDEO_DEC_H__ */