📄 mpegdecoder.cc
字号:
size_t cbOffset = baseOffset + frameSize * i + lumaSize; size_t crOffset = baseOffset + frameSize * i + lumaSize + chromaSize; for(size_t j = 0; j<lumaSize; ++j) { unichrome.io.getFrameBuffer()[yOffset+j] = 16; } for(size_t j = 0; j<chromaSize; ++j) { unichrome.io.getFrameBuffer()[cbOffset+j] = 128; unichrome.io.getFrameBuffer()[crOffset+j] = 128; } frameBuffers[i].yOffset = yOffset; frameBuffers[i].cbOffset = cbOffset; frameBuffers[i].crOffset = crOffset; } } sequenceHeader = header; sequenceAspectRatio = aspectRatio; sequenceQuantMatrixLoaded = false; isSecondField = true;// Log::debug("Sequence header:\n");// sequenceHeader.log();}//------------------------------------------------------------------------------void MPEGDecoder::setQuantMatrix(const QuantMatrix& quantMatrix){ if (quantMatrix.loadIntraQMX) { unichrome.io.reg(Register::MPEG_QM_TYPE) = Constant::MPEG_QM_TYPE_INTRA; loadQMX(quantMatrix.intraQMX); } if (quantMatrix.loadNonIntraQMX) { unichrome.io.reg(Register::MPEG_QM_TYPE) = Constant::MPEG_QM_TYPE_NONINTRA; loadQMX(quantMatrix.nonIntraQMX); } if (quantMatrix.loadChromaIntraQMX) { unichrome.io.reg(Register::MPEG_QM_TYPE) = Constant::MPEG_QM_TYPE_CHROMA_INTRA; loadQMX(quantMatrix.chromaIntraQMX); } if (quantMatrix.loadChromaNonIntraQMX) { unichrome.io.reg(Register::MPEG_QM_TYPE) = Constant::MPEG_QM_TYPE_CHROMA_NONINTRA; loadQMX(quantMatrix.chromaNonIntraQMX); }}//------------------------------------------------------------------------------void MPEGDecoder::startPicture(const PictureHeader& header){ pictureHeader = header;// Log::debug("Picture header:\n");// pictureHeader.log(); bool isFramePicture = header.pictureStructure == PictureHeader::PICTURE_FRAME; processSlice = false; if (playIntra) { if (header.codingType!=PictureHeader::CODING_I && isSecondField) return; isSecondField = isFramePicture || !isSecondField; if (isFramePicture || !isSecondField) { destBuffer = 0; displayBuffer = 0; bwRefBuffer = 0; fwRefBuffer = 0; displayInfo.setup(sequenceHeader, header, packetPTS); } } else { bool isFirstField = isFramePicture || isSecondField; isSecondField = isFramePicture || !isSecondField; if (isFirstField) { if (header.codingType==PictureHeader::CODING_I || header.codingType==PictureHeader::CODING_P) { size_t tmp = bwRefBuffer; bwRefBuffer = fwRefBuffer; fwRefBuffer = tmp; destBuffer = tmp; displayBuffer = pendingIP; displayInfo = pendingInfo; pendingIP = destBuffer; pendingInfo.setup(sequenceHeader, header, packetPTS); } else { size_t tmp = idleBuffer; idleBuffer = bBuffer; bBuffer = tmp; destBuffer = tmp; displayBuffer = tmp; displayInfo.setup(sequenceHeader, header, packetPTS); } } } processSlice = true; unichrome.io.reg(Register::MPEG_DEST_Y) = (frameBuffers[destBuffer].yOffset+pictureOffset) >> 3; unichrome.io.reg(Register::MPEG_DEST_CB) = (frameBuffers[destBuffer].cbOffset+pictureOffset/4) >> 3; unichrome.io.reg(Register::MPEG_DEST_CR) = (frameBuffers[destBuffer].crOffset+pictureOffset/4) >> 3; unichrome.io.reg(Register::MPEG_BW_Y) = (frameBuffers[bwRefBuffer].yOffset+pictureOffset) >> 3; unichrome.io.reg(Register::MPEG_BW_CB) = (frameBuffers[bwRefBuffer].cbOffset+pictureOffset/4) >> 3; unichrome.io.reg(Register::MPEG_BW_CR) = (frameBuffers[bwRefBuffer].crOffset+pictureOffset/4) >> 3; unichrome.io.reg(Register::MPEG_FW_Y) = (frameBuffers[fwRefBuffer].yOffset+pictureOffset) >> 3; unichrome.io.reg(Register::MPEG_FW_CB) = (frameBuffers[fwRefBuffer].cbOffset+pictureOffset/4) >> 3; unichrome.io.reg(Register::MPEG_FW_CR) = (frameBuffers[fwRefBuffer].crOffset+pictureOffset/4) >> 3; uint32_t coding = 0; switch(header.pictureStructure) { case PictureHeader::PICTURE_TOP: //Log::debug("top field!\n"); coding |= Constant::MPEG_PICTURE_CODING_TOP; break; case PictureHeader::PICTURE_BOTTOM: //Log::debug("bottom field!\n"); coding |= Constant::MPEG_PICTURE_CODING_BOTTOM; break; case PictureHeader::PICTURE_FRAME: coding |= Constant::MPEG_PICTURE_CODING_FRAME; break; default: Log::debug("Unhandled picture structure!\n"); break; } switch(header.codingType) { case PictureHeader::CODING_I: coding |= Constant::MPEG_PICTURE_CODING_I; break; case PictureHeader::CODING_P: coding |= Constant::MPEG_PICTURE_CODING_P; break; case PictureHeader::CODING_B: coding |= Constant::MPEG_PICTURE_CODING_B; break; default: Log::debug("Unhandled picture coding type!\n"); break; } if (header.alternateScan) coding |= Constant::MPEG_PICTURE_CODING_ALT_SCAN; unichrome.io.reg(Register::MPEG_PICTURE_CODING) = coding; if (!sequenceQuantMatrixLoaded) { setQuantMatrix(getDefaultQuantMatrix()); setQuantMatrix(sequenceHeader.quantMatrix); sequenceQuantMatrixLoaded = true; } size_t mbWidth = (sequenceHeader.horizontalSize+15)>>4; size_t mbHeight = 0; if (sequenceHeader.progressive) { mbHeight = (sequenceHeader.verticalSize+15)>>4; } else { mbHeight = (sequenceHeader.verticalSize+31)>>5; mbHeight <<= 1; } uint32_t mblockInfo = (mbWidth*mbHeight) & 0x3fff; if (header.onlyFramePredAndDCT) mblockInfo |= Constant::MPEG_MBLOCK_ONLY_FRAME_PRED_AND_DCT; if (header.topFieldFirst) mblockInfo |= Constant::MPEG_MBLOCK_TOP_FIELD_FIRST; mblockInfo |= Constant::MPEG_MBLOCK_USE_MPEG2; mblockInfo |= (mbWidth&0xff)<<18; unichrome.io.reg(Register::MPEG_MBLOCK_INFO) = mblockInfo; uint32_t mcompInfo = 0; if (header.hasConcealmentMotionVectors) mcompInfo |= Constant::MPEG_MCOMP_HAS_CONCEALMENT_MOTION_VECTORS; if (header.quantiserScaleType) mcompInfo |= Constant::MPEG_MCOMP_QUANTISER_SCALE_TYPE; if (header.intraVLCFormat) mcompInfo |= Constant::MPEG_MCOMP_INTRA_VLC_FORMAT; mcompInfo |= (header.intraDCPrecision&3)<<2; mcompInfo |= ((0x100000/mbWidth + 1)&0xfffff)<<4; unichrome.io.reg(Register::MPEG_MCOMP_INFO) = mcompInfo; uint32_t fCode = 0x00a60000;; fCode |= ((header.fCode[0][0]-1)&0xf) << 0; fCode |= ((header.fCode[0][1]-1)&0xf) << 4; fCode |= ((header.fCode[1][0]-1)&0xf) << 8; fCode |= ((header.fCode[1][1]-1)&0xf) << 12; if (!isFramePicture && isSecondField) { fCode |= Constant::MPEG_FCODE_SECOND_FIELD; } unichrome.io.reg(Register::MPEG_FCODE) = fCode;}//------------------------------------------------------------------------------void MPEGDecoder::addSlice(const unsigned char* slice, size_t length){ if (!processSlice) return; size_t numWords = length>>2; size_t remainder = length & 3; if (remainder>0) length += 4 - remainder; length += 8; const uint32_t* buf = reinterpret_cast<const uint32_t*>(slice); unichrome.io.reg(Register::MPEG_SLICE_LENGTH) = length; for(size_t i = 0; i<numWords; ++i) { unichrome.io.reg(Register::MPEG_SLICE_DATA) = *buf++; } if (remainder>0) { unichrome.io.reg(Register::MPEG_SLICE_DATA) = *buf & ((1 << (remainder << 3)) - 1); } unichrome.io.reg(Register::MPEG_SLICE_DATA) = 0; unichrome.io.reg(Register::MPEG_SLICE_DATA) = 0;}//------------------------------------------------------------------------------void MPEGDecoder::endSequence(){ if (pendingIP!=INVALID_BUFFER) { displayBuffer = pendingIP; displayInfo = pendingInfo; pendingIP = INVALID_BUFFER; pendingInfo.reset(); }}//------------------------------------------------------------------------------bool MPEGDecoder::isDisplayable() const{ return displayBuffer!=INVALID_BUFFER && isSecondField;}//------------------------------------------------------------------------------const MPEGDecoder::PictureInfo& MPEGDecoder::getDisplayInfo() const{ return displayInfo;}//------------------------------------------------------------------------------void MPEGDecoder::displayPicture(){ assert(isDisplayable()); if (displayBuffer!=INVALID_BUFFER) { unichrome.setV1Buffer(frameBuffers[displayBuffer].yOffset, frameBuffers[displayBuffer].cbOffset, frameBuffers[displayBuffer].crOffset); if (playIntra) { displayBuffer = INVALID_BUFFER; } }}//------------------------------------------------------------------------------void MPEGDecoder::loadQMX(const unsigned char* qmx){ for(size_t i = 0; i<64; i+=4) { uint32_t data = (qmx[quantMatrixScan[i+0]]<< 0) | (qmx[quantMatrixScan[i+1]]<< 8) | (qmx[quantMatrixScan[i+2]]<<16) | (qmx[quantMatrixScan[i+3]]<<24); unichrome.io.reg(Register::MPEG_QM_DATA) = data; }}//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -