Files
2026-08-24 10:03:24 +08:00

268 lines
9.0 KiB
C

/*
* mpegtsbase.h - GStreamer MPEG transport stream base class
* Copyright (C) 2009 Edward Hervey <[email protected]>
* 2007 Alessandro Decina
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
* Author: Youness Alaoui <[email protected]>, Collabora Ltd.
* Author: Sebastian Dröge <[email protected]>, Collabora Ltd.
*
* Authors:
* Alessandro Decina <[email protected]>
* Edward Hervey <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef GST_AML_TS_BASE_H
#define GST_AML_TS_BASE_H
#include <gst/gst.h>
#include "amltspacketizer.h"
G_BEGIN_DECLS
#define GST_TYPE_AMLTS_BASE \
(amlts_base_get_type())
#define GST_AMLTS_BASE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AMLTS_BASE,AmlTSBase))
#define GST_AMLTS_BASE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AMLTS_BASE,AmlTSBaseClass))
#define GST_IS_AMLTS_BASE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AMLTS_BASE))
#define GST_IS_AMLTS_BASE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AMLTS_BASE))
#define GST_AMLTS_BASE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_AMLTS_BASE, AmlTSBaseClass))
#define AML_TS_BASE_PACKETIZER(b) (((AmlTSBase*)b)->packetizer)
typedef struct _AmlTSBase AmlTSBase;
typedef struct _AmlTSBaseClass AmlTSBaseClass;
typedef struct _AmlTSBaseStream AmlTSBaseStream;
typedef struct _AmlTSBaseProgram AmlTSBaseProgram;
struct _AmlTSBaseStream
{
guint16 pid;
guint8 stream_type;
/* Content of the registration descriptor (if present) */
guint32 registration_id;
GstAmlMpegtsPMTStream *stream;
GstStream *stream_object;
gboolean in_collection;
gchar *stream_id;
};
struct _AmlTSBaseProgram
{
gint program_number;
guint16 pmt_pid;
guint16 pcr_pid;
/* Content of the registration descriptor (if present) */
guint32 registration_id;
GstAmlMpegtsSection *section;
const GstAmlMpegtsPMT *pmt;
AmlTSBaseStream **streams;
GList *stream_list;
gint patcount;
GstStreamCollection *collection;
/* Pending Tags for the program */
GstTagList *tags;
guint event_id;
/* TRUE if the program is currently being used */
gboolean active;
/* TRUE if this is the first program created */
gboolean initial_program;
/* TRUE if the program shouldn't be freed */
gboolean recycle;
};
typedef enum {
/* PULL MODE */
BASE_MODE_SCANNING, /* Looking for PAT/PMT */
BASE_MODE_SEEKING, /* Seeking */
BASE_MODE_STREAMING, /* Normal mode (pushing out data) */
/* PUSH MODE */
BASE_MODE_PUSHING
} AmlTSBaseMode;
struct _AmlTSBase {
GstElement element;
GstPad *sinkpad;
/* pull-based behaviour */
AmlTSBaseMode mode;
/* Current pull offset (also set by seek handler) */
guint64 seek_offset;
/* Cached packetsize */
guint16 packetsize;
/* the following vars must be protected with the OBJECT_LOCK as they can be
* accessed from the application thread and the streaming thread */
GPtrArray *programs;
GPtrArray *pat;
AmlTSPacketizer2 *packetizer;
/* arrays that say whether a pid is a known psi pid or a pes pid */
/* Use MPEGTS_BIT_* to set/unset/check the values */
guint8 *known_psi;
guint8 *is_pes;
gboolean disposed;
/* size of the MpegTSBaseProgram structure, can be overridden
* by subclasses if they have their own MpegTSBaseProgram subclasses. */
gsize program_size;
/* size of the MpegTSBaseStream structure, can be overridden
* by subclasses if they have their own MpegTSBaseStream subclasses */
gsize stream_size;
/* Whether we saw a PAT yet */
gboolean seen_pat;
/* Upstream segment */
GstSegment segment;
/* Downstream segment, for use by sub-classes */
GstSegment out_segment;
/* Last received seek event seqnum (default GST_SEQNUM_INVALID) */
guint last_seek_seqnum;
/* Whether to parse private section or not */
gboolean parse_private_sections;
/* Whether to push data and/or sections to subclasses */
gboolean push_data;
gboolean push_section;
gboolean push_unknown;
/* Whether the parent bin is streams-aware, meaning we can
* add/remove streams at any point in time */
gboolean streams_aware;
/* save seek flag */
gboolean no_audio_set;
/* Do not use the PCR stream for timestamp calculation. Useful for
* streams with broken/invalid PCR streams. */
gboolean ignore_pcr;
/* Used for delayed seek events */
GstEvent *seek_event;
/* save buffers until handling A/V, probe stage. */
GstBufferList *probe_buflist;
/* after av start, push ts data again which be parsed for scanning AV. */
gboolean av_started;
gboolean push_scandata;
};
struct _AmlTSBaseClass {
GstElementClass parent_class;
/* Virtual methods */
void (*reset) (AmlTSBase *base);
GstFlowReturn (*push) (AmlTSBase *base, AmlTSPacketizerPacket *packet, GstAmlMpegtsSection * section);
void (*inspect_packet) (AmlTSBase *base, AmlTSPacketizerPacket *packet);
/* takes ownership of @event */
gboolean (*push_event) (AmlTSBase *base, GstEvent * event);
void (*handle_psi) (AmlTSBase *base, GstAmlMpegtsSection * section);
/* program_started gets called when program's pmt arrives for first time */
void (*program_started) (AmlTSBase *base, AmlTSBaseProgram *program);
/* program_stopped gets called when pat no longer has program's pmt */
void (*program_stopped) (AmlTSBase *base, AmlTSBaseProgram *program);
void (*update_program) (AmlTSBase *base, AmlTSBaseProgram *program);
/* Whether mpegtbase can deactivate/free a program or whether the subclass will do it
* If the subclass responds TRUE, it should call amlts_base_deactivate_and_free_program()
* when it wants to remove it */
gboolean (*can_remove_program) (AmlTSBase *base, AmlTSBaseProgram *program);
/* stream_added is called whenever a new stream has been identified */
gboolean (*stream_added) (AmlTSBase *base, AmlTSBaseStream *stream, AmlTSBaseProgram *program);
/* stream_removed is called whenever a stream is no longer referenced */
void (*stream_removed) (AmlTSBase *base, AmlTSBaseStream *stream);
/* find_timestamps is called to find PCR */
GstFlowReturn (*find_timestamps) (AmlTSBase * base, guint64 initoff, guint64 *offset);
/* seek is called to wait for seeking */
GstFlowReturn (*seek) (AmlTSBase * base, GstEvent * event);
/* Drain all currently pending data */
GstFlowReturn (*drain) (AmlTSBase * base);
/* flush all streams
* The hard inicator is used to flush completely on FLUSH_STOP events
* or partially in pull mode seeks of tsdemux */
void (*flush) (AmlTSBase * base, gboolean hard);
/* Notifies subclasses input buffer has been handled */
GstFlowReturn (*input_done) (AmlTSBase *base);
/* signals */
void (*pat_info) (GstStructure *pat);
void (*pmt_info) (GstStructure *pmt);
void (*nit_info) (GstStructure *nit);
void (*sdt_info) (GstStructure *sdt);
void (*eit_info) (GstStructure *eit);
/* takes ownership of @query */
gboolean (*sink_query) (AmlTSBase *base, GstQuery * query);
};
#define MPEGTS_BIT_SET(field, offs) ((field)[(offs) >> 3] |= (1 << ((offs) & 0x7)))
#define MPEGTS_BIT_UNSET(field, offs) ((field)[(offs) >> 3] &= ~(1 << ((offs) & 0x7)))
#define MPEGTS_BIT_IS_SET(field, offs) ((field)[(offs) >> 3] & (1 << ((offs) & 0x7)))
G_GNUC_INTERNAL GType amlts_base_get_type(void);
G_GNUC_INTERNAL AmlTSBaseProgram *amlts_base_get_program (AmlTSBase * base, gint program_number);
G_GNUC_INTERNAL AmlTSBaseProgram *amlts_base_add_program (AmlTSBase * base, gint program_number, guint16 pmt_pid);
G_GNUC_INTERNAL const GstAmlMpegtsDescriptor *amlts_get_descriptor_from_stream (AmlTSBaseStream * stream, guint8 tag);
G_GNUC_INTERNAL const GstAmlMpegtsDescriptor *amlts_get_descriptor_from_stream_with_extension (AmlTSBaseStream * stream, guint8 tag, guint8 tag_extension);
G_GNUC_INTERNAL const GstAmlMpegtsDescriptor *amlts_get_descriptor_from_program (AmlTSBaseProgram * program, guint8 tag);
G_GNUC_INTERNAL gboolean
amlts_base_handle_seek_event(AmlTSBase * base, GstPad * pad, GstEvent * event);
G_GNUC_INTERNAL gboolean gst_amltsbase_plugin_init (GstPlugin * plugin);
G_GNUC_INTERNAL void amlts_base_deactivate_and_free_program (AmlTSBase *base, AmlTSBaseProgram *program);
G_END_DECLS
#endif /* GST_AML_TS_BASE_H */