mirror of https://github.com/mpv-player/mpv
added support for older YUV4MPEG format (used by xawtv)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3790 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
ecee4bef8c
commit
46fb559fd7
|
@ -1,5 +1,6 @@
|
||||||
// Y4M file parser by Rik Snel (using yuv4mpeg*.[ch] from
|
// Y4M file parser by Rik Snel (using yuv4mpeg*.[ch] from
|
||||||
// mjpeg.sourceforge.net) (derived from demux_viv.c)
|
// mjpeg.sourceforge.net) (derived from demux_viv.c)
|
||||||
|
// older YUV4MPEG (used by xawtv) support by Alex Beregszaszi
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -19,27 +20,40 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int framenum;
|
int framenum;
|
||||||
y4m_stream_info_t* si;
|
y4m_stream_info_t* si;
|
||||||
|
int is_older;
|
||||||
} y4m_priv_t;
|
} y4m_priv_t;
|
||||||
|
|
||||||
int y4m_check_file(demuxer_t* demuxer){
|
int y4m_check_file(demuxer_t* demuxer){
|
||||||
int orig_pos = stream_tell(demuxer->stream);
|
int orig_pos = stream_tell(demuxer->stream);
|
||||||
char buf[10];
|
char buf[10];
|
||||||
|
y4m_priv_t* priv;
|
||||||
|
|
||||||
mp_msg(MSGT_DEMUX, MSGL_V, "Checking for YUV4MPEG2\n");
|
mp_msg(MSGT_DEMUX, MSGL_V, "Checking for YUV4MPEG2\n");
|
||||||
|
|
||||||
stream_read(demuxer->stream, buf, 9);
|
stream_read(demuxer->stream, buf, 9);
|
||||||
buf[9] = 0;
|
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");
|
mp_msg(MSGT_DEMUX, MSGL_DBG2, "Failed: YUV4MPEG2\n");
|
||||||
return 0;
|
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");
|
mp_msg(MSGT_DEMUX,MSGL_DBG2,"Success: YUV4MPEG2\n");
|
||||||
|
|
||||||
stream_seek(demuxer->stream, orig_pos);
|
stream_seek(demuxer->stream, orig_pos);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,10 +79,20 @@ int demux_y4m_fill_buffer(demuxer_t *demux) {
|
||||||
buf[1] = dp->buffer + 5*size/4;
|
buf[1] = dp->buffer + 5*size/4;
|
||||||
buf[2] = dp->buffer + size;
|
buf[2] = dp->buffer + size;
|
||||||
|
|
||||||
|
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) {
|
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));
|
mp_msg(MSGT_DEMUX, MSGL_V, "error reading frame %s\n", y4m_strerr(err));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* This seems to be the right way to calculate the presentation time stamp */
|
/* This seems to be the right way to calculate the presentation time stamp */
|
||||||
dp->pts=(float)priv->framenum/((sh_video_t*)ds->sh)->fps;
|
dp->pts=(float)priv->framenum/((sh_video_t*)ds->sh)->fps;
|
||||||
|
@ -81,23 +105,76 @@ int demux_y4m_fill_buffer(demuxer_t *demux) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void demux_open_y4m(demuxer_t* demuxer){
|
void demux_open_y4m(demuxer_t* demuxer){
|
||||||
y4m_priv_t* priv;
|
y4m_priv_t* priv = demuxer->priv;
|
||||||
y4m_ratio_t framerate;
|
y4m_ratio_t framerate;
|
||||||
sh_video_t* sh=new_sh_video(demuxer,0);
|
sh_video_t* sh=new_sh_video(demuxer,0);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
demuxer->priv = malloc(sizeof(y4m_priv_t));
|
|
||||||
priv = demuxer->priv;
|
|
||||||
|
|
||||||
priv->framenum = 0;
|
priv->framenum = 0;
|
||||||
priv->si = malloc(sizeof(y4m_stream_info_t));
|
priv->si = malloc(sizeof(y4m_stream_info_t));
|
||||||
|
|
||||||
|
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);
|
y4m_init_stream_info(priv->si);
|
||||||
if ((err=y4m_read_stream_header(demuxer->stream, priv->si)) != Y4M_OK)
|
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));
|
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) {
|
if(!sh->fps) {
|
||||||
framerate = y4m_si_get_framerate(priv->si);
|
framerate = y4m_si_get_framerate(priv->si);
|
||||||
if (framerate.d != 0)
|
if (framerate.d != 0)
|
||||||
|
@ -109,12 +186,15 @@ void demux_open_y4m(demuxer_t* demuxer){
|
||||||
|
|
||||||
sh->disp_w = y4m_si_get_width(priv->si);
|
sh->disp_w = y4m_si_get_width(priv->si);
|
||||||
sh->disp_h = y4m_si_get_height(priv->si);
|
sh->disp_h = y4m_si_get_height(priv->si);
|
||||||
|
}
|
||||||
|
|
||||||
|
sh->format = mmioFOURCC('Y', 'V', '1', '2');
|
||||||
|
|
||||||
sh->bih=malloc(sizeof(BITMAPINFOHEADER));
|
sh->bih=malloc(sizeof(BITMAPINFOHEADER));
|
||||||
memset(sh->bih,0,sizeof(BITMAPINFOHEADER));
|
memset(sh->bih,0,sizeof(BITMAPINFOHEADER));
|
||||||
sh->bih->biSize=40;
|
sh->bih->biSize=40;
|
||||||
sh->bih->biWidth = priv->si->width;
|
sh->bih->biWidth = sh->disp_w;
|
||||||
sh->bih->biHeight = priv->si->height;
|
sh->bih->biHeight = sh->disp_h;
|
||||||
sh->bih->biPlanes=3;
|
sh->bih->biPlanes=3;
|
||||||
sh->bih->biBitCount=12;
|
sh->bih->biBitCount=12;
|
||||||
sh->bih->biCompression=sh->format;
|
sh->bih->biCompression=sh->format;
|
||||||
|
@ -134,6 +214,9 @@ void demux_open_y4m(demuxer_t* demuxer){
|
||||||
|
|
||||||
void demux_close_y4m(demuxer_t *demuxer)
|
void demux_close_y4m(demuxer_t *demuxer)
|
||||||
{
|
{
|
||||||
|
y4m_priv_t* priv;
|
||||||
|
|
||||||
|
if (!priv->is_older)
|
||||||
y4m_fini_stream_info(((y4m_priv_t*)demuxer->priv)->si);
|
y4m_fini_stream_info(((y4m_priv_t*)demuxer->priv)->si);
|
||||||
free(((y4m_priv_t*)demuxer->priv)->si);
|
free(((y4m_priv_t*)demuxer->priv)->si);
|
||||||
free(demuxer->priv);
|
free(demuxer->priv);
|
||||||
|
|
Loading…
Reference in New Issue