Mercurial > mplayer.hg
annotate libmpdemux/demux_smjpeg.c @ 31246:cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
This avoids some issues with H.264 PAFF due to dropping PTS values too
early because only every second packet actually produced output.
Just keeping up to one additional pts value would have avoided this
particular issue as well, but this is more generic.
author | reimar |
---|---|
date | Thu, 03 Jun 2010 20:59:40 +0000 |
parents | 0f1b5b68af32 |
children | cd81fce1f010 |
rev | line source |
---|---|
7382 | 1 /* |
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
2 * SMJPEG file parser |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
3 * copyright (c) 2002 Alex Beregszaszi |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
4 * based on text by Arpi (SMJPEG-format.txt) and later on |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
5 * http://www.lokigames.com/development/download/smjpeg/SMJPEG.txt |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
6 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
7 * This file is part of MPlayer. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
8 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
9 * MPlayer is free software; you can redistribute it and/or modify |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
10 * it under the terms of the GNU General Public License as published by |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
11 * the Free Software Foundation; either version 2 of the License, or |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
12 * (at your option) any later version. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
13 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
14 * MPlayer is distributed in the hope that it will be useful, |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
17 * GNU General Public License for more details. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
18 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
19 * You should have received a copy of the GNU General Public License along |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
20 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26299
diff
changeset
|
22 */ |
7382 | 23 |
24 #include <stdio.h> | |
25 #include <stdlib.h> | |
26 #include <unistd.h> | |
27 #include <string.h> /* strtok */ | |
28 | |
29 #include "config.h" | |
30 #include "mp_msg.h" | |
31 #include "help_mp.h" | |
32 | |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
21421
diff
changeset
|
33 #include "stream/stream.h" |
7382 | 34 #include "demuxer.h" |
35 #include "stheader.h" | |
36 | |
16175 | 37 static int smjpeg_check_file(demuxer_t* demuxer){ |
7382 | 38 int orig_pos = stream_tell(demuxer->stream); |
11109
084c271c785e
10l found by Mark Berryman <mplayer@theberrymans.com>
alex
parents:
7382
diff
changeset
|
39 char buf[8]; |
7382 | 40 int version; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
41 |
7382 | 42 mp_msg(MSGT_DEMUX, MSGL_V, "Checking for SMJPEG\n"); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
43 |
7382 | 44 if (stream_read_word(demuxer->stream) == 0xA) |
45 { | |
46 stream_read(demuxer->stream, buf, 6); | |
47 buf[7] = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
48 |
7382 | 49 if (strncmp("SMJPEG", buf, 6)) { |
50 mp_msg(MSGT_DEMUX, MSGL_DBG2, "Failed: SMJPEG\n"); | |
51 return 0; | |
52 } | |
53 } | |
54 else | |
55 return 0; | |
56 | |
57 version = stream_read_dword(demuxer->stream); | |
58 if (version != 0) | |
59 { | |
60 mp_msg(MSGT_DEMUX, MSGL_ERR, "Unknown version (%d) of SMJPEG. Please report!\n", | |
61 version); | |
62 return 0; | |
63 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
64 |
7382 | 65 stream_seek(demuxer->stream, orig_pos); |
66 | |
16175 | 67 return DEMUXER_TYPE_SMJPEG; |
7382 | 68 } |
69 | |
70 | |
71 // return value: | |
72 // 0 = EOF or no stream found | |
73 // 1 = successfully read a packet | |
16175 | 74 static int demux_smjpeg_fill_buffer(demuxer_t *demux, demux_stream_t *ds) |
7382 | 75 { |
76 int dtype, dsize, dpts; | |
77 | |
78 demux->filepos = stream_tell(demux->stream); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
79 |
7382 | 80 dtype = stream_read_dword_le(demux->stream); |
81 dpts = stream_read_dword(demux->stream); | |
82 dsize = stream_read_dword(demux->stream); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
83 |
7382 | 84 switch(dtype) |
85 { | |
86 case mmioFOURCC('s','n','d','D'): | |
87 /* fixme, but no decoder implemented yet */ | |
88 ds_read_packet(demux->audio, demux->stream, dsize, | |
89 (float)dpts/1000.0, demux->filepos, 0); | |
90 break; | |
91 case mmioFOURCC('v','i','d','D'): | |
92 ds_read_packet(demux->video, demux->stream, dsize, | |
93 (float)dpts/1000.0, demux->filepos, 0); | |
94 break; | |
95 case mmioFOURCC('D','O','N','E'): | |
96 return 1; | |
97 default: | |
98 return 0; | |
99 } | |
100 | |
101 return 1; | |
102 } | |
103 | |
16175 | 104 static demuxer_t* demux_open_smjpeg(demuxer_t* demuxer){ |
7382 | 105 sh_video_t* sh_video; |
106 sh_audio_t* sh_audio; | |
107 unsigned int htype = 0, hleng; | |
108 int i = 0; | |
109 | |
110 /* file header */ | |
111 stream_skip(demuxer->stream, 8); /* \x00\x0aSMJPEG */ | |
112 stream_skip(demuxer->stream, 4); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
113 |
7382 | 114 mp_msg(MSGT_DEMUX, MSGL_INFO, "This clip is %d seconds\n", |
115 stream_read_dword(demuxer->stream)); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
116 |
7382 | 117 /* stream header */ |
118 while (i < 3) | |
119 { | |
120 i++; | |
121 htype = stream_read_dword_le(demuxer->stream); | |
122 if (htype == mmioFOURCC('H','E','N','D')) | |
123 break; | |
124 hleng = (stream_read_word(demuxer->stream)<<16)|stream_read_word(demuxer->stream); | |
125 switch(htype) | |
126 { | |
127 case mmioFOURCC('_','V','I','D'): | |
128 sh_video = new_sh_video(demuxer, 0); | |
129 demuxer->video->sh = sh_video; | |
130 sh_video->ds = demuxer->video; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
131 |
7382 | 132 sh_video->bih = malloc(sizeof(BITMAPINFOHEADER)); |
133 memset(sh_video->bih, 0, sizeof(BITMAPINFOHEADER)); | |
134 | |
135 stream_skip(demuxer->stream, 4); /* number of frames */ | |
136 // sh_video->fps = 24; | |
137 // sh_video->frametime = 1.0f/sh_video->fps; | |
138 sh_video->disp_w = stream_read_word(demuxer->stream); | |
139 sh_video->disp_h = stream_read_word(demuxer->stream); | |
140 sh_video->format = stream_read_dword_le(demuxer->stream); | |
141 | |
142 /* these are false values */ | |
143 sh_video->bih->biSize = 40; | |
144 sh_video->bih->biWidth = sh_video->disp_w; | |
145 sh_video->bih->biHeight = sh_video->disp_h; | |
146 sh_video->bih->biPlanes = 3; | |
147 sh_video->bih->biBitCount = 12; | |
148 sh_video->bih->biCompression = sh_video->format; | |
149 sh_video->bih->biSizeImage = sh_video->disp_w*sh_video->disp_h; | |
150 break; | |
151 case mmioFOURCC('_','S','N','D'): | |
152 sh_audio = new_sh_audio(demuxer, 0); | |
26299
4d56038ec730
Fix lots and lots of other demuxers broken by r26301
reimar
parents:
25707
diff
changeset
|
153 demuxer->audio->id = 0; |
7382 | 154 demuxer->audio->sh = sh_audio; |
155 sh_audio->ds = demuxer->audio; | |
156 | |
157 sh_audio->wf = malloc(sizeof(WAVEFORMATEX)); | |
158 memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX)); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
159 |
7382 | 160 sh_audio->samplerate = stream_read_word(demuxer->stream); |
161 sh_audio->wf->wBitsPerSample = stream_read_char(demuxer->stream); | |
162 sh_audio->channels = stream_read_char(demuxer->stream); | |
163 sh_audio->format = stream_read_dword_le(demuxer->stream); | |
164 sh_audio->wf->wFormatTag = sh_audio->format; | |
165 sh_audio->wf->nChannels = sh_audio->channels; | |
166 sh_audio->wf->nSamplesPerSec = sh_audio->samplerate; | |
167 sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels* | |
168 sh_audio->wf->wBitsPerSample*sh_audio->wf->nSamplesPerSec/8; | |
169 sh_audio->wf->nBlockAlign = sh_audio->channels *2; | |
170 sh_audio->wf->cbSize = 0; | |
171 break; | |
172 case mmioFOURCC('_','T','X','T'): | |
173 stream_skip(demuxer->stream, stream_read_dword(demuxer->stream)); | |
174 break; | |
175 } | |
176 } | |
177 | |
178 demuxer->seekable = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
179 |
16175 | 180 return demuxer; |
7382 | 181 } |
182 | |
16175 | 183 static void demux_close_smjpeg(demuxer_t *demuxer) |
7382 | 184 { |
185 return; | |
186 } | |
16175 | 187 |
188 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
22605
diff
changeset
|
189 const demuxer_desc_t demuxer_desc_smjpeg = { |
16175 | 190 "smjpeg demuxer", |
191 "smjpeg", | |
192 "SMJPEG", | |
193 "Alex Beregszasi", | |
194 "", | |
195 DEMUXER_TYPE_SMJPEG, | |
196 1, // safe autodetect | |
197 smjpeg_check_file, | |
198 demux_smjpeg_fill_buffer, | |
199 demux_open_smjpeg, | |
200 demux_close_smjpeg, | |
201 NULL, | |
202 NULL | |
203 }; |