📄 decoder.c
字号:
u32 GetPTS(u8 *data, u32* MediaPointer, int mpeg, int hlength,int off){ u32 PTS = 0xFFFFFFFFUL; int p = 0; // Read PTS, if present if ((mpeg == 2 && data[p + 7] & 0x80) || (mpeg == 1 && off)) { if (mpeg == 1) p = off-9; PTS = (data[p + 9] >> 1) & 0x03UL; PTS = (PTS << 8) | (data[p + 10] & 0xFFUL); PTS = (PTS << 7) | ((data[p + 11] >> 1) & 0x7FUL); PTS = (PTS << 8) | (data[p + 12] & 0xFFULL); PTS = (PTS << 7) | ((data[p + 13] >> 1) & 0x7FUL); } // Now, skip rest of PES header and stuffing if (mpeg == 2){ p += (9 + (data[p + 8] & 0xFF)); p = ((p + 7) / 8) * 8; } else p = hlength+7; if (!(data[p++] | data[p++] | data[p++] | data[p++])) { *MediaPointer = (u32)data[p++] & 0xFF; *MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF); *MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF); *MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF); } else { *MediaPointer = 0xFFFFFFFFUL; } return PTS;}int ReadPESChunk(struct cvdv_cards *card, u32 *addr, u8 *data, u32 start, u32 end){ int i = 5, err = -1; while (err && (i--)) err &= DRAMReadByte(card, *addr << 2, 8, &data[0], 0); if (err) return 1; (*addr)++; if (*addr >= end) *addr = start; return 0;}void ReadPESHeaders(struct cvdv_cards *card){ u8 startcode[] = {0x00, 0x00, 0x01}; int LoopCount; u32 LastVAddr; // Current Video Address u32 LastAAddr; // Current Audio Address u32 Addr; // Current Header Address u32 PESAddr; // Pointer from Header Block u32 PTS; // PTS from Header Block u8 Data[32]; u32 AudioPESStart; u32 AudioPESEnd; int i, j, p, fail; u32 FailAddr; int hlength=0; int mpeg=0; int check; int mp=0; int off=0; AudioPESStart = (DecoderReadWord(card, 0x058) & 0x3FFF) << 5; AudioPESEnd = ((DecoderReadWord(card, 0x05A) & 0x3FFF) + 1) << 5; LastVAddr = DecoderReadRWAddr(card, 0x060); LastAAddr = DecoderReadRWAddr(card, 0x063); if (card->LastAddr == 0) card->LastAddr = AudioPESStart; //Read the PES header buffer Addr = DecoderReadRWAddr(card, 0x072) & 0x0007FFFF; if (Addr >= AudioPESEnd) { Addr = card->LastAddr = AudioPESStart; } LoopCount = 0; while ((card->LastAddr != Addr) && (LoopCount++ < 200)) { FailAddr = card->LastAddr; fail = 0; p = 0; if (ReadPESChunk(card, &card->LastAddr, &Data[p], AudioPESStart, AudioPESEnd)) continue; p+=8; j=1; if (memcmp(Data, startcode, 3)) continue; if ((Data[3] == 0xE0) || (Data[3] == 0xBD) || ((Data[3] & 0xE0) == 0xC0)) { fail |= ReadPESChunk(card, &card->LastAddr, &Data[p], AudioPESStart, AudioPESEnd); p+=8; j++; if ( (Data[6] & 0xC0) == 0x80 ){ hlength = 9+Data[8]; mpeg = 2; } else { mpeg = 1; mp = 6; check = Data[mp]; mp++; while (check == 0xFF){ if (!fail && mp == p) { fail |= ReadPESChunk( card, &card->LastAddr, &Data[p], AudioPESStart, AudioPESEnd); p+=8; j++; } check = Data[mp]; mp++; } if (!fail && mp == p) { fail |= ReadPESChunk( card, &card->LastAddr, &Data[p], AudioPESStart, AudioPESEnd); p+=8; j++; } if ( !fail && (check & 0xC0) == 0x40){ check = Data[mp]; mp++; if (!fail && mp == p) { fail |= ReadPESChunk( card, &card->LastAddr, &Data[p], AudioPESStart, AudioPESEnd); p+=8; j++; } check = Data[mp]; mp++; } if ( !fail && (check & 0x20)){ if (check & 0x30) hlength = mp+10; else hlength = mp+5; off = mp-1; } } for (i = 1; (i < ((hlength+7) / 8)) && (!fail); i++) { fail |= ReadPESChunk(card, &card->LastAddr, &Data[p], AudioPESStart, AudioPESEnd); p+=8; j++; } if (!fail) { PTS = GetPTS(Data, &PESAddr, mpeg, hlength,off); if ((PTS != 0xFFFFFFFF) && (PESAddr != 0xFFFFFFFF)) { if (Data[3] == 0xE0) { // Video PTSStoreAdd(&card->VideoPTSStore, PTS, PESAddr, LastVAddr); } else { // Audio PTSStoreAdd(&card->AudioPTSStore, PTS, PESAddr, LastAAddr); } } } } else { //card->LastAddr = Addr; } // In case of error, rewind and try again if (fail) card->LastAddr = FailAddr; }}void L64021Intr(struct cvdv_cards *card) { u32 SCR_base, SCR_compareV, SCR_compareA; u32 VideoAddr, AudioAddr, PTS; int i, a, v, as, vs, ap, vp; u8 intr[5]; u8 layer; long ISRTime, DeltaSyncTime, Offset; int used = 0; u8 err; err = DecoderReadByte(card, 0x095); if (err & 0x17) { MDEBUG(0, ": Packet Error: 0x%02X\n", err); } ISRTime = 0; // TODO system time for (i = 0; i < 5; i++) if ((intr[i] = DecoderReadByte(card, i))) used = 1; if (used) { if (intr[0] & 0x80) { // new field card->fields++; if (card->videoffwd){ if (!card->videoffwd_last){ AudioStopDecode(card); card->videosync = 0; card->videoskip = card->videoffwd; card->videoskip = 0; card->videoffwd_last = 1; card->videoskip_last = 0; } else { if (card->videoskip_last == -1){ card->videoskip = card->videoffwd; } if (!card->videoskip) card->videoskip_last = -1; else card->videoffwd_last = card->videoffwd; } } else if( card->videoffwd_last ){ card->videoffwd_last = 0; if (card->audiostate.AV_sync_state) card->videosync = 1; AudioStartDecode(card); } if (card->videoslow){ if (!card->videoslow_last){ AudioStopDecode(card); card->videosync = 0; card->videodelay = card->videoslow; card->videoskip = 0; card->videoslow_last = 1; card->videodelay_last = 0; } else { if (card->videodelay_last == -1){ card->videodelay = card->videoslow; } if (!card->videodelay) card->videodelay_last = -1; else card->videodelay_last = card->videodelay; } } else if( card->videoslow_last ){ card->videoslow_last = 0; if (card->audiostate.AV_sync_state) card->videosync = 1; AudioStartDecode(card); } if (card->videodelay > 0) { if( (DecoderReadByte(card, 0x0ED) & 0x03) == 0x00) { card->videodelay--; if(card->videodelay){ DecoderWriteByte(card, 0x0ED, 0x01); } else { DecoderWriteByte(card, 0x0ED, 0x00); } } else { card->videodelay--; if(!card->videodelay){ DecoderWriteByte(card, 0x0ED, 0x00); } } } else if (card->videoskip > 0) { if ((DecoderReadByte(card, 0x0EC) & 0x03) == 0x00) { if (DecoderReadWord(card, 0x096) > 5){ // pictures in video ES channel card->videoskip--; if(card->videoskip) { DecoderWriteByte(card, 0x0EC ,0x03); } else { DecoderWriteByte(card, 0x0EC ,0x00); } } else { card->videoskip = 0; DecoderWriteByte (card, 0x0EC, 0x00); } } } i = (DecoderReadByte(card, 0x113) & 0xFC) | (DecoderReadByte(card, 0x114) & 0x01); v = DecoderGetVideoESLevel(card); if (card->startingV) { vs = card->VideoESSize; if (vs > 0) vp = (100 * v) / vs; else vp = 0; if (vp > 90) { MDEBUG(0,": Delayed Video Decoder start\n"); card->startingV = 0; DecoderStartDecode(card); //DecoderSetVideoPanic(card, 1, 3); // video panic at 3 pictures //DecoderSetVideoPanic(card, 0, DecoderGetVideoESSize(card) / 4); // video panic at 25 percent } } a = DecoderGetAudioESLevel(card); if (card->startingA) { as = card->AudioESSize; if (as > 0) ap = (100 * a) / as; else ap = 0; if (ap > 90) { MDEBUG(0,": Delayed Audio Decoder start\n"); AudioSetPlayMode(card, MAUDIO_PLAY); if (!AudioStart(card)) { card->startingA = 0; } } } if (card->fields >= 250) { // 5 seconds (PAL) SCR_base = DecoderReadSCR(card, 0x009); SCR_compareA = DecoderReadSCR(card, 0x014); SCR_compareV = DecoderReadSCR(card, 0x00D); if (DecoderReadByte(card, 0x013) & 0x03) card->fields = 0; } } if (intr[0] & 0x04) { // First Slice Start Code if (card->showvideo) { // Unmute card video if first picture slice detected VideoSetBackground(card, 0, 0, 0, 0); // Video on black card->showvideo = 0; } } if (intr[0] & 0x02 ) { // Aux/User Data Fifo used = 0; while ( (used++ < 1000) && (layer = DecoderReadByte(card, 0x040)) & 0x03){ card->AuxFifo[card->AuxFifoHead] = ((layer << 6) & 0x0700) | DecoderReadByte(card, 0x043); card->AuxFifoHead = (card->AuxFifoHead + 1) & FIFO_MASK; } if (used < 1000) DecoderReadAuxFifo(card); used = 0; while ( (used++ < 1000) && (layer = DecoderReadByte(card, 0x041)) & 0x03){ card->DataFifo[card->DataFifoHead] = ((layer << 6) & 0x0300) | DecoderReadByte(card, 0x043); card->DataFifoHead = (card->DataFifoHead + 1) & FIFO_MASK; } if (used < 1000 ) DecoderReadDataFifo(card); } if ((intr[0] & 0x01) != card->intdecodestatus) { // decode status card->intdecodestatus = intr[0] & 0x01; MDEBUG(0, ": Int - decode status now %s\n", ((card->intdecodestatus) ? "running" : "stopped"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -