diff --git a/pcsx2/IPU/IPU.c b/pcsx2/IPU/IPU.c index e244110..552c041 100644 --- a/pcsx2/IPU/IPU.c +++ b/pcsx2/IPU/IPU.c @@ -68,7 +68,7 @@ PCSX2_ALIGNED16(u32 fifo_input[32]); PCSX2_ALIGNED16(u32 fifo_output[32]); void ReorderBitstream(); -u16 FillInternalBuffer(u32 * pointer, u32 advance); +u16 FillInternalBuffer(u32 * pointer, u32 advance, u32 size); // the BP doesn't advance and returns -1 if there is no data to be read tIPU_BP g_BP; @@ -605,9 +605,11 @@ static void ipuBCLR(u32 val) { FIFOto_clear(); g_BP.BP = val & 0x7F; g_BP.FP = 0; + g_BP.bufferhasnew = 0; g_BP.IFC = 0; ipuRegs->ctrl.BUSY = 0; ipuRegs->cmd.BUSY = 0; + memset(readbits,0,80); #ifdef IPU_LOG IPU_LOG("Clear IPU input FIFO. Set Bit offset=0x%X\n", g_BP.BP); #endif @@ -652,6 +654,9 @@ static BOOL ipuIDEC(u32 val) s_routine = so_create(mpeg2sliceIDEC, &s_RoutineDone, s_tempstack, sizeof(s_tempstack)); assert( s_routine != NULL ); so_call(s_routine); + if(s_RoutineDone) + s_routine = NULL; + return s_RoutineDone; } @@ -702,6 +707,8 @@ static BOOL ipuBDEC(u32 val) s_routine = so_create(mpeg2_slice, &s_RoutineDone, s_tempstack, sizeof(s_tempstack)); assert( s_routine != NULL ); so_call(s_routine); + if(s_RoutineDone) + s_routine = NULL; return s_RoutineDone; } @@ -716,7 +723,6 @@ static BOOL ipuVDEC(u32 val) { g_decoder.bitstream_bits = -16; BigEndian(g_decoder.bitstream_buf, g_decoder.bitstream_buf); - //value = BigEndian(value); switch((val >> 26) & 3){ case 0://Macroblock Address Increment g_decoder.mpeg1 =ipuRegs->ctrl.MP1; @@ -729,21 +735,20 @@ static BOOL ipuVDEC(u32 val) { break; case 2://Motion Code //known issues: no error detected ipuRegs->cmd.DATA=get_motion_delta(&g_decoder,0); - //g_BP.BP += ipuRegs->cmd.DATA >> 16; break; case 3://DMVector ipuRegs->cmd.DATA=get_dmv(&g_decoder); - //g_BP.BP += ipuRegs->cmd.DATA >> 16; break; } - //g_BP.BP += ipuRegs->cmd.DATA >> 16; g_BP.BP+=(g_decoder.bitstream_bits+16); if((int)g_BP.BP < 0) { g_BP.BP += 128; ReorderBitstream(); } + FillInternalBuffer(&g_BP.BP,1,0); + ipuRegs->cmd.DATA = (ipuRegs->cmd.DATA & 0xFFFF) | ((g_decoder.bitstream_bits+16) << 16); ipuRegs->ctrl.ECD = (ipuRegs->cmd.DATA==0); @@ -770,13 +775,11 @@ static BOOL ipuVDEC(u32 val) { static BOOL ipuFDEC(u32 val) { - u32 temp; if( !getBits32((u8*)&ipuRegs->cmd.DATA, 0) ) return FALSE; BigEndian(ipuRegs->cmd.DATA, ipuRegs->cmd.DATA); - temp = ipuRegs->cmd.DATA; - ipuRegs->top = temp; + ipuRegs->top = ipuRegs->cmd.DATA; #ifdef IPU_LOG IPU_LOG("FDEC read: 0x%8.8x\n", ipuRegs->top); @@ -989,7 +992,6 @@ void IPUCMD_WRITE(u32 val) { // check if enough data in queue if( ipuVDEC(val) ) { - IPU_INTERRUPT(DMAC_TO_IPU); return; } @@ -1008,7 +1010,6 @@ void IPUCMD_WRITE(u32 val) { g_BP.BP+= val & 0x3F; if( ipuFDEC(val) ) { - IPU_INTERRUPT(DMAC_TO_IPU); return; } @@ -1034,14 +1035,12 @@ void IPUCMD_WRITE(u32 val) { g_BP.BP+= val & 0x3F; if( ipuSETIQ(ipuRegs->cmd.DATA) ) { - IPU_INTERRUPT(DMAC_TO_IPU); return; } break; case SCE_IPU_SETVQ: if( ipuSETVQ(ipuRegs->cmd.DATA) ) { - IPU_INTERRUPT(DMAC_TO_IPU); return; } @@ -1053,7 +1052,6 @@ void IPUCMD_WRITE(u32 val) { if( ipuCSC(ipuRegs->cmd.DATA) ) { if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) INT(DMAC_FROM_IPU,0); - IPU_INTERRUPT(DMAC_FROM_IPU); FreezeMMXRegs(0); return; } @@ -1067,7 +1065,6 @@ void IPUCMD_WRITE(u32 val) { FreezeMMXRegs(1); if( ipuPACK(ipuRegs->cmd.DATA) ) { - IPU_INTERRUPT(DMAC_TO_IPU); FreezeMMXRegs(0); return; } @@ -1096,6 +1093,9 @@ void IPUCMD_WRITE(u32 val) { FreezeMMXRegs(1); if( ipuBDEC(val)) { if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) INT(DMAC_FROM_IPU,0); + if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) + hwIntcIrq(INTC_IPU); + FreezeMMXRegs(0); return; } @@ -1180,15 +1180,10 @@ void IPUWorker() case SCE_IPU_IDEC: so_call(s_routine); if( !s_RoutineDone ) { + hwIntcIrq(INTC_IPU); return; } -// if( (g_nDMATransfer&IPU_DMA_ACTV1) && (ipu1dma->chcr&0x100) && g_BP.IFC > 0 ) { -// ipu1dma->madr -= g_BP.IFC * 16; -// ipu1dma->qwc += g_BP.IFC; -// g_BP.IFC = 0; -// } - ipuRegs->ctrl.OFC = 0; ipuRegs->ctrl.BUSY = 0; ipuRegs->topbusy = 0; @@ -1197,12 +1192,14 @@ void IPUWorker() // CHECK!: IPU0dma remains when IDEC is done, so we need to clear it if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) INT(DMAC_FROM_IPU,0); - return; + + s_routine = NULL; + break; case SCE_IPU_BDEC: so_call(s_routine); if(!s_RoutineDone) { - //hwIntcIrq(INTC_IPU); + hwIntcIrq(INTC_IPU); return; } @@ -1211,7 +1208,9 @@ void IPUWorker() ipuRegs->cmd.BUSY = 0; ipuCurCmd = 0xffffffff; if(ipu0dma->qwc > 0 && (ipu0dma->chcr & 0x100)) INT(DMAC_FROM_IPU,0); - + s_routine = NULL; + if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) + hwIntcIrq(INTC_IPU); return; default: @@ -1222,7 +1221,6 @@ void IPUWorker() // success ipuRegs->ctrl.BUSY = 0; ipuCurCmd = 0xffffffff; - IPU_INTERRUPT(DMAC_TO_IPU); } ///////////////// @@ -1232,13 +1230,13 @@ void IPUWorker() __forceinline void inc_readbits() { readbits += 16; - if( readbits >= _readbits+64 ) { - + if( readbits >= _readbits+64 ) { + // move back - *(u64*)(_readbits) = *(u64*)(_readbits+64); - *(u64*)(_readbits+8) = *(u64*)(_readbits+72); - readbits = _readbits; - } + *(u64*)(_readbits) = *(u64*)(_readbits+64); + *(u64*)(_readbits+8) = *(u64*)(_readbits+72); + readbits = _readbits; + } } // returns the pointer of readbits moved by 1 qword @@ -1246,73 +1244,63 @@ __forceinline u8* next_readbits() { return readbits + 16; } - + // returns the pointer of readbits moved by 1 qword u8* prev_readbits() { if( readbits < _readbits+16 ) { return _readbits+48-(readbits-_readbits); } - - return readbits-16; + + return readbits-16; } - + void ReorderBitstream() { readbits = prev_readbits(); - g_BP.bufferhasnew = 1; - //g_BP.FP++; + g_BP.FP = 2; } + // IPU has a 2qword internal buffer whose status is pointed by FP. // If FP is 1, there's 1 qword in buffer. Second qword is only loaded // incase there are less than 32bits available in the first qword. // \return Number of bits available (clamps at 16 bits) -u16 FillInternalBuffer(u32 * pointer, u32 advance) +u16 FillInternalBuffer(u32 * pointer, u32 advance, u32 size) { if(g_BP.FP == 0) { if( FIFOto_read(next_readbits()) == 0 ) - return 0; + return 0; - g_BP.bufferhasnew = 0; inc_readbits(); g_BP.FP = 1; } - else if(g_BP.FP < 2 && g_BP.bufferhasnew == 0) + else if(g_BP.FP < 2 && (*(int*)pointer+size) >= 128) { - // in reality, need only > 96, but IPU reads ahead - if( *(int*)pointer >= 96) { - if( FIFOto_read(next_readbits()) ) - { - g_BP.FP += 1; - }else if(*(int*)pointer >= 128) - return 0; - + if( FIFOto_read(next_readbits()) ) + { + g_BP.FP += 1; } } if(*(int*)pointer >= 128) { - assert( g_BP.FP >= 1 || g_BP.bufferhasnew); - inc_readbits(); + assert( g_BP.FP >= 1); + + if(g_BP.FP > 1) + { + inc_readbits(); + } if(advance) { - // Incase BDEC reorders bits, we need to make sure we have the old - // data backed up. So we store the last read qword into the 2nd slot - // of the internal buffer. After that we copy the new qword read in - // the 2nd slot to the 1st slot to be read. - if( !g_BP.bufferhasnew ) - g_BP.FP--; - g_BP.bufferhasnew = 0; + g_BP.FP--; + *pointer &= 127; } - - *pointer &= 127; } - // fixed : added (g_BP.FP+g_BP.bufferhasnew)*128 as fp could have been 0 - return (g_BP.FP+g_BP.bufferhasnew) == 1 ? g_BP.FP*128-(*(int*)pointer) : 128; + return g_BP.FP >= 1 ? g_BP.FP*128-(*(int*)pointer) : 0; } // whenever reading fractions of bytes. The low bits always come from the next byte @@ -1323,7 +1311,7 @@ u8 getBits32(u8 *address, u32 advance) u8* readpos; // Check if the current BP has exceeded or reached the limit of 128 - if( FillInternalBuffer(&g_BP.BP,1) < 32 ) + if( FillInternalBuffer(&g_BP.BP,1,32) < 32 ) return 0; readpos = readbits+(int)g_BP.BP/8; @@ -1339,7 +1327,9 @@ u8 getBits32(u8 *address, u32 advance) else *(u32*)address = *(u32*)readpos; - if (advance) g_BP.BP+=32; + if (advance) + g_BP.BP+=32; + return 1; } @@ -1349,8 +1339,10 @@ u8 getBits16(u8 *address, u32 advance) u8* readpos; // Check if the current BP has exceeded or reached the limit of 128 - if( FillInternalBuffer(&g_BP.BP,1) < 16 ) + if( FillInternalBuffer(&g_BP.BP,1,16) < 16 ) + { return 0; + } readpos = readbits+(int)g_BP.BP/8; @@ -1365,7 +1357,9 @@ u8 getBits16(u8 *address, u32 advance) else *(u16*)address = *(u16*)readpos; - if (advance) g_BP.BP+=16; + if (advance) + g_BP.BP+=16; + return 1; } @@ -1375,7 +1369,7 @@ u8 getBits8(u8 *address, u32 advance) u8* readpos; // Check if the current BP has exceeded or reached the limit of 128 - if( FillInternalBuffer(&g_BP.BP,1) < 8 ) + if( FillInternalBuffer(&g_BP.BP,1,8) < 8 ) return 0; readpos = readbits+(int)g_BP.BP/8; @@ -1390,7 +1384,9 @@ u8 getBits8(u8 *address, u32 advance) else *(u8*)address = *(u8*)readpos; - if (advance) g_BP.BP+=8; + if (advance) + g_BP.BP+=8; + return 1; } @@ -1401,7 +1397,7 @@ int getBits(u8 *address, u32 size, u32 advance) u32 pointer = 0; // Check if the current BP has exceeded or reached the limit of 128 - if( FillInternalBuffer(&g_BP.BP,1) < 8 ) + if( FillInternalBuffer(&g_BP.BP,1,8) < 8 ) return 0; oldbits = readbits; @@ -1418,11 +1414,19 @@ int getBits(u8 *address, u32 size, u32 advance) *++address=0; shift=8; } - if( FillInternalBuffer(&pointer,advance) < 8 ) - return address-oldaddr; - + howmuch = min(min(8-(pointer&7), 128-pointer), min(size, shift)); + + if( FillInternalBuffer(&pointer,advance,8) < 8 ) + { + if(advance) + { + g_BP.BP = pointer; + } + return address-oldaddr; + } + mask = ((0xFF >> (pointer&7)) << (8-howmuch-(pointer&7))) & 0xFF; mask &= readbits[((pointer)>>3)]; @@ -1440,8 +1444,14 @@ int getBits(u8 *address, u32 size, u32 advance) u8* readmem; while (size) { - if( FillInternalBuffer(&pointer,advance) < 8 ) + if( FillInternalBuffer(&pointer,advance,8) < 8 ) + { + if(advance) + { + g_BP.BP = pointer; + } return address-oldaddr; + } howmuch = min(128-pointer, size); size -= howmuch; @@ -1473,7 +1483,11 @@ int getBits(u8 *address, u32 size, u32 advance) } // If not advance then reset the Reading buffer value - if(advance) g_BP.BP = pointer; + if(advance) + { + g_BP.BP = pointer; + + } else readbits = oldbits; // restore the last pointer return address-oldaddr; @@ -1597,8 +1611,9 @@ void ipu_copy(struct macroblock_8 *mb8, struct macroblock_16 *mb16){ void FIFOto_clear() { //assert( g_BP.IFC == 0 ); - //memset(fifo_input,0,sizeof(fifo_input)); + memset(fifo_input,0,sizeof(fifo_input)); g_BP.IFC = 0; + ipuRegs->ctrl.IFC = 0; FIreadpos = 0; FIwritepos = 0; } @@ -1737,11 +1752,16 @@ int IPU1dma() // Transfer Dn_QWC from Dn_MADR to GIF if ((ipu1dma->chcr & 0xc) == 0 || ipu1dma->qwc > 0) { // Normal Mode +#ifdef IPU_LOG + IPU_LOG("dmaIPU1 Normal size=%d, addr=%lx, fifosize=%x\n", + ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC); +#endif IPU1chain(); INT(DMAC_TO_IPU, (ipu1cycles+totalqwc)*BIAS); return totalqwc; } - else { + else + { // Chain Mode //while (done == 0) { // Loop while Dn_CHCR.STR is 1 ptag = (u32*)dmaGetAddr(ipu1dma->tadr); //Set memory pointer to TADR @@ -1856,8 +1876,14 @@ int FIFOfrom_write(u32 *value,int size) { int transsize; int firsttrans; - - if((int)ipuRegs->ctrl.OFC >= 8) IPU0dma(); + + if((int)ipuRegs->ctrl.OFC >= 8) + { + if(IPU0dma() == 0) + { +// ipuRegs->ctrl.OFC = 0; + } + } transsize = min(size,8-(int)ipuRegs->ctrl.OFC); firsttrans = transsize; @@ -1964,6 +1990,7 @@ void dmaIPU0() // fromIPU void dmaIPU1() // toIPU { + //g_nDMATransfer &= ~(IPU_DMA_ACTV1|IPU_DMA_DOTIE1); IPU1dma(); if( ipuRegs->ctrl.BUSY ) IPUWorker(); diff --git a/pcsx2/IPU/mpeg2lib/Mpeg.c b/pcsx2/IPU/mpeg2lib/Mpeg.c index 809dffa..f9311dd 100644 --- a/pcsx2/IPU/mpeg2lib/Mpeg.c +++ b/pcsx2/IPU/mpeg2lib/Mpeg.c @@ -203,8 +203,8 @@ static int get_luma_dc_dct_diff (decoder_t * const decoder) tab = DC_lum_5 + UBITS (bit_buf, 5); size = tab->size; if (size) { - bits += tab->len + size; - bit_buf <<= tab->len; + DUMPBITS (bit_buf, bits, tab->len); + bits += size; dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); bit_buf <<= size; @@ -215,7 +215,7 @@ static int get_luma_dc_dct_diff (decoder_t * const decoder) } } - tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); + tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0);//0x1e0); size = tab->size; DUMPBITS (bit_buf, bits, tab->len); NEEDBITS (bit_buf, bits, bit_ptr); @@ -241,8 +241,8 @@ static int get_chroma_dc_dct_diff (decoder_t * const decoder) tab = DC_chrom_5 + UBITS (bit_buf, 5); size = tab->size; if (size) { - bits += tab->len + size; - bit_buf <<= tab->len; + DUMPBITS (bit_buf, bits, tab->len); + bits += size; dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); bit_buf <<= size; @@ -375,7 +375,7 @@ static void get_intra_block_B14 (decoder_t * const decoder) dest[63] ^= mismatch & 1; if( (bit_buf>>30) != 0x2 ) ipuRegs->ctrl.ECD = 1; - DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */ decoder->bitstream_buf = bit_buf; decoder->bitstream_bits = bits; } @@ -434,7 +434,7 @@ static void get_intra_block_B15 (decoder_t * const decoder) } else { /* end of block. I commented out this code because if we */ /* dont exit here we will still exit at the later test :) */ - /* if (i >= 128) break; */ /* end of block */ + //if (i >= 128) break; /* end of block */ /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; @@ -480,7 +480,7 @@ static void get_intra_block_B15 (decoder_t * const decoder) dest[63] ^= mismatch & 1; if( (bit_buf>>28) != 0x6 ) ipuRegs->ctrl.ECD = 1; - DUMPBITS (bit_buf, bits, 4); /* dump end of block code */ + DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */ decoder->bitstream_buf = bit_buf; decoder->bitstream_bits = bits; } @@ -501,7 +501,7 @@ static int get_non_intra_block (decoder_t * const decoder) s16 * dest; i = -1; - mismatch = 1; + mismatch = -1; dest = decoder->DCTblock; @@ -604,7 +604,7 @@ static int get_non_intra_block (decoder_t * const decoder) if( (bit_buf>>30) != 0x2 ) ipuRegs->ctrl.ECD = 1; - DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */ decoder->bitstream_buf = bit_buf; decoder->bitstream_bits = bits; return i; @@ -877,6 +877,7 @@ static void slice_intra_DCT (decoder_t * const decoder, const int cc, /* Get the intra DC coefficient and inverse quantize it */ if (cc == 0) decoder->dc_dct_pred[0] += get_luma_dc_dct_diff (decoder); else decoder->dc_dct_pred[cc] += get_chroma_dc_dct_diff (decoder); + decoder->DCTblock[0] = decoder->dc_dct_pred[cc] << (3 - decoder->intra_dc_precision); if (decoder->mpeg1) get_mpeg1_intra_block (decoder); @@ -901,7 +902,7 @@ static void slice_non_intra_DCT (decoder_t * const decoder, } extern int coded_block_pattern; -extern u8 FillInternalBuffer(u32 * pointer, u32 advance); +extern u16 FillInternalBuffer(u32 * pointer, u32 advance, u32 size); extern decoder_t g_decoder; extern int g_nIPU0Data; // or 0x80000000 whenever transferring extern u8* g_pIPU0Pointer; @@ -967,42 +968,55 @@ void SaveRGB32(u8* ptr) void waitForSCD() { - u8 bit8; - while( !getBits8((u8*)&bit8, 0) ) + u8 bit8 = 1; + + while(!getBits8((u8*)&bit8, 0)) so_resume(); - if (bit8==0) { - if( g_BP.BP & 7 ) - g_BP.BP += 8 - (g_BP.BP&7); - ipuRegs->ctrl.SCD = 1; - } - + + if (bit8==0) + { + if (g_BP.BP & 7) + g_BP.BP += 8 - (g_BP.BP&7); + + ipuRegs->ctrl.SCD = 1; + } + while(!getBits32((u8*)&ipuRegs->top, 0)) { so_resume(); } + BigEndian(ipuRegs->top, ipuRegs->top); - if( ipuRegs->ctrl.SCD ) { - while( !(ipuRegs->top & 0x100) ) { - while(!getBits8((u8*)&bit8, 1)) - so_resume(); - while(!getBits32((u8*)&ipuRegs->top, 0)) - so_resume(); - BigEndian(ipuRegs->top, ipuRegs->top); - } + if(ipuRegs->ctrl.SCD) + { + switch(ipuRegs->top & 0xFFFFFFF0) + { + case 0x100: + case 0x1A0: + break; + case 0x1B0: + ipuRegs->ctrl.SCD = 0; + if(ipuRegs->top == 0x1b4) ipuRegs->ctrl.ECD = 1; + //else + //{ + // do + // { + // while(!getBits32((u8*)&ipuRegs->top, 1)) + // { + // so_resume(); + // } - if( ipuRegs->top == 0x1b3 ) { - // fixes srs - SysPrintf("bad start code %x, will manuall skip stream\n", ipuRegs->top); - while( ipuRegs->top != 0x100 ) { - while(!getBits8((u8*)&bit8, 1)) - so_resume(); - while(!getBits32((u8*)&ipuRegs->top, 0)) - so_resume(); - BigEndian(ipuRegs->top, ipuRegs->top); - } - } - } + // BigEndian(ipuRegs->top, ipuRegs->top); + // } + // while((ipuRegs->top & 0xfffffff0) != 0x100); + //} + break; + default: + ipuRegs->ctrl.SCD = 0; + break; + } + } } void mpeg2sliceIDEC(void* pdone) @@ -1070,7 +1084,9 @@ void mpeg2sliceIDEC(void* pdone) while(g_nIPU0Data > 0) { read = FIFOfrom_write((u32*)g_pIPU0Pointer,g_nIPU0Data); if( read == 0 ) + { so_resume(); + } else { g_pIPU0Pointer += read*16; g_nIPU0Data -= read; @@ -1119,21 +1135,11 @@ void mpeg2sliceIDEC(void* pdone) continue; default: /* end of slice/frame, or error? */ { - //int i; - ipuRegs->ctrl.SCD = 0; coded_block_pattern=decoder->coded_block_pattern; -// for (i=0; i<2; i++) { -// u8 byte; -// while(!getBits8(&byte, 0)) -// so_resume(); -// if (byte == 0) break; -// g_BP.BP+= 8; -// } - g_BP.BP+=decoder->bitstream_bits-16; - //g_BP.BP-=32;//bitstream_init takes 32 bits - + g_BP.BP+=decoder->bitstream_bits-16; + if((int)g_BP.BP < 0) { g_BP.BP = 128 + (int)g_BP.BP; @@ -1141,12 +1147,11 @@ void mpeg2sliceIDEC(void* pdone) // so that reading may continue properly ReorderBitstream(); } - - waitForSCD(); - if( ipuRegs->ctrl.SCD ) { - //SysPrintf("top %d: %8.8x\n", s_frame++, ipuRegs->top); - } - + + FillInternalBuffer(&g_BP.BP,1,0); + + waitForSCD(); + *(int*)pdone = 1; so_exit(); } @@ -1169,10 +1174,7 @@ void mpeg2sliceIDEC(void* pdone) coded_block_pattern=decoder->coded_block_pattern; - //ipuRegs->ctrl.ECD=!ipuRegs->ctrl.SCD; - //g_BP.BP-=32;//bitstream_init takes 32 bits - - g_BP.BP+=decoder->bitstream_bits-16; + g_BP.BP+=decoder->bitstream_bits-16; if((int)g_BP.BP < 0) { g_BP.BP = 128 + (int)g_BP.BP; @@ -1181,11 +1183,10 @@ void mpeg2sliceIDEC(void* pdone) // so that reading may continue properly ReorderBitstream(); } - - waitForSCD(); - if( ipuRegs->ctrl.SCD ) { - //SysPrintf("idectop: %8.8x, bp = %x\n", ipuRegs->top, g_BP.BP); - } + + FillInternalBuffer(&g_BP.BP,1,0); + + waitForSCD(); *(int*)pdone = 1; so_exit(); @@ -1212,7 +1213,6 @@ void mpeg2_slice(void* pdone) decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] = decoder->dc_dct_pred[2] = 128 << decoder->intra_dc_precision; - NEEDBITS (decoder->bitstream_buf, decoder->bitstream_bits, decoder->bitstream_ptr); if (decoder->macroblock_modes & DCT_TYPE_INTERLACED) { DCT_offset = decoder->stride; DCT_stride = decoder->stride * 2; @@ -1249,11 +1249,8 @@ void mpeg2_slice(void* pdone) ipuRegs->ctrl.SCD=0; coded_block_pattern=decoder->coded_block_pattern; - //FillInternalBuffer(&g_BP.BP, 1); - bp = g_BP.BP; - g_BP.BP+=decoder->bitstream_bits-16; - + g_BP.BP+=((int)decoder->bitstream_bits-16); // BP goes from 0 to 128, so negative values mean to read old buffer // so we minus from 128 to get the correct BP if((int)g_BP.BP < 0) { @@ -1264,6 +1261,8 @@ void mpeg2_slice(void* pdone) ReorderBitstream(); } + FillInternalBuffer(&g_BP.BP,1,0); + decoder->mbc = 1; g_nIPU0Data = 48; g_pIPU0Pointer = (u8*)decoder->mb16; @@ -1277,14 +1276,9 @@ void mpeg2_slice(void* pdone) } } - IPU_LOG("BDEC %x, %d\n",g_BP.BP,g_BP.FP); - waitForSCD(); - if( ipuRegs->ctrl.SCD ) { - //SysPrintf("bdectop: %8.8x, bp = %x\n", ipuRegs->top, g_BP.BP); - } - + decoder->bitstream_bits = 0; *(int*)pdone = 1; so_exit(); } diff --git a/pcsx2/IPU/mpeg2lib/Vlc.h b/pcsx2/IPU/mpeg2lib/Vlc.h index 774d0b6..7eacf64 100644 --- a/pcsx2/IPU/mpeg2lib/Vlc.h +++ b/pcsx2/IPU/mpeg2lib/Vlc.h @@ -30,10 +30,15 @@ static u8 data[2]; static u8 dword[4]; +extern tIPU_BP g_BP; +extern decoder_t g_decoder; +extern void ReorderBitstream(); static void GETWORD(u32 * bit_buf,int bits) { while(!getBits16(data,1)) + { so_resume(); + } *bit_buf |= ((data[0] << 8) | data[1]) << (bits); }