From 719027139e9e5327399c276b531445153f274dc3 Mon Sep 17 00:00:00 2001 From: Changtao Hu Date: Thu, 22 Jun 2017 09:05:36 +0800 Subject: [PATCH] gstreamer upgrade: ogg bugs Make patch for gstreamer upgrade Test: OK Signed-off-by: Changtao Hu CR-Id: AUTO00005189 --- ext/ogg/gstoggdemux.c | 62 ++++++++++++++++++++++++++++++++++++++++++++------ ext/ogg/gstoggstream.c | 19 ++++++++++++++-- ext/ogg/gstoggstream.h | 2 ++ 3 files changed, 74 insertions(+), 9 deletions(-) diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index 10c34a8..15356fb 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -49,6 +49,8 @@ /* we hope we get a granpos within this many bytes off the end */ #define DURATION_CHUNK_OFFSET (64*1024) +/*search max page count*/ +#define SEARCH_MAX_PAGE 75 /* An Ogg page can not be larger than 255 segments of 255 bytes, plus 26 bytes of header */ @@ -191,7 +193,9 @@ gst_ogg_pad_init (GstOggPad * pad) pad->map.granulerate_n = 0; pad->map.granulerate_d = 0; - pad->map.granuleshift = -1; + pad->map.granuleshift = 0; + pad->map.channel = 0; + pad->map.bitspersample = 0; } static void @@ -813,7 +817,8 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet, if (!packet->b_o_s || push_headers) { if (pad->last_ret == GST_FLOW_OK) { GST_LOG_OBJECT (ogg, "Pushing buf %" GST_PTR_FORMAT, buf); - ret = gst_pad_push (GST_PAD_CAST (pad), buf); + if (gst_buffer_get_size (buf) > 0) + ret = gst_pad_push (GST_PAD_CAST (pad), buf); } else { GST_DEBUG_OBJECT (ogg, "not pushing buffer on error pad"); ret = pad->last_ret; @@ -2682,6 +2687,7 @@ gst_ogg_demux_get_prev_page (GstOggDemux * ogg, ogg_page * og, gint64 * offset) gint64 begin = ogg->offset; gint64 end = begin; gint64 cur_offset = -1; + gint hit_limit_cnt = 0; GST_LOG_OBJECT (ogg, "getting page before %" G_GINT64_FORMAT, begin); @@ -2712,7 +2718,12 @@ gst_ogg_demux_get_prev_page (GstOggDemux * ogg, ogg_page * og, gint64 * offset) ret = gst_ogg_demux_get_next_page (ogg, og, boundary, &new_offset); /* we hit the upper limit, offset contains the last page start */ if (ret == GST_FLOW_LIMIT) { - GST_LOG_OBJECT (ogg, "hit limit"); + hit_limit_cnt++; + GST_INFO_OBJECT (ogg, "hit limit, cnt=%d", hit_limit_cnt); + if (hit_limit_cnt >= 3){ + ret = GST_FLOW_OK; + goto beach; + } break; } /* something went wrong */ @@ -2899,8 +2910,12 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain, gst_ogg_pad_mark_discont (pad); pad->last_ret = GST_FLOW_OK; + GST_DEBUG_OBJECT (ogg, + "serialno %08x time %" GST_TIME_FORMAT, + pad->map.serialno, GST_TIME_ARGS (pad->start_time)); + if (pad->map.is_skeleton || pad->map.is_cmml || pad->added - || !pad->map.caps) + || !pad->map.caps || (pad->start_time == GST_CLOCK_TIME_NONE)) continue; GST_DEBUG_OBJECT (ogg, "adding pad %" GST_PTR_FORMAT, pad); @@ -4003,6 +4018,7 @@ gst_ogg_demux_read_chain (GstOggDemux * ogg, GstOggChain ** res_chain) gint64 offset = ogg->offset; ogg_page og; gboolean done; + gint loop_page_cnt = 0; gint i; GST_LOG_OBJECT (ogg, "reading chain at %" G_GINT64_FORMAT, offset); @@ -4114,7 +4130,7 @@ gst_ogg_demux_read_chain (GstOggDemux * ogg, GstOggChain ** res_chain) if (!pad->map.is_sparse) done &= (pad->start_time != GST_CLOCK_TIME_NONE); - GST_LOG_OBJECT (ogg, "done %08x now %d", pad->map.serialno, done); + GST_LOG_OBJECT (ogg, "done %08x now %d time %" GST_TIME_FORMAT, pad->map.serialno, done, GST_TIME_ARGS (pad->start_time)); } /* we read a page not belonging to the current chain: seek back to the @@ -4126,8 +4142,14 @@ gst_ogg_demux_read_chain (GstOggDemux * ogg, GstOggChain ** res_chain) break; } + if ((loop_page_cnt >= SEARCH_MAX_PAGE) && (done == FALSE)) { + done = TRUE; + GST_ERROR_OBJECT (ogg, "(loop_page_cnt >= SEARCH_MAX_PAGE) && (done == FALSE)"); + break; + } if (!done) { ret = gst_ogg_demux_get_next_page (ogg, &og, -1, NULL); + loop_page_cnt++; if (ret != GST_FLOW_OK) break; } @@ -4154,6 +4176,7 @@ gst_ogg_demux_read_end_chain (GstOggDemux * ogg, GstOggChain * chain) gboolean done = FALSE; ogg_page og; gint i; + gint hit_limit_count = 0; while (!done) { begin -= ogg->chunk_size; @@ -4168,8 +4191,14 @@ gst_ogg_demux_read_end_chain (GstOggDemux * ogg, GstOggChain * chain) while (ogg->offset < end) { ret = gst_ogg_demux_get_next_page (ogg, &og, end - ogg->offset, NULL); - if (ret == GST_FLOW_LIMIT) + if (ret == GST_FLOW_LIMIT) { + hit_limit_count++; + GST_INFO_OBJECT (ogg, "hit_limit_count=%d", hit_limit_count); + if (hit_limit_count >= 3) { + done = TRUE; + } break; + } if (ret != GST_FLOW_OK) return ret; @@ -4313,6 +4342,12 @@ gst_ogg_demux_find_chains (GstOggDemux * ogg) GstOggChain *chain; GstFlowReturn ret; + /*init og header and body*/ + og.header_len = 0; + og.body_len = 0; + og.header = NULL; + og.body = NULL; + /* get peer to figure out length */ if ((peer = gst_pad_get_peer (ogg->sinkpad)) == NULL) goto no_peer; @@ -4344,7 +4379,20 @@ gst_ogg_demux_find_chains (GstOggDemux * ogg) if (ret != GST_FLOW_OK) goto no_last_page; - serialno = ogg_page_serialno (&og); + GST_DEBUG_OBJECT (ogg, "ogg_page_serialno,og.header_len=%d,og.body_len=%d",og.header_len,og.body_len); + if ((og.header_len > 27) && (og.header_len <= (27 + 255))) { + serialno = ogg_page_serialno (&og); + } + else { + gint i; + for (i = 0; i < chain->streams->len; i++) { + GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i); + if (pad != NULL) { + serialno = pad->map.serialno; + break; + } + } + } if (!gst_ogg_chain_has_stream (chain, serialno)) { /* the last page is not in the first stream, this means we should diff --git a/ext/ogg/gstoggstream.c b/ext/ogg/gstoggstream.c index 8426e46..e332156 100644 --- a/ext/ogg/gstoggstream.c +++ b/ext/ogg/gstoggstream.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -1599,16 +1600,30 @@ setup_ogmaudio_mapper (GstOggStream * pad, ogg_packet * packet) GST_DEBUG ("fourcc: %s", fstr); /* FIXME: Need to do something with the reorder map */ + gchar *pchar=NULL; + guint16 n_fourcc=strtol((const char *)fstr,&pchar,16); + + pad->channel = GST_READ_UINT16_LE (data + 45); + pad->bitspersample = GST_READ_UINT32_LE (data + 41); pad->caps = - gst_riff_create_audio_caps (fourcc, NULL, NULL, NULL, NULL, NULL, NULL); + gst_riff_create_audio_caps (n_fourcc, NULL, NULL, NULL, NULL, NULL, NULL); - GST_LOG ("sample rate: %d", pad->granulerate_n); + GST_LOG ("sample rate: %d,pad->channel: %d", pad->granulerate_n, pad->channel); if (pad->granulerate_n == 0) return FALSE; if (pad->caps) { gst_caps_set_simple (pad->caps, "rate", G_TYPE_INT, pad->granulerate_n, NULL); + gst_caps_set_simple (pad->caps, + "channels", G_TYPE_INT, pad->channel, NULL); + if (GST_RIFF_WAVE_FORMAT_PCM == n_fourcc) { + GstAudioFormat format; + gint wd = GST_ROUND_UP_8 (pad->bitspersample); + format = gst_audio_format_build_integer (wd != 8, G_LITTLE_ENDIAN, wd, wd); + gst_caps_set_simple (pad->caps, + "format", G_TYPE_STRING, gst_audio_format_to_string (format), NULL); + } } else { pad->caps = gst_caps_new_simple ("audio/x-ogm-unknown", "fourcc", G_TYPE_STRING, fstr, diff --git a/ext/ogg/gstoggstream.h b/ext/ogg/gstoggstream.h index d49527f..2822a93 100644 --- a/ext/ogg/gstoggstream.h +++ b/ext/ogg/gstoggstream.h @@ -111,6 +111,8 @@ struct _GstOggStream GstOggIndex *index; guint64 kp_denom; guint64 idx_bitrate; + guint16 channel; + guint32 bitspersample; }; -- 1.9.1