Mercurial > libavformat.hg
annotate nut.c @ 271:e35faf19f79f libavformat
fixed time base and sample rate handling
| author | al3x |
|---|---|
| date | Thu, 02 Oct 2003 22:33:55 +0000 |
| parents | 6821ccd70a1c |
| children | 13cbfe47f085 |
| rev | line source |
|---|---|
| 219 | 1 /* |
| 2 * NUT (de)muxer based on initial draft | |
| 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 * | |
| 21 * Compatible with draft version 20030906 | |
| 22 * | |
| 23 */ | |
| 24 | |
| 25 /* | |
| 26 * TODO: | |
| 27 * - checksumming | |
| 28 * - correct timestamp handling | |
| 29 * - index writing | |
| 30 * - info and index packet reading support | |
| 31 * - startcode searching for broken streams | |
| 32 * - subpacket support | |
| 33 * - handling of codec specific headers | |
| 34 */ | |
| 35 | |
| 36 //#define DEBUG 1 | |
| 37 | |
| 38 #include "avformat.h" | |
| 39 #include "mpegaudio.h" | |
| 228 | 40 #include "avi.h" |
| 219 | 41 |
| 220 | 42 //from /dev/random |
| 43 | |
| 44 #define MAIN_STARTCODE (0xF9526A6200000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'M') | |
| 45 #define STREAM_STARTCODE (0xD667773F00000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'S') | |
| 46 #define KEYFRAME_STARTCODE (0xCB86308700000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'K') | |
| 47 #define INDEX_STARTCODE (0xEBFCDE0E00000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'X') | |
| 48 #define INFO_STARTCODE (0xA37B643500000000ULL + ('N'<<24) + ('U'<<16) + ('T'<<8) + 'I') | |
| 49 | |
| 219 | 50 typedef struct { |
| 51 int curr_frame_start; | |
| 52 int last_frame_size; | |
| 53 int curr_frame_size; | |
| 54 } NUTContext; | |
| 55 | |
| 56 static int bytes_left(ByteIOContext *bc) | |
| 57 { | |
| 58 return bc->buf_end - bc->buf_ptr; | |
| 59 } | |
| 60 | |
| 61 static uint64_t get_v(ByteIOContext *bc) | |
| 62 { | |
| 63 uint64_t val = 0; | |
| 64 | |
| 65 for(; bytes_left(bc) > 0; ) | |
| 66 { | |
| 67 int tmp = get_byte(bc); | |
| 68 | |
| 69 if (tmp&0x80) | |
| 70 val= (val<<7) + tmp - 0x80; | |
| 71 else | |
| 72 return (val<<7) + tmp; | |
| 73 } | |
| 74 return -1; | |
| 75 } | |
| 76 | |
| 77 static int64_t get_s(ByteIOContext *bc) | |
| 78 { | |
| 79 int64_t v = get_v(bc) + 1; | |
| 80 | |
| 81 if (v&1) | |
| 82 return -(v>>1); | |
| 83 else | |
| 84 return (v>>1); | |
| 85 } | |
| 86 | |
| 240 | 87 static int get_b(ByteIOContext *bc, char *data, int maxlen) |
| 219 | 88 { |
| 240 | 89 int i, len; |
| 219 | 90 |
| 91 len = get_v(bc); | |
| 240 | 92 for (i = 0; i < len && i < maxlen; i++) |
| 93 data[i] = get_byte(bc); | |
|
270
6821ccd70a1c
fix fabrice's broken get_bi and some minor changes in draft
al3x
parents:
241
diff
changeset
|
94 /* skip remaining bytes */ |
|
6821ccd70a1c
fix fabrice's broken get_bi and some minor changes in draft
al3x
parents:
241
diff
changeset
|
95 for (; i < len; i++) |
|
6821ccd70a1c
fix fabrice's broken get_bi and some minor changes in draft
al3x
parents:
241
diff
changeset
|
96 get_byte(bc); |
| 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 */ |
|
6821ccd70a1c
fix fabrice's broken get_bi and some minor changes in draft
al3x
parents:
241
diff
changeset
|
109 for (; i < len; i++) |
|
6821ccd70a1c
fix fabrice's broken get_bi and some minor changes in draft
al3x
parents:
241
diff
changeset
|
110 get_byte(bc); |
| 240 | 111 |
| 228 | 112 return val; |
| 219 | 113 } |
| 114 | |
| 115 static int get_packetheader(NUTContext *nut, ByteIOContext *bc) | |
| 116 { | |
| 117 nut->curr_frame_start = url_ftell(bc); | |
| 118 nut->curr_frame_size = get_v(bc); | |
| 119 nut->last_frame_size = get_v(bc); | |
| 120 dprintf("Packet: fwd: %d bwd: %d\n", | |
| 121 nut->curr_frame_size, nut->last_frame_size); | |
| 122 | |
| 123 return 0; | |
| 124 } | |
| 125 | |
| 221 | 126 /** |
| 127 * | |
| 128 */ | |
| 129 static int get_length(uint64_t val){ | |
| 130 int i; | |
| 219 | 131 |
| 221 | 132 for (i=7; ; i+=7) |
| 133 if ((val>>i) == 0) | |
| 134 return i; | |
| 219 | 135 |
| 221 | 136 return 7; //not reached |
| 219 | 137 } |
| 138 | |
| 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 | |
| 219 | 239 /* stream headers */ |
| 240 for (i = 0; i < s->nb_streams; i++) | |
| 241 { | |
| 271 | 242 int nom, denom; |
| 243 | |
| 219 | 244 codec = &s->streams[i]->codec; |
| 245 | |
| 223 | 246 put_be64(bc, STREAM_STARTCODE); |
| 221 | 247 put_packetheader(nut, bc, 120); |
| 222 | 248 put_v(bc, i /*s->streams[i]->index*/); |
| 219 | 249 put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0); |
| 250 if (codec->codec_tag) | |
| 228 | 251 put_bi(bc, codec->codec_tag); |
| 219 | 252 else if (codec->codec_type == CODEC_TYPE_VIDEO) |
| 253 { | |
| 254 int tmp = codec_get_bmp_tag(codec->codec_id); | |
| 228 | 255 put_bi(bc, tmp); |
| 271 | 256 nom = codec->frame_rate; |
| 257 denom = codec->frame_rate_base; | |
| 219 | 258 } |
| 259 else if (codec->codec_type == CODEC_TYPE_AUDIO) | |
| 260 { | |
| 261 int tmp = codec_get_wav_tag(codec->codec_id); | |
| 228 | 262 put_bi(bc, tmp); |
| 271 | 263 nom = codec->sample_rate/8; |
| 264 denom = 8; | |
| 219 | 265 } |
| 266 put_v(bc, codec->bit_rate); | |
| 267 put_v(bc, 0); /* no language code */ | |
| 271 | 268 put_v(bc, nom); |
| 269 put_v(bc, denom); | |
| 270 put_v(bc, 0); /* msb timestamp_shift */ | |
| 219 | 271 put_v(bc, 0); /* shuffle type */ |
| 272 put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */ | |
| 273 | |
| 274 put_v(bc, 0); /* no codec specific headers */ | |
| 275 | |
| 276 switch(codec->codec_type) | |
| 277 { | |
| 278 case CODEC_TYPE_AUDIO: | |
| 271 | 279 put_v(bc, (codec->sample_rate * denom) / nom); |
| 219 | 280 put_v(bc, codec->channels); |
| 220 | 281 put_be32(bc, 0); /* FIXME: checksum */ |
| 219 | 282 break; |
| 283 case CODEC_TYPE_VIDEO: | |
| 284 put_v(bc, codec->width); | |
| 285 put_v(bc, codec->height); | |
| 286 put_v(bc, 0); /* aspected w */ | |
| 287 put_v(bc, 0); /* aspected h */ | |
| 288 put_v(bc, 0); /* csp type -- unknown */ | |
| 220 | 289 put_be32(bc, 0); /* FIXME: checksum */ |
| 219 | 290 break; |
| 228 | 291 default: |
| 292 break; | |
| 219 | 293 } |
| 221 | 294 update_packetheader(nut, bc, 0); |
| 219 | 295 } |
| 296 | |
| 297 #if 0 | |
| 298 /* info header */ | |
| 223 | 299 put_be64(bc, INFO_STARTCODE); |
| 219 | 300 put_packetheader(nut, bc, 16+strlen(s->author)+strlen(s->title)+ |
| 221 | 301 strlen(s->comment)+strlen(s->copyright)); |
| 219 | 302 if (s->author[0]) |
| 303 { | |
| 304 put_v(bc, 5); /* type */ | |
| 305 put_b(bc, s->author, strlen(s->author)); | |
| 306 } | |
| 307 if (s->title[0]) | |
| 308 { | |
| 309 put_v(bc, 6); /* type */ | |
| 310 put_b(bc, s->title, strlen(s->title)); | |
| 311 } | |
| 312 if (s->comment[0]) | |
| 313 { | |
| 314 put_v(bc, 7); /* type */ | |
| 315 put_b(bc, s->comment, strlen(s->comment)); | |
| 316 } | |
| 317 if (s->copyright[0]) | |
| 318 { | |
| 319 put_v(bc, 8); /* type */ | |
| 320 put_b(bc, s->copyright, strlen(s->copyright)); | |
| 321 } | |
| 322 /* encoder */ | |
| 323 put_v(bc, 9); /* type */ | |
| 222 | 324 put_b(bc, LIBAVFORMAT_IDENT "\0", strlen(LIBAVFORMAT_IDENT)); |
| 325 | |
| 326 put_v(bc, 0); /* eof info */ | |
| 219 | 327 |
| 220 | 328 put_be32(bc, 0); /* FIXME: checksum */ |
| 221 | 329 update_packetheader(nut, bc, 0); |
| 219 | 330 #endif |
| 331 | |
| 332 put_flush_packet(bc); | |
| 333 | |
| 334 return 0; | |
| 335 } | |
| 336 | |
| 337 static int nut_write_packet(AVFormatContext *s, int stream_index, | |
| 241 | 338 const uint8_t *buf, int size, int64_t pts) |
| 219 | 339 { |
| 340 NUTContext *nut = s->priv_data; | |
| 341 ByteIOContext *bc = &s->pb; | |
| 342 int key_frame = 0; | |
| 228 | 343 int flags; |
| 219 | 344 AVCodecContext *enc; |
| 345 | |
| 346 if (stream_index > s->nb_streams) | |
| 347 return 1; | |
| 348 | |
| 349 enc = &s->streams[stream_index]->codec; | |
| 240 | 350 key_frame = enc->coded_frame->key_frame; |
| 219 | 351 |
| 352 if (key_frame) | |
| 220 | 353 put_be64(bc, KEYFRAME_STARTCODE); |
| 354 | |
| 355 flags=0; | |
| 356 flags<<=2; flags|=1; //priority | |
| 357 flags<<=1; flags|=0; //checksum | |
| 358 flags<<=1; flags|=0; //msb_timestamp_flag | |
| 359 flags<<=2; flags|=1; //subpacket_type | |
| 360 flags<<=1; flags|=0; //reserved | |
| 361 | |
| 362 put_byte(bc, flags); | |
| 223 | 363 |
| 364 put_packetheader(nut, bc, size+20); | |
| 219 | 365 put_v(bc, stream_index); |
| 241 | 366 put_s(bc, pts); /* lsb_timestamp */ |
| 221 | 367 update_packetheader(nut, bc, size); |
| 219 | 368 |
| 369 put_buffer(bc, buf, size); | |
| 370 | |
| 371 put_flush_packet(bc); | |
| 372 | |
| 373 return 0; | |
| 374 } | |
| 375 | |
| 376 static int nut_write_trailer(AVFormatContext *s) | |
| 377 { | |
| 378 ByteIOContext *bc = &s->pb; | |
| 379 #if 0 | |
| 380 int i; | |
| 381 | |
| 382 /* WRITE INDEX */ | |
| 383 | |
| 384 for (i = 0; s->nb_streams; i++) | |
| 385 { | |
| 223 | 386 put_be64(bc, INDEX_STARTCODE); |
| 221 | 387 put_packetheader(nut, bc, 64); |
| 219 | 388 put_v(bc, s->streams[i]->id); |
| 389 put_v(bc, ...); | |
| 220 | 390 put_be32(bc, 0); /* FIXME: checksum */ |
| 221 | 391 update_packetheader(nut, bc, 0); |
| 219 | 392 } |
| 393 #endif | |
| 394 | |
| 395 put_flush_packet(bc); | |
| 396 | |
| 397 return 0; | |
| 398 } | |
| 399 | |
| 400 static int nut_probe(AVProbeData *p) | |
| 401 { | |
| 220 | 402 int i; |
| 403 uint64_t code; | |
| 404 | |
| 405 code = 0xff; | |
| 406 for (i = 0; i < p->buf_size; i++) { | |
| 407 int c = p->buf[i]; | |
| 408 code = (code << 8) | c; | |
| 409 if (code == MAIN_STARTCODE) | |
| 410 return AVPROBE_SCORE_MAX; | |
| 411 } | |
| 412 return 0; | |
| 219 | 413 } |
| 414 | |
| 415 static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap) | |
| 416 { | |
| 417 NUTContext *nut = s->priv_data; | |
| 418 ByteIOContext *bc = &s->pb; | |
| 220 | 419 uint64_t tmp; |
| 219 | 420 int cur_stream, nb_streams; |
| 421 | |
| 422 /* main header */ | |
| 220 | 423 tmp = get_be64(bc); |
| 424 if (tmp != MAIN_STARTCODE) | |
| 425 fprintf(stderr, "damaged? startcode!=1 (%Ld)\n", tmp); | |
| 223 | 426 get_packetheader(nut, bc); |
| 219 | 427 |
| 428 tmp = get_v(bc); | |
| 429 if (tmp != 0) | |
| 220 | 430 fprintf(stderr, "bad version (%Ld)\n", tmp); |
| 219 | 431 |
| 432 nb_streams = get_v(bc); | |
| 220 | 433 get_be32(bc); /* checkusm */ |
| 219 | 434 |
| 435 s->bit_rate = 0; | |
| 436 | |
| 437 /* stream header */ | |
| 438 for (cur_stream = 0; cur_stream < nb_streams; cur_stream++) | |
| 439 { | |
| 271 | 440 int class, nom, denom; |
| 219 | 441 AVStream *st; |
| 442 | |
| 220 | 443 tmp = get_be64(bc); |
| 444 if (tmp != STREAM_STARTCODE) | |
| 445 fprintf(stderr, "damaged? startcode!=1 (%Ld)\n", tmp); | |
| 223 | 446 get_packetheader(nut, bc); |
| 219 | 447 st = av_new_stream(s, get_v(bc)); |
| 448 if (!st) | |
| 449 return AVERROR_NOMEM; | |
| 450 class = get_v(bc); | |
| 240 | 451 tmp = get_bi(bc); |
| 219 | 452 switch(class) |
| 453 { | |
| 454 case 0: | |
| 455 st->codec.codec_type = CODEC_TYPE_VIDEO; | |
| 456 st->codec.codec_id = codec_get_bmp_id(tmp); | |
| 457 if (st->codec.codec_id == CODEC_ID_NONE) | |
| 458 fprintf(stderr, "Unknown codec?!\n"); | |
| 459 break; | |
| 460 case 32: | |
| 461 st->codec.codec_type = CODEC_TYPE_AUDIO; | |
| 462 st->codec.codec_id = codec_get_wav_id(tmp); | |
| 463 if (st->codec.codec_id == CODEC_ID_NONE) | |
| 464 fprintf(stderr, "Unknown codec?!\n"); | |
| 465 break; | |
| 466 default: | |
| 467 fprintf(stderr, "Unknown stream class (%d)\n", class); | |
| 468 return -1; | |
| 469 } | |
| 470 s->bit_rate += get_v(bc); | |
| 240 | 471 get_b(bc, NULL, 0); /* language code */ |
| 271 | 472 nom = get_v(bc); |
| 473 denom = get_v(bc); | |
| 219 | 474 get_v(bc); /* FIXME: msb timestamp base */ |
| 475 get_v(bc); /* shuffle type */ | |
| 476 get_byte(bc); /* flags */ | |
| 477 | |
| 478 get_v(bc); /* FIXME: codec specific data headers */ | |
| 479 | |
| 480 if (class == 0) /* VIDEO */ | |
| 481 { | |
| 482 st->codec.width = get_v(bc); | |
| 483 st->codec.height = get_v(bc); | |
| 484 get_v(bc); /* aspected w */ | |
| 485 get_v(bc); /* aspected h */ | |
| 486 get_v(bc); /* csp type */ | |
| 240 | 487 get_be32(bc); /* checksum */ |
| 271 | 488 |
| 489 st->codec.frame_rate = nom; | |
| 490 st->codec.frame_rate_base = denom; | |
| 219 | 491 } |
| 492 if (class == 32) /* AUDIO */ | |
| 493 { | |
| 271 | 494 st->codec.sample_rate = (get_v(bc) * nom) / denom; |
| 219 | 495 st->codec.channels = get_v(bc); |
| 240 | 496 get_be32(bc); /* checksum */ |
| 219 | 497 } |
| 498 } | |
| 499 | |
| 500 return 0; | |
| 501 } | |
| 502 | |
| 503 static int nut_read_packet(AVFormatContext *s, AVPacket *pkt) | |
| 504 { | |
| 505 NUTContext *nut = s->priv_data; | |
| 506 ByteIOContext *bc = &s->pb; | |
| 220 | 507 int id, timestamp, size; |
| 219 | 508 int key_frame = 0; |
| 220 | 509 uint64_t tmp; |
| 219 | 510 |
| 511 | |
| 512 if (url_feof(bc)) | |
| 513 return -1; | |
| 514 | |
| 515 tmp = get_byte(bc); | |
| 220 | 516 if (tmp & 0x80) /* zero bit set? */ |
| 219 | 517 { |
| 220 | 518 tmp<<=8 ; tmp |= get_byte(bc); |
| 519 tmp<<=16; tmp |= get_be16(bc); | |
| 520 tmp<<=32; tmp |= get_be32(bc); | |
| 521 if (tmp == KEYFRAME_STARTCODE) | |
| 219 | 522 { |
| 523 key_frame = 1; | |
| 524 tmp = get_byte(bc); /* flags */ | |
| 525 } | |
| 526 else | |
| 220 | 527 fprintf(stderr, "error in zero bit / startcode %LX\n", tmp); |
| 219 | 528 } |
| 223 | 529 get_packetheader(nut, bc); |
| 220 | 530 #if 0 |
| 531 if (((tmp & 0x60)>>5) > 3) /* priority <= 3 */ | |
| 219 | 532 fprintf(stderr, "sanity check failed!\n"); |
| 220 | 533 #endif |
| 219 | 534 id = get_v(bc); |
| 535 timestamp = get_s(bc); | |
| 536 | |
| 537 size = (nut->curr_frame_size - (url_ftell(bc)-nut->curr_frame_start)); | |
| 220 | 538 dprintf("flags: 0x%Lx, timestamp: %d, packet size: %d\n", tmp, timestamp, size); |
| 219 | 539 |
| 540 if (size < 0) | |
| 541 return -1; | |
| 542 | |
| 543 av_new_packet(pkt, size); | |
| 544 get_buffer(bc, pkt->data, size); | |
| 545 pkt->stream_index = id; | |
| 546 if (key_frame) | |
| 547 pkt->flags |= PKT_FLAG_KEY; | |
| 548 pkt->pts = timestamp; | |
| 549 | |
| 550 return 0; | |
| 551 } | |
| 552 | |
| 553 static AVInputFormat nut_iformat = { | |
| 554 "nut", | |
| 555 "nut format", | |
| 556 sizeof(NUTContext), | |
| 557 nut_probe, | |
| 558 nut_read_header, | |
| 559 nut_read_packet, | |
| 560 // nut_read_close, | |
| 561 // nut_read_seek, | |
| 562 .extensions = "nut", | |
| 563 }; | |
| 564 | |
| 565 static AVOutputFormat nut_oformat = { | |
| 566 "nut", | |
| 567 "nut format", | |
| 568 "video/x-nut", | |
| 569 "nut", | |
| 570 sizeof(NUTContext), | |
| 571 #ifdef CONFIG_VORBIS | |
| 572 CODEC_ID_VORBIS, | |
| 573 #elif defined(CONFIG_MP3LAME) | |
| 232 | 574 CODEC_ID_MP3, |
| 219 | 575 #else |
| 223 | 576 CODEC_ID_MP2, /* AC3 needs liba52 decoder */ |
| 219 | 577 #endif |
| 578 CODEC_ID_MPEG4, | |
| 579 nut_write_header, | |
| 580 nut_write_packet, | |
| 581 nut_write_trailer, | |
| 582 }; | |
| 583 | |
| 584 int nut_init(void) | |
| 585 { | |
| 586 av_register_input_format(&nut_iformat); | |
| 587 av_register_output_format(&nut_oformat); | |
| 588 return 0; | |
| 589 } |
