Mercurial > mplayer.hg
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 } |