Skip to content

mpegtspacketizer: avoid calling gst_util_uint64_scale with negative values

In my case I was tracking a bug that occurred when I did the following: gst_element_seek_simple(pipeline, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT), 0)

The src was a souphttpsrc.

The stream was a mpegts.

Since I searched for GST_FORMAT_TIME, the mpegtsdemux element did the conversion to bytes. This conversion resulted in a byte value that was extremely large, and thus far beyond the end of the file. At another place the byte position was truncated to the file length +1. But basically the problem was found in the mpegtspacketizer. There, in the mpegts_packetizer_ts_to_offset function the offset is calculated.

The makro querypcr = GSTTIME_TO_PCRTIME (ts); breaks the querypcr, which is 0 in my case.

In the function the variable ret is first set to res = firstoffset; which I can understand.

But after that the following is done:

if (lastpcr != firstpcr)
    res += gst_util_uint64_scale (querypcr - firstpcr,
        lastoffset - firstoffset, lastpcr - firstpcr);

So here the scaled value for querypcr is added to res. In my case, however, querypcr is smaller than firstpcr. Since the parameter is unsigned, a negative and thus extremely large positive value is passed here. gst_util_uint64_scale thus returns extremely wrong values. Why firstpct has a value of about 8460 is another matter but in my opinion gst_util_uint64_scale must only be called if querypcr > firstpcr.

Therefore I recommend to change the line like this:

if (lastpcr != firstpcr && querypcr > firstpcr)
    res += gst_util_uint64_scale (querypcr - firstpcr,
        lastoffset - firstoffset, lastpcr - firstpcr);

In my case it fixed my problem. But I would like to know your opinion about this.

Merge request reports