[MPlayer-dev-eng] YUV4MPEG (not 2) seek

Alex Beregszaszi alex at naxine.org
Fri Dec 28 23:52:52 CET 2001


Hi Rik,

Thanks for you patch, I applied it.

On Fri, Dec 28, 2001 at 09:53:27PM +0100, Rik Snel wrote:
> Hello Alex,
> 
> This patch implements seek support for YUV4MPEG(1). (btw: why does your
> framenumber start at 1 and not at 0, I didn't see immediately why mplayer
> tried to seek to negative offsets while seeking back, it got me confused).

Also i removed this hack (priv->framenumber = 1), it was becouse of some
errors i got under writeing support for YUV4MPEG.

> 
> The problem with YUV4MPEG2 is that (formally) the FRAME header doesn't
> have a fixed length. (possible solution for backseeking: keep a (one
> second resolution) index to the previous frames) Maybe forward seeking
> must be done by assuming a minimal FRAME length, then take a big step
> forward rel_seek_frames*(minimal frame length), and then seek forward to
> the next legal FRAME header. (there is, of course, a possibility that a
> part of the YUV data is accidentally a valid FRAME header...)
> 
> Greetings,
> 
> Rik.
> 
> --------
> Nothing is ever a total loss; it can always serve as a bad example.

> diff -Naur main/libmpdemux/demux_y4m.c main.dev/libmpdemux/demux_y4m.c
> --- main/libmpdemux/demux_y4m.c	Fri Dec 28 09:38:59 2001
> +++ main.dev/libmpdemux/demux_y4m.c	Fri Dec 28 21:38:02 2001
> @@ -200,6 +200,7 @@
>  
>  	sh->disp_w = y4m_si_get_width(priv->si);
>  	sh->disp_h = y4m_si_get_height(priv->si);
> +    	demuxer->seekable = 0;
>      }
>  
>      sh->format = mmioFOURCC('Y', 'V', '1', '2');
> @@ -218,12 +219,42 @@
>      sh->ds=demuxer->video;
>      demuxer->video->id=0;
>  		
> -    /* disable seeking, lazy */
> -    demuxer->seekable = 0;
>  
>      printf("YUV4MPEG2 Video stream %d size: display: %dx%d, codec: %ux%u\n",
>              demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth,
>              sh->bih->biHeight);
> +}
> +
> +int demux_seek_y4m(demuxer_t *demuxer, float rel_seek_secs, int flags) {
> +    sh_video_t* sh = demuxer->video->sh;
> +    y4m_priv_t* priv = demuxer->priv;
> +    int rel_seek_frames = sh->fps*rel_seek_secs;
> +    int size = 3*sh->disp_w*sh->disp_h/2;
> +    off_t curr_pos = stream_tell(demuxer->stream);
> +
> +    if (priv->framenum + rel_seek_frames < 0) rel_seek_frames = -priv->framenum;
> +
> +    //printf("seektoframe=%d rel_seek_secs=%f seektooffset=%ld\n", priv->framenum + rel_seek_frames, rel_seek_secs, curr_pos + rel_seek_frames*(size+6));
> +    //printf("framenum=%d, curr_pos=%ld, currpos/(size+6)=%f\n", priv->framenum, curr_pos, (float)curr_pos/(float)(size+6));
> +    priv->framenum += rel_seek_frames;
> +
> +    if (priv->is_older) {
> +        /* Well this is easy: every frame takes up size+6 bytes
> +         * in the stream and we may assume that the stream pointer
> +         * is always at the beginning of a frame.
> +         * framenum is the number of the frame that is about to be
> +         * demuxed (counting from ONE (see demux_open_y4m)) */
> +        if (priv->framenum == 0) { //this is because framenum starts at 1
> +            priv->framenum=1;
> +	    rel_seek_frames++;
> +	}
> +        stream_seek(demuxer->stream, curr_pos + rel_seek_frames*(size+6));
> +    } else {
> +	    /* should never come here, because seeking for YUV4MPEG2 
> +	     * is disabled. */
> +	    printf("not yet implemented!\n");
> +    }
> +    return 0; 
>  }
>  
>  void demux_close_y4m(demuxer_t *demuxer)
> diff -Naur main/libmpdemux/demuxer.c main.dev/libmpdemux/demuxer.c
> --- main/libmpdemux/demuxer.c	Fri Dec 28 17:53:20 2001
> +++ main.dev/libmpdemux/demuxer.c	Fri Dec 28 21:35:45 2001
> @@ -658,6 +658,7 @@
>  int demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,int flags);
>  int demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,int flags);
>  int demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,int flags);
> +int demux_seek_y4m(demuxer_t *demuxer,float rel_seek_secs,int flags);
>  int demux_seek_fli(demuxer_t *demuxer,float rel_seek_secs,int flags);
>  void demux_seek_mov(demuxer_t *demuxer,float pts,int flags);
>  
> @@ -708,6 +709,9 @@
>  
>    case DEMUXER_TYPE_MOV:
>        demux_seek_mov(demuxer,rel_seek_secs,flags);  break;
> +
> +  case DEMUXER_TYPE_Y4M:
> +      demux_seek_y4m(demuxer,rel_seek_secs,flags);  break;
>  
>    case DEMUXER_TYPE_FLI:
>        demux_seek_fli(demuxer,rel_seek_secs,flags);  break;




More information about the MPlayer-dev-eng mailing list