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

📄 video.cpp

📁 This code is based on mpeg_play, available from: http://bmrc.berkeley.edu/frame/research/mpeg/
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 *    A pointer to the new PictImage structure. * * Side effects: *    None. * *-------------------------------------------------------------- */PictImage* NewPictImage( VidStream* vid_stream, int w, int h, SDL_Surface *dst ){    PictImage* pi;    /* Allocate memory space for pi structure. */    pi = (PictImage *) malloc(sizeof(PictImage));    /* Create a YV12 image (Y + V + U) */#ifdef USE_ATI    pi->image = vhar128_newimage(vid_stream->ati_handle, w, h);#else    pi->image = (unsigned char *) malloc(w*h*12/8);    pi->luminance = (unsigned char *)pi->image;    pi->Cr = pi->luminance + (w*h);    pi->Cb = pi->luminance + (w*h) + (w*h)/4;#endif      /* Alloc space for filter info */    pi->mb_qscale = (unsigned short int *) malloc(vid_stream->mb_width * vid_stream->mb_height * sizeof(unsigned int));    /* Reset locked flag. */      pi->locked = 0;    /* Return pointer to pi structure. */    return pi;}bool InitPictImages( VidStream* vid_stream, int w, int h, SDL_Surface* dst ){    int i;    vid_stream->current = vid_stream->past = vid_stream->future = NULL;    for (i = 0; i < RING_BUF_SIZE; i++) {        if ( vid_stream->ring[i] ) {            DestroyPictImage(vid_stream, vid_stream->ring[i]);        }        vid_stream->ring[i] = NewPictImage( vid_stream, w, h, dst );        if ( ! vid_stream->ring[i] )            return false;    }#ifdef USE_ATI    struct vhar128_image * ring[RING_BUF_SIZE];    for (i = 0; i < RING_BUF_SIZE; i++) {      ring[i] = vid_stream->ring[i]->image;    }    vhar128_init(vid_stream->ati_handle, w, h, ring, RING_BUF_SIZE);#endif    return true;}/* *-------------------------------------------------------------- * * DestroyPictImage -- * *    Deallocates a PictImage structure. * * Results: *    None. * * Side effects: *    None. * *-------------------------------------------------------------- */void DestroyPictImage( VidStream* vid_stream, PictImage* apictimage ){#ifdef USE_ATI  vhar128_destroyimage(vid_stream->ati_handle, apictimage->image);#else  if (apictimage->image != NULL) free(apictimage->image);#endif  free(apictimage->mb_qscale);  free(apictimage);}/* *-------------------------------------------------------------- * * mpegVidRsrc -- * *      Parses bit stream until MB_QUANTUM number of *      macroblocks have been decoded or current slice or *      picture ends, whichever comes first. If the start *      of a frame is encountered, the frame is time stamped *      with the value passed in time_stamp. If the value *      passed in buffer is not null, the video stream buffer *      is set to buffer and the length of the buffer is *      expected in value passed in through length. * * Results: *      A pointer to the video stream structure used. * * Side effects: *      Bit stream is irreversibly parsed. If a picture is completed, *      a function is called to display the frame at the correct time. * *-------------------------------------------------------------- */VidStream* mpegVidRsrc( TimeStamp time_stamp, VidStream* vid_stream, int first ){    unsigned int data;    int i, status;    /*    * If called for the first time, find start code, make sure it is a    * sequence start code.    */    if( first )    {        vid_stream->num_left       = 0;        vid_stream->leftover_bytes = 0;        vid_stream->Parse_done     = FALSE;        next_start_code(vid_stream);  /* sets curBits */        show_bits32(data);        if( data != SEQ_START_CODE )        {            vid_stream->_smpeg->SetError("Invalid sequence in video stream");            /* Let whoever called NewVidStream call DestroyVidStream - KR            DestroyVidStream( vid_stream );            */            return 0;        }    }    else    {#ifdef UTIL2        vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;#else        vid_stream->curBits = *vid_stream->buffer;#endif    }    /* Get next 32 bits (size of start codes). */    show_bits32(data);    /* Check for end of file */    if(vid_stream->EOF_flag)    {        /* Display last frame if not looping */	if(!vid_stream->_smpeg->mpeg->is_looping())	{	  /* Set ended flag first so that ExecuteDisplay may check it. */	  vid_stream->film_has_ended = TRUE;	  if( vid_stream->future != NULL )	  {            vid_stream->current = vid_stream->future;            vid_stream->_smpeg->ExecuteDisplay( vid_stream );	  }#ifdef ANALYSIS	  PrintAllStats(vid_stream);#endif	  goto done;	}	else	  vid_stream->EOF_flag = 0;    }    /*    * Process according to start code (or parse macroblock if not a start code    * at all).    */    switch( data )    {    case SEQ_END_CODE:    case 0x000001b9:   /*  handle ISO_11172_END_CODE too */#ifdef VERBOSE_DEBUG        printf("SEQ_END_CODE\n");#endif        flush_bits32;        goto done;        break;    case SEQ_START_CODE:        /* Sequence start code. Parse sequence header. */#ifdef VERBOSE_DEBUG        printf("SEQ_START_CODE\n");#endif        if( ParseSeqHead( vid_stream ) != PARSE_OK )        {            fprintf( stderr, "mpegVidRsrc ParseSeqHead\n" );            goto error;        }        /*        * Return after sequence start code so that application above can use        * info in header.        */        goto done;    case GOP_START_CODE:        /* Group of Pictures start code. Parse gop header. */#ifdef VERBOSE_DEBUG        printf("GOP_START_CODE\n");#endif        if( ParseGOP(vid_stream) != PARSE_OK )        {            fprintf( stderr, "mpegVidRsrc ParseGOP\n" );            goto error;        }	/* need adjust current_frame (after Seek) */	if (vid_stream->need_frameadjust) {		int prev;		prev = vid_stream->totNumFrames;		vid_stream->current_frame = (int)		(		vid_stream->group.tc_hours * 3600 * vid_stream->rate_deal +		vid_stream->group.tc_minutes * 60 * vid_stream->rate_deal +		vid_stream->group.tc_seconds * vid_stream->rate_deal +		vid_stream->group.tc_pictures);		vid_stream->need_frameadjust=false;		vid_stream->totNumFrames=vid_stream->current_frame;#if 0	printf("Adjusted Frame %d -> %d\n",prev,vid_stream->current_frame);#endif	}        goto done;    case PICTURE_START_CODE:        /* Picture start code. Parse picture header and first slice header. */#ifdef VERBOSE_DEBUG        printf("PICTURE_START_CODE\n");#endif	if (vid_stream->timestamp_mark < vid_stream->buffer	    && !vid_stream->timestamp_used){	  vid_stream->timestamp_used = true;	  status = ParsePicture( vid_stream, vid_stream->timestamp );	} else	  status = ParsePicture( vid_stream, -1);        if((vid_stream->picture.code_type == B_TYPE) &&            vid_stream->_skipFrame && (vid_stream->_jumpFrame < 0))        {            status = SKIP_PICTURE;        }		if( !vid_stream->current )	    status = SKIP_PICTURE;        if( status == SKIP_PICTURE )        {            //fprintf( stderr, "%d\r", vid_stream->totNumFrames );            next_start_code( vid_stream );            while( ! next_bits( 32, PICTURE_START_CODE, vid_stream ) )            {                if( next_bits( 32, GOP_START_CODE, vid_stream) )                    break;                else if( next_bits( 32, SEQ_END_CODE, vid_stream ) )                    break;                flush_bits( 24 );                next_start_code( vid_stream );            }            vid_stream->_smpeg->timeSync( vid_stream );            goto done;        }        else if( status != PARSE_OK )        {            fprintf( stderr, "mpegVidRsrc ParsePicture\n" );            goto error;        }        if( ParseSlice(vid_stream) != PARSE_OK )        {            fprintf( stderr, "mpegVidRsrc ParseSlice\n" );            goto error;        }        break;    case SEQUENCE_ERROR_CODE:#ifdef VERBOSE_DEBUG        printf("SEQUENCE_ERROR_CODE\n");#endif        flush_bits32;        next_start_code(vid_stream);        goto done;    default:	/* No base picture for decoding */	if( !vid_stream->current )	{	    flush_bits32;	    next_start_code(vid_stream);#ifdef VERBOSE_DEBUG            printf("No base picture, flushing to next start code\n");#endif	    goto done;	}        /* Check for slice start code. */        if( (data >= SLICE_MIN_START_CODE) && (data <= SLICE_MAX_START_CODE) )        {            /* Slice start code. Parse slice header. */            if( ParseSlice(vid_stream) != PARSE_OK )            {                fprintf( stderr, "mpegVidRsrc ParseSlice\n" );                goto error;            }        }#ifdef VERBOSE_DEBUG        else            fprintf(stderr, "Unknown data [%x] - not slice start code!\n", data);#endif        break;    }    /* Parse next MB_QUANTUM macroblocks. */    for( i = 0; i < MB_QUANTUM; i++ )    {        /* Check to see if actually a startcode and not a macroblock. */        if( ! next_bits( 23, 0x00000000, vid_stream ) &&            ! vid_stream->film_has_ended )        {            /* Not start code. Parse Macroblock. */            if (ParseMacroBlock(vid_stream) != PARSE_OK)            {#ifdef VERBOSE_WARNINGS                fprintf( stderr, "mpegVidRsrc ParseMacroBlock\n" );#endif                goto error;            }        }        else        {            /* Not macroblock, actually start code. Get start code. */            next_start_code(vid_stream);            show_bits32(data);            /*            * If start code is outside range of slice start codes, frame is            * complete, display frame.            */            if( ((data<SLICE_MIN_START_CODE) || (data>SLICE_MAX_START_CODE)) &&                (data != SEQUENCE_ERROR_CODE) )            {                DoPictureDisplay( vid_stream );            }            goto done;        }    }    /* Check if we just finished a picture on the MB_QUANTUMth macroblock */    if( next_bits( 23, 0x00000000, vid_stream ) )    {        next_start_code(vid_stream);        show_bits32(data);        if( (data < SLICE_MIN_START_CODE) || (data > SLICE_MAX_START_CODE) )        {            DoPictureDisplay( vid_stream );        }    }    goto done;error:    next_start_code( vid_stream );    return vid_stream;done:    return vid_stream;}/* *-------------------------------------------------------------- * * ParseSeqHead -- * *      Assumes bit stream is at the begining of the sequence *      header start code. Parses off the sequence header. * * Results: *      Fills the vid_stream structure with values derived and *      decoded from the sequence header. Allocates the pict image *      structures based on the dimensions of the image space *      found in the sequence header. * * Side effects: *      Bit stream irreversibly parsed off. * *-------------------------------------------------------------- */static int ParseSeqHead( VidStream* vid_stream ){  unsigned int data;  int i, j;#ifndef DISABLE_DITHER  int ditherType=vid_stream->ditherType;#endif  /* Flush off sequence start code. */  flush_bits32;  /* Get horizontal size of image space. */  get_bits12(data);  vid_stream->h_size = (data + 15) & ~15;  /* Get vertical size of image space. */  get_bits12(data);  vid_stream->v_size = (data + 15) & ~15;  /* Calculate macroblock width and height of image space. */

⌨️ 快捷键说明

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