summaryrefslogtreecommitdiffstats
path: root/libmpdemux/demux_y4m.c
diff options
context:
space:
mode:
authoralex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-12-27 11:30:07 +0000
committeralex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-12-27 11:30:07 +0000
commit46fb559fd70bd26da60ff44d7c750fa95fda53e8 (patch)
tree034c99bca03d891d4bb86a429bb362dbec0529bb /libmpdemux/demux_y4m.c
parentecee4bef8c071b34e7e1622ba61783cab7950978 (diff)
downloadmpv-46fb559fd70bd26da60ff44d7c750fa95fda53e8.tar.bz2
mpv-46fb559fd70bd26da60ff44d7c750fa95fda53e8.tar.xz
added support for older YUV4MPEG format (used by xawtv)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3790 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux/demux_y4m.c')
-rw-r--r--libmpdemux/demux_y4m.c133
1 files changed, 108 insertions, 25 deletions
diff --git a/libmpdemux/demux_y4m.c b/libmpdemux/demux_y4m.c
index 4c96b950e3..5484e2c7cd 100644
--- a/libmpdemux/demux_y4m.c
+++ b/libmpdemux/demux_y4m.c
@@ -1,5 +1,6 @@
// Y4M file parser by Rik Snel (using yuv4mpeg*.[ch] from
// mjpeg.sourceforge.net) (derived from demux_viv.c)
+// older YUV4MPEG (used by xawtv) support by Alex Beregszaszi
#include <stdio.h>
#include <stdlib.h>
@@ -19,27 +20,40 @@
typedef struct {
int framenum;
y4m_stream_info_t* si;
+ int is_older;
} y4m_priv_t;
int y4m_check_file(demuxer_t* demuxer){
int orig_pos = stream_tell(demuxer->stream);
char buf[10];
+ y4m_priv_t* priv;
mp_msg(MSGT_DEMUX, MSGL_V, "Checking for YUV4MPEG2\n");
stream_read(demuxer->stream, buf, 9);
buf[9] = 0;
-
- if (strncmp("YUV4MPEG2", buf, 9)) {
+
+ if (strncmp("YUV4MPEG2", buf, 9) && strncmp("YUV4MPEG ", buf, 9)) {
mp_msg(MSGT_DEMUX, MSGL_DBG2, "Failed: YUV4MPEG2\n");
return 0;
}
+ demuxer->priv = malloc(sizeof(y4m_priv_t));
+ priv = demuxer->priv;
+
+ priv->is_older = 0;
+
+ if (!strncmp("YUV4MPEG ", buf, 9))
+ {
+ mp_msg(MSGT_DEMUX, MSGL_V, "Found older YUV4MPEG format (used by xawtv)\n");
+ priv->is_older = 1;
+ }
+
mp_msg(MSGT_DEMUX,MSGL_DBG2,"Success: YUV4MPEG2\n");
stream_seek(demuxer->stream, orig_pos);
-return 1;
+ return 1;
}
@@ -65,9 +79,19 @@ int demux_y4m_fill_buffer(demuxer_t *demux) {
buf[1] = dp->buffer + 5*size/4;
buf[2] = dp->buffer + size;
- if ((err=y4m_read_frame(demux->stream, priv->si, &fi, buf)) != Y4M_OK) {
+ if (priv->is_older)
+ {
+ stream_skip(demux->stream, 6); /* FRAME\n */
+ stream_read(demux->stream, buf[0], size);
+ stream_read(demux->stream, buf[1], size/4);
+ stream_read(demux->stream, buf[2], size/4);
+ }
+ else
+ {
+ if ((err=y4m_read_frame(demux->stream, priv->si, &fi, buf)) != Y4M_OK) {
mp_msg(MSGT_DEMUX, MSGL_V, "error reading frame %s\n", y4m_strerr(err));
return 0;
+ }
}
/* This seems to be the right way to calculate the presentation time stamp */
@@ -81,40 +105,96 @@ int demux_y4m_fill_buffer(demuxer_t *demux) {
}
void demux_open_y4m(demuxer_t* demuxer){
- y4m_priv_t* priv;
+ y4m_priv_t* priv = demuxer->priv;
y4m_ratio_t framerate;
sh_video_t* sh=new_sh_video(demuxer,0);
int err;
- demuxer->priv = malloc(sizeof(y4m_priv_t));
- priv = demuxer->priv;
-
priv->framenum = 0;
priv->si = malloc(sizeof(y4m_stream_info_t));
- y4m_init_stream_info(priv->si);
- if ((err=y4m_read_stream_header(demuxer->stream, priv->si)) != Y4M_OK)
+ if (priv->is_older)
+ {
+ char buf[4];
+ int frame_rate_code;
+
+ priv->framenum = 1;
+ stream_skip(demuxer->stream, 8); /* YUV4MPEG */
+ stream_skip(demuxer->stream, 1); /* space */
+ stream_read(demuxer->stream, (char *)&buf[0], 3);
+ buf[3] = 0;
+ sh->disp_w = atoi(buf);
+ stream_skip(demuxer->stream, 1); /* space */
+ stream_read(demuxer->stream, (char *)&buf[0], 3);
+ buf[3] = 0;
+ sh->disp_h = atoi(buf);
+ stream_skip(demuxer->stream, 1); /* space */
+ stream_read(demuxer->stream, (char *)&buf[0], 1);
+ buf[1] = 0;
+ frame_rate_code = atoi(buf);
+ stream_skip(demuxer->stream, 1); /* new-line */
+
+ if (!sh->fps)
+ {
+ /* values from xawtv */
+ switch(frame_rate_code)
+ {
+ case 1:
+ sh->fps = 23.976f;
+ break;
+ case 2:
+ sh->fps = 24.0f;
+ break;
+ case 3:
+ sh->fps = 25.0f;
+ break;
+ case 4:
+ sh->fps = 29.97f;
+ break;
+ case 5:
+ sh->fps = 30.0f;
+ break;
+ case 6:
+ sh->fps = 50.0f;
+ break;
+ case 7:
+ sh->fps = 59.94f;
+ break;
+ case 8:
+ sh->fps = 60.0f;
+ break;
+ default:
+ sh->fps = 25.0f;
+ }
+ }
+ sh->frametime = 1.0f/sh->fps;
+ }
+ else
+ {
+ y4m_init_stream_info(priv->si);
+ if ((err=y4m_read_stream_header(demuxer->stream, priv->si)) != Y4M_OK)
mp_msg(MSGT_DEMUXER, MSGL_FATAL, "error parsing YUV4MPEG header: %s\n", y4m_strerr(err));
-
- sh->format = mmioFOURCC('Y', 'V', '1', '2');
-
- if(!sh->fps) {
- framerate = y4m_si_get_framerate(priv->si);
- if (framerate.d != 0)
- sh->fps=(float)framerate.n/(float)framerate.d;
- else
- sh->fps=15.0f;
+
+ if(!sh->fps) {
+ framerate = y4m_si_get_framerate(priv->si);
+ if (framerate.d != 0)
+ sh->fps=(float)framerate.n/(float)framerate.d;
+ else
+ sh->fps=15.0f;
+ }
+ sh->frametime=1.0f/sh->fps;
+
+ sh->disp_w = y4m_si_get_width(priv->si);
+ sh->disp_h = y4m_si_get_height(priv->si);
}
- sh->frametime=1.0f/sh->fps;
- sh->disp_w = y4m_si_get_width(priv->si);
- sh->disp_h = y4m_si_get_height(priv->si);
+ sh->format = mmioFOURCC('Y', 'V', '1', '2');
sh->bih=malloc(sizeof(BITMAPINFOHEADER));
memset(sh->bih,0,sizeof(BITMAPINFOHEADER));
sh->bih->biSize=40;
- sh->bih->biWidth = priv->si->width;
- sh->bih->biHeight = priv->si->height;
+ sh->bih->biWidth = sh->disp_w;
+ sh->bih->biHeight = sh->disp_h;
sh->bih->biPlanes=3;
sh->bih->biBitCount=12;
sh->bih->biCompression=sh->format;
@@ -134,7 +214,10 @@ void demux_open_y4m(demuxer_t* demuxer){
void demux_close_y4m(demuxer_t *demuxer)
{
- y4m_fini_stream_info(((y4m_priv_t*)demuxer->priv)->si);
+ y4m_priv_t* priv;
+
+ if (!priv->is_older)
+ y4m_fini_stream_info(((y4m_priv_t*)demuxer->priv)->si);
free(((y4m_priv_t*)demuxer->priv)->si);
free(demuxer->priv);
return;