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