Esempio n. 1
0
LossyDepthFrameReader::LossyDepthFrameReader(IO::File& sSource)
	:source(sSource),
	 sourceHasTheora(false)
	{
	/* Read the frame size from the source: */
	for(int i=0;i<2;++i)
		size[i]=source.read<Misc::UInt32>();
	
	/* Read the stream header's size: */
	size_t streamHeaderSize=source.read<Misc::UInt32>();
	sourceHasTheora=streamHeaderSize>0;
	
	if(sourceHasTheora)
		{
		#if VIDEO_CONFIG_HAVE_THEORA
		
		/* Create the setup structures: */
		Video::TheoraInfo theoraInfo;
		Video::TheoraComment theoraComments;
		Video::TheoraDecoder::Setup theoraSetup;
		
		/* Read and process all stream header packets: */
		while(streamHeaderSize>0)
			{
			/* Read and process the next header packet: */
			Video::TheoraPacket packet;
			packet.read(source);
			Video::TheoraDecoder::processHeader(packet,theoraInfo,theoraComments,theoraSetup);
			streamHeaderSize-=packet.getWireSize();
			}
		
		/* Initialize the Theora decoder: */
		theoraDecoder.init(theoraInfo,theoraSetup);
		
		#else
		
		/* Skip the stream header packets: */
		source.skip<Misc::UInt8>(streamHeaderSize);
		
		#endif
		}
	}
Esempio n. 2
0
FrameBuffer LossyDepthFrameReader::readNextFrame(void)
	{
	/* Create the result frame: */
	FrameBuffer result(size[0],size[1],size[1]*size[0]*sizeof(FrameSource::DepthPixel));
	
	/* Return a dummy frame if the file is over: */
	if(source.eof())
		{
		result.timeStamp=Math::Constants<double>::max;
		return result;
		}
	
	/* Read the frame's time stamp from the source: */
	result.timeStamp=source.read<Misc::Float64>();
	
	if(sourceHasTheora)
		{
		#if VIDEO_CONFIG_HAVE_THEORA
		
		/* Read and process a single Theora packet: */
		{
		/* Read and process the next packet: */
		Video::TheoraPacket packet;
		packet.read(source);
		
		theoraDecoder.processPacket(packet);
		}
		
		/* Extract the decompressed frame: */
		Video::TheoraFrame theoraFrame;
		theoraDecoder.decodeFrame(theoraFrame);
		
		/* Convert the decompressed frame from Y'CbCr 4:2:0 to 11-bit depth: */
		FrameSource::DepthPixel* resultRowPtr=result.getData<FrameSource::DepthPixel>();
		const unsigned char* ypRowPtr=static_cast<const unsigned char*>(theoraFrame.planes[0].data)+theoraFrame.offsets[0];
		const unsigned char* cbRowPtr=static_cast<const unsigned char*>(theoraFrame.planes[1].data)+theoraFrame.offsets[1];
		const unsigned char* crRowPtr=static_cast<const unsigned char*>(theoraFrame.planes[2].data)+theoraFrame.offsets[2];
		for(unsigned int y=0;y<size[1];y+=2)
			{
			FrameSource::DepthPixel* resultPtr=resultRowPtr;
			const unsigned char* ypPtr=ypRowPtr;
			const unsigned char* cbPtr=cbRowPtr;
			const unsigned char* crPtr=crRowPtr;
			for(unsigned int x=0;x<size[0];x+=2)
				{
				/* Assemble the block's 4 11-bit depth values from the 4 8-bit yp values and the 8-bit cb and cr values: */
				resultPtr[0]=((FrameSource::DepthPixel(ypPtr[0])<<3)&0x7f8U)|(FrameSource::DepthPixel(*cbPtr)>>4);
				resultPtr[1]=((FrameSource::DepthPixel(ypPtr[1])<<3)&0x7f8U)|(FrameSource::DepthPixel(*cbPtr)&0x0fU);
				resultPtr[size[0]]=((FrameSource::DepthPixel(ypPtr[theoraFrame.planes[0].stride])<<3)&0x7f8U)|(FrameSource::DepthPixel(*cbPtr)>>4);
				resultPtr[size[0]+1]=((FrameSource::DepthPixel(ypPtr[theoraFrame.planes[0].stride+1])<<3)&0x7f8U)|(FrameSource::DepthPixel(*cbPtr)&0x0fU);
				
				/* Go to the next pixel block: */
				resultPtr+=2;
				ypPtr+=2;
				++cbPtr;
				++crPtr;
				}
			
			/* Go to the next pixel block row: */
			resultRowPtr+=size[0]*2;
			ypRowPtr+=theoraFrame.planes[0].stride*2;
			cbRowPtr+=theoraFrame.planes[1].stride;
			crRowPtr+=theoraFrame.planes[2].stride;
			}
		
		#else
		
		/**********************
		Skip one Theora packet:
		**********************/
		
		/* Skip packet flags: */
		source.skip<char>(1);
		
		/* Skip 64-bit granule position and packet number: */
		source.skip<Misc::SInt64>(2);
		
		/* Read the packet data size: */
		size_t packetSize=source.read<unsigned int>();
		source.skip<Misc::UInt8>(packetSize);
		
		/* Initialize the frame to all invalid pixels: */
		FrameSource::DepthPixel* resultPtr=result.getData<FrameSource::DepthPixel>();
		for(unsigned int y=0;y<size[1];++y)
			for(unsigned int x=0;x<size[0];++x,++resultPtr)
				*resultPtr=FrameSource::invalidDepth;
		
		#endif
		}
	else
		{
FrameBuffer ColorFrameReader::readNextFrame(void)
{
    /* Create the result frame: */
    FrameBuffer result(size[0],size[1],size[1]*size[0]*3*sizeof(unsigned char));

    /* Return a dummy frame if the file is over: */
    if(source.eof())
    {
        result.timeStamp=Math::Constants<double>::max;
        return result;
    }

    /* Read the frame's time stamp from the source: */
    result.timeStamp=source.read<double>();

    if(sourceHasTheora)
    {
#if VIDEO_CONFIG_HAVE_THEORA

        /* Read and process a single Theora packet: */
        {
            /* Read and process the next packet: */
            Video::TheoraPacket packet;
            packet.read(source);

            theoraDecoder.processPacket(packet);
        }

        /* Extract the decompressed frame: */
        Video::TheoraFrame theoraFrame;
        theoraDecoder.decodeFrame(theoraFrame);

        /* Convert the decompressed frame from Y'CbCr 4:2:0 to RGB: */
        unsigned char* resultRowPtr=static_cast<unsigned char*>(result.getBuffer())+(size[1]-1)*size[0]*3;
        const unsigned char* ypRowPtr=static_cast<const unsigned char*>(theoraFrame.planes[0].data)+theoraFrame.offsets[0];
        const unsigned char* cbRowPtr=static_cast<const unsigned char*>(theoraFrame.planes[1].data)+theoraFrame.offsets[1];
        const unsigned char* crRowPtr=static_cast<const unsigned char*>(theoraFrame.planes[2].data)+theoraFrame.offsets[2];
        for(unsigned int y=0; y<size[1]; y+=2)
        {
            unsigned char* resultPtr=resultRowPtr;
            const unsigned char* ypPtr=ypRowPtr;
            const unsigned char* cbPtr=cbRowPtr;
            const unsigned char* crPtr=crRowPtr;
            for(unsigned int x=0; x<size[0]; x+=2)
            {
                /* Convert the four pixels in the 2x2 block from Y'CbCr to RGB: */
                unsigned char ypcbcr[3];
                ypcbcr[0]=ypPtr[0];
                ypcbcr[1]=*cbPtr;
                ypcbcr[2]=*crPtr;
                Video::ypcbcrToRgb(ypcbcr,resultPtr);

                ypcbcr[0]=ypPtr[1];
                Video::ypcbcrToRgb(ypcbcr,resultPtr+3);

                ypcbcr[0]=ypPtr[theoraFrame.planes[0].stride];
                Video::ypcbcrToRgb(ypcbcr,resultPtr-size[0]*3);

                ypcbcr[0]=ypPtr[theoraFrame.planes[0].stride+1];
                Video::ypcbcrToRgb(ypcbcr,resultPtr-size[0]*3+3);

                /* Go to the next pixel: */
                resultPtr+=2*3;
                ypPtr+=2;
                ++cbPtr;
                ++crPtr;
            }

            /* Go to the next row: */
            resultRowPtr-=2*size[0]*3;
            ypRowPtr+=2*theoraFrame.planes[0].stride;
            cbRowPtr+=theoraFrame.planes[1].stride;
            crRowPtr+=theoraFrame.planes[2].stride;
        }

#else

        /**********************
        Skip one Theora packet:
        **********************/

        /* Skip packet flags: */
        source.skip<char>(1);

        /* Skip 64-bit granule position and packet number: */
        source.skip<Misc::SInt64>(2);

        /* Read the packet data size: */
        size_t packetSize=source.read<unsigned int>();
        source.skip<Misc::UInt8>(packetSize);

        /* Initialize the frame to 50% grey (why not?): */
        unsigned char* resultPtr=static_cast<unsigned char*>(result.getBuffer());
        for(unsigned int y=0; y<size[1]; ++y)
            for(unsigned int x=0; x<size[0]; ++x,resultPtr+=3)
            {
                resultPtr[0]=(unsigned char)(128);
                resultPtr[1]=(unsigned char)(128);
                resultPtr[2]=(unsigned char)(128);
            }

#endif
    }
    else
    {
        /* Initialize the frame to 50% grey (why not?): */
        unsigned char* resultPtr=static_cast<unsigned char*>(result.getBuffer());
        for(unsigned int y=0; y<size[1]; ++y)
            for(unsigned int x=0; x<size[0]; ++x,resultPtr+=3)
            {
                resultPtr[0]=(unsigned char)(128);
                resultPtr[1]=(unsigned char)(128);
                resultPtr[2]=(unsigned char)(128);
            }
    }

    return result;
}