Changeset 1859127


Ignore:
Timestamp:
09/26/11 20:48:11 (5 years ago)
Author:
jstebbins <jstebbins.hb@…>
Branches:
master
Children:
4c69e1c
Parents:
070be6a
Message:

handle TS streams that have no PCRs better

For TS streams that don't have PCRs, we substitute the DTS timestamp
from the video track (or PTS if we don't see DTS). But these can bounce
around or be wider spaced in the stream that PCRs are meant to be. So I
have added a test to see if the timestamp looks like a discontinuity.
Then I only pass the timestamp as a PCR if there appears to be a
discontinuity. This prevents a lot of scr_offset thrashing.

I have also fixed an error in our scr_offset processing. It is rarely
triggered and it's effects are so minor with well behaved streams that
it would be completely unnoticed. But with the test stream I was using,
it caused a factor of 10 times more "audio went backwards" errors.

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4254 b64f7644-9d1e-0410-96f1-a4d463321fa5

Location:
libhb
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libhb/reader.c

    r3cdb1f2 r1859127  
    2323typedef struct
    2424{
     25    int    startup;
    2526    double average; // average time between packets
    2627    int64_t last;   // last timestamp seen on this stream
     
    110111    r->stream_timing[0].last = -r->stream_timing[0].average;
    111112    r->stream_timing[0].valid = 1;
     113    r->stream_timing[0].startup = 10;
    112114    r->stream_timing[1].id = -1;
    113115
     
    229231        st->id = buf->id;
    230232        st->average = 30.*90.;
     233        st->startup = 10;
    231234        st->last = -st->average;
    232235        if ( ( st->is_audio = is_audio( r, buf->id ) ) != 0 )
     
    246249{
    247250    stream_timing_t *st = id_to_st( r, buf, 1 );
     251
     252    if( buf->renderOffset < 0 )
     253    {
     254        st->last += st->average;
     255        return;
     256    }
     257
    248258    double dt = buf->renderOffset - st->last;
    249259    // Protect against spurious bad timestamps
    250260    if ( dt > -5 * 90000LL && dt < 5 * 90000LL )
    251261    {
    252         st->average += ( dt - st->average ) * (1./32.);
     262        if( st->startup )
     263        {
     264            st->average += ( dt - st->average ) * (1./2.);
     265            st->startup--;
     266        }
     267        else
     268        {
     269            st->average += ( dt - st->average ) * (1./32.);
     270        }
    253271        st->last = buf->renderOffset;
    254272    }
     
    282300    //    buf->id, last, st->average, nxt, buf->renderOffset, r->scr_offset);
    283301    r->scr_changes = r->demux.scr_changes;
    284     st->last = nxt;
    285302}
    286303
     
    588605                if ( buf->renderOffset != -1 )
    589606                {
    590                     if ( r->scr_changes == r->demux.scr_changes )
    591                     {
    592                         // This packet is referenced to the same SCR as the last.
    593                         // Adjust timestamp to remove the System Clock Reference
    594                         // offset then update the average inter-packet time
    595                         // for this stream.
    596                         buf->renderOffset -= r->scr_offset;
    597                         update_ipt( r, buf );
    598                     }
     607                    // This packet is referenced to the same SCR as the last.
     608                    // Adjust timestamp to remove the System Clock Reference
     609                    // offset then update the average inter-packet time
     610                    // for this stream.
     611                    buf->renderOffset -= r->scr_offset;
     612                    update_ipt( r, buf );
     613                }
     614                else
     615                {
     616                    update_ipt( r, buf );
    599617                }
    600618                if ( !r->start_found )
  • libhb/stream.c

    rd36f10c r1859127  
    162162        int64_t pcr;            // most recent input pcr
    163163        int64_t pcr_current;    // circular buffer of output pcrs
     164        int64_t last_timestamp; // used for discontinuity detection when
     165                                // there are no PCRs
    164166
    165167        uint8_t *packet;        // buffer for one TS packet
     
    44134415        int64_t bufpcr = b->pcr;
    44144416        int64_t curpcr = stream->ts.pcr_current;
    4415         if ( b->cur < stream->ts.pcr_out &&
    4416              bufpcr != -1 && curpcr != -1 && curpcr - bufpcr > 200*90LL )
     4417        if ( stream->ts.found_pcr &&  b->cur < stream->ts.pcr_out &&
     4418             bufpcr != -1 && curpcr != -1 &&
     4419             (uint64_t)( curpcr - bufpcr ) > 200*90LL )
     4420        {
     4421            // we've sent up a new pcr but have a packet referenced to an
     4422            // old pcr and the difference was enough to trigger a discontinuity
     4423            // correction. smash the timestamps or we'll mess up the correction.
     4424            buf->start = -1;
     4425            buf->renderOffset = -1;
     4426            buf->stop = -1;
     4427            buf->pcr = -1;
     4428        }
     4429        else if ( b->cur < stream->ts.pcr_out &&
     4430                  bufpcr != -1 && curpcr != -1 &&
     4431                  ( curpcr - bufpcr > 200*90LL || bufpcr - curpcr > 200*90LL ) )
    44174432        {
    44184433            // we've sent up a new pcr but have a packet referenced to an
     
    46424657
    46434658            // if we don't have a pcr yet use the dts from this frame
     4659            // to attempt to detect discontinuities
    46444660            if ( !stream->ts.found_pcr )
    46454661            {
     
    46534669                }
    46544670                // if we have a dts use it otherwise use the pts
    4655                 stream->ts.pcr = pes_timestamp( pes + ( pes[7] & 0x40?14:9 ) );
    4656                 ++stream->ts.pcr_in;
     4671                int64_t timestamp;
     4672                timestamp = pes_timestamp( pes + ( pes[7] & 0x40?14:9 ) );
     4673                if( stream->ts.last_timestamp < 0 ||
     4674                    timestamp - stream->ts.last_timestamp > 90 * 600 ||
     4675                    stream->ts.last_timestamp - timestamp > 90 * 600 )
     4676                {
     4677                    stream->ts.pcr = timestamp;
     4678                    ++stream->ts.pcr_in;
     4679                }
     4680                stream->ts.last_timestamp = timestamp;
    46574681            }
    46584682        }
     
    47504774    stream->ts.pcr = -1;
    47514775    stream->ts.pcr_current = -1;
     4776    stream->ts.last_timestamp = -1;
    47524777
    47534778    stream->frames = 0;
Note: See TracChangeset for help on using the changeset viewer.