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