comparison libmpdemux/demux_y4m.c @ 3786:7ebf504c92d6

yuv4mpeg2 (mjpegtools) support by Rik Snel <rsnel@cube.dyndns.org>
author arpi
date Thu, 27 Dec 2001 02:08:31 +0000
parents
children 811b2e1ff030
comparison
equal deleted inserted replaced
3785:44c74b600573 3786:7ebf504c92d6
1 // Y4M file parser by Rik Snel (using yuv4mpeg*.[ch] from
2 // mjpeg.sourceforge.net) (derived from demux_viv.c)
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <string.h> /* strtok */
8
9 #include "config.h"
10 #include "mp_msg.h"
11 #include "help_mp.h"
12 #include "yuv4mpeg.h"
13
14 //#include "stream.h"
15 #include "demuxer.h"
16 #include "stheader.h"
17 #include "bswap.h"
18
19 typedef struct {
20 int framenum;
21 y4m_stream_info_t* si;
22 } y4m_priv_t;
23
24 int y4m_check_file(demuxer_t* demuxer){
25 int orig_pos = stream_tell(demuxer->stream);
26 char buf[10];
27
28 mp_msg(MSGT_DEMUX, MSGL_V, "Checking for YUV4MPEG2\n");
29
30 stream_read(demuxer->stream, buf, 9);
31 buf[9] = 0;
32
33 if (strncmp("YUV4MPEG2", buf, 9)) {
34 mp_msg(MSGT_DEMUX, MSGL_DBG2, "Failed: YUV4MPEG2\n");
35 return 0;
36 }
37
38 mp_msg(MSGT_DEMUX,MSGL_DBG2,"Success: YUV4MPEG2\n");
39
40 stream_seek(demuxer->stream, orig_pos);
41
42 return 1;
43 }
44
45
46 // return value:
47 // 0 = EOF or no stream found
48 // 1 = successfully read a packet
49 int demux_y4m_fill_buffer(demuxer_t *demux) {
50 demux_stream_t *ds=demux->video;
51 demux_packet_t *dp;
52 y4m_priv_t *priv=demux->priv;
53 y4m_frame_info_t fi;
54 unsigned char *buf[3];
55 int err, size;
56
57 demux->filepos=stream_tell(demux->stream);
58
59 size = ((sh_video_t*)ds->sh)->disp_w*((sh_video_t*)ds->sh)->disp_h;
60
61 dp = new_demux_packet(3*size/2);
62
63 /* swap U and V components */
64 buf[0] = dp->buffer;
65 buf[1] = dp->buffer + 5*size/4;
66 buf[2] = dp->buffer + size;
67
68 if ((err=y4m_read_frame(demux->stream, priv->si, &fi, buf)) != Y4M_OK) {
69 mp_msg(MSGT_DEMUX, MSGL_V, "error reading frame %s\n", y4m_strerr(err));
70 return 0;
71 }
72
73 /* This seems to be the right way to calculate the presentation time stamp */
74 dp->pts=(float)priv->framenum/((sh_video_t*)ds->sh)->fps;
75 priv->framenum++;
76 dp->pos=demux->filepos;
77 dp->flags=0;
78 ds_add_packet(ds, dp);
79
80 return 1;
81 }
82
83 void demux_open_y4m(demuxer_t* demuxer){
84 y4m_priv_t* priv;
85 y4m_ratio_t framerate;
86 sh_video_t* sh=new_sh_video(demuxer,0);
87 int err;
88
89 demuxer->priv = malloc(sizeof(y4m_priv_t));
90 priv = demuxer->priv;
91
92 priv->framenum = 0;
93 priv->si = malloc(sizeof(y4m_stream_info_t));
94
95 y4m_init_stream_info(priv->si);
96 if ((err=y4m_read_stream_header(demuxer->stream, priv->si)) != Y4M_OK)
97 mp_msg(MSGT_DEMUXER, MSGL_FATAL, "error parsing YUV4MPEG header: %s\n", y4m_strerr(err));
98
99 sh->format = mmioFOURCC('Y', 'V', '1', '2');
100
101 if(!sh->fps) {
102 framerate = y4m_si_get_framerate(priv->si);
103 if (framerate.d != 0)
104 sh->fps=(float)framerate.n/(float)framerate.d;
105 else
106 sh->fps=15.0f;
107 }
108 sh->frametime=1.0f/sh->fps;
109
110 sh->disp_w = y4m_si_get_width(priv->si);
111 sh->disp_h = y4m_si_get_height(priv->si);
112
113 sh->bih=malloc(sizeof(BITMAPINFOHEADER));
114 memset(sh->bih,0,sizeof(BITMAPINFOHEADER));
115 sh->bih->biSize=40;
116 sh->bih->biWidth = priv->si->width;
117 sh->bih->biHeight = priv->si->height;
118 sh->bih->biPlanes=3;
119 sh->bih->biBitCount=12;
120 sh->bih->biCompression=sh->format;
121 sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight*3/2; /* YV12 */
122
123 demuxer->video->sh=sh;
124 sh->ds=demuxer->video;
125 demuxer->video->id=0;
126
127 /* disable seeking, lazy */
128 demuxer->seekable = 0;
129
130 printf("YUV4MPEG2 Video stream %d size: display: %dx%d, codec: %ux%u\n",
131 demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth,
132 sh->bih->biHeight);
133 }
134
135 void demux_close_y4m(demuxer_t *demuxer)
136 {
137 y4m_fini_stream_info(((y4m_priv_t*)demuxer->priv)->si);
138 free(((y4m_priv_t*)demuxer->priv)->si);
139 free(demuxer->priv);
140 return;
141 }