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;