⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdecoder.cc

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 CC
📖 第 1 页 / 共 5 页
字号:
/********************************************************************************    Copyright (C) 1999  Dirk Farin    This program is distributed under GNU Public License (GPL) as    outlined in the COPYING file that comes with the source distribution.    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA ********************************************************************************/#include "video12/vdecoder.hh"#include "video12/constants.hh"#include "video12/vlc.hh"#include "video12/viddec_mods.hh"#include "system/system1.hh"#include "error.hh"#include "video12/modules/idct_arai.hh" ////////////////////// TODO#include "video12/modules/mcomp_sgl_simple.hh"#include "libvideogfx/utility/bitstream/membitsread.hh"#include "libvideogfx/utility/bitstream/fastbitbuf.hh"#include <iostream.h>#include <iomanip.h>#include <string.h>#include <strings.h>#define SHOW_FRAMESIZE 0#if ENABLE_MMX#define MMX_DCT 1#else#define MMX_DCT 0#endif#undef SEND_FULL_BFRAMESextern "C" void IDCT_mmx(short* in,short* out);extern "C" void IDCT_16bit8bit(short* in,Pixel* out,int skip);extern "C" void IDCT_16bit8bit_add(short* in,Pixel* out,int skip);extern void PrintDataHex(uint8* data,uint32 len);extern void PrintDataBin(uint8* data,uint32 len);#include "video12/vlc.cc"#include "video12/dctblk.cc"#define NOBZERO 0inline void DIV2(int& x) { if (x>=0) x/=2; else x=(x-1)/2; }/*  implemented syntax elements:   ( - not, o partial, + full )  - video_sequence: o  - sequence_header: +  - extension_and_user_data: o  - extension_data: o  - user_data: -  - sequence_extension: +  - sequence_display_extension: -  - sequence_scalable_extension: -  - group_of_pictures_header: +  - picture_header: + (excluding extra_information_picture)  - picture_coding_extension: +  - quant_matrix_extension: -  - picture_display_extension: -  - picture_temporal_scalable_extension: -  - picture_spatial_scalable_extension: -  - copyright_extension: -  - picture_data: +  - slice: +  - macroblock: +  - macroblock_modes: o  - motion_vectors: +  - motion_vector: +  - coded_block_pattern: +  - block: +*/static const int qcode2qscale[2][32] ={//  - 1 2 3 4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29  30  31  { 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58, 60, 62 },  { 0,1,2,3,4, 5, 6, 7, 8,10,12,14,16,18,20,22,24,28,32,36,40,44,48,52,56,64,72,80,88,96,104,112 }};static const int scan[2][64] ={  { /* Zig-Zag scan pattern  */    0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,    12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,    35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,    58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63  },  { /* Alternate scan pattern */    0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49,    41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43,    51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45,    53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63  }};static const int AlternateFromZigZag[64] ={// 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   0, 2, 3, 9, 1, 4, 5, 7, 8,11,10,20,21,35,36,34,  22,19,18,12, 6,13,14,16,17,24,23,33,37,48,32,38,  47,49,25,31,15,26,27,29,30,40,39,46,50,57,45,51,  56,58,41,44,28,42,43,53,52,55,59,62,54,60,61,63};VideoSyntaxTrace_Options::VideoSyntaxTrace_Options(){  Trace_SeqH =  Trace_GOPH =  Trace_PicH =  Trace_SlcH =  Trace_MB   =  Trace_SliceData = false;  Trace_DCTCoeff  = false;}VideoFrameSkip_Options::VideoFrameSkip_Options(){  DecodeI = true;  DecodeP = true;  DecodeB = true;}VideoDecoder::VideoDecoder(class PacketSource& source)  : d_source(&source),    d_sink(NULL),    d_picdata(NULL),    d_SequenceHeaderRead(false),    d_next_packet(NULL),    d_BFrameAvailable(false),    d_FirstFieldInFrame(true),    d_next_IsEmpty(true),    d_skip_this_frame(false),    d_curr(NULL), d_next(NULL), d_last(NULL),    d_motcomp(NULL){  d_motcomp = MotionCompensation_SglMB::Create();#if MMX_DCT  for (int i=0;i<2;i++)    for (int n=0;n<64;n++)      {	int r=scan[i][n]/8;	int c=scan[i][n]%8;	d_scan[i][n]=c*8+r;      }#else  for (int i=0;i<2;i++)    for (int n=0;n<64;n++)      d_scan[i][n]=scan[i][n];#endif}VideoDecoder::~VideoDecoder(){  if (d_next_packet)    delete d_next_packet;  if (d_motcomp) delete d_motcomp;}SysPacket_Packet* VideoDecoder::GetNextPacket(){  SysPacket_Packet* pck;  if (d_next_packet)    {      pck = d_next_packet;      d_next_packet=NULL;    }  else    {      pck = d_source->GetNextPacket();      if (pck==NULL)        return NULL;    }  return pck;}void VideoDecoder::PushbackPacket(SysPacket_Packet* pck){  Assert(d_next_packet==NULL);  d_next_packet=pck;}bool VideoDecoder::DecodeAFrame(){  int  LastSliceRead = 0;  bool BeganPictureDecoding = false;  for (;;) // Read as much packets as are required to decode a picture.    {      // Get next stream packet.      SysPacket_Packet* pck = GetNextPacket();      if (pck==NULL)        {	  // We reached the end of the stream. Flush the remaining images.	  // B-picture	  if (d_BFrameAvailable)	    {	      Assert(d_curr);#if SEND_FULL_BFRAMES	      d_curr->m_may_modify = true;	      d_sink->ShowAllMBRows(d_curr);  // Show image#endif	      d_sink->FinishedPicture();	      d_curr->FreePictureData();      // Remove additional information data	      	      delete d_curr;	      d_curr=NULL;	      d_BFrameAvailable=false;	      return true;	    }	  // Future reference picture	  if (!d_next_IsEmpty)	    {	      d_next->m_may_modify = true;	      d_sink->BeginPicture(d_next);	      d_sink->ShowAllMBRows(d_next); // Show last decoded I- or P-image.	      d_sink->FinishedPicture();	      d_next->FreePictureData();     // Free the additional information data.	      	      delete d_last;	      delete d_next;	      d_last = d_next = NULL;	      d_next_IsEmpty=true;	    }          return false;        }      // Decode packet data.      MemBitstreamReader bitstream(pck->data.AskContents() , pck->data.AskLength());      uint32 startcode = bitstream.PeekBits(32);      Assert((startcode & 0x00000100) != 0); // TODO: throw excpt      if (IsMPEG_SLICE_START(startcode&0xFF) && d_SequenceHeaderRead && BeganPictureDecoding)        {          if (d_options.Trace_SliceData)            {              cout << "Slice Data:\n";              PrintDataBin(pck->data.AskContents(),pck->data.AskLength());            }	  FastBitBuf fastbitbuf(pck->data.AskContents() , pck->data.AskLength());          DecodeSlice(fastbitbuf);        }      else        {	  // If we were just decoding a picture and a new picture begins, end decoding of the picture.	  if ((startcode == STARTCODE_SEQUENCE_HEADER ||	       startcode == STARTCODE_GROUP_START ||	       startcode == STARTCODE_PICTURE_START) &&	      BeganPictureDecoding)	    {	      PushbackPacket(pck); // This packet already belongs to the next picture.	      /* If there's an B-image ready for display, show it.	       */	      if (d_BFrameAvailable)		{		  Assert(d_curr);	      #if SEND_FULL_BFRAMES		  d_curr->m_may_modify=true;		  d_sink->ShowAllMBRows(d_curr);  // Show image#endif		  d_sink->FinishedPicture();		  d_curr->FreePictureData();         // Remove additional information data		  d_BFrameAvailable=false;		}	      return true;	    }	  switch (startcode)	    {	    case STARTCODE_SEQUENCE_HEADER:	      {		DecodeSequenceHeader(bitstream,d_seqdata,d_quant_zz);		d_SequenceHeaderRead=true;		// Try to read Sequence-Extension.				SysPacket_Packet* pck = GetNextPacket();		if (pck)		  {		    MemBitstreamReader bs(pck->data.AskContents() , pck->data.AskLength());    		    uint32 startcode = bs.GetBits(32);		    if (startcode==STARTCODE_EXTENSION_START)		      {			if (bs.GetBits(4)==EXTID_SequenceExtension)			  DecodeSequenceHeaderExt(bs,d_seqdata);			delete pck;		      }		    else		      PushbackPacket(pck);		  }		// Allocate images and precalculate some values.				PostSequenceHeader();		if (d_options.Trace_SeqH)		  TraceSequenceHeader(d_seqdata);	      }	      break;	    case STARTCODE_GROUP_START:	      {		GOPHeader gopdata;		DecodeGOPHeader(bitstream,gopdata);		if (d_options.Trace_GOPH)		  TraceGOPHeader(gopdata);	      }	      break;	    case STARTCODE_PICTURE_START:	      if (d_SequenceHeaderRead)		{		  DecodePictureHeader(bitstream,d_pichdr);		  BeganPictureDecoding=true;		  // Try to read Picture-Coding-Extension.		  SysPacket_Packet* pck2 = GetNextPacket();		  if (pck2)		    {		      MemBitstreamReader bs(pck2->data.AskContents() , pck2->data.AskLength());    		      uint32 startcode = bs.GetBits(32);		      if (startcode==STARTCODE_EXTENSION_START)			{			  if (bs.GetBits(4)==EXTID_PictureCodingExtension)			    DecodePictureCodingExt(bs,d_pichdr);			  delete pck2;			}		      else			PushbackPacket(pck2);		    }		  DecodeExtensions(2);		  // Do some precalculations, pointer settings...		  PostPictureHeader(pck->timing);		  if (d_options.Trace_PicH)		    TracePictureHeader(d_pichdr);		}	      break;#if 0	    case STARTCODE_EXTENSION_START:	      bitstream.SkipBits(32);	      switch (bitstream.GetBits(4))		{		case EXTID_SequenceExtension: DecodeSequenceExtension(bitstream); break;		default:		  //assert(0);		  break;		}	      break;	    case STARTCODE_ISO11172_END:	      Assert(0); /* TODO: check: I think we'll never see this as this is thrown away because			    it's a syntax stream element.			 */              //Append(d_next);              	      break;#endif	    default:	      break;	    }	}      delete pck;    }  return true;}void VideoDecoder::PostSequenceHeader(){  d_IsMPEG2 = d_seqdata.m_IsMPEG2;  d_ChromaFormat = d_seqdata.m_ChromaFormat;  switch (d_ChromaFormat)    {    case CHROMA_420: d_dctblks= 6; d_intra_cbp=0xFC0; mb_chr_w= 8; mb_chr_h= 8; break;    case CHROMA_422: d_dctblks= 8; d_intra_cbp=0xFF0; mb_chr_w= 8; mb_chr_h=16; break;    case CHROMA_444: d_dctblks=12; d_intra_cbp=0xFFF; mb_chr_w=16; mb_chr_h=16; break;    }  d_MBWidth  = d_seqdata.m_MBWidth =(d_seqdata.m_Width +15)/16;  d_MBHeight = d_seqdata.m_MBHeight=(d_seqdata.m_Height+15)/16;  ImageParam param;  if (d_last) d_last->m_image.Image<Pixel>::GetParam(param);  if (!d_last ||      param.width  != d_seqdata.m_Width ||      param.height != d_seqdata.m_Height)    {      specs.width  = d_seqdata.m_Width;      specs.height = d_seqdata.m_Height;      specs.halign = 16;      specs.valign = 16;      specs.exact_size = true;      specs.reduced_chroma_size = true;      switch (d_seqdata.m_ChromaFormat)        {        case CHROMA_444: specs.chroma = Chroma444; break;        case CHROMA_422: specs.chroma = Chroma422; break;        case CHROMA_420: specs.chroma = Chroma420; break;        }      Assert(d_sink != NULL);      if (d_last) delete d_last;      if (d_curr) delete d_curr;      if (d_next) delete d_next;      d_last=d_curr=d_next=NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -