Mercurial > libavformat.hg
comparison nut.c @ 221:fa80efcf8e39 libavformat
padding fix
| author | michaelni |
|---|---|
| date | Sat, 06 Sep 2003 16:29:05 +0000 |
| parents | 1dbacadcd222 |
| children | 1da43d2bdcae |
comparison
equal
deleted
inserted
replaced
| 220:1dbacadcd222 | 221:fa80efcf8e39 |
|---|---|
| 25 /* | 25 /* |
| 26 * TODO: | 26 * TODO: |
| 27 * - checksumming | 27 * - checksumming |
| 28 * - correct rate denom/nom and sample_mul | 28 * - correct rate denom/nom and sample_mul |
| 29 * - correct timestamp handling | 29 * - correct timestamp handling |
| 30 * - correct startcodes | |
| 31 * - index writing | 30 * - index writing |
| 32 * - info and index packet reading support | 31 * - info and index packet reading support |
| 33 * - startcode searching for broken streams | 32 * - startcode searching for broken streams |
| 34 * - subpacket support | 33 * - subpacket support |
| 35 * - handling of codec specific headers | 34 * - handling of codec specific headers |
| 112 nut->curr_frame_size, nut->last_frame_size); | 111 nut->curr_frame_size, nut->last_frame_size); |
| 113 | 112 |
| 114 return 0; | 113 return 0; |
| 115 } | 114 } |
| 116 | 115 |
| 117 static int get_padding(NUTContext *nut, ByteIOContext *bc) | 116 /** |
| 118 { | 117 * |
| 119 int i, tmp, len = nut->curr_frame_size - (url_ftell(bc) - nut->curr_frame_start); | 118 */ |
| 120 | 119 static int get_length(uint64_t val){ |
| 121 for (i = 0; i < len; i++) | 120 int i; |
| 122 { | 121 |
| 123 tmp = get_byte(bc); | 122 for (i=7; ; i+=7) |
| 124 if (tmp != 0) | 123 if ((val>>i) == 0) |
| 125 fprintf(stderr, "bad padding\n"); | 124 return i; |
| 126 } | 125 |
| 127 | 126 return 7; //not reached |
| 128 return 0; | |
| 129 } | 127 } |
| 130 | 128 |
| 131 static int put_v(ByteIOContext *bc, uint64_t val) | 129 static int put_v(ByteIOContext *bc, uint64_t val) |
| 132 { | 130 { |
| 133 int i; | 131 int i; |
| 137 | 135 |
| 138 if (bytes_left(bc) < 1) | 136 if (bytes_left(bc) < 1) |
| 139 return -1; | 137 return -1; |
| 140 | 138 |
| 141 val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently | 139 val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently |
| 142 for (i=7; ; i+=7) | 140 i= get_length(val); |
| 143 if ((val>>i) == 0) | |
| 144 break; | |
| 145 | 141 |
| 146 for (i-=7; i>0; i-=7){ | 142 for (i-=7; i>0; i-=7){ |
| 147 put_byte(bc, 0x80 | (val>>i)); | 143 put_byte(bc, 0x80 | (val>>i)); |
| 148 } | 144 } |
| 149 | 145 |
| 169 put_byte(bc, data[i]); | 165 put_byte(bc, data[i]); |
| 170 | 166 |
| 171 return 0; | 167 return 0; |
| 172 } | 168 } |
| 173 | 169 |
| 174 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int est_size) | 170 static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size) |
| 175 { | 171 { |
| 176 put_flush_packet(bc); | 172 put_flush_packet(bc); |
| 177 nut->curr_frame_start = url_ftell(bc); | 173 nut->curr_frame_start = url_ftell(bc); |
| 178 nut->curr_frame_size = est_size; | 174 nut->curr_frame_size = max_size; |
| 179 | 175 |
| 180 /* packet header */ | 176 /* packet header */ |
| 181 put_v(bc, nut->curr_frame_size); /* forward ptr */ | 177 put_v(bc, nut->curr_frame_size); /* forward ptr */ |
| 182 put_v(bc, nut->last_frame_size); /* backward ptr */ | 178 put_v(bc, nut->last_frame_size); /* backward ptr */ |
| 183 dprintf("Packet: fwd: %d, bwd: %d\n", | 179 dprintf("Packet: fwd: %d, bwd: %d\n", |
| 186 nut->last_frame_size = nut->curr_frame_size; | 182 nut->last_frame_size = nut->curr_frame_size; |
| 187 | 183 |
| 188 return 0; | 184 return 0; |
| 189 } | 185 } |
| 190 | 186 |
| 191 static int put_padding(NUTContext *nut, ByteIOContext *bc) | 187 static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size){ |
| 192 { | 188 offset_t start= nut->curr_frame_start; |
| 193 int i, len = nut->curr_frame_size - (url_ftell(bc) - nut->curr_frame_start); | 189 offset_t cur= url_ftell(bc); |
| 194 | 190 int size= cur - start + additional_size; |
| 195 put_flush_packet(bc); | 191 |
| 196 for (i = 0; i < len; i++) | 192 assert( size <= nut->curr_frame_size ); |
| 197 put_byte(bc, 0); | 193 |
| 198 | 194 url_fseek(bc, start, SEEK_SET); |
| 199 dprintf("padded %d bytes\n", i); | 195 put_v(bc, size); |
| 200 | 196 if(get_length(size) < get_length(nut->curr_frame_size)) |
| 197 put_byte(bc, 0x80); | |
| 198 nut->curr_frame_size= size; | |
| 199 dprintf("Packet update: size: %d\n", size); | |
| 200 | |
| 201 url_fseek(bc, cur, SEEK_SET); | |
| 202 | |
| 201 return 0; | 203 return 0; |
| 202 } | 204 } |
| 203 | 205 |
| 204 static int nut_write_header(AVFormatContext *s) | 206 static int nut_write_header(AVFormatContext *s) |
| 205 { | 207 { |
| 213 { | 215 { |
| 214 if (stream_length < (s->streams[i]->duration * (AV_TIME_BASE / 1000))) | 216 if (stream_length < (s->streams[i]->duration * (AV_TIME_BASE / 1000))) |
| 215 stream_length = s->streams[i]->duration * (AV_TIME_BASE / 1000); | 217 stream_length = s->streams[i]->duration * (AV_TIME_BASE / 1000); |
| 216 } | 218 } |
| 217 | 219 |
| 218 put_packetheader(nut, bc, 16); /* FIXME: estimation */ | 220 put_packetheader(nut, bc, 120); |
| 219 | 221 |
| 220 /* main header */ | 222 /* main header */ |
| 221 put_be64(bc, MAIN_STARTCODE); | 223 put_be64(bc, MAIN_STARTCODE); |
| 222 put_v(bc, 0); /* version */ | 224 put_v(bc, 0); /* version */ |
| 223 put_v(bc, s->nb_streams); | 225 put_v(bc, s->nb_streams); |
| 224 put_v(bc, 0); /* file size */ | 226 put_v(bc, 0); /* file size */ |
| 225 put_v(bc, stream_length); /* len in msec */ | 227 put_v(bc, stream_length); /* len in msec */ |
| 226 put_padding(nut, bc); | |
| 227 put_be32(bc, 0); /* FIXME: checksum */ | 228 put_be32(bc, 0); /* FIXME: checksum */ |
| 229 | |
| 230 update_packetheader(nut, bc, 0); | |
| 228 | 231 |
| 229 /* stream headers */ | 232 /* stream headers */ |
| 230 for (i = 0; i < s->nb_streams; i++) | 233 for (i = 0; i < s->nb_streams; i++) |
| 231 { | 234 { |
| 232 codec = &s->streams[i]->codec; | 235 codec = &s->streams[i]->codec; |
| 233 | 236 |
| 234 put_packetheader(nut, bc, 64); /* FIXME: estimation */ | 237 put_packetheader(nut, bc, 120); |
| 235 put_be64(bc, STREAM_STARTCODE); | 238 put_be64(bc, STREAM_STARTCODE); |
| 236 put_v(bc, s->streams[i]->index); | 239 put_v(bc, s->streams[i]->index); |
| 237 put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0); | 240 put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0); |
| 238 if (codec->codec_tag) | 241 if (codec->codec_tag) |
| 239 put_b(bc, &codec->codec_tag, 4); | 242 put_b(bc, &codec->codec_tag, 4); |
| 264 switch(codec->codec_type) | 267 switch(codec->codec_type) |
| 265 { | 268 { |
| 266 case CODEC_TYPE_AUDIO: | 269 case CODEC_TYPE_AUDIO: |
| 267 put_v(bc, codec->sample_rate / (double)(codec->frame_rate_base / codec->frame_rate)); | 270 put_v(bc, codec->sample_rate / (double)(codec->frame_rate_base / codec->frame_rate)); |
| 268 put_v(bc, codec->channels); | 271 put_v(bc, codec->channels); |
| 269 put_padding(nut, bc); | |
| 270 put_be32(bc, 0); /* FIXME: checksum */ | 272 put_be32(bc, 0); /* FIXME: checksum */ |
| 271 break; | 273 break; |
| 272 case CODEC_TYPE_VIDEO: | 274 case CODEC_TYPE_VIDEO: |
| 273 put_v(bc, codec->width); | 275 put_v(bc, codec->width); |
| 274 put_v(bc, codec->height); | 276 put_v(bc, codec->height); |
| 275 put_v(bc, 0); /* aspected w */ | 277 put_v(bc, 0); /* aspected w */ |
| 276 put_v(bc, 0); /* aspected h */ | 278 put_v(bc, 0); /* aspected h */ |
| 277 put_v(bc, 0); /* csp type -- unknown */ | 279 put_v(bc, 0); /* csp type -- unknown */ |
| 278 put_padding(nut, bc); | |
| 279 put_be32(bc, 0); /* FIXME: checksum */ | 280 put_be32(bc, 0); /* FIXME: checksum */ |
| 280 break; | 281 break; |
| 281 } | 282 } |
| 283 update_packetheader(nut, bc, 0); | |
| 282 } | 284 } |
| 283 | 285 |
| 284 #if 0 | 286 #if 0 |
| 285 /* info header */ | 287 /* info header */ |
| 286 put_packetheader(nut, bc, 16+strlen(s->author)+strlen(s->title)+ | 288 put_packetheader(nut, bc, 16+strlen(s->author)+strlen(s->title)+ |
| 287 strlen(s->comment)+strlen(s->copyright)); /* FIXME: estimation */ | 289 strlen(s->comment)+strlen(s->copyright)); |
| 288 put_be64(bc, INFO_STARTCODE); | 290 put_be64(bc, INFO_STARTCODE); |
| 289 if (s->author[0]) | 291 if (s->author[0]) |
| 290 { | 292 { |
| 291 put_v(bc, 5); /* type */ | 293 put_v(bc, 5); /* type */ |
| 292 put_b(bc, s->author, strlen(s->author)); | 294 put_b(bc, s->author, strlen(s->author)); |
| 308 } | 310 } |
| 309 /* encoder */ | 311 /* encoder */ |
| 310 put_v(bc, 9); /* type */ | 312 put_v(bc, 9); /* type */ |
| 311 put_b(bc, LIBAVFORMAT_IDENT, strlen(LIBAVFORMAT_IDENT)); | 313 put_b(bc, LIBAVFORMAT_IDENT, strlen(LIBAVFORMAT_IDENT)); |
| 312 | 314 |
| 313 put_padding(nut, bc); | |
| 314 put_be32(bc, 0); /* FIXME: checksum */ | 315 put_be32(bc, 0); /* FIXME: checksum */ |
| 316 update_packetheader(nut, bc, 0); | |
| 315 #endif | 317 #endif |
| 316 | 318 |
| 317 put_flush_packet(bc); | 319 put_flush_packet(bc); |
| 318 | 320 |
| 319 return 0; | 321 return 0; |
| 333 | 335 |
| 334 enc = &s->streams[stream_index]->codec; | 336 enc = &s->streams[stream_index]->codec; |
| 335 if (enc->codec_type == CODEC_TYPE_VIDEO) | 337 if (enc->codec_type == CODEC_TYPE_VIDEO) |
| 336 key_frame = enc->coded_frame->key_frame; | 338 key_frame = enc->coded_frame->key_frame; |
| 337 | 339 |
| 338 put_packetheader(nut, bc, size+(key_frame?16:8)+4); /* FIXME: estimation */ | 340 put_packetheader(nut, bc, size+(key_frame?8:0)+20); |
| 339 | 341 |
| 340 if (key_frame) | 342 if (key_frame) |
| 341 put_be64(bc, KEYFRAME_STARTCODE); | 343 put_be64(bc, KEYFRAME_STARTCODE); |
| 342 | 344 |
| 343 flags=0; | 345 flags=0; |
| 348 flags<<=1; flags|=0; //reserved | 350 flags<<=1; flags|=0; //reserved |
| 349 | 351 |
| 350 put_byte(bc, flags); | 352 put_byte(bc, flags); |
| 351 put_v(bc, stream_index); | 353 put_v(bc, stream_index); |
| 352 put_s(bc, 0); /* lsb_timestamp */ | 354 put_s(bc, 0); /* lsb_timestamp */ |
| 355 update_packetheader(nut, bc, size); | |
| 353 | 356 |
| 354 put_buffer(bc, buf, size); | 357 put_buffer(bc, buf, size); |
| 355 | 358 |
| 356 put_padding(nut, bc); | |
| 357 | |
| 358 put_flush_packet(bc); | 359 put_flush_packet(bc); |
| 359 | 360 |
| 360 return 0; | 361 return 0; |
| 361 } | 362 } |
| 362 | 363 |
| 369 | 370 |
| 370 /* WRITE INDEX */ | 371 /* WRITE INDEX */ |
| 371 | 372 |
| 372 for (i = 0; s->nb_streams; i++) | 373 for (i = 0; s->nb_streams; i++) |
| 373 { | 374 { |
| 374 put_packetheader(nut, bc, 64); /* FIXME: estimation */ | 375 put_packetheader(nut, bc, 64); |
| 375 put_be64(bc, INDEX_STARTCODE); | 376 put_be64(bc, INDEX_STARTCODE); |
| 376 put_v(bc, s->streams[i]->id); | 377 put_v(bc, s->streams[i]->id); |
| 377 put_v(bc, ...); | 378 put_v(bc, ...); |
| 378 put_padding(nut, bc); | |
| 379 put_be32(bc, 0); /* FIXME: checksum */ | 379 put_be32(bc, 0); /* FIXME: checksum */ |
| 380 update_packetheader(nut, bc, 0); | |
| 380 } | 381 } |
| 381 #endif | 382 #endif |
| 382 | 383 |
| 383 put_flush_packet(bc); | 384 put_flush_packet(bc); |
| 384 | 385 |
| 421 nb_streams = get_v(bc); | 422 nb_streams = get_v(bc); |
| 422 | 423 |
| 423 s->file_size = get_v(bc); | 424 s->file_size = get_v(bc); |
| 424 s->duration = get_v(bc) / (AV_TIME_BASE / 1000); | 425 s->duration = get_v(bc) / (AV_TIME_BASE / 1000); |
| 425 | 426 |
| 426 get_padding(nut, bc); | |
| 427 get_be32(bc); /* checkusm */ | 427 get_be32(bc); /* checkusm */ |
| 428 | 428 |
| 429 s->bit_rate = 0; | 429 s->bit_rate = 0; |
| 430 | 430 |
| 431 /* stream header */ | 431 /* stream header */ |
| 483 st->codec.width = get_v(bc); | 483 st->codec.width = get_v(bc); |
| 484 st->codec.height = get_v(bc); | 484 st->codec.height = get_v(bc); |
| 485 get_v(bc); /* aspected w */ | 485 get_v(bc); /* aspected w */ |
| 486 get_v(bc); /* aspected h */ | 486 get_v(bc); /* aspected h */ |
| 487 get_v(bc); /* csp type */ | 487 get_v(bc); /* csp type */ |
| 488 get_padding(nut, bc); | |
| 489 get_le32(bc); /* checksum */ | 488 get_le32(bc); /* checksum */ |
| 490 } | 489 } |
| 491 if (class == 32) /* AUDIO */ | 490 if (class == 32) /* AUDIO */ |
| 492 { | 491 { |
| 493 st->codec.sample_rate = get_v(bc) * (double)(st->codec.frame_rate_base / st->codec.frame_rate); | 492 st->codec.sample_rate = get_v(bc) * (double)(st->codec.frame_rate_base / st->codec.frame_rate); |
| 494 st->codec.channels = get_v(bc); | 493 st->codec.channels = get_v(bc); |
| 495 get_padding(nut, bc); | |
| 496 get_le32(bc); /* checksum */ | 494 get_le32(bc); /* checksum */ |
| 497 } | 495 } |
| 498 } | 496 } |
| 499 | 497 |
| 500 return 0; | 498 return 0; |
