Ticket #2984: avformatdecoder_scanstartcode.diff
File avformatdecoder_scanstartcode.diff, 8.8 KB (added by , 17 years ago) |
---|
-
libs/libmythtv/avformatdecoder.h
221 221 222 222 bool gotvideo; 223 223 224 u nsigned char prvpkt[3];224 uint32_t lastpkt; 225 225 226 226 long long lastvpts; 227 227 long long lastapts; -
libs/libmythtv/avformatdecoder.cpp
1 1 // C headers 2 2 #include <cassert> 3 3 #include <unistd.h> 4 #include <arpa/inet.h> 4 5 5 6 // C++ headers 6 7 #include <algorithm> … … 274 275 gopset(false), seen_gop(false), 275 276 seq_count(0), firstgoppos(0), 276 277 prevgoppos(0), gotvideo(false), 278 lastpkt(0xFFFFFFFF), 277 279 lastvpts(0), lastapts(0), 278 280 lastccptsu(0), 279 281 using_null_videoout(use_null_videoout), … … 296 298 dvd_xvmc_enabled(false), dvd_video_codec_changed(false) 297 299 { 298 300 bzero(¶ms, sizeof(AVFormatParameters)); 299 bzero(prvpkt, 3 * sizeof(char));300 301 bzero(audioSamples, AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof(short int)); 301 302 ccd608->SetIgnoreTimecode(true); 302 303 … … 1973 1974 } 1974 1975 } 1975 1976 1976 #define SEQ_START 0x 000001b31977 #define GOP_START 0x 000001b81978 #define PICTURE_START 0x00 0001001979 #define SLICE_MIN 0x0 00001011980 #define SLICE_MAX 0x 000001af1981 #define SEQ_END_CODE 0x 000001b71977 #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 1982 1983 1983 1984 void AvFormatDecoder::MpegPreProcessPkt(AVStream *stream, AVPacket *pkt) 1984 1985 { 1985 1986 AVCodecContext *context = stream->codec; 1986 1987 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; 1990 1990 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) 1992 2000 { 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; 1995 2020 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)2003 2021 { 2004 dvdvideopause = true; 2005 d->ResetMPEG2(); 2006 return; 2007 } 2022 // At this point we have seen the start code 0 0 1 2023 ++bufptr; 2024 startcode: 2025 state = *bufptr; 2026 bufptr++; 2008 2027 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); 2018 2034 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(); 2023 2039 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); 2028 2045 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); 2033 2050 2034 GetNVP()->SetVideoParams(awidth, aheight, seqFPS,2035 keyframedist, aspect,2036 kScan_Detect);2051 GetNVP()->SetVideoParams(awidth, aheight, seqFPS, 2052 keyframedist, aspect, 2053 kScan_Detect); 2037 2054 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 } 2042 2080 } 2043 2044 current_width = width;2045 current_height = height;2046 current_aspect = aspect;2047 fps = seqFPS;2048 2081 2049 d->ResetMPEG2();2082 seq_count++; 2050 2083 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) 2058 2085 { 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; 2062 2088 } 2063 2089 } 2064 2065 seq_count++; 2066 2067 if (!seen_gop && seq_count > 1) 2090 else if (GOP_START == state) 2068 2091 { 2069 2092 HandleGopStart(pkt); 2093 seen_gop = true; 2070 2094 pkt->flags |= PKT_FLAG_KEY; 2071 2095 } 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++; 2072 2104 } 2073 else if (GOP_START == state)2074 {2075 HandleGopStart(pkt);2076 seen_gop = true;2077 pkt->flags |= PKT_FLAG_KEY;2078 }2079 2105 } 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); 2082 2109 } 2083 2110 2084 2111 void AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt)