mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 18:35:35 +00:00
oggmux: implement vp8 granulepos function
Add an extra function to the oggstream map to inform it about the incoming buffers. This way oggmux can keep a count on the vp8 invisible frames and calculate the granulepos correctly. https://bugzilla.gnome.org/show_bug.cgi?id=722682
This commit is contained in:
parent
e00c306571
commit
a2633b7cf1
4 changed files with 60 additions and 6 deletions
|
@ -524,6 +524,8 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
|||
GST_DEBUG_OBJECT (ogg,
|
||||
"%p streaming to peer serial %08x", pad, pad->map.serialno);
|
||||
|
||||
gst_ogg_stream_update_stats (&pad->map, packet);
|
||||
|
||||
if (pad->map.is_ogm) {
|
||||
const guint8 *data;
|
||||
long bytes;
|
||||
|
|
|
@ -847,7 +847,11 @@ gst_ogg_mux_decorate_buffer (GstOggMux * ogg_mux, GstOggPadData * pad,
|
|||
gst_buffer_map (buf, &map, GST_MAP_READ);
|
||||
packet.packet = map.data;
|
||||
packet.bytes = map.size;
|
||||
|
||||
gst_ogg_stream_update_stats (&pad->map, &packet);
|
||||
|
||||
duration = gst_ogg_stream_get_packet_duration (&pad->map, &packet);
|
||||
|
||||
gst_buffer_unmap (buf, &map);
|
||||
|
||||
/* give up if no duration can be determined, relying on upstream */
|
||||
|
|
|
@ -69,6 +69,8 @@ typedef gint64 (*GstOggMapGranuleposToKeyGranuleFunc) (GstOggStream * pad,
|
|||
gint64 granulepos);
|
||||
|
||||
typedef GstBuffer *(*GstOggMapGetHeadersFunc) (GstOggStream * pad);
|
||||
typedef void (*GstOggMapUpdateStatsFunc) (GstOggStream * pad,
|
||||
ogg_packet * packet);
|
||||
|
||||
#define SKELETON_FISBONE_MIN_SIZE 52
|
||||
#define SKELETON_FISHEAD_3_3_MIN_SIZE 112
|
||||
|
@ -91,6 +93,7 @@ struct _GstOggMap
|
|||
GstOggMapGranuleposToKeyGranuleFunc granulepos_to_key_granule_func;
|
||||
GstOggMapExtractTagsFunc extract_tags_func;
|
||||
GstOggMapGetHeadersFunc get_headers_func;
|
||||
GstOggMapUpdateStatsFunc update_stats_func;
|
||||
};
|
||||
|
||||
extern const GstOggMap mappers[];
|
||||
|
@ -280,6 +283,15 @@ gst_ogg_stream_get_headers (GstOggStream * pad)
|
|||
return mappers[pad->map].get_headers_func (pad);
|
||||
}
|
||||
|
||||
void
|
||||
gst_ogg_stream_update_stats (GstOggStream * pad, ogg_packet * packet)
|
||||
{
|
||||
if (!mappers[pad->map].get_headers_func)
|
||||
return;
|
||||
|
||||
return mappers[pad->map].update_stats_func (pad, packet);
|
||||
}
|
||||
|
||||
/* some generic functions */
|
||||
|
||||
static gboolean
|
||||
|
@ -742,11 +754,14 @@ static gint64
|
|||
granule_to_granulepos_vp8 (GstOggStream * pad, gint64 granule,
|
||||
gint64 keyframe_granule)
|
||||
{
|
||||
/* FIXME: This requires to look into the content of the packets
|
||||
* because the simple granule counter doesn't know about invisible
|
||||
* frames...
|
||||
*/
|
||||
return -1;
|
||||
guint inv;
|
||||
gint64 granulepos;
|
||||
|
||||
inv = (pad->invisible_count <= 0) ? 0x3 : pad->invisible_count - 1;
|
||||
|
||||
granulepos =
|
||||
(granule << 32) | (inv << 30) | ((granule - keyframe_granule) << 3);
|
||||
return granulepos;
|
||||
}
|
||||
|
||||
/* Check if this packet contains an invisible frame or not */
|
||||
|
@ -813,6 +828,18 @@ get_headers_vp8 (GstOggStream * pad)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
update_stats_vp8 (GstOggStream * pad, ogg_packet * packet)
|
||||
{
|
||||
if (packet_duration_vp8 (pad, packet)) {
|
||||
/* set to -1 as when we get thefirst invisible it should be
|
||||
* set to 0 */
|
||||
pad->invisible_count = -1;
|
||||
} else {
|
||||
pad->invisible_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* vorbis */
|
||||
|
||||
static gboolean
|
||||
|
@ -2221,6 +2248,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_constant,
|
||||
NULL,
|
||||
extract_tags_theora,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2236,6 +2264,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_vorbis,
|
||||
NULL,
|
||||
extract_tags_vorbis,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2251,6 +2280,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_constant,
|
||||
NULL,
|
||||
extract_tags_count,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2266,6 +2296,7 @@ const GstOggMap mappers[] = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2281,6 +2312,7 @@ const GstOggMap mappers[] = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2296,6 +2328,7 @@ const GstOggMap mappers[] = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2311,6 +2344,7 @@ const GstOggMap mappers[] = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2326,6 +2360,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_flac,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2341,6 +2376,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_flac,
|
||||
NULL,
|
||||
extract_tags_flac,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2355,6 +2391,7 @@ const GstOggMap mappers[] = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2370,6 +2407,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_constant,
|
||||
NULL,
|
||||
extract_tags_count,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2385,6 +2423,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_kate,
|
||||
NULL,
|
||||
extract_tags_kate,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2400,6 +2439,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_constant,
|
||||
granulepos_to_key_granule_dirac,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2415,7 +2455,8 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_vp8,
|
||||
granulepos_to_key_granule_vp8,
|
||||
extract_tags_vp8,
|
||||
get_headers_vp8
|
||||
get_headers_vp8,
|
||||
update_stats_vp8
|
||||
},
|
||||
{
|
||||
"OpusHead", 8, 0,
|
||||
|
@ -2430,6 +2471,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_opus,
|
||||
NULL,
|
||||
extract_tags_opus,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2445,6 +2487,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_ogm,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2460,6 +2503,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_constant,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2475,6 +2519,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_ogm,
|
||||
NULL,
|
||||
extract_tags_ogm,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
@ -2490,6 +2535,7 @@ const GstOggMap mappers[] = {
|
|||
packet_duration_constant,
|
||||
NULL,
|
||||
extract_tags_daala,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ struct _GstOggStream
|
|||
gboolean theora_has_zero_keyoffset;
|
||||
/* VP8 stuff */
|
||||
gboolean is_vp8;
|
||||
gint64 invisible_count;
|
||||
/* opus stuff */
|
||||
gint64 first_granpos;
|
||||
/* OGM stuff */
|
||||
|
@ -136,6 +137,7 @@ gint64 gst_ogg_stream_get_packet_duration (GstOggStream * pad, ogg_packet *packe
|
|||
void gst_ogg_stream_extract_tags (GstOggStream * pad, ogg_packet * packet);
|
||||
const char *gst_ogg_stream_get_media_type (GstOggStream * pad);
|
||||
GstBuffer *gst_ogg_stream_get_headers (GstOggStream *pad);
|
||||
void gst_ogg_stream_update_stats (GstOggStream * pad, ogg_packet * packet);
|
||||
|
||||
gboolean gst_ogg_map_parse_fisbone (GstOggStream * pad, const guint8 * data, guint size,
|
||||
guint32 * serialno, GstOggSkeleton *type);
|
||||
|
|
Loading…
Reference in a new issue