mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-09 05:38:58 +00:00
This allows: * Better duration estimation * More accurate PCR location * Overall more accurate running-time location and calculation Location and values of PCR are recorded in groups (PCROffsetGroup) with notable PCR/Offset observations in them (when bitrate changed for example). PCR and offset are stored as 32bit values to reduce memory usage (they are differences against that group's first_{pcr|offset}. Those groups each contain a global PCR offset (pcr_offset) which indicates how far in the stream that group is. Whenever new PCR values are observed, we store them in a sliding window estimator (PCROffsetGroupCurrent). When a reset/wrapover/gap is detected, we close the current group with current values and start a new one (the pcr_offset of that new group is also calculated). When a notable change in bitrate is observed (+/- 10%), we record new values in the current group. This is a compromise between storing all PCR/offset observations and none, while at the same time providing better information for running-time<=>offset calculation in VBR streams. Whenever a new non-contiguous group is start (due to seeking for example) we re-evaluate the pcr_offset of each groups. This allows detecting as quickly as possible PCR wrapover/reset. When wanting to find the offset of a certain running-time, one can iterate the groups by looking at the pcr_offset (which in essence *is* the running-time of that group in the overall stream). Once a group (or neighbouring groups if the running-time is between two groups) is found, once can use the recorded values to find the most accurate offset. Right now this code is only used in pull-mode , but could also be activated later on for any seekable stream, like live timeshift with queue2. Future improvements: * some heuristics to "compress" the stored values in groups so as to keep the memory usage down while still keeping a decent amount of notable points. * After a seek compare expected and obtained PCR/Offset and if the difference is too big, re-calculate position with newly observed values and seek to that more accurate position. Note that this code will *not* provide keyframe-accurate seeking, but will allow a much more accurate PCR/running-time/offset location on any random stream. For past (observed) values it will be as accurate as can be. For future values it will be better than the current situation. Finally the more you seek, the more accurate your positioning will be.
118 lines
4.4 KiB
C
118 lines
4.4 KiB
C
/*
|
|
*
|
|
* 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.
|
|
*
|
|
* The Original Code is Fluendo MPEG Demuxer plugin.
|
|
*
|
|
* The Initial Developer of the Original Code is Fluendo, S.L.
|
|
* Portions created by Fluendo, S.L. are Copyright (C) 2005
|
|
* Fluendo, S.L. All Rights Reserved.
|
|
*
|
|
* Contributor(s): Wim Taymans <wim@fluendo.com>
|
|
*/
|
|
|
|
#ifndef __GST_MPEG_DEFS_H__
|
|
#define __GST_MPEG_DEFS_H__
|
|
#include <glib/gprintf.h>
|
|
|
|
#define SAFE_FOURCC_FORMAT "02x%02x%02x%02x (%c%c%c%c)"
|
|
#define SAFE_CHAR(a) (g_ascii_isalnum((gchar) (a)) ? ((gchar)(a)) : '.')
|
|
#define SAFE_FOURCC_ARGS(a) \
|
|
((guint8) ((a)>>24)), \
|
|
((guint8) ((a) >> 16 & 0xff)), \
|
|
((guint8) a >> 8 & 0xff), \
|
|
((guint8) a & 0xff), \
|
|
SAFE_CHAR((a)>>24), \
|
|
SAFE_CHAR((a) >> 16 & 0xff), \
|
|
SAFE_CHAR((a) >> 8 & 0xff), \
|
|
SAFE_CHAR(a & 0xff)
|
|
|
|
/* Stream type assignments */
|
|
/* FIXME: Put these in mpegts lib separate stream type enums */
|
|
/* Un-official Dirac extension */
|
|
#define ST_VIDEO_DIRAC 0xd1
|
|
|
|
/* private stream types */
|
|
#define ST_PS_VIDEO_MPEG2_DCII 0x80
|
|
#define ST_PS_AUDIO_AC3 0x81
|
|
#define ST_PS_AUDIO_DTS 0x8a
|
|
#define ST_PS_AUDIO_LPCM 0x8b
|
|
#define ST_PS_DVD_SUBPICTURE 0xff
|
|
|
|
/* Blu-ray related (registration: 'HDMV'*/
|
|
#define ST_BD_AUDIO_LPCM 0x80
|
|
#define ST_BD_AUDIO_AC3 0x81
|
|
#define ST_BD_AUDIO_DTS 0x82
|
|
#define ST_BD_AUDIO_AC3_TRUE_HD 0x83
|
|
#define ST_BD_AUDIO_AC3_PLUS 0x84
|
|
#define ST_BD_AUDIO_DTS_HD 0x85
|
|
#define ST_BD_AUDIO_DTS_HD_MASTER_AUDIO 0x86
|
|
#define ST_BD_AUDIO_EAC3 0x87
|
|
#define ST_BD_PGS_SUBPICTURE 0x90
|
|
#define ST_BD_IGS 0x91
|
|
#define ST_BD_SUBTITLE 0x92
|
|
#define ST_BD_SECONDARY_AC3_PLUS 0xa1
|
|
#define ST_BD_SECONDARY_DTS_HD 0xa2
|
|
|
|
/* defined for VC1 extension in RP227 */
|
|
#define ST_PRIVATE_EA 0xea
|
|
|
|
/* Following only apply for streams identified as HDV,
|
|
* According to specification 61834-11 the PMT will use
|
|
* a registration descriptor with values TSMV or TSHV */
|
|
/* HDV AUX stream mapping
|
|
* 0xA0 ISO/IEC 61834-11
|
|
* 0xA1 ISO/IEC 61834-11
|
|
*/
|
|
#define ST_HDV_AUX_A 0xa0
|
|
#define ST_HDV_AUX_V 0xa1
|
|
|
|
#define CLOCK_BASE 9LL
|
|
#define CLOCK_FREQ (CLOCK_BASE * 10000)
|
|
|
|
/* Numerical values for second/millisecond in PCR units */
|
|
#define PCR_SECOND 27000000
|
|
#define PCR_MSECOND 27000
|
|
|
|
/* PCR_TO_GST calculation requires at least 10 extra bits.
|
|
* Since maximum PCR value is coded with 42 bits, we are
|
|
* safe to use direct calculation (10+42 < 63)*/
|
|
#define PCRTIME_TO_GSTTIME(t) ((t) * 1000 / 27)
|
|
|
|
/* MPEG_TO_GST calculation requires at least 17 extra bits (100000)
|
|
* Since maximum PTS/DTS value is coded with 33bits, we are
|
|
* safe to use direct calculation (17+33 < 63) */
|
|
#define MPEGTIME_TO_GSTTIME(t) ((t) * 100000 / 9)
|
|
|
|
#define GSTTIME_TO_MPEGTIME(time) (gst_util_uint64_scale ((time), \
|
|
CLOCK_BASE, GST_MSECOND/10))
|
|
#define GSTTIME_TO_PCRTIME(time) (gst_util_uint64_scale ((time), \
|
|
300 * CLOCK_BASE, GST_MSECOND/10))
|
|
|
|
#define MPEG_MUX_RATE_MULT 50
|
|
|
|
/* sync:4 == 00xx ! pts:3 ! 1 ! pts:15 ! 1 | pts:15 ! 1 */
|
|
#define READ_TS(data, target, lost_sync_label) \
|
|
if ((*data & 0x01) != 0x01) goto lost_sync_label; \
|
|
target = ((guint64) (*data++ & 0x0E)) << 29; \
|
|
target |= ((guint64) (*data++ )) << 22; \
|
|
if ((*data & 0x01) != 0x01) goto lost_sync_label; \
|
|
target |= ((guint64) (*data++ & 0xFE)) << 14; \
|
|
target |= ((guint64) (*data++ )) << 7; \
|
|
if ((*data & 0x01) != 0x01) goto lost_sync_label; \
|
|
target |= ((guint64) (*data++ & 0xFE)) >> 1;
|
|
|
|
#endif /* __GST_MPEG_DEFS_H__ */
|