Mercurial > mplayer.hg
annotate libmpdemux/demux_viv.c @ 32334:541a774ce8e4
Drop removal of AAC encoder from list of FFmpeg encoders.
The original reason to drop this particular encoder, that it
failed to build on many platforms, should no longer be the case.
author | diego |
---|---|
date | Fri, 01 Oct 2010 16:04:43 +0000 |
parents | 0e09b34b0c47 |
children | 914208d188b9 |
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 |
2788 | 235 if (buf) |
236 free(buf); | |
237 if (opt) | |
238 free(opt); | |
239 if (param) | |
240 free(param); | |
2784 | 241 } |
242 | |
16175 | 243 static int vivo_check_file(demuxer_t* demuxer){ |
2687 | 244 int i=0; |
245 int len; | |
246 int c; | |
247 unsigned char buf[2048+256]; | |
248 vivo_priv_t* priv; | |
2784 | 249 int orig_pos = stream_tell(demuxer->stream); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
250 |
2687 | 251 mp_msg(MSGT_DEMUX,MSGL_V,"Checking for VIVO\n"); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
252 |
2687 | 253 c=stream_read_char(demuxer->stream); |
2792 | 254 if(c==-256) return 0; |
2687 | 255 len=0; |
256 while((c=stream_read_char(demuxer->stream))>=0x80){ | |
257 len+=0x80*(c-0x80); | |
258 if(len>1024) return 0; | |
259 } | |
260 len+=c; | |
6139
3898967fcc96
some more output cosmetics, especially for vivo and mov demuxers
arpi
parents:
4407
diff
changeset
|
261 mp_msg(MSGT_DEMUX,MSGL_V,"header block 1 size: %d\n",len); |
2687 | 262 //stream_skip(demuxer->stream,len); |
2928 | 263 |
264 priv=malloc(sizeof(vivo_priv_t)); | |
265 memset(priv,0,sizeof(vivo_priv_t)); | |
266 demuxer->priv=priv; | |
2784 | 267 |
2805 | 268 #if 0 |
2785 | 269 vivo_parse_text_header(demuxer, len); |
2784 | 270 if (priv->supported == 0) |
271 return 0; | |
272 #else | |
2928 | 273 /* this is enought for check (for now) */ |
274 stream_read(demuxer->stream,buf,len); | |
275 buf[len]=0; | |
276 // printf("VIVO header: '%s'\n",buf); | |
277 | |
2687 | 278 // parse header: |
279 i=0; | |
280 while(i<len && buf[i]==0x0D && buf[i+1]==0x0A) i+=2; // skip empty lines | |
2695 | 281 if(strncmp(buf+i,"Version:Vivo/",13)) return 0; // bad version/type! |
2784 | 282 #endif |
2687 | 283 |
2695 | 284 #if 0 |
2687 | 285 c=stream_read_char(demuxer->stream); |
286 if(c) return 0; | |
287 len2=0; | |
288 while((c=stream_read_char(demuxer->stream))>=0x80){ | |
289 len2+=0x80*(c-0x80); | |
290 if(len+len2>2048) return 0; | |
291 } | |
292 len2+=c; | |
6139
3898967fcc96
some more output cosmetics, especially for vivo and mov demuxers
arpi
parents:
4407
diff
changeset
|
293 mp_msg(MSGT_DEMUX,MSGL_V,"header block 2 size: %d\n",len2); |
2687 | 294 stream_skip(demuxer->stream,len2); |
295 // stream_read(demuxer->stream,buf+len,len2); | |
2695 | 296 #endif |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
297 |
2687 | 298 // c=stream_read_char(demuxer->stream); |
299 // printf("first packet: %02X\n",c); | |
300 | |
2784 | 301 stream_seek(demuxer->stream, orig_pos); |
302 | |
16175 | 303 return DEMUXER_TYPE_VIVO; |
2687 | 304 } |
305 | |
3733 | 306 static int audio_pos=0; |
307 static int audio_rate=0; | |
3526 | 308 |
2687 | 309 // return value: |
310 // 0 = EOF or no stream found | |
311 // 1 = successfully read a packet | |
16175 | 312 static int demux_vivo_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){ |
2687 | 313 demux_stream_t *ds=NULL; |
314 int c; | |
315 int len=0; | |
316 int seq; | |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
317 int prefix=0; |
2687 | 318 demux->filepos=stream_tell(demux->stream); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
319 |
2687 | 320 c=stream_read_char(demux->stream); |
2792 | 321 if (c == -256) /* EOF */ |
322 return 0; | |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
323 // printf("c=%x,%02X\n",c,c&0xf0); |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
324 if (c == 0x82) |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
325 { |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
326 /* ok, this works, but pts calculating from header is required! */ |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
327 #warning "Calculate PTS from picture header!" |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
328 prefix = 1; |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
329 c = stream_read_char(demux->stream); |
19075 | 330 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
|
331 (int)stream_tell(demux->stream), c); |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
332 } |
2687 | 333 switch(c&0xF0){ |
2695 | 334 case 0x00: // header - skip it! |
2784 | 335 { |
2687 | 336 len=stream_read_char(demux->stream); |
2695 | 337 if(len>=0x80) len=0x80*(len-0x80)+stream_read_char(demux->stream); |
19075 | 338 mp_msg(MSGT_DEMUX, MSGL_V, "vivo extra header: %d bytes\n",len); |
2784 | 339 #ifdef TEXTPARSE_ALL |
340 { | |
341 int pos; | |
342 /* also try to parse all headers */ | |
343 pos = stream_tell(demux->stream); | |
344 vivo_parse_text_header(demux, len); | |
345 stream_seek(demux->stream, pos); | |
346 } | |
347 #endif | |
2687 | 348 break; |
2784 | 349 } |
2687 | 350 case 0x10: // video packet |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
351 if (prefix == 1) |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
352 len = stream_read_char(demux->stream); |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
353 else |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
354 len=128; |
2687 | 355 ds=demux->video; |
356 break; | |
357 case 0x20: // video packet | |
358 len=stream_read_char(demux->stream); | |
359 ds=demux->video; | |
360 break; | |
3068 | 361 case 0x30: // audio packet |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
362 if (prefix == 1) |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
363 len = stream_read_char(demux->stream); |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
364 else |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
365 len=40; /* 40kbps */ |
2695 | 366 ds=demux->audio; |
3526 | 367 audio_pos+=len; |
2695 | 368 break; |
2687 | 369 case 0x40: // audio packet |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
370 if (prefix == 1) |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
371 len = stream_read_char(demux->stream); |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
372 else |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
373 len=24; /* 24kbps */ |
2687 | 374 ds=demux->audio; |
3526 | 375 audio_pos+=len; |
2687 | 376 break; |
377 default: | |
17366 | 378 mp_msg(MSGT_DEMUX,MSGL_WARN,"VIVO - unknown ID found: %02X at pos %"PRIu64" contact author!\n", |
379 c, (int64_t)stream_tell(demux->stream)); | |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
380 return 0; |
2687 | 381 } |
3245
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
382 |
1e2a87b7cae8
added support for packet 0x82 (from vivodump.c by arpi)
alex
parents:
3113
diff
changeset
|
383 // printf("chunk=%x, len=%d\n", c, len); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
384 |
2695 | 385 if(!ds || ds->id<-1){ |
2687 | 386 if(len) stream_skip(demux->stream,len); |
387 return 1; | |
388 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
389 |
2687 | 390 seq=c&0x0F; |
391 | |
392 if(ds->asf_packet){ | |
393 if(ds->asf_seq!=seq){ | |
394 // closed segment, finalize packet: | |
395 ds_add_packet(ds,ds->asf_packet); | |
396 ds->asf_packet=NULL; | |
2695 | 397 // printf("packet!\n"); |
2687 | 398 } else { |
399 // append data to it! | |
400 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
|
401 if(dp->len + len + MP_INPUT_BUFFER_PADDING_SIZE < 0) |
18558
4928dd61f136
Fix potential integer overflows in memory allocation.
rtogni
parents:
17366
diff
changeset
|
402 return 0; |
27282
16beae919ff1
Avoid including avcodec.h in demuxer.h (and thus many other files) just to get
reimar
parents:
27269
diff
changeset
|
403 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
|
404 memset(dp->buffer+dp->len+len, 0, MP_INPUT_BUFFER_PADDING_SIZE); |
2687 | 405 //memcpy(dp->buffer+dp->len,data,len); |
406 stream_read(demux->stream,dp->buffer+dp->len,len); | |
407 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len); | |
408 dp->len+=len; | |
409 // we are ready now. | |
2695 | 410 if((c&0xF0)==0x20) --ds->asf_seq; // hack! |
2687 | 411 return 1; |
412 } | |
413 } | |
414 // create new packet: | |
415 { demux_packet_t* dp; | |
416 dp=new_demux_packet(len); | |
417 //memcpy(dp->buffer,data,len); | |
418 stream_read(demux->stream,dp->buffer,len); | |
3526 | 419 dp->pts=audio_rate?((float)audio_pos/(float)audio_rate):0; |
2687 | 420 // dp->flags=keyframe; |
421 // if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur); | |
422 dp->pos=demux->filepos; | |
423 ds->asf_packet=dp; | |
424 ds->asf_seq=seq; | |
425 // we are ready now. | |
426 return 1; | |
427 } | |
428 | |
429 } | |
430 | |
431 static const short h263_format[8][2] = { | |
432 { 0, 0 }, | |
433 { 128, 96 }, | |
434 { 176, 144 }, | |
435 { 352, 288 }, | |
436 { 704, 576 }, | |
437 { 1408, 1152 }, | |
2784 | 438 { 320, 240 } // ??????? or 240x180 (found in vivo2) ? |
2687 | 439 }; |
440 | |
441 static unsigned char* buffer; | |
442 static int bufptr=0; | |
443 static int bitcnt=0; | |
444 static unsigned char buf=0; | |
445 static int format, width, height; | |
446 | |
447 static unsigned int x_get_bits(int n){ | |
448 unsigned int x=0; | |
449 while(n-->0){ | |
450 if(!bitcnt){ | |
451 // fill buff | |
452 buf=buffer[bufptr++]; | |
453 bitcnt=8; | |
454 } | |
455 //x=(x<<1)|(buf&1);buf>>=1; | |
456 x=(x<<1)|(buf>>7);buf<<=1; | |
457 --bitcnt; | |
458 } | |
459 return x; | |
460 } | |
461 | |
462 #define get_bits(xxx,n) x_get_bits(n) | |
463 #define get_bits1(xxx) x_get_bits(1) | |
464 #define skip_bits(xxx,n) x_get_bits(n) | |
465 #define skip_bits1(xxx) x_get_bits(1) | |
466 | |
467 /* most is hardcoded. should extend to handle all h263 streams */ | |
468 static int h263_decode_picture_header(unsigned char *b_ptr) | |
469 { | |
2928 | 470 // int i; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
471 |
2695 | 472 // 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
|
473 |
2687 | 474 buffer=b_ptr; |
475 bufptr=bitcnt=buf=0; | |
476 | |
477 /* picture header */ | |
2695 | 478 if (get_bits(&s->gb, 22) != 0x20){ |
19075 | 479 mp_msg(MSGT_DEMUX, MSGL_FATAL, "bad picture header\n"); |
2687 | 480 return -1; |
2695 | 481 } |
2687 | 482 skip_bits(&s->gb, 8); /* picture timestamp */ |
483 | |
2695 | 484 if (get_bits1(&s->gb) != 1){ |
19075 | 485 mp_msg(MSGT_DEMUX, MSGL_FATAL, "bad marker\n"); |
2687 | 486 return -1; /* marker */ |
2695 | 487 } |
488 if (get_bits1(&s->gb) != 0){ | |
19075 | 489 mp_msg(MSGT_DEMUX, MSGL_FATAL, "bad h263 id\n"); |
2687 | 490 return -1; /* h263 id */ |
2695 | 491 } |
2687 | 492 skip_bits1(&s->gb); /* split screen off */ |
493 skip_bits1(&s->gb); /* camera off */ | |
494 skip_bits1(&s->gb); /* freeze picture release off */ | |
495 | |
496 format = get_bits(&s->gb, 3); | |
497 | |
498 if (format != 7) { | |
19075 | 499 mp_msg(MSGT_DEMUX, MSGL_V, "h263_plus = 0 format = %d\n", format); |
2687 | 500 /* H.263v1 */ |
501 width = h263_format[format][0]; | |
502 height = h263_format[format][1]; | |
19075 | 503 mp_msg(MSGT_DEMUX, MSGL_V, "%d x %d\n", width, height); |
2695 | 504 // if (!width) return -1; |
2687 | 505 |
19075 | 506 mp_msg(MSGT_DEMUX, MSGL_V, "pict_type=%d\n", get_bits1(&s->gb)); |
507 mp_msg(MSGT_DEMUX, MSGL_V, "unrestricted_mv=%d\n", get_bits1(&s->gb)); | |
2687 | 508 #if 1 |
19075 | 509 mp_msg(MSGT_DEMUX, MSGL_V, "SAC: %d\n", get_bits1(&s->gb)); |
510 mp_msg(MSGT_DEMUX, MSGL_V, "advanced prediction mode: %d\n", get_bits1(&s->gb)); | |
511 mp_msg(MSGT_DEMUX, MSGL_V, "PB frame: %d\n", get_bits1(&s->gb)); | |
2687 | 512 #else |
513 if (get_bits1(&s->gb) != 0) | |
514 return -1; /* SAC: off */ | |
515 if (get_bits1(&s->gb) != 0) | |
516 return -1; /* advanced prediction mode: off */ | |
517 if (get_bits1(&s->gb) != 0) | |
518 return -1; /* not PB frame */ | |
519 #endif | |
19075 | 520 mp_msg(MSGT_DEMUX, MSGL_V, "qscale=%d\n", get_bits(&s->gb, 5)); |
2687 | 521 skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ |
522 } else { | |
19075 | 523 mp_msg(MSGT_DEMUX, MSGL_V, "h263_plus = 1\n"); |
2687 | 524 /* H.263v2 */ |
2695 | 525 if (get_bits(&s->gb, 3) != 1){ |
19075 | 526 mp_msg(MSGT_DEMUX, MSGL_FATAL, "H.263v2 A error\n"); |
2687 | 527 return -1; |
2695 | 528 } |
529 if (get_bits(&s->gb, 3) != 6){ /* custom source format */ | |
19075 | 530 mp_msg(MSGT_DEMUX, MSGL_FATAL, "custom source format\n"); |
2687 | 531 return -1; |
2695 | 532 } |
2687 | 533 skip_bits(&s->gb, 12); |
534 skip_bits(&s->gb, 3); | |
19075 | 535 mp_msg(MSGT_DEMUX, MSGL_V, "pict_type=%d\n", get_bits(&s->gb, 3) + 1); |
2687 | 536 // if (s->pict_type != I_TYPE && |
537 // s->pict_type != P_TYPE) | |
538 // return -1; | |
539 skip_bits(&s->gb, 7); | |
540 skip_bits(&s->gb, 4); /* aspect ratio */ | |
541 width = (get_bits(&s->gb, 9) + 1) * 4; | |
542 skip_bits1(&s->gb); | |
543 height = get_bits(&s->gb, 9) * 4; | |
19075 | 544 mp_msg(MSGT_DEMUX, MSGL_V, "%d x %d\n", width, height); |
2695 | 545 //if (height == 0) |
546 // return -1; | |
19075 | 547 mp_msg(MSGT_DEMUX, MSGL_V, "qscale=%d\n", get_bits(&s->gb, 5)); |
2687 | 548 } |
549 | |
550 /* PEI */ | |
551 while (get_bits1(&s->gb) != 0) { | |
552 skip_bits(&s->gb, 8); | |
553 } | |
554 // s->f_code = 1; | |
555 // s->width = width; | |
556 // s->height = height; | |
557 return 0; | |
558 } | |
559 | |
560 | |
2695 | 561 |
16175 | 562 static demuxer_t* demux_open_vivo(demuxer_t* demuxer){ |
2687 | 563 vivo_priv_t* priv=demuxer->priv; |
564 | |
565 if(!ds_fill_buffer(demuxer->video)){ | |
566 mp_msg(MSGT_DEMUX,MSGL_ERR,"VIVO: " MSGTR_MissingVideoStreamBug); | |
16175 | 567 return NULL; |
2687 | 568 } |
3526 | 569 |
570 audio_pos=0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
571 |
2687 | 572 h263_decode_picture_header(demuxer->video->buffer); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
573 |
3503 | 574 if (vivo_param_version != -1) |
575 priv->version = '0' + vivo_param_version; | |
2687 | 576 |
577 { 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
|
578 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
579 /* viv1, viv2 (for better codecs.conf) */ |
3113
c0e6a39d2ab7
changed to generate fourcc's like: viv<version> -> viv1,viv2
alex
parents:
3069
diff
changeset
|
580 sh->format = mmioFOURCC('v', 'i', 'v', priv->version); |
2784 | 581 if(!sh->fps) |
2928 | 582 { |
2784 | 583 if (priv->fps) |
584 sh->fps=priv->fps; | |
585 else | |
586 sh->fps=15.0f; | |
2928 | 587 } |
2687 | 588 sh->frametime=1.0f/sh->fps; |
2805 | 589 |
3502 | 590 /* XXX: FIXME: can't scale image. */ |
591 /* hotfix to disable: */ | |
2805 | 592 priv->disp_width = priv->width; |
593 priv->disp_height = priv->height; | |
594 | |
3502 | 595 if (vivo_param_width != -1) |
596 priv->disp_width = priv->width = vivo_param_width; | |
597 | |
598 if (vivo_param_height != -1) | |
599 priv->disp_height = priv->height = vivo_param_height; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
600 |
3502 | 601 if (vivo_param_vformat != -1) |
602 { | |
603 priv->disp_width = priv->width = h263_format[vivo_param_vformat][0]; | |
604 priv->disp_height = priv->height = h263_format[vivo_param_vformat][1]; | |
605 } | |
606 | |
2784 | 607 if (priv->disp_width) |
608 sh->disp_w = priv->disp_width; | |
609 else | |
610 sh->disp_w = width; | |
611 if (priv->disp_height) | |
612 sh->disp_h = priv->disp_height; | |
613 else | |
614 sh->disp_h = height; | |
2687 | 615 |
616 // emulate BITMAPINFOHEADER: | |
32100 | 617 sh->bih=calloc(1, sizeof(*sh->bih)); |
2687 | 618 sh->bih->biSize=40; |
2784 | 619 if (priv->width) |
620 sh->bih->biWidth = priv->width; | |
621 else | |
622 sh->bih->biWidth = width; | |
623 if (priv->height) | |
624 sh->bih->biHeight = priv->height; | |
625 else | |
626 sh->bih->biHeight = height; | |
2687 | 627 sh->bih->biPlanes=1; |
628 sh->bih->biBitCount=24; | |
629 sh->bih->biCompression=sh->format; | |
630 sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight*3; | |
3502 | 631 |
632 /* insert as stream */ | |
633 demuxer->video->sh=sh; | |
634 sh->ds=demuxer->video; | |
2687 | 635 demuxer->video->id=0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
636 |
3502 | 637 /* disable seeking */ |
2928 | 638 demuxer->seekable = 0; |
2788 | 639 |
19075 | 640 mp_msg(MSGT_DEMUX,MSGL_V,"VIVO Video stream %d size: display: %dx%d, codec: %ux%u\n", |
2788 | 641 demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth, |
642 sh->bih->biHeight); | |
2687 | 643 } |
644 | |
3502 | 645 /* AUDIO init */ |
646 if (demuxer->audio->id >= -1){ | |
2687 | 647 if(!ds_fill_buffer(demuxer->audio)){ |
648 mp_msg(MSGT_DEMUX,MSGL_ERR,"VIVO: " MSGTR_MissingAudioStream); | |
649 } else | |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
31413
diff
changeset
|
650 { sh_audio_t* sh=new_sh_audio(demuxer,1, NULL); |
2788 | 651 |
3502 | 652 /* Select audio codec */ |
3471 | 653 if (priv->audio_codec == 0) |
654 { | |
655 if (priv->version == '2') | |
656 priv->audio_codec = VIVO_AUDIO_SIREN; | |
657 else | |
658 priv->audio_codec = VIVO_AUDIO_G723; | |
659 } | |
3502 | 660 if (vivo_param_acodec != NULL) |
661 { | |
662 if (!strcasecmp(vivo_param_acodec, "g723")) | |
663 priv->audio_codec = VIVO_AUDIO_G723; | |
664 if (!strcasecmp(vivo_param_acodec, "siren")) | |
665 priv->audio_codec = VIVO_AUDIO_SIREN; | |
666 } | |
3471 | 667 |
3502 | 668 if (priv->audio_codec == VIVO_AUDIO_G723) |
669 sh->format = 0x111; | |
9955
d6be831a5f9a
fixed 2 10l-s (bug found in the spring cleanup patch by Raindel Shachar
alex
parents:
8254
diff
changeset
|
670 else if (priv->audio_codec == VIVO_AUDIO_SIREN) |
3502 | 671 sh->format = 0x112; |
9955
d6be831a5f9a
fixed 2 10l-s (bug found in the spring cleanup patch by Raindel Shachar
alex
parents:
8254
diff
changeset
|
672 else |
3502 | 673 { |
674 mp_msg(MSGT_DEMUX, MSGL_ERR, "VIVO: Not support audio codec (%d)\n", | |
675 priv->audio_codec); | |
18708
9e2b300db17b
Change free_sh_audio() to take demuxer and stream id as parameters
uau
parents:
18558
diff
changeset
|
676 free_sh_audio(demuxer, 1); |
3502 | 677 goto nosound; |
678 } | |
3439
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
679 |
2687 | 680 // Emulate WAVEFORMATEX struct: |
32100 | 681 sh->wf=calloc(1, sizeof(*sh->wf)); |
3439
192449c155c7
fixed Waveformatheader emu and added vivo1/2 audio detection
alex
parents:
3245
diff
changeset
|
682 sh->wf->wFormatTag=sh->format; |
3502 | 683 sh->wf->nChannels=1; /* 1 channels for both Siren and G.723 */ |
684 | |
685 /* Set bits per sample */ | |
3471 | 686 if (priv->audio_codec == VIVO_AUDIO_SIREN) |
3502 | 687 sh->wf->wBitsPerSample = 16; |
3471 | 688 else |
3502 | 689 if (priv->audio_codec == VIVO_AUDIO_G723) |
690 sh->wf->wBitsPerSample = 8; | |
691 | |
692 /* Set sampling rate */ | |
693 if (priv->audio_samplerate) /* got from header */ | |
694 sh->wf->nSamplesPerSec = priv->audio_samplerate; | |
3471 | 695 else |
696 { | |
697 if (priv->audio_codec == VIVO_AUDIO_SIREN) | |
3502 | 698 sh->wf->nSamplesPerSec = 16000; |
699 if (priv->audio_codec == VIVO_AUDIO_G723) | |
700 sh->wf->nSamplesPerSec = 8000; | |
3471 | 701 } |
3502 | 702 if (vivo_param_samplerate != -1) |
703 sh->wf->nSamplesPerSec = vivo_param_samplerate; | |
704 | |
705 /* Set audio bitrate */ | |
706 if (priv->audio_bitrate) /* got from header */ | |
707 sh->wf->nAvgBytesPerSec = priv->audio_bitrate; | |
2784 | 708 else |
3471 | 709 { |
710 if (priv->audio_codec == VIVO_AUDIO_SIREN) | |
711 sh->wf->nAvgBytesPerSec = 2000; | |
3502 | 712 if (priv->audio_codec == VIVO_AUDIO_G723) |
3471 | 713 sh->wf->nAvgBytesPerSec = 800; |
714 } | |
3502 | 715 if (vivo_param_abitrate != -1) |
716 sh->wf->nAvgBytesPerSec = vivo_param_abitrate; | |
3526 | 717 audio_rate=sh->wf->nAvgBytesPerSec; |
3502 | 718 |
3471 | 719 if (!priv->audio_bytesperblock) |
720 { | |
721 if (priv->audio_codec == VIVO_AUDIO_SIREN) | |
3502 | 722 sh->wf->nBlockAlign = 40; |
723 if (priv->audio_codec == VIVO_AUDIO_G723) | |
724 sh->wf->nBlockAlign = 24; | |
3471 | 725 } |
726 else | |
3502 | 727 sh->wf->nBlockAlign = priv->audio_bytesperblock; |
728 if (vivo_param_bytesperblock != -1) | |
729 sh->wf->nBlockAlign = vivo_param_bytesperblock; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
730 |
8254
772d6d27fd66
warning patch by (Dominik Mierzejewski <dominik at rangers dot eu dot org>)
michael
parents:
7472
diff
changeset
|
731 /*sound_ok:*/ |
3502 | 732 /* insert as stream */ |
733 demuxer->audio->sh=sh; | |
734 sh->ds=demuxer->audio; | |
2687 | 735 demuxer->audio->id=1; |
3502 | 736 nosound: |
16175 | 737 return demuxer; |
2687 | 738 } |
2695 | 739 } |
16175 | 740 return demuxer; |
741 } | |
2687 | 742 |
16175 | 743 static void demux_close_vivo(demuxer_t *demuxer) |
2788 | 744 { |
745 vivo_priv_t* priv=demuxer->priv; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
746 |
2809 | 747 if (priv) { |
748 if (priv->title) | |
749 free(priv->title); | |
750 if (priv->author) | |
751 free(priv->author); | |
752 if (priv->copyright) | |
753 free(priv->copyright); | |
754 if (priv->producer) | |
755 free(priv->producer); | |
2788 | 756 free(priv); |
2809 | 757 } |
2788 | 758 return; |
759 } | |
16175 | 760 |
761 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
22605
diff
changeset
|
762 const demuxer_desc_t demuxer_desc_vivo = { |
16175 | 763 "Vivo demuxer", |
764 "vivo", | |
765 "VIVO", | |
766 "A'rpi, Alex Beregszasi", | |
767 "", | |
768 DEMUXER_TYPE_VIVO, | |
769 0, // unsafe autodetect | |
770 vivo_check_file, | |
771 demux_vivo_fill_buffer, | |
772 demux_open_vivo, | |
773 demux_close_vivo, | |
774 NULL, | |
775 NULL | |
776 }; |