Пример #1
0
func (this *TAppDecTop) IsNaluWithinTargetDecLayerIdSet(nalu *TLibDecoder.InputNALUnit) bool {
	if this.m_targetDecLayerIdSet.Len() == 0 { // By default, the set is empty, meaning all LayerIds are allowed
		return true
	}
	for e := this.m_targetDecLayerIdSet.Front(); e != nil; e = e.Next() {
		it := e.Value.(int)
		if int(nalu.GetReservedZero6Bits()) == it {
			return true
		}
	}
	return false
}
Пример #2
0
func (this *TAppDecTop) Decode() (err error) {
	bSkipPictureForBLA := false
	var poc int
	var pcListPic *list.List           // = NULL;
	var nalUnit, oldNalUnit *list.List //vector<uint8_t>
	var nalu TLibDecoder.InputNALUnit

	bitstreamFile, err := os.Open(this.m_pchBitstreamFile)
	if err != nil {
		fmt.Printf("\nfailed to open bitstream file `%s' for reading\n", this.m_pchBitstreamFile)
		return err
	}
	defer bitstreamFile.Close()

	bytestream := TLibDecoder.NewInputByteStream(bitstreamFile)

	// create & initialize internal classes
	this.xCreateDecLib()
	this.xInitDecLib()
	this.m_iPOCLastDisplay += this.m_iSkipFrame // set the last displayed POC correctly for skip forward.

	// main decoder loop
	recon_opened := false // reconstruction file not yet opened. (must be performed after SPS is seen)
	eof := false
	bNewPicture := false
	iDecodedFrameNum := 0
	for !eof || bNewPicture { // (!!bitstreamFile)
		/* location serves to work around a design fault in the decoder, whereby
		 * the process of reading a new slice that is the first slice of a new frame
		 * requires the TDecTop::decode() method to be called again with the same
		 * nal unit. */
		//streampos location = bitstreamFile.tellg();
		var stats TLibDecoder.AnnexBStats // stats = AnnexBStats();
		bPreviousPictureDecoded := false

		if !bNewPicture {
			nalUnit = list.New() //vector<uint8_t>
			eof, _ = bytestream.ByteStreamNALUnit(nalUnit, &stats)
		} else {
			nalUnit = oldNalUnit
		}

		// call actual decoding function
		if nalUnit.Len() == 0 {
			/* this can happen if the following occur:
			 *  - empty input file
			 *  - two back-to-back start_code_prefixes
			 *  - start_code_prefix immediately followed by EOF
			 */
			fmt.Printf("Warning: Attempt to decode an empty NAL unit\n")
			break
		} else {
			//fmt.Printf("NalUnit Len=%d\n", nalUnit.Len())
			oldNalUnit = nalu.Read(nalUnit)

			//fmt.Printf("Type=%d\n", nalu.GetNalUnitType())

			if (this.m_iMaxTemporalLayer >= 0 && int(nalu.GetTemporalId()) > this.m_iMaxTemporalLayer) ||
				!this.IsNaluWithinTargetDecLayerIdSet(&nalu) {
				if bPreviousPictureDecoded {
					bNewPicture = true
					bPreviousPictureDecoded = false
				} else {
					bNewPicture = false
				}
			} else {
				bNewPicture = this.m_cTDecTop.Decode(&nalu, &this.m_iSkipFrame, &this.m_iPOCLastDisplay, &bSkipPictureForBLA, !bNewPicture)
				bPreviousPictureDecoded = true
			}
		}
		if bNewPicture || eof {
			pcListPic = this.m_cTDecTop.ExecuteLoopFilters(&poc, bSkipPictureForBLA)
		}

		if pcListPic != nil {
			if this.m_pchReconFile != "" && !recon_opened {
				if this.m_outputBitDepthY == 0 {
					this.m_outputBitDepthY = TLibCommon.G_bitDepthY
				}
				if this.m_outputBitDepthC == 0 {
					this.m_outputBitDepthC = TLibCommon.G_bitDepthC
				}

				this.m_cTVideoIOYuvReconFile.Open(this.m_pchReconFile, true, this.m_outputBitDepthY, this.m_outputBitDepthC, TLibCommon.G_bitDepthY, TLibCommon.G_bitDepthC) // write mode
				recon_opened = true
			}
			//fmt.Printf("bNewPicture=%d m_nalUnitType=%d ", TLibCommon.B2U(bNewPicture), nalu.GetNalUnitType());
			if bNewPicture &&
				(nalu.GetNalUnitType() == TLibCommon.NAL_UNIT_CODED_SLICE_IDR ||
					nalu.GetNalUnitType() == TLibCommon.NAL_UNIT_CODED_SLICE_IDR_N_LP ||
					nalu.GetNalUnitType() == TLibCommon.NAL_UNIT_CODED_SLICE_BLA_N_LP ||
					nalu.GetNalUnitType() == TLibCommon.NAL_UNIT_CODED_SLICE_BLANT ||
					nalu.GetNalUnitType() == TLibCommon.NAL_UNIT_CODED_SLICE_BLA) {
				this.xFlushOutput(pcListPic)
			}
			// write reconstruction to file
			if bNewPicture {
				this.xWriteOutput(pcListPic, nalu.GetTemporalId())

				iDecodedFrameNum++
				if iDecodedFrameNum >= this.m_iFrameNum && this.m_iFrameNum > 0 {
					break
				}
			}
		}
	}

	this.xFlushOutput(pcListPic)
	// delete buffers
	this.m_cTDecTop.DeletePicBuffer()

	// destroy internal classes
	this.xDestroyDecLib()

	return nil
}