Mercurial > libavformat.hg
annotate nut.c @ 346:e154eb1b7149 libavformat
caching of timestamps for mpeg-ps so seeking is faster
move (av_)find_stream_index() to utils.c as its usefull outside mpeg.c
assert checking enabled, to find bugs quicker, should obviously be disabled later
(av_)add_index_entry() inserts new entries so that the list stays ordered and updates entries if already in it
(av_)index_search_timestamp() cleanup (kill ugly goto) and shorter
author | michael |
---|---|
date | Tue, 13 Jan 2004 22:02:49 +0000 |
parents | 137b4ce31b0f |
children | 845f9de2c883 |
rev | line source |
---|---|
219 | 1 /* |
272 | 2 * "NUT" Container Format muxer and demuxer (DRAFT-20031003) |
219 | 3 * Copyright (c) 2003 Alex Beregszaszi |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 * | |
19 * NUT DRAFT can be found in MPlayer CVS at DOCS/tech/mpcf.txt | |
20 * | |
272 | 21 * AND http://people.fsn.hu/~alex/nut/ (TeX, pdf, ps, dvi, ..) |
219 | 22 * |
23 */ | |
24 | |
25 /* | |
26 * TODO: | |
27 * - checksumming | |
272 | 28 * - optimal timestamp handling |
219 | 29 * - index writing |
30 * - info and index packet reading support | |
31 * - startcode searching for broken streams | |
32 * - subpacket support | |
33 */ | |
34 | |
35 //#define DEBUG 1 | |
36 | |
37 #include "avformat.h" | |
38 #include "mpegaudio.h" | |
228 | 39 #include "avi.h" |
219 | 40 |
220 | 41 //from /dev/random |
42 | |
43 #define MAIN_STARTCODE (0xF9526A6200000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'M') | |
44 #define STREAM_STARTCODE (0xD667773F00000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'S') | |
45 #define KEYFRAME_STARTCODE (0xCB86308700000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'K') | |
46 #define INDEX_STARTCODE (0xEBFCDE0E00000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'X') | |
47 #define INFO_STARTCODE (0xA37B643500000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'I') | |
48 | |
219 | 49 typedef struct { |
50 int curr_frame_start; | |
51 int last_frame_size; | |
52 int curr_frame_size; | |
328 | 53 int *msb_timestamp_shift; |
54 int64_t *last_msb_timestamp; | |
219 | 55 } NUTContext; |
56 | |
57 static int bytes_left(ByteIOContext *bc) | |
58 { | |
59 return bc->buf_end - bc->buf_ptr; | |
60 } | |
61 | |
62 static uint64_t get_v(ByteIOContext *bc) | |
63 { | |
64 uint64_t val = 0; | |
65 | |
66 for(; bytes_left(bc) > 0; ) | |
67 { | |
68 int tmp = get_byte(bc); | |
69 | |
70 if (tmp&0x80) | |
71 val= (val<<7) + tmp - 0x80; | |
72 else | |
73 return (val<<7) + tmp; | |
74 } | |
75 return -1; | |
76 } | |
77 | |
78 static int64_t get_s(ByteIOContext *bc) | |
79 { | |
80 int64_t v = get_v(bc) + 1; | |
81 | |
82 if (v&1) | |
83 return -(v>>1); | |
84 else | |
85 return (v>>1); | |
86 } | |
87 | |
240 | 88 static int get_b(ByteIOContext *bc, char *data, int maxlen) |
219 | 89 { |
240 | 90 int i, len; |
219 | 91 |
92 len = get_v(bc); | |
240 | 93 for (i = 0; i < len && i < maxlen; i++) |
94 data[i] = get_byte(bc); | |
270
6821ccd70a1c
fix fabrice's broken get_bi and some minor changes in draft
al3x
parents:
241
diff
changeset
|
95 /* skip remaining bytes */ |
272 | 96 url_fskip(bc, len-i); |
240 | 97 |
98 return 0; | |
99 } | |
100 | |
101 static int get_bi(ByteIOContext *bc) | |
102 { | |
270
6821ccd70a1c
fix fabrice's broken get_bi and some minor changes in draft
al3x
parents:
241
diff
changeset
|
103 int i, len, val = 0; |
240 | 104 |
105 len = get_v(bc); | |
270
6821ccd70a1c
fix fabrice's broken get_bi and some minor changes in draft
al3x
parents:
241
diff
changeset
|
106 for (i = 0; i < len && i <= 4; i++) |
240 | 107 val |= get_byte(bc) << (i * 8); |
270
6821ccd70a1c
fix fabrice's broken get_bi and some minor changes in draft
al3x
parents:
241
diff
changeset
|
108 /* skip remaining bytes */ |
272 | 109 url_fskip(bc, len-i); |
240 | 110 |
228 | 111 return val; |
219 | 112 } |
113 | |
114 static int get_packetheader(NUTContext *nut, ByteIOContext *bc) | |
115 { | |
116 nut->curr_frame_start = url_ftell(bc); | |
117 nut->curr_frame_size = get_v(bc); | |
118 nut->last_frame_size = get_v(bc); | |
119 dprintf("Packet: fwd: %d bwd: %d\n", | |
120 nut->curr_frame_size, nut->last_frame_size); | |
121 | |
122 return 0; | |
123 } | |
124 | |
221 | 125 /** |
126 * | |
127 */ | |
128 static int get_length(uint64_t val){ | |
129 int i; | |
219 | 130 |
221 | 131 for (i=7; ; i+=7) |
132 if ((val>>i) == 0) | |
133 return i; | |
219 | 134 |
221 | 135 return 7; //not reached |
219 | 136 } |
137 | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
272
diff
changeset
|
138 #ifdef CONFIG_ENCODERS |
219 | 139 static int put_v(ByteIOContext *bc, uint64_t val) |
140 { | |
141 int i; | |
142 | |
143 // if (bytes_left(s)*8 < 9) | |
144 // return -1; | |
145 | |
146 if (bytes_left(bc) < 1) | |
147 return -1; | |
148 | |
149 val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently | |
221 | 150 i= get_length(val); |
219 | 151 |
220 | 152 for (i-=7; i>0; i-=7){ |
219 | 153 put_byte(bc, 0x80 | (val>>i)); |
220 | 154 } |
219 | 155 |
156 put_byte(bc, val&0x7f); | |
157 | |
158 return 0; | |
159 } | |
160 | |
161 static int put_s(ByteIOContext *bc, uint64_t val) | |
162 { | |
163 if (val<=0) | |
164 return put_v(bc, -2*val); | |
165 else | |
166 return put_v(bc, 2*val-1); | |
167 } | |
168 | |
169 static int put_b(ByteIOContext *bc, char *data, int len) | |
170 { | |
171 int i; | |
172 | |
173 put_v(bc, len); | |
174 for (i = 0; i < len; i++) | |
175 put_byte(bc, data[i]); | |
176 | |
177 return 0; | |
178 } | |
179 | |
228 | 180 static int put_bi(ByteIOContext *bc, int val) |
181 { | |
182 put_v(bc, 4); | |
183 put_le32(bc, val); | |
184 return 0; | |
185 } | |
186 | |
221 | 187 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size) |
219 | 188 { |
189 put_flush_packet(bc); | |
190 nut->curr_frame_start = url_ftell(bc); | |
221 | 191 nut->curr_frame_size = max_size; |
219 | 192 |
193 /* packet header */ | |
194 put_v(bc, nut->curr_frame_size); /* forward ptr */ | |
195 put_v(bc, nut->last_frame_size); /* backward ptr */ | |
196 dprintf("Packet: fwd: %d, bwd: %d\n", | |
197 nut->curr_frame_size, nut->last_frame_size); | |
198 | |
199 nut->last_frame_size = nut->curr_frame_size; | |
200 | |
201 return 0; | |
202 } | |
203 | |
221 | 204 static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size){ |
205 offset_t start= nut->curr_frame_start; | |
206 offset_t cur= url_ftell(bc); | |
207 int size= cur - start + additional_size; | |
208 | |
209 assert( size <= nut->curr_frame_size ); | |
219 | 210 |
221 | 211 url_fseek(bc, start, SEEK_SET); |
212 put_v(bc, size); | |
213 if(get_length(size) < get_length(nut->curr_frame_size)) | |
214 put_byte(bc, 0x80); | |
215 nut->curr_frame_size= size; | |
216 dprintf("Packet update: size: %d\n", size); | |
219 | 217 |
221 | 218 url_fseek(bc, cur, SEEK_SET); |
219 | |
219 | 220 return 0; |
221 } | |
222 | |
223 static int nut_write_header(AVFormatContext *s) | |
224 { | |
225 NUTContext *nut = s->priv_data; | |
226 ByteIOContext *bc = &s->pb; | |
227 AVCodecContext *codec; | |
228 int i; | |
229 | |
230 /* main header */ | |
220 | 231 put_be64(bc, MAIN_STARTCODE); |
223 | 232 put_packetheader(nut, bc, 120); |
219 | 233 put_v(bc, 0); /* version */ |
234 put_v(bc, s->nb_streams); | |
220 | 235 put_be32(bc, 0); /* FIXME: checksum */ |
219 | 236 |
221 | 237 update_packetheader(nut, bc, 0); |
238 | |
328 | 239 nut->msb_timestamp_shift = |
240 av_mallocz(sizeof(nut->msb_timestamp_shift)*s->nb_streams); | |
241 nut->last_msb_timestamp = | |
242 av_mallocz(sizeof(nut->last_msb_timestamp)*s->nb_streams); | |
243 | |
219 | 244 /* stream headers */ |
245 for (i = 0; i < s->nb_streams; i++) | |
246 { | |
271 | 247 int nom, denom; |
248 | |
219 | 249 codec = &s->streams[i]->codec; |
250 | |
223 | 251 put_be64(bc, STREAM_STARTCODE); |
221 | 252 put_packetheader(nut, bc, 120); |
222 | 253 put_v(bc, i /*s->streams[i]->index*/); |
219 | 254 put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0); |
255 if (codec->codec_tag) | |
228 | 256 put_bi(bc, codec->codec_tag); |
219 | 257 else if (codec->codec_type == CODEC_TYPE_VIDEO) |
258 { | |
259 int tmp = codec_get_bmp_tag(codec->codec_id); | |
228 | 260 put_bi(bc, tmp); |
219 | 261 } |
262 else if (codec->codec_type == CODEC_TYPE_AUDIO) | |
263 { | |
264 int tmp = codec_get_wav_tag(codec->codec_id); | |
228 | 265 put_bi(bc, tmp); |
282 | 266 } |
267 | |
268 if (codec->codec_type == CODEC_TYPE_VIDEO) | |
269 { | |
270 nom = codec->frame_rate; | |
271 denom = codec->frame_rate_base; | |
272 } | |
273 else | |
274 { | |
271 | 275 nom = codec->sample_rate/8; |
276 denom = 8; | |
219 | 277 } |
278 put_v(bc, codec->bit_rate); | |
279 put_v(bc, 0); /* no language code */ | |
271 | 280 put_v(bc, nom); |
281 put_v(bc, denom); | |
328 | 282 nut->msb_timestamp_shift[i] = 0; |
283 put_v(bc, nut->msb_timestamp_shift[i]); | |
219 | 284 put_v(bc, 0); /* shuffle type */ |
285 put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */ | |
286 | |
287 put_v(bc, 0); /* no codec specific headers */ | |
288 | |
289 switch(codec->codec_type) | |
290 { | |
291 case CODEC_TYPE_AUDIO: | |
271 | 292 put_v(bc, (codec->sample_rate * denom) / nom); |
219 | 293 put_v(bc, codec->channels); |
220 | 294 put_be32(bc, 0); /* FIXME: checksum */ |
219 | 295 break; |
296 case CODEC_TYPE_VIDEO: | |
297 put_v(bc, codec->width); | |
298 put_v(bc, codec->height); | |
299 put_v(bc, 0); /* aspected w */ | |
300 put_v(bc, 0); /* aspected h */ | |
301 put_v(bc, 0); /* csp type -- unknown */ | |
220 | 302 put_be32(bc, 0); /* FIXME: checksum */ |
219 | 303 break; |
228 | 304 default: |
305 break; | |
219 | 306 } |
221 | 307 update_packetheader(nut, bc, 0); |
219 | 308 } |
309 | |
310 #if 0 | |
311 /* info header */ | |
223 | 312 put_be64(bc, INFO_STARTCODE); |
219 | 313 put_packetheader(nut, bc, 16+strlen(s->author)+strlen(s->title)+ |
221 | 314 strlen(s->comment)+strlen(s->copyright)); |
219 | 315 if (s->author[0]) |
316 { | |
317 put_v(bc, 5); /* type */ | |
318 put_b(bc, s->author, strlen(s->author)); | |
319 } | |
320 if (s->title[0]) | |
321 { | |
322 put_v(bc, 6); /* type */ | |
323 put_b(bc, s->title, strlen(s->title)); | |
324 } | |
325 if (s->comment[0]) | |
326 { | |
327 put_v(bc, 7); /* type */ | |
328 put_b(bc, s->comment, strlen(s->comment)); | |
329 } | |
330 if (s->copyright[0]) | |
331 { | |
332 put_v(bc, 8); /* type */ | |
333 put_b(bc, s->copyright, strlen(s->copyright)); | |
334 } | |
335 /* encoder */ | |
336 put_v(bc, 9); /* type */ | |
222 | 337 put_b(bc, LIBAVFORMAT_IDENT "\0", strlen(LIBAVFORMAT_IDENT)); |
338 | |
339 put_v(bc, 0); /* eof info */ | |
219 | 340 |
220 | 341 put_be32(bc, 0); /* FIXME: checksum */ |
221 | 342 update_packetheader(nut, bc, 0); |
219 | 343 #endif |
344 | |
345 put_flush_packet(bc); | |
346 | |
347 return 0; | |
348 } | |
349 | |
350 static int nut_write_packet(AVFormatContext *s, int stream_index, | |
241 | 351 const uint8_t *buf, int size, int64_t pts) |
219 | 352 { |
353 NUTContext *nut = s->priv_data; | |
354 ByteIOContext *bc = &s->pb; | |
328 | 355 int key_frame = 0, flags, msb_pts = 0; |
219 | 356 AVCodecContext *enc; |
328 | 357 int64_t lsb_pts; |
219 | 358 |
359 if (stream_index > s->nb_streams) | |
360 return 1; | |
361 | |
362 enc = &s->streams[stream_index]->codec; | |
328 | 363 // FIXME, lavc reports always keyframes for audio, which will make |
364 // _huge_ overhead | |
365 if (enc->codec_type == CODEC_TYPE_VIDEO) | |
366 key_frame = enc->coded_frame->key_frame; | |
219 | 367 |
328 | 368 if (key_frame /*|| |
369 ((pts - (nut->last_msb_timestamp[stream_index] << | |
370 nut->msb_timestamp_shift[stream_index])) > 1024)*/) | |
371 { | |
372 msb_pts = 1; | |
373 nut->last_msb_timestamp[stream_index] = pts >> nut->msb_timestamp_shift[stream_index]; | |
374 } | |
375 | |
376 lsb_pts = pts - (nut->last_msb_timestamp[stream_index] << nut->msb_timestamp_shift[stream_index]); | |
220 | 377 |
378 flags=0; | |
379 flags<<=2; flags|=1; //priority | |
380 flags<<=1; flags|=0; //checksum | |
328 | 381 flags<<=1; flags|=msb_pts; //msb_timestamp_flag |
220 | 382 flags<<=2; flags|=1; //subpacket_type |
383 flags<<=1; flags|=0; //reserved | |
384 | |
328 | 385 if (key_frame) |
386 put_be64(bc, KEYFRAME_STARTCODE); | |
220 | 387 put_byte(bc, flags); |
223 | 388 |
389 put_packetheader(nut, bc, size+20); | |
219 | 390 put_v(bc, stream_index); |
328 | 391 if (msb_pts) |
392 put_v(bc, nut->last_msb_timestamp[stream_index]); | |
393 put_v(bc, lsb_pts); /* lsb_timestamp */ | |
221 | 394 update_packetheader(nut, bc, size); |
219 | 395 |
396 put_buffer(bc, buf, size); | |
397 | |
398 put_flush_packet(bc); | |
399 | |
400 return 0; | |
401 } | |
402 | |
403 static int nut_write_trailer(AVFormatContext *s) | |
404 { | |
328 | 405 NUTContext *nut = s->priv_data; |
219 | 406 ByteIOContext *bc = &s->pb; |
407 #if 0 | |
408 int i; | |
409 | |
410 /* WRITE INDEX */ | |
411 | |
412 for (i = 0; s->nb_streams; i++) | |
413 { | |
223 | 414 put_be64(bc, INDEX_STARTCODE); |
221 | 415 put_packetheader(nut, bc, 64); |
219 | 416 put_v(bc, s->streams[i]->id); |
417 put_v(bc, ...); | |
220 | 418 put_be32(bc, 0); /* FIXME: checksum */ |
221 | 419 update_packetheader(nut, bc, 0); |
219 | 420 } |
421 #endif | |
422 | |
423 put_flush_packet(bc); | |
328 | 424 |
425 if (nut->last_msb_timestamp) | |
426 av_free(nut->last_msb_timestamp); | |
427 if (nut->msb_timestamp_shift) | |
428 av_free(nut->msb_timestamp_shift); | |
219 | 429 |
430 return 0; | |
431 } | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
272
diff
changeset
|
432 #endif //CONFIG_ENCODERS |
219 | 433 |
434 static int nut_probe(AVProbeData *p) | |
435 { | |
220 | 436 int i; |
437 uint64_t code; | |
438 | |
439 code = 0xff; | |
440 for (i = 0; i < p->buf_size; i++) { | |
441 int c = p->buf[i]; | |
442 code = (code << 8) | c; | |
443 if (code == MAIN_STARTCODE) | |
444 return AVPROBE_SCORE_MAX; | |
445 } | |
446 return 0; | |
219 | 447 } |
448 | |
449 static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap) | |
450 { | |
451 NUTContext *nut = s->priv_data; | |
452 ByteIOContext *bc = &s->pb; | |
220 | 453 uint64_t tmp; |
219 | 454 int cur_stream, nb_streams; |
455 | |
456 /* main header */ | |
220 | 457 tmp = get_be64(bc); |
458 if (tmp != MAIN_STARTCODE) | |
459 fprintf(stderr, "damaged? startcode!=1 (%Ld)\n", tmp); | |
223 | 460 get_packetheader(nut, bc); |
219 | 461 |
462 tmp = get_v(bc); | |
463 if (tmp != 0) | |
220 | 464 fprintf(stderr, "bad version (%Ld)\n", tmp); |
219 | 465 |
466 nb_streams = get_v(bc); | |
220 | 467 get_be32(bc); /* checkusm */ |
219 | 468 |
469 s->bit_rate = 0; | |
328 | 470 |
471 nut->msb_timestamp_shift = | |
472 av_malloc(sizeof(nut->msb_timestamp_shift)*s->nb_streams); | |
473 nut->last_msb_timestamp = | |
474 av_malloc(sizeof(nut->last_msb_timestamp)*s->nb_streams); | |
219 | 475 |
476 /* stream header */ | |
477 for (cur_stream = 0; cur_stream < nb_streams; cur_stream++) | |
478 { | |
271 | 479 int class, nom, denom; |
219 | 480 AVStream *st; |
481 | |
220 | 482 tmp = get_be64(bc); |
483 if (tmp != STREAM_STARTCODE) | |
484 fprintf(stderr, "damaged? startcode!=1 (%Ld)\n", tmp); | |
223 | 485 get_packetheader(nut, bc); |
219 | 486 st = av_new_stream(s, get_v(bc)); |
487 if (!st) | |
488 return AVERROR_NOMEM; | |
489 class = get_v(bc); | |
240 | 490 tmp = get_bi(bc); |
219 | 491 switch(class) |
492 { | |
493 case 0: | |
494 st->codec.codec_type = CODEC_TYPE_VIDEO; | |
495 st->codec.codec_id = codec_get_bmp_id(tmp); | |
496 if (st->codec.codec_id == CODEC_ID_NONE) | |
497 fprintf(stderr, "Unknown codec?!\n"); | |
498 break; | |
499 case 32: | |
500 st->codec.codec_type = CODEC_TYPE_AUDIO; | |
501 st->codec.codec_id = codec_get_wav_id(tmp); | |
502 if (st->codec.codec_id == CODEC_ID_NONE) | |
503 fprintf(stderr, "Unknown codec?!\n"); | |
504 break; | |
505 default: | |
506 fprintf(stderr, "Unknown stream class (%d)\n", class); | |
507 return -1; | |
508 } | |
509 s->bit_rate += get_v(bc); | |
240 | 510 get_b(bc, NULL, 0); /* language code */ |
271 | 511 nom = get_v(bc); |
512 denom = get_v(bc); | |
328 | 513 nut->msb_timestamp_shift[cur_stream] = get_v(bc); |
219 | 514 get_v(bc); /* shuffle type */ |
515 get_byte(bc); /* flags */ | |
272 | 516 |
517 /* codec specific data headers */ | |
518 while(get_v(bc) != 0) | |
519 url_fskip(bc, get_v(bc)); | |
219 | 520 |
521 if (class == 0) /* VIDEO */ | |
522 { | |
523 st->codec.width = get_v(bc); | |
524 st->codec.height = get_v(bc); | |
525 get_v(bc); /* aspected w */ | |
526 get_v(bc); /* aspected h */ | |
527 get_v(bc); /* csp type */ | |
240 | 528 get_be32(bc); /* checksum */ |
271 | 529 |
530 st->codec.frame_rate = nom; | |
531 st->codec.frame_rate_base = denom; | |
219 | 532 } |
533 if (class == 32) /* AUDIO */ | |
534 { | |
271 | 535 st->codec.sample_rate = (get_v(bc) * nom) / denom; |
219 | 536 st->codec.channels = get_v(bc); |
240 | 537 get_be32(bc); /* checksum */ |
219 | 538 } |
539 } | |
540 | |
541 return 0; | |
542 } | |
543 | |
544 static int nut_read_packet(AVFormatContext *s, AVPacket *pkt) | |
545 { | |
546 NUTContext *nut = s->priv_data; | |
547 ByteIOContext *bc = &s->pb; | |
328 | 548 int id, size; |
219 | 549 int key_frame = 0; |
220 | 550 uint64_t tmp; |
328 | 551 int64_t pts = 0; |
219 | 552 |
553 if (url_feof(bc)) | |
554 return -1; | |
555 | |
556 tmp = get_byte(bc); | |
220 | 557 if (tmp & 0x80) /* zero bit set? */ |
219 | 558 { |
220 | 559 tmp<<=8 ; tmp |= get_byte(bc); |
560 tmp<<=16; tmp |= get_be16(bc); | |
561 tmp<<=32; tmp |= get_be32(bc); | |
562 if (tmp == KEYFRAME_STARTCODE) | |
219 | 563 { |
564 key_frame = 1; | |
565 tmp = get_byte(bc); /* flags */ | |
566 } | |
567 else | |
220 | 568 fprintf(stderr, "error in zero bit / startcode %LX\n", tmp); |
219 | 569 } |
223 | 570 get_packetheader(nut, bc); |
220 | 571 #if 0 |
572 if (((tmp & 0x60)>>5) > 3) /* priority <= 3 */ | |
219 | 573 fprintf(stderr, "sanity check failed!\n"); |
220 | 574 #endif |
219 | 575 id = get_v(bc); |
328 | 576 if ((tmp & 0x8) >> 3) |
577 pts = get_v(bc) << nut->msb_timestamp_shift[id]; | |
578 pts += get_v(bc); | |
219 | 579 |
580 size = (nut->curr_frame_size - (url_ftell(bc)-nut->curr_frame_start)); | |
328 | 581 dprintf("flags: 0x%llx, timestamp: %llx, packet size: %d\n", tmp, pts, size); |
219 | 582 |
583 if (size < 0) | |
584 return -1; | |
585 | |
586 av_new_packet(pkt, size); | |
587 get_buffer(bc, pkt->data, size); | |
588 pkt->stream_index = id; | |
589 if (key_frame) | |
590 pkt->flags |= PKT_FLAG_KEY; | |
328 | 591 pkt->pts = pts; |
219 | 592 |
593 return 0; | |
594 } | |
595 | |
596 static AVInputFormat nut_iformat = { | |
597 "nut", | |
598 "nut format", | |
599 sizeof(NUTContext), | |
600 nut_probe, | |
601 nut_read_header, | |
602 nut_read_packet, | |
603 // nut_read_close, | |
604 // nut_read_seek, | |
605 .extensions = "nut", | |
606 }; | |
607 | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
272
diff
changeset
|
608 #ifdef CONFIG_ENCODERS |
219 | 609 static AVOutputFormat nut_oformat = { |
610 "nut", | |
611 "nut format", | |
612 "video/x-nut", | |
613 "nut", | |
614 sizeof(NUTContext), | |
615 #ifdef CONFIG_VORBIS | |
616 CODEC_ID_VORBIS, | |
617 #elif defined(CONFIG_MP3LAME) | |
232 | 618 CODEC_ID_MP3, |
219 | 619 #else |
223 | 620 CODEC_ID_MP2, /* AC3 needs liba52 decoder */ |
219 | 621 #endif |
622 CODEC_ID_MPEG4, | |
623 nut_write_header, | |
624 nut_write_packet, | |
625 nut_write_trailer, | |
626 }; | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
272
diff
changeset
|
627 #endif //CONFIG_ENCODERS |
219 | 628 |
629 int nut_init(void) | |
630 { | |
631 av_register_input_format(&nut_iformat); | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
272
diff
changeset
|
632 #ifdef CONFIG_ENCODERS |
219 | 633 av_register_output_format(&nut_oformat); |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
272
diff
changeset
|
634 #endif //CONFIG_ENCODERS |
219 | 635 return 0; |
636 } |