Mercurial > mplayer.hg
annotate libmpdemux/demux_viv.c @ 33244:cee07c3dbff5
Do not remove video filters.
If a video filter option isn't set, it does not mean to remove the
filter, but such option (if set) should only cause adding the filter
(if not already present). That way filters can be specified in MPlayer's
config or on the command line, too.
This closes Bugzilla #1442.
author | ib |
---|---|
date | Mon, 25 Apr 2011 14:25:15 +0000 |
parents | 8fa2f43cb760 |
children | 25667edae85c |
rev | line source |
---|---|
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
1 /* |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
2 * VIVO file parser |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
3 * copyright (c) 2001 A'rpi |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
4 * VIVO text header parser and audio support by alex |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
5 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
6 * This file is part of MPlayer. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
7 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
8 * MPlayer is free software; you can redistribute it and/or modify |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
9 * 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:
27282
diff
changeset
|
10 * the Free Software Foundation; either version 2 of the License, or |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
11 * (at your option) any later version. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
12 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
13 * MPlayer is distributed in the hope that it will be useful, |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
16 * GNU General Public License for more details. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
17 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
18 * 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:
27282
diff
changeset
|
19 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27282
diff
changeset
|
21 */ |
2687 | 22 |
23 #include <stdio.h> | |
24 #include <stdlib.h> | |
25 #include <unistd.h> | |
2928 | 26 #include <string.h> /* strtok */ |
2687 | 27 |
28 #include "config.h" | |
29 #include "mp_msg.h" | |
30 #include "help_mp.h" | |
31 | |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
22283
diff
changeset
|
32 #include "stream/stream.h" |
2687 | 33 #include "demuxer.h" |
34 #include "stheader.h" | |
31413
0f5751eb7126
Add header file for VIVO extern variable declarations.
diego
parents:
29288
diff
changeset
|
35 #include "demux_viv.h" |
2687 | 36 |
3502 | 37 /* parameters ! */ |
3503 | 38 int vivo_param_version = -1; |
3502 | 39 char *vivo_param_acodec = NULL; |
40 int vivo_param_abitrate = -1; | |
41 int vivo_param_samplerate = -1; | |
42 int vivo_param_bytesperblock = -1; | |
43 int vivo_param_width = -1; | |
44 int vivo_param_height = -1; | |
45 int vivo_param_vformat = -1; | |
46 | |
3471 | 47 /* VIVO audio standards from vivog723.acm: |
48 | |
49 G.723: | |
50 FormatTag = 0x111 | |
51 Channels = 1 - mono | |
52 SamplesPerSec = 8000 - 8khz | |
53 AvgBytesPerSec = 800 | |
54 BlockAlign (bytes per block) = 24 | |
55 BitsPerSample = 8 | |
56 | |
57 Siren: | |
58 FormatTag = 0x112 | |
59 Channels = 1 - mono | |
60 SamplesPerSec = 16000 - 16khz | |
61 AvgBytesPerSec = 2000 | |
62 BlockAlign (bytes per block) = 40 | |
63 BitsPerSample = 8 | |
64 */ | |
65 | |
3502 | 66 //enum { VIVO_AUDIO_G723, VIVO_AUDIO_SIREN }; |
67 | |
3471 | 68 #define VIVO_AUDIO_G723 1 |
69 #define VIVO_AUDIO_SIREN 2 | |
2687 | 70 |
71 typedef struct { | |
2784 | 72 /* generic */ |
3113
c0e6a39d2ab7
changed to generate fourcc's like: viv<version> -> viv1,viv2
alex
parents:
3069
diff
changeset
|
73 char version; |
2784 | 74 int supported; |
75 /* info */ | |
76 char *title; | |
77 char *author; | |
78 char *copyright; | |
79 char *producer; | |
80 /* video */ | |
81 float fps; | |
82 int width; | |
83 int height; | |
84 int disp_width; | |
85 int disp_height; | |
86 /* audio */ | |
3471 | 87 int audio_codec; |
88 int audio_bitrate; | |
89 int audio_samplerate; | |
90 int audio_bytesperblock; | |
2687 | 91 } vivo_priv_t; |
92 | |
2784 | 93 /* parse all possible extra headers */ |
22283
bc9e95184521
cosmetics: Fix some common typos, sepErate --> sepArate, deciSSion --> deciSion.
diego
parents:
21421
diff
changeset
|
94 /* (audio headers are separate - mostly with recordtype=3 or 4) */ |
2784 | 95 #define TEXTPARSE_ALL 1 |
96 | |
97 static void vivo_parse_text_header(demuxer_t *demux, int header_len) | |
98 { | |
99 vivo_priv_t* priv = demux->priv; | |
100 char *buf; | |
101 int i; | |
102 char *token; | |
103 char *opt, *param; | |
3439
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
104 int parser_in_audio_block = 0; |
2784 | 105 |
106 if (!demux->priv) | |
107 { | |
108 priv = malloc(sizeof(vivo_priv_t)); | |
109 memset(priv, 0, sizeof(vivo_priv_t)); | |
110 demux->priv = priv; | |
111 priv->supported = 0; | |
112 } | |
113 | |
114 buf = malloc(header_len); | |
115 opt = malloc(header_len); | |
116 param = malloc(header_len); | |
117 stream_read(demux->stream, buf, header_len); | |
118 i=0; | |
119 while(i<header_len && buf[i]==0x0D && buf[i+1]==0x0A) i+=2; // skip empty lines | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
120 |
2784 | 121 token = strtok(buf, (char *)&("\x0d\x0a")); |
122 while (token && (header_len>2)) | |
123 { | |
124 header_len -= strlen(token)+2; | |
125 if (sscanf(token, "%[^:]:%[^\n]", opt, param) != 2) | |
126 { | |
17366 | 127 mp_msg(MSGT_DEMUX, MSGL_V, "viv_text_header_parser: bad line: '%s' at ~%#"PRIx64"\n", |
128 token, (int64_t)stream_tell(demux->stream)); | |
2784 | 129 break; |
130 } | |
3471 | 131 mp_dbg(MSGT_DEMUX, MSGL_DBG3, "token: '%s' (%d bytes/%d bytes left)\n", |
2784 | 132 token, strlen(token), header_len); |
3471 | 133 mp_dbg(MSGT_DEMUX, MSGL_DBG3, "token => o: '%s', p: '%s'\n", |
2784 | 134 opt, param); |
135 | |
136 /* checking versions: only v1 or v2 is suitable (or known?:) */ | |
137 if (!strcmp(opt, "Version")) | |
138 { | |
139 mp_msg(MSGT_DEMUX, MSGL_DBG2, "Version: %s\n", param); | |
2928 | 140 if (!strncmp(param, "Vivo/1", 6) || !strncmp(param, "Vivo/2", 6)) |
3113
c0e6a39d2ab7
changed to generate fourcc's like: viv<version> -> viv1,viv2
alex
parents:
3069
diff
changeset
|
141 { |
2784 | 142 priv->supported = 1; |
3439
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
143 /* save major version for fourcc */ |
3113
c0e6a39d2ab7
changed to generate fourcc's like: viv<version> -> viv1,viv2
alex
parents:
3069
diff
changeset
|
144 priv->version = param[5]; |
c0e6a39d2ab7
changed to generate fourcc's like: viv<version> -> viv1,viv2
alex
parents:
3069
diff
changeset
|
145 } |
2784 | 146 } |
147 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
148 /* video specific */ |
2784 | 149 if (!strcmp(opt, "FPS")) |
150 { | |
151 mp_msg(MSGT_DEMUX, MSGL_DBG2, "FPS: %f\n", atof(param)); | |
152 priv->fps = atof(param); | |
153 } | |
154 if (!strcmp(opt, "Width")) | |
155 { | |
156 mp_msg(MSGT_DEMUX, MSGL_DBG2, "Width: %d\n", atoi(param)); | |
157 priv->width = atoi(param); | |
158 } | |
159 if (!strcmp(opt, "Height")) | |
160 { | |
161 mp_msg(MSGT_DEMUX, MSGL_DBG2, "Height: %d\n", atoi(param)); | |
162 priv->height = atoi(param); | |
163 } | |
164 if (!strcmp(opt, "DisplayWidth")) | |
165 { | |
166 mp_msg(MSGT_DEMUX, MSGL_DBG2, "Display Width: %d\n", atoi(param)); | |
167 priv->disp_width = atoi(param); | |
168 } | |
169 if (!strcmp(opt, "DisplayHeight")) | |
170 { | |
171 mp_msg(MSGT_DEMUX, MSGL_DBG2, "Display Height: %d\n", atoi(param)); | |
172 priv->disp_height = atoi(param); | |
173 } | |
174 | |
175 /* audio specific */ | |
3439
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
176 if (!strcmp(opt, "RecordType")) |
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
177 { |
3471 | 178 /* no audio recordblock by Vivo/1.00, 3 and 4 by Vivo/2.00 */ |
3439
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
179 if ((atoi(param) == 3) || (atoi(param) == 4)) |
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
180 parser_in_audio_block = 1; |
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
181 else |
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
182 parser_in_audio_block = 0; |
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
183 } |
2784 | 184 if (!strcmp(opt, "NominalBitrate")) |
185 { | |
3471 | 186 priv->audio_bitrate = atoi(param); |
187 if (priv->audio_bitrate == 2000) | |
188 priv->audio_codec = VIVO_AUDIO_SIREN; | |
189 if (priv->audio_bitrate == 800) | |
190 priv->audio_codec = VIVO_AUDIO_G723; | |
2784 | 191 } |
192 if (!strcmp(opt, "SamplingFrequency")) | |
193 { | |
3471 | 194 priv->audio_samplerate = atoi(param); |
195 if (priv->audio_samplerate == 16000) | |
196 priv->audio_codec = VIVO_AUDIO_SIREN; | |
197 if (priv->audio_samplerate == 8000) | |
198 priv->audio_codec = VIVO_AUDIO_G723; | |
2784 | 199 } |
3439
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
200 if (!strcmp(opt, "Length") && (parser_in_audio_block == 1)) |
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
201 { |
3471 | 202 priv->audio_bytesperblock = atoi(param); /* 24 or 40 kbps */ |
203 if (priv->audio_bytesperblock == 40) | |
204 priv->audio_codec = VIVO_AUDIO_SIREN; | |
205 if (priv->audio_bytesperblock == 24) | |
206 priv->audio_codec = VIVO_AUDIO_G723; | |
3439
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
207 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
208 |
2784 | 209 /* only for displaying some informations about movie*/ |
210 if (!strcmp(opt, "Title")) | |
211 { | |
29288
4a1c217a844b
In all demux_info_add calls change "name" to "title".
reimar
parents:
29263
diff
changeset
|
212 demux_info_add(demux, "title", param); |
3612 | 213 priv->title = strdup(param); |
2784 | 214 } |
215 if (!strcmp(opt, "Author")) | |
216 { | |
3068 | 217 demux_info_add(demux, "author", param); |
3612 | 218 priv->author = strdup(param); |
2784 | 219 } |
220 if (!strcmp(opt, "Copyright")) | |
221 { | |
3068 | 222 demux_info_add(demux, "copyright", param); |
3612 | 223 priv->copyright = strdup(param); |
2784 | 224 } |
225 if (!strcmp(opt, "Producer")) | |
226 { | |
3069 | 227 demux_info_add(demux, "encoder", param); |
3612 | 228 priv->producer = strdup(param); |
2784 | 229 } |
230 | |
231 /* get next token */ | |
232 token = strtok(NULL, (char *)&("\x0d\x0a")); | |
233 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
234 |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32394
diff
changeset
|
235 free(buf); |
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32394
diff
changeset
|
236 free(opt); |
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32394
diff
changeset
|
237 free(param); |
2784 | 238 } |
239 | |
16175 | 240 static int vivo_check_file(demuxer_t* demuxer){ |
2687 | 241 int i=0; |
242 int len; | |
243 int c; | |
244 unsigned char buf[2048+256]; | |
245 vivo_priv_t* priv; | |
2784 | 246 int orig_pos = stream_tell(demuxer->stream); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
247 |
2687 | 248 mp_msg(MSGT_DEMUX,MSGL_V,"Checking for VIVO\n"); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
249 |
2687 | 250 c=stream_read_char(demuxer->stream); |
2792 | 251 if(c==-256) return 0; |
2687 | 252 len=0; |
253 while((c=stream_read_char(demuxer->stream))>=0x80){ | |
254 len+=0x80*(c-0x80); | |
255 if(len>1024) return 0; | |
256 } | |
257 len+=c; | |
6139
3898967fcc96
some more output cosmetics, especially for vivo and mov demuxers
arpi
parents:
4407
diff
changeset
|
258 mp_msg(MSGT_DEMUX,MSGL_V,"header block 1 size: %d\n",len); |
2687 | 259 //stream_skip(demuxer->stream,len); |
2928 | 260 |
261 priv=malloc(sizeof(vivo_priv_t)); | |
262 memset(priv,0,sizeof(vivo_priv_t)); | |
263 demuxer->priv=priv; | |
2784 | 264 |
2805 | 265 #if 0 |
2785 | 266 vivo_parse_text_header(demuxer, len); |
2784 | 267 if (priv->supported == 0) |
268 return 0; | |
269 #else | |
2928 | 270 /* this is enought for check (for now) */ |
271 stream_read(demuxer->stream,buf,len); | |
272 buf[len]=0; | |
273 // printf("VIVO header: '%s'\n",buf); | |
274 | |
2687 | 275 // parse header: |
276 i=0; | |
277 while(i<len && buf[i]==0x0D && buf[i+1]==0x0A) i+=2; // skip empty lines | |
2695 | 278 if(strncmp(buf+i,"Version:Vivo/",13)) return 0; // bad version/type! |
2784 | 279 #endif |
2687 | 280 |
2695 | 281 #if 0 |
2687 | 282 c=stream_read_char(demuxer->stream); |
283 if(c) return 0; | |
284 len2=0; | |
285 while((c=stream_read_char(demuxer->stream))>=0x80){ | |
286 len2+=0x80*(c-0x80); | |
287 if(len+len2>2048) return 0; | |
288 } | |
289 len2+=c; | |
6139
3898967fcc96
some more output cosmetics, especially for vivo and mov demuxers
arpi
parents:
4407
diff
changeset
|
290 mp_msg(MSGT_DEMUX,MSGL_V,"header block 2 size: %d\n",len2); |
2687 | 291 stream_skip(demuxer->stream,len2); |
292 // stream_read(demuxer->stream,buf+len,len2); | |
2695 | 293 #endif |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
294 |
2687 | 295 // c=stream_read_char(demuxer->stream); |
296 // printf("first packet: %02X\n",c); | |
297 | |
2784 | 298 stream_seek(demuxer->stream, orig_pos); |
299 | |
16175 | 300 return DEMUXER_TYPE_VIVO; |
2687 | 301 } |
302 | |
3733 | 303 static int audio_pos=0; |
304 static int audio_rate=0; | |
3526 | 305 |
2687 | 306 // return value: |
307 // 0 = EOF or no stream found | |
308 // 1 = successfully read a packet | |
16175 | 309 static int demux_vivo_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){ |
2687 | 310 demux_stream_t *ds=NULL; |
311 int c; | |
312 int len=0; | |
313 int seq; | |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
314 int prefix=0; |
2687 | 315 demux->filepos=stream_tell(demux->stream); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
316 |
2687 | 317 c=stream_read_char(demux->stream); |
2792 | 318 if (c == -256) /* EOF */ |
319 return 0; | |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
320 // printf("c=%x,%02X\n",c,c&0xf0); |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
321 if (c == 0x82) |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
322 { |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
323 /* ok, this works, but pts calculating from header is required! */ |
32394
914208d188b9
Remove #warning preprocessor directives or replace them by suitable comments.
diego
parents:
32100
diff
changeset
|
324 /* FIXME: "Calculate PTS from picture header!" */ |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
325 prefix = 1; |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
326 c = stream_read_char(demux->stream); |
19075 | 327 mp_msg(MSGT_DEMUX, MSGL_V, "packet 0x82(pos=%u) chunk=%x\n", |
7472
c4434bdf6e51
tons of warning fixes, also some 10l bugfixes, including Dominik's PVA bug
arpi
parents:
6139
diff
changeset
|
328 (int)stream_tell(demux->stream), c); |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
329 } |
2687 | 330 switch(c&0xF0){ |
2695 | 331 case 0x00: // header - skip it! |
2784 | 332 { |
2687 | 333 len=stream_read_char(demux->stream); |
2695 | 334 if(len>=0x80) len=0x80*(len-0x80)+stream_read_char(demux->stream); |
19075 | 335 mp_msg(MSGT_DEMUX, MSGL_V, "vivo extra header: %d bytes\n",len); |
2784 | 336 #ifdef TEXTPARSE_ALL |
337 { | |
338 int pos; | |
339 /* also try to parse all headers */ | |
340 pos = stream_tell(demux->stream); | |
341 vivo_parse_text_header(demux, len); | |
342 stream_seek(demux->stream, pos); | |
343 } | |
344 #endif | |
2687 | 345 break; |
2784 | 346 } |
2687 | 347 case 0x10: // video packet |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
348 if (prefix == 1) |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
349 len = stream_read_char(demux->stream); |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
350 else |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
351 len=128; |
2687 | 352 ds=demux->video; |
353 break; | |
354 case 0x20: // video packet | |
355 len=stream_read_char(demux->stream); | |
356 ds=demux->video; | |
357 break; | |
3068 | 358 case 0x30: // audio packet |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
359 if (prefix == 1) |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
360 len = stream_read_char(demux->stream); |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
361 else |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
362 len=40; /* 40kbps */ |
2695 | 363 ds=demux->audio; |
3526 | 364 audio_pos+=len; |
2695 | 365 break; |
2687 | 366 case 0x40: // audio packet |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
367 if (prefix == 1) |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
368 len = stream_read_char(demux->stream); |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
369 else |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
370 len=24; /* 24kbps */ |
2687 | 371 ds=demux->audio; |
3526 | 372 audio_pos+=len; |
2687 | 373 break; |
374 default: | |
17366 | 375 mp_msg(MSGT_DEMUX,MSGL_WARN,"VIVO - unknown ID found: %02X at pos %"PRIu64" contact author!\n", |
376 c, (int64_t)stream_tell(demux->stream)); | |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
377 return 0; |
2687 | 378 } |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
379 |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
380 // printf("chunk=%x, len=%d\n", c, len); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
381 |
2695 | 382 if(!ds || ds->id<-1){ |
2687 | 383 if(len) stream_skip(demux->stream,len); |
384 return 1; | |
385 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
386 |
2687 | 387 seq=c&0x0F; |
388 | |
389 if(ds->asf_packet){ | |
390 if(ds->asf_seq!=seq){ | |
391 // closed segment, finalize packet: | |
392 ds_add_packet(ds,ds->asf_packet); | |
393 ds->asf_packet=NULL; | |
2695 | 394 // printf("packet!\n"); |
2687 | 395 } else { |
396 // append data to it! | |
397 demux_packet_t* dp=ds->asf_packet; | |
27282
16beae919ff1
Avoid including avcodec.h in demuxer.h (and thus many other files) just to get
reimar
parents:
27269
diff
changeset
|
398 if(dp->len + len + MP_INPUT_BUFFER_PADDING_SIZE < 0) |
18558
4928dd61f136
Fix potential integer overflows in memory allocation.
rtogni
parents:
17366
diff
changeset
|
399 return 0; |
27282
16beae919ff1
Avoid including avcodec.h in demuxer.h (and thus many other files) just to get
reimar
parents:
27269
diff
changeset
|
400 dp->buffer=realloc(dp->buffer,dp->len+len+MP_INPUT_BUFFER_PADDING_SIZE); |
16beae919ff1
Avoid including avcodec.h in demuxer.h (and thus many other files) just to get
reimar
parents:
27269
diff
changeset
|
401 memset(dp->buffer+dp->len+len, 0, MP_INPUT_BUFFER_PADDING_SIZE); |
2687 | 402 //memcpy(dp->buffer+dp->len,data,len); |
403 stream_read(demux->stream,dp->buffer+dp->len,len); | |
404 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len); | |
405 dp->len+=len; | |
406 // we are ready now. | |
2695 | 407 if((c&0xF0)==0x20) --ds->asf_seq; // hack! |
2687 | 408 return 1; |
409 } | |
410 } | |
411 // create new packet: | |
412 { demux_packet_t* dp; | |
413 dp=new_demux_packet(len); | |
414 //memcpy(dp->buffer,data,len); | |
415 stream_read(demux->stream,dp->buffer,len); | |
3526 | 416 dp->pts=audio_rate?((float)audio_pos/(float)audio_rate):0; |
2687 | 417 // dp->flags=keyframe; |
418 // if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur); | |
419 dp->pos=demux->filepos; | |
420 ds->asf_packet=dp; | |
421 ds->asf_seq=seq; | |
422 // we are ready now. | |
423 return 1; | |
424 } | |
425 | |
426 } | |
427 | |
428 static const short h263_format[8][2] = { | |
429 { 0, 0 }, | |
430 { 128, 96 }, | |
431 { 176, 144 }, | |
432 { 352, 288 }, | |
433 { 704, 576 }, | |
434 { 1408, 1152 }, | |
2784 | 435 { 320, 240 } // ??????? or 240x180 (found in vivo2) ? |
2687 | 436 }; |
437 | |
438 static unsigned char* buffer; | |
439 static int bufptr=0; | |
440 static int bitcnt=0; | |
441 static unsigned char buf=0; | |
442 static int format, width, height; | |
443 | |
444 static unsigned int x_get_bits(int n){ | |
445 unsigned int x=0; | |
446 while(n-->0){ | |
447 if(!bitcnt){ | |
448 // fill buff | |
449 buf=buffer[bufptr++]; | |
450 bitcnt=8; | |
451 } | |
452 //x=(x<<1)|(buf&1);buf>>=1; | |
453 x=(x<<1)|(buf>>7);buf<<=1; | |
454 --bitcnt; | |
455 } | |
456 return x; | |
457 } | |
458 | |
459 #define get_bits(xxx,n) x_get_bits(n) | |
460 #define get_bits1(xxx) x_get_bits(1) | |
461 #define skip_bits(xxx,n) x_get_bits(n) | |
462 #define skip_bits1(xxx) x_get_bits(1) | |
463 | |
464 /* most is hardcoded. should extend to handle all h263 streams */ | |
465 static int h263_decode_picture_header(unsigned char *b_ptr) | |
466 { | |
2928 | 467 // int i; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
468 |
2695 | 469 // for(i=0;i<16;i++) printf(" %02X",b_ptr[i]); printf("\n"); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
470 |
2687 | 471 buffer=b_ptr; |
472 bufptr=bitcnt=buf=0; | |
473 | |
474 /* picture header */ | |
2695 | 475 if (get_bits(&s->gb, 22) != 0x20){ |
19075 | 476 mp_msg(MSGT_DEMUX, MSGL_FATAL, "bad picture header\n"); |
2687 | 477 return -1; |
2695 | 478 } |
2687 | 479 skip_bits(&s->gb, 8); /* picture timestamp */ |
480 | |
2695 | 481 if (get_bits1(&s->gb) != 1){ |
19075 | 482 mp_msg(MSGT_DEMUX, MSGL_FATAL, "bad marker\n"); |
2687 | 483 return -1; /* marker */ |
2695 | 484 } |
485 if (get_bits1(&s->gb) != 0){ | |
19075 | 486 mp_msg(MSGT_DEMUX, MSGL_FATAL, "bad h263 id\n"); |
2687 | 487 return -1; /* h263 id */ |
2695 | 488 } |
2687 | 489 skip_bits1(&s->gb); /* split screen off */ |
490 skip_bits1(&s->gb); /* camera off */ | |
491 skip_bits1(&s->gb); /* freeze picture release off */ | |
492 | |
493 format = get_bits(&s->gb, 3); | |
494 | |
495 if (format != 7) { | |
19075 | 496 mp_msg(MSGT_DEMUX, MSGL_V, "h263_plus = 0 format = %d\n", format); |
2687 | 497 /* H.263v1 */ |
498 width = h263_format[format][0]; | |
499 height = h263_format[format][1]; | |
19075 | 500 mp_msg(MSGT_DEMUX, MSGL_V, "%d x %d\n", width, height); |
2695 | 501 // if (!width) return -1; |
2687 | 502 |
19075 | 503 mp_msg(MSGT_DEMUX, MSGL_V, "pict_type=%d\n", get_bits1(&s->gb)); |
504 mp_msg(MSGT_DEMUX, MSGL_V, "unrestricted_mv=%d\n", get_bits1(&s->gb)); | |
2687 | 505 #if 1 |
19075 | 506 mp_msg(MSGT_DEMUX, MSGL_V, "SAC: %d\n", get_bits1(&s->gb)); |
507 mp_msg(MSGT_DEMUX, MSGL_V, "advanced prediction mode: %d\n", get_bits1(&s->gb)); | |
508 mp_msg(MSGT_DEMUX, MSGL_V, "PB frame: %d\n", get_bits1(&s->gb)); | |
2687 | 509 #else |
510 if (get_bits1(&s->gb) != 0) | |
511 return -1; /* SAC: off */ | |
512 if (get_bits1(&s->gb) != 0) | |
513 return -1; /* advanced prediction mode: off */ | |
514 if (get_bits1(&s->gb) != 0) | |
515 return -1; /* not PB frame */ | |
516 #endif | |
19075 | 517 mp_msg(MSGT_DEMUX, MSGL_V, "qscale=%d\n", get_bits(&s->gb, 5)); |
2687 | 518 skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ |
519 } else { | |
19075 | 520 mp_msg(MSGT_DEMUX, MSGL_V, "h263_plus = 1\n"); |
2687 | 521 /* H.263v2 */ |
2695 | 522 if (get_bits(&s->gb, 3) != 1){ |
19075 | 523 mp_msg(MSGT_DEMUX, MSGL_FATAL, "H.263v2 A error\n"); |
2687 | 524 return -1; |
2695 | 525 } |
526 if (get_bits(&s->gb, 3) != 6){ /* custom source format */ | |
19075 | 527 mp_msg(MSGT_DEMUX, MSGL_FATAL, "custom source format\n"); |
2687 | 528 return -1; |
2695 | 529 } |
2687 | 530 skip_bits(&s->gb, 12); |
531 skip_bits(&s->gb, 3); | |
19075 | 532 mp_msg(MSGT_DEMUX, MSGL_V, "pict_type=%d\n", get_bits(&s->gb, 3) + 1); |
2687 | 533 // if (s->pict_type != I_TYPE && |
534 // s->pict_type != P_TYPE) | |
535 // return -1; | |
536 skip_bits(&s->gb, 7); | |
537 skip_bits(&s->gb, 4); /* aspect ratio */ | |
538 width = (get_bits(&s->gb, 9) + 1) * 4; | |
539 skip_bits1(&s->gb); | |
540 height = get_bits(&s->gb, 9) * 4; | |
19075 | 541 mp_msg(MSGT_DEMUX, MSGL_V, "%d x %d\n", width, height); |
2695 | 542 //if (height == 0) |
543 // return -1; | |
19075 | 544 mp_msg(MSGT_DEMUX, MSGL_V, "qscale=%d\n", get_bits(&s->gb, 5)); |
2687 | 545 } |
546 | |
547 /* PEI */ | |
548 while (get_bits1(&s->gb) != 0) { | |
549 skip_bits(&s->gb, 8); | |
550 } | |
551 // s->f_code = 1; | |
552 // s->width = width; | |
553 // s->height = height; | |
554 return 0; | |
555 } | |
556 | |
557 | |
2695 | 558 |
16175 | 559 static demuxer_t* demux_open_vivo(demuxer_t* demuxer){ |
2687 | 560 vivo_priv_t* priv=demuxer->priv; |
561 | |
562 if(!ds_fill_buffer(demuxer->video)){ | |
563 mp_msg(MSGT_DEMUX,MSGL_ERR,"VIVO: " MSGTR_MissingVideoStreamBug); | |
16175 | 564 return NULL; |
2687 | 565 } |
3526 | 566 |
567 audio_pos=0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
568 |
2687 | 569 h263_decode_picture_header(demuxer->video->buffer); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
570 |
3503 | 571 if (vivo_param_version != -1) |
572 priv->version = '0' + vivo_param_version; | |
2687 | 573 |
574 { sh_video_t* sh=new_sh_video(demuxer,0); | |
3113
c0e6a39d2ab7
changed to generate fourcc's like: viv<version> -> viv1,viv2
alex
parents:
3069
diff
changeset
|
575 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
576 /* viv1, viv2 (for better codecs.conf) */ |
3113
c0e6a39d2ab7
changed to generate fourcc's like: viv<version> -> viv1,viv2
alex
parents:
3069
diff
changeset
|
577 sh->format = mmioFOURCC('v', 'i', 'v', priv->version); |
2784 | 578 if(!sh->fps) |
2928 | 579 { |
2784 | 580 if (priv->fps) |
581 sh->fps=priv->fps; | |
582 else | |
583 sh->fps=15.0f; | |
2928 | 584 } |
2687 | 585 sh->frametime=1.0f/sh->fps; |
2805 | 586 |
3502 | 587 /* XXX: FIXME: can't scale image. */ |
588 /* hotfix to disable: */ | |
2805 | 589 priv->disp_width = priv->width; |
590 priv->disp_height = priv->height; | |
591 | |
3502 | 592 if (vivo_param_width != -1) |
593 priv->disp_width = priv->width = vivo_param_width; | |
594 | |
595 if (vivo_param_height != -1) | |
596 priv->disp_height = priv->height = vivo_param_height; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
597 |
3502 | 598 if (vivo_param_vformat != -1) |
599 { | |
600 priv->disp_width = priv->width = h263_format[vivo_param_vformat][0]; | |
601 priv->disp_height = priv->height = h263_format[vivo_param_vformat][1]; | |
602 } | |
603 | |
2784 | 604 if (priv->disp_width) |
605 sh->disp_w = priv->disp_width; | |
606 else | |
607 sh->disp_w = width; | |
608 if (priv->disp_height) | |
609 sh->disp_h = priv->disp_height; | |
610 else | |
611 sh->disp_h = height; | |
2687 | 612 |
613 // emulate BITMAPINFOHEADER: | |
32100 | 614 sh->bih=calloc(1, sizeof(*sh->bih)); |
2687 | 615 sh->bih->biSize=40; |
2784 | 616 if (priv->width) |
617 sh->bih->biWidth = priv->width; | |
618 else | |
619 sh->bih->biWidth = width; | |
620 if (priv->height) | |
621 sh->bih->biHeight = priv->height; | |
622 else | |
623 sh->bih->biHeight = height; | |
2687 | 624 sh->bih->biPlanes=1; |
625 sh->bih->biBitCount=24; | |
626 sh->bih->biCompression=sh->format; | |
627 sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight*3; | |
3502 | 628 |
629 /* insert as stream */ | |
630 demuxer->video->sh=sh; | |
631 sh->ds=demuxer->video; | |
2687 | 632 demuxer->video->id=0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
633 |
3502 | 634 /* disable seeking */ |
2928 | 635 demuxer->seekable = 0; |
2788 | 636 |
19075 | 637 mp_msg(MSGT_DEMUX,MSGL_V,"VIVO Video stream %d size: display: %dx%d, codec: %ux%u\n", |
2788 | 638 demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth, |
639 sh->bih->biHeight); | |
2687 | 640 } |
641 | |
3502 | 642 /* AUDIO init */ |
643 if (demuxer->audio->id >= -1){ | |
2687 | 644 if(!ds_fill_buffer(demuxer->audio)){ |
645 mp_msg(MSGT_DEMUX,MSGL_ERR,"VIVO: " MSGTR_MissingAudioStream); | |
646 } else | |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
31413
diff
changeset
|
647 { sh_audio_t* sh=new_sh_audio(demuxer,1, NULL); |
2788 | 648 |
3502 | 649 /* Select audio codec */ |
3471 | 650 if (priv->audio_codec == 0) |
651 { | |
652 if (priv->version == '2') | |
653 priv->audio_codec = VIVO_AUDIO_SIREN; | |
654 else | |
655 priv->audio_codec = VIVO_AUDIO_G723; | |
656 } | |
3502 | 657 if (vivo_param_acodec != NULL) |
658 { | |
659 if (!strcasecmp(vivo_param_acodec, "g723")) | |
660 priv->audio_codec = VIVO_AUDIO_G723; | |
661 if (!strcasecmp(vivo_param_acodec, "siren")) | |
662 priv->audio_codec = VIVO_AUDIO_SIREN; | |
663 } | |
3471 | 664 |
3502 | 665 if (priv->audio_codec == VIVO_AUDIO_G723) |
666 sh->format = 0x111; | |
9955
d6be831a5f9a
fixed 2 10l-s (bug found in the spring cleanup patch by Raindel Shachar
alex
parents:
8254
diff
changeset
|
667 else if (priv->audio_codec == VIVO_AUDIO_SIREN) |
3502 | 668 sh->format = 0x112; |
9955
d6be831a5f9a
fixed 2 10l-s (bug found in the spring cleanup patch by Raindel Shachar
alex
parents:
8254
diff
changeset
|
669 else |
3502 | 670 { |
671 mp_msg(MSGT_DEMUX, MSGL_ERR, "VIVO: Not support audio codec (%d)\n", | |
672 priv->audio_codec); | |
18708
9e2b300db17b
Change free_sh_audio() to take demuxer and stream id as parameters
uau
parents:
18558
diff
changeset
|
673 free_sh_audio(demuxer, 1); |
3502 | 674 goto nosound; |
675 } | |
3439
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
676 |
2687 | 677 // Emulate WAVEFORMATEX struct: |
32100 | 678 sh->wf=calloc(1, sizeof(*sh->wf)); |
3439
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
679 sh->wf->wFormatTag=sh->format; |
3502 | 680 sh->wf->nChannels=1; /* 1 channels for both Siren and G.723 */ |
681 | |
682 /* Set bits per sample */ | |
3471 | 683 if (priv->audio_codec == VIVO_AUDIO_SIREN) |
3502 | 684 sh->wf->wBitsPerSample = 16; |
3471 | 685 else |
3502 | 686 if (priv->audio_codec == VIVO_AUDIO_G723) |
687 sh->wf->wBitsPerSample = 8; | |
688 | |
689 /* Set sampling rate */ | |
690 if (priv->audio_samplerate) /* got from header */ | |
691 sh->wf->nSamplesPerSec = priv->audio_samplerate; | |
3471 | 692 else |
693 { | |
694 if (priv->audio_codec == VIVO_AUDIO_SIREN) | |
3502 | 695 sh->wf->nSamplesPerSec = 16000; |
696 if (priv->audio_codec == VIVO_AUDIO_G723) | |
697 sh->wf->nSamplesPerSec = 8000; | |
3471 | 698 } |
3502 | 699 if (vivo_param_samplerate != -1) |
700 sh->wf->nSamplesPerSec = vivo_param_samplerate; | |
701 | |
702 /* Set audio bitrate */ | |
703 if (priv->audio_bitrate) /* got from header */ | |
704 sh->wf->nAvgBytesPerSec = priv->audio_bitrate; | |
2784 | 705 else |
3471 | 706 { |
707 if (priv->audio_codec == VIVO_AUDIO_SIREN) | |
708 sh->wf->nAvgBytesPerSec = 2000; | |
3502 | 709 if (priv->audio_codec == VIVO_AUDIO_G723) |
3471 | 710 sh->wf->nAvgBytesPerSec = 800; |
711 } | |
3502 | 712 if (vivo_param_abitrate != -1) |
713 sh->wf->nAvgBytesPerSec = vivo_param_abitrate; | |
3526 | 714 audio_rate=sh->wf->nAvgBytesPerSec; |
3502 | 715 |
3471 | 716 if (!priv->audio_bytesperblock) |
717 { | |
718 if (priv->audio_codec == VIVO_AUDIO_SIREN) | |
3502 | 719 sh->wf->nBlockAlign = 40; |
720 if (priv->audio_codec == VIVO_AUDIO_G723) | |
721 sh->wf->nBlockAlign = 24; | |
3471 | 722 } |
723 else | |
3502 | 724 sh->wf->nBlockAlign = priv->audio_bytesperblock; |
725 if (vivo_param_bytesperblock != -1) | |
726 sh->wf->nBlockAlign = vivo_param_bytesperblock; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
727 |
8254
772d6d27fd66
warning patch by (Dominik Mierzejewski <dominik at rangers dot eu dot org>)
michael
parents:
7472
diff
changeset
|
728 /*sound_ok:*/ |
3502 | 729 /* insert as stream */ |
730 demuxer->audio->sh=sh; | |
731 sh->ds=demuxer->audio; | |
2687 | 732 demuxer->audio->id=1; |
3502 | 733 nosound: |
16175 | 734 return demuxer; |
2687 | 735 } |
2695 | 736 } |
16175 | 737 return demuxer; |
738 } | |
2687 | 739 |
16175 | 740 static void demux_close_vivo(demuxer_t *demuxer) |
2788 | 741 { |
742 vivo_priv_t* priv=demuxer->priv; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
743 |
2809 | 744 if (priv) { |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32394
diff
changeset
|
745 free(priv->title); |
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32394
diff
changeset
|
746 free(priv->author); |
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32394
diff
changeset
|
747 free(priv->copyright); |
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32394
diff
changeset
|
748 free(priv->producer); |
2788 | 749 free(priv); |
2809 | 750 } |
2788 | 751 return; |
752 } | |
16175 | 753 |
754 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
22605
diff
changeset
|
755 const demuxer_desc_t demuxer_desc_vivo = { |
16175 | 756 "Vivo demuxer", |
757 "vivo", | |
758 "VIVO", | |
759 "A'rpi, Alex Beregszasi", | |
760 "", | |
761 DEMUXER_TYPE_VIVO, | |
762 0, // unsafe autodetect | |
763 vivo_check_file, | |
764 demux_vivo_fill_buffer, | |
765 demux_open_vivo, | |
766 demux_close_vivo, | |
767 NULL, | |
768 NULL | |
769 }; |