mpegtspacketizer: Improve ts_to_offset code

* Search in current pending values first. For CBR streams we can very
  easily end up having just one initial observations and then nothing
  else (since the bitrate doesn't change).
* Use one group whether we are in that group *OR* if there is only
  one group.
* If the group to use isn't closed (points are being accumulated in the
  PCROffsetCurrent), use the latest data available for calculation
* If in the unlikelyness that all of this *still* didn't produce more
  than one data point, just return the initial offset
This commit is contained in:
Edward Hervey 2014-04-18 16:23:43 +02:00
parent f96604099d
commit f062b78051

View file

@ -2211,6 +2211,7 @@ mpegts_packetizer_ts_to_offset (MpegTSPacketizer2 * packetizer,
guint64 res; guint64 res;
PCROffsetGroup *nextgroup = NULL, *prevgroup = NULL; PCROffsetGroup *nextgroup = NULL, *prevgroup = NULL;
guint64 querypcr, firstpcr, lastpcr, firstoffset, lastoffset; guint64 querypcr, firstpcr, lastpcr, firstoffset, lastoffset;
PCROffsetCurrent *current;
GList *tmp; GList *tmp;
if (!packetizer->calculate_offset) if (!packetizer->calculate_offset)
@ -2225,6 +2226,16 @@ mpegts_packetizer_ts_to_offset (MpegTSPacketizer2 * packetizer,
GST_DEBUG ("Searching offset for ts %" GST_TIME_FORMAT, GST_TIME_ARGS (ts)); GST_DEBUG ("Searching offset for ts %" GST_TIME_FORMAT, GST_TIME_ARGS (ts));
/* First check if we're within the current pending group */
current = pcrtable->current;
if (current && current->group && (querypcr >= current->group->pcr_offset) &&
querypcr - current->group->pcr_offset <=
current->pending[current->last].pcr) {
GST_DEBUG ("pcr is in current group");
nextgroup = current->group;
goto calculate_points;
}
/* Find the neighbouring groups */ /* Find the neighbouring groups */
for (tmp = pcrtable->groups; tmp; tmp = tmp->next) { for (tmp = pcrtable->groups; tmp; tmp = tmp->next) {
nextgroup = (PCROffsetGroup *) tmp->data; nextgroup = (PCROffsetGroup *) tmp->data;
@ -2256,15 +2267,25 @@ mpegts_packetizer_ts_to_offset (MpegTSPacketizer2 * packetizer,
} }
} }
if (nextgroup == prevgroup) { calculate_points:
GST_DEBUG ("In group");
firstoffset = prevgroup->first_offset; GST_DEBUG ("nextgroup:%p, prevgroup:%p", nextgroup, prevgroup);
firstpcr = prevgroup->pcr_offset;
lastoffset = if (nextgroup == prevgroup || prevgroup == NULL) {
prevgroup->values[prevgroup->last_value].offset + /* We use the current group to calculate position:
prevgroup->first_offset; * * if the PCR is within this group
lastpcr = * * if there is only one group to use for calculation
prevgroup->values[prevgroup->last_value].pcr + prevgroup->pcr_offset; */
GST_DEBUG ("In group or after last one");
lastoffset = firstoffset = nextgroup->first_offset;
lastpcr = firstpcr = nextgroup->pcr_offset;
if (current && nextgroup == current->group) {
lastoffset += current->pending[current->last].offset;
lastpcr += current->pending[current->last].pcr;
} else {
lastoffset += nextgroup->values[nextgroup->last_value].offset;
lastpcr += nextgroup->values[nextgroup->last_value].pcr;
}
} else if (prevgroup) { } else if (prevgroup) {
GST_DEBUG ("Between group"); GST_DEBUG ("Between group");
lastoffset = nextgroup->first_offset; lastoffset = nextgroup->first_offset;
@ -2284,7 +2305,9 @@ mpegts_packetizer_ts_to_offset (MpegTSPacketizer2 * packetizer,
GST_DEBUG ("Using last PCR %" G_GUINT64_FORMAT " offset %" G_GUINT64_FORMAT, GST_DEBUG ("Using last PCR %" G_GUINT64_FORMAT " offset %" G_GUINT64_FORMAT,
lastpcr, lastoffset); lastpcr, lastoffset);
res = firstoffset + gst_util_uint64_scale (querypcr - firstpcr, res = firstoffset;
if (lastpcr != firstpcr)
res += gst_util_uint64_scale (querypcr - firstpcr,
lastoffset - firstoffset, lastpcr - firstpcr); lastoffset - firstoffset, lastpcr - firstpcr);
GST_DEBUG ("Returning offset %" G_GUINT64_FORMAT " for ts %" GST_DEBUG ("Returning offset %" G_GUINT64_FORMAT " for ts %"