Ticket #2984: avformatdecoder_scanstartcode.diff

File avformatdecoder_scanstartcode.diff, 8.8 KB (added by gnome42@…, 19 years ago)

avformatdecoder patch

  • libs/libmythtv/avformatdecoder.h

     
    221221
    222222    bool gotvideo;
    223223
    224     unsigned char prvpkt[3];
     224    uint32_t lastpkt;
    225225
    226226    long long lastvpts;
    227227    long long lastapts;
  • libs/libmythtv/avformatdecoder.cpp

     
    11// C headers
    22#include <cassert>
    33#include <unistd.h>
     4#include <arpa/inet.h>
    45
    56// C++ headers
    67#include <algorithm>
     
    274275      gopset(false),                seen_gop(false),
    275276      seq_count(0),                 firstgoppos(0),
    276277      prevgoppos(0),                gotvideo(false),
     278      lastpkt(0xFFFFFFFF),
    277279      lastvpts(0),                  lastapts(0),
    278280      lastccptsu(0),
    279281      using_null_videoout(use_null_videoout),
     
    296298      dvd_xvmc_enabled(false), dvd_video_codec_changed(false)
    297299{
    298300    bzero(&params, sizeof(AVFormatParameters));
    299     bzero(prvpkt, 3 * sizeof(char));
    300301    bzero(audioSamples, AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof(short int));
    301302    ccd608->SetIgnoreTimecode(true);
    302303
     
    19731974    }
    19741975}
    19751976
    1976 #define SEQ_START     0x000001b3
    1977 #define GOP_START     0x000001b8
    1978 #define PICTURE_START 0x00000100
    1979 #define SLICE_MIN     0x00000101
    1980 #define SLICE_MAX     0x000001af
    1981 #define SEQ_END_CODE  0x000001b7
     1977#define SEQ_START     0xb3
     1978#define GOP_START     0xb8
     1979#define PICTURE_START 0x00
     1980#define SLICE_MIN     0x01
     1981#define SLICE_MAX     0xaf
     1982#define SEQ_END_CODE  0xb7
    19821983
    19831984void AvFormatDecoder::MpegPreProcessPkt(AVStream *stream, AVPacket *pkt)
    19841985{
    19851986    AVCodecContext *context = stream->codec;
    19861987    unsigned char *bufptr = pkt->data;
    1987     //unsigned char *bufend = pkt->data + pkt->size;
    1988     unsigned int state = 0xFFFFFFFF, v = 0;
    1989     int prvcount = -1;
     1988    const unsigned char* const end = pkt->data + pkt->size - 1;
     1989    unsigned int state = 0xFFFFFFFF;
    19901990
    1991     while (bufptr < pkt->data + pkt->size)
     1991    int match = 0;
     1992    if (lastpkt << 8 == 0x00000100)
     1993        match = 3;
     1994    else if (!(lastpkt << 16) && bufptr[0] == 0x01)
     1995        match = 2;
     1996    else if (!(lastpkt << 24) && !bufptr[0] && bufptr[1] == 0x01)
     1997        match = 1;
     1998
     1999    if (match)
    19922000    {
    1993         if (++prvcount < 3)
    1994             v = prvpkt[prvcount];
     2001#if 0
     2002       VERBOSE(VB_PLAYBACK, LOC +
     2003          QString("AVF Matched!  %1  %2 %3%4%5%6").arg(match)
     2004          .arg(lastpkt).arg(bufptr[0],2,16).arg(bufptr[1],2,16)
     2005          .arg(bufptr[2],2,16).arg(bufptr[3],2,16));
     2006#endif
     2007       bufptr += 3 - match;
     2008       goto startcode;
     2009    }
     2010    bufptr += 2; // two zeros
     2011
     2012    while (bufptr < end)
     2013    {
     2014        if (*bufptr > 0x01)
     2015           bufptr += 3;
     2016        else if (!(*bufptr))
     2017           bufptr++;
     2018        else if (bufptr[-2] || bufptr[-1])
     2019           bufptr += 3;
    19952020        else
    1996             v = *bufptr++;
    1997 
    1998         unsigned int last_state = state;
    1999         state = ((state << 8) | v) & 0xFFFFFF;
    2000 
    2001         if (ringBuffer->isDVD() && pkt->size == 4 &&
    2002             state == SEQ_END_CODE && !dvdvideopause)
    20032021        {
    2004             dvdvideopause = true;
    2005             d->ResetMPEG2();
    2006             return;
    2007         }
     2022            // At this point we have seen the start code 0 0 1
     2023            ++bufptr;
     2024startcode:
     2025            state = *bufptr;
     2026            bufptr++;
    20082027
    2009         if (last_state != 0x000001)
    2010             continue;
    2011         else if (state >= SLICE_MIN && state <= SLICE_MAX)
    2012             continue;
    2013         else if (SEQ_START == state)
    2014         {
    2015             if (bufptr + 11 >= pkt->data + pkt->size)
    2016                 continue; // not enough valid data...
    2017             SequenceHeader *seq = reinterpret_cast<SequenceHeader*>(bufptr);
     2028            if (SEQ_START == state)
     2029            {
     2030                if (bufptr + 11 >= pkt->data + pkt->size)
     2031                    continue; // not enough valid data...
     2032                SequenceHeader *seq =
     2033                              reinterpret_cast<SequenceHeader*>(bufptr);
    20182034
    2019             uint  width  = seq->width();
    2020             uint  height = seq->height();
    2021             float aspect = seq->aspect(context->sub_id == 1);
    2022             float seqFPS = seq->fps();
     2035                uint  width  = seq->width();
     2036                uint  height = seq->height();
     2037                float aspect = seq->aspect(context->sub_id == 1);
     2038                float seqFPS = seq->fps();
    20232039
    2024             bool changed = (seqFPS > fps+0.01) || (seqFPS < fps-0.01);
    2025             changed |= (width  != (uint)current_width );
    2026             changed |= (height != (uint)current_height);
    2027             changed |= (aspect != current_aspect);
     2040                bool changed = (seqFPS > fps+0.01) ||
     2041                               (seqFPS < fps-0.01);
     2042                changed |= (width  != (uint)current_width );
     2043                changed |= (height != (uint)current_height);
     2044                changed |= (aspect != current_aspect);
    20282045
    2029             if (changed)
    2030             {
    2031                 uint awidth = width, aheight = height;
    2032                 align_dimensions(context, awidth, aheight);
     2046                if (changed)
     2047                {
     2048                    uint awidth = width, aheight = height;
     2049                    align_dimensions(context, awidth, aheight);
    20332050
    2034                 GetNVP()->SetVideoParams(awidth, aheight, seqFPS,
    2035                                          keyframedist, aspect,
    2036                                          kScan_Detect);
     2051                    GetNVP()->SetVideoParams(awidth, aheight, seqFPS,
     2052                                             keyframedist, aspect,
     2053                                             kScan_Detect);
    20372054               
    2038                 if (ringBuffer->InDVDMenuOrStillFrame())
    2039                 {
    2040                     ringBuffer->DVD()->SeekCellStart();
    2041                     av_read_frame_flush(ic);
     2055                    if (ringBuffer->InDVDMenuOrStillFrame())
     2056                    {
     2057                        ringBuffer->DVD()->SeekCellStart();
     2058                        av_read_frame_flush(ic);
     2059                    }
     2060                   
     2061                    current_width  = width;
     2062                    current_height = height;
     2063                    current_aspect = aspect;
     2064                    fps            = seqFPS;
     2065   
     2066                    d->ResetMPEG2();
     2067   
     2068                    gopset = false;
     2069                    prevgoppos = 0;
     2070                    lastapts = lastvpts = lastccptsu = 0;
     2071
     2072                    // fps debugging info
     2073                    float avFPS = normalized_fps(stream, context);
     2074                    if ((seqFPS > avFPS+0.01) || (seqFPS < avFPS-0.01))
     2075                    {
     2076                        VERBOSE(VB_PLAYBACK, LOC +
     2077                                QString("avFPS(%1) != seqFPS(%2)")
     2078                                .arg(avFPS).arg(seqFPS));
     2079                    }
    20422080                }
    2043                
    2044                 current_width  = width;
    2045                 current_height = height;
    2046                 current_aspect = aspect;
    2047                 fps            = seqFPS;
    20482081
    2049                 d->ResetMPEG2();
     2082                seq_count++;
    20502083
    2051                 gopset = false;
    2052                 prevgoppos = 0;
    2053                 lastapts = lastvpts = lastccptsu = 0;
    2054 
    2055                 // fps debugging info
    2056                 float avFPS = normalized_fps(stream, context);
    2057                 if ((seqFPS > avFPS+0.01) || (seqFPS < avFPS-0.01))
     2084                if (!seen_gop && seq_count > 1)
    20582085                {
    2059                     VERBOSE(VB_PLAYBACK, LOC +
    2060                             QString("avFPS(%1) != seqFPS(%2)")
    2061                             .arg(avFPS).arg(seqFPS));
     2086                    HandleGopStart(pkt);
     2087                    pkt->flags |= PKT_FLAG_KEY;
    20622088                }
    20632089            }
    2064 
    2065             seq_count++;
    2066 
    2067             if (!seen_gop && seq_count > 1)
     2090            else if (GOP_START == state)
    20682091            {
    20692092                HandleGopStart(pkt);
     2093                seen_gop = true;
    20702094                pkt->flags |= PKT_FLAG_KEY;
    20712095            }
     2096            else if (SEQ_END_CODE == state && ringBuffer->isDVD() &&
     2097                     pkt->size == 4 && !dvdvideopause)
     2098            {
     2099                dvdvideopause = true;
     2100                d->ResetMPEG2();
     2101                return;
     2102            }
     2103            bufptr++;
    20722104        }
    2073         else if (GOP_START == state)
    2074         {
    2075             HandleGopStart(pkt);
    2076             seen_gop = true;
    2077             pkt->flags |= PKT_FLAG_KEY;
    2078         }
    20792105    }
    2080 
    2081     memcpy(prvpkt, pkt->data + pkt->size - 3, 3);
     2106    // Save last 4 bytes for next time
     2107    unsigned long *last_word = (unsigned long *)(end - 3);
     2108    lastpkt = ntohl(*last_word);
    20822109}
    20832110
    20842111void AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt)