[MPlayer-dev-eng] [PATCH] DVDNAV Still frames supprt
Reimar Döffinger
Reimar.Doeffinger at stud.uni-karlsruhe.de
Fri Jan 25 11:47:55 CET 2008
Hello,
On Thu, Jan 24, 2008 at 11:29:28PM +0100, Benjamin Zores wrote:
> +/* state flags */
> +typedef enum {
> + NAV_FLAG_EOF = 0x0001, /* end of stream has been reached */
> + NAV_FLAG_WAIT = 0x0002, /* wait event */
> + NAV_FLAG_WAIT_SKIP = 0x0004, /* wait skip disable */
> + NAV_FLAG_CELL_CHANGED = 0x0008, /* cell change event */
> + NAV_FLAG_WAIT_READ_AUTO = 0x0010, /* wait read auto mode */
> + NAV_FLAG_WAIT_READ = 0x0020, /* suspend read from stream */
> + NAV_FLAG_VTS_DOMAIN = 0x0040, /* vts domain */
> +} dvdnav_state_t;
1 << 0
to
1 << 6
would be nicer IMO.
> + /* set still frame duration */
> + priv->duration =
> + (priv->still_length != 255) ? priv->still_length * 1000 : 0;
This kind of conversions is done at least three times (once in the form
of if (...== 255) ).
IMO make a static inline still_duration function or something like this
for this conversion.
> + if (priv->still_length <= 1) {
> + pci_t *pnavpci = dvdnav_get_current_nav_pci (priv->dvdnav);
> + priv->duration = mp_dvdtimetomsec (&(pnavpci->pci_gi.e_eltm));
Innermost () are not necessary
> +int mp_dvdnav_skip_still (stream_t *stream) {
> + dvdnav_priv_t *priv = (dvdnav_priv_t *) stream->priv;
IIRC priv is void *, so all these casts are not necessary (there are at
least 4).
> + if (priv->still_length == 0xff)
This is the "if" I meant in the first comment.
> + if (clear) {
> + priv->state &= ~NAV_FLAG_CELL_CHANGED;
> + }
Useless {}
> +#ifdef USE_DVDNAV
> +/* store decoded video image */
> +static mp_image_t * mp_dvdnav_copympi(mp_image_t* to_mpi,
> + mp_image_t* from_mpi) {
Not a doxygen comment.
> + mp_image_t *mpi;
> +
> + if (!from_mpi)
> + return NULL;
Is this case _supposed_ to happen?
> + /* Do not store B-frames */
> + if (from_mpi->pict_type == 3)
Hmm... are there no constants/defines for pict_type?
> + return to_mpi;
> +
> + if (to_mpi &&
> + to_mpi->w == from_mpi->w &&
> + to_mpi->h == from_mpi->h &&
> + to_mpi->imgfmt == from_mpi->imgfmt)
> + mpi = to_mpi;
> + else {
> + if (to_mpi)
> + free_mp_image(to_mpi);
Indentation is only 2 elsewhere.
> +/* video frame pre-processing: will be called before decode_video() */
> +static void * mp_dvdnav_decode_video_pre(int *in_size,
> + unsigned char **start,
> + mp_image_t* decoded_frame) {
Not doxygen-compatible either.
> + /* change in dvdnav stream */
> + if (mp_dvdnav_cell_has_changed(mpctx->stream,0)) {
> + /* suspend read from dvdnav stream, and set auto_wait */
> + mp_dvdnav_read_wait(mpctx->stream, 1, 1);
> + /* free the last stored video frame */
> + if (mpctx->smpi) free_mp_image(mpctx->smpi);
> + mpctx->smpi = NULL;
> + if (mpctx->last_buffer) free(mpctx->last_buffer);
> + mpctx->last_buffer = NULL;
> + mpctx->last_in_size = 0;
> + if (mpctx->d_sub) dvdsub_id = -2;
> +
> + if (mpctx->sh_video) {
> + /* clear video pts */
> + mpctx->d_video->pts = 0.0f;
> + mpctx->sh_video->pts = 0.0f;
> + mpctx->sh_video->i_pts = 0.0f;
> + mpctx->sh_video->last_pts = 0.0f;
> + mpctx->sh_video->num_buffered_pts = 0;
> + mpctx->sh_video->num_frames = 0;
> + mpctx->sh_video->num_frames_decoded = 0;
> + mpctx->sh_video->timer = 0.0f;
> + mpctx->sh_video->stream_delay = 0.0f;
> + mpctx->demuxer->stream_pts = MP_NOPTS_VALUE;
> + mpctx->sh_video->timer = 0;
> + }
> +
> + if (mpctx->sh_audio) {
> + /* free audio packets and reset */
> + ds_free_packs(mpctx->d_audio);
> + audio_delay -= mpctx->sh_audio->stream_delay;
> + mpctx->delay =- audio_delay;
That - is placed weirdly. I am also not too happy that this code messes
directly with mplayer.c "internals", but that may be hard to avoid.
> + mpctx->dup_frame = 0;
> + if (*in_size < 0 && mpctx->last_buffer) {
> + mpctx->dup_frame = 1;
Hmm. how about
> mpctx->dup_frame = *in_size < 0 && mpctx->last_buffer;
> if (mpctx->dup_frame)
?
I think this conveys the meaning of the code better, but I may have
misunderstood the code.
> + if (!mpctx->libmpeg2_count)
> + mpctx->libmpeg2_count = 5;
> +
> + if (mpctx->last_start) {
> + *start = mpctx->last_start;
> + *in_size = mpctx->last_in_size;
> + memcpy(*start,mpctx->last_buffer,*in_size);
> + } else {
> + *start = mpctx->last_buffer;
> + *in_size = mpctx->last_in_size;
> + }
in_size is set to the same thing in both cases, it might make sense
to pull it out of the if.
Actually I think that
> memcpy(*start,mpctx->last_buffer,mpctx->last_in_size);
might make more sense (and allows setting in_size below the if which I
think would result in the most readable code - YMMV though, do as you
find suitable).
> + if ((mpctx->sh_video->pts >= len || !mpctx->smpi) &&
> + (mpctx->sh_video->pts > 0.0) && (len > 0.0)) {
Useless () around the comparisons.
> + mp_msg(MSGT_CPLAYER,MSGL_ERR,
> + "Can't decode still frame.\n"
> + "Please, you try play dvdnav to -vc ffmpeg12 option.\n");
That's not quite English.
> + if (mpctx->last_buffer)
> + memcpy(mpctx->last_buffer,start,in_size);
> + else
> + mpctx->last_in_size=-1;
I'd have to do a second review pass to be sure, but I have some doubts
the mpctx->last_in_size==-1 case is handled correctly everywhere.
What does it signify anyway compared to 0 (this probably should be
documented at the declaration)?
> +#ifdef USE_DVDNAV
> + if (mpctx->stream->type == STREAMTYPE_DVDNAV)
> + decoded_frame = mp_dvdnav_decode_video_pre(&in_size,
> + &start,decoded_frame);
> + /* if image has been stored, there's no need to call decode_video() */
> + if (in_size > 0 && !decoded_frame)
> +#endif
> current_module = "decode_video";
> decoded_frame = decode_video(sh_video, start, in_size, drop_frame,
> sh_video->pts);
Something looks fishy to me here.
> - current_module = "filter_video";
> +#ifdef USE_DVDNAV
> + if (mpctx->stream->type == STREAMTYPE_DVDNAV)
> + decoded_frame = mp_dvdnav_decode_video_post(in_size,
> + start,decoded_frame,
> + sh_video, drop_frame);
> +#endif
> + current_module = "filter_video";
> *blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame,
Surrounding code uses a tab for indentation so this should as well.
> +#ifdef USE_DVDNAV
> + void *smpi; ///< store last decoded video image
> + void *last_buffer; ///< store last read video frame
> + void *last_start; ///< video read buffer ptr
> + int last_in_size; ///< last read size
> + int libmpeg2_count; ///< libmpeg2 repeat decode counter
> + int dup_frame; ///< duplicate frame mode
Have a quick thought if you can improve these, esp. the "last read size"
does not provide any information that variable name does not already.
Note that this is only a very quick review, I have not truly understood
even half of the code...
Greetings,
Reimar Döffinger
More information about the MPlayer-dev-eng
mailing list