comparison movenc.c @ 971:43f85eba04c4 libavformat

CTTS support patch by (Baptiste COUDURIER <baptiste.coudurier smartjog com>)
author michael
date Wed, 22 Feb 2006 23:46:20 +0000
parents 4e7a66723f1d
children 955d23ed733f
comparison
equal deleted inserted replaced
970:2266681a4a52 971:43f85eba04c4
39 unsigned int flags, size; 39 unsigned int flags, size;
40 uint64_t pos; 40 uint64_t pos;
41 unsigned int samplesInChunk; 41 unsigned int samplesInChunk;
42 char key_frame; 42 char key_frame;
43 unsigned int entries; 43 unsigned int entries;
44 int64_t cts;
44 } MOVIentry; 45 } MOVIentry;
45 46
46 typedef struct MOVIndex { 47 typedef struct MOVIndex {
47 int mode; 48 int mode;
48 int entry; 49 int entry;
52 long time; 53 long time;
53 long trackDuration; 54 long trackDuration;
54 long sampleCount; 55 long sampleCount;
55 long sampleDuration; 56 long sampleDuration;
56 int hasKeyframes; 57 int hasKeyframes;
58 int hasBframes;
57 int language; 59 int language;
58 int trackID; 60 int trackID;
59 AVCodecContext *enc; 61 AVCodecContext *enc;
60 62
61 int vosLen; 63 int vosLen;
540 else if (track->enc->codec_type == CODEC_TYPE_AUDIO) 542 else if (track->enc->codec_type == CODEC_TYPE_AUDIO)
541 mov_write_audio_tag(pb, track); 543 mov_write_audio_tag(pb, track);
542 return updateSize(pb, pos); 544 return updateSize(pb, pos);
543 } 545 }
544 546
547 static int mov_write_ctts_tag(ByteIOContext *pb, MOVTrack* track)
548 {
549 Time2Sample *ctts_entries;
550 uint32_t entries = 0;
551 uint32_t atom_size;
552 int i;
553
554 ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */
555 ctts_entries[0].count = 1;
556 ctts_entries[0].duration = track->cluster[0][0].cts;
557 for (i=1; i<track->entry; i++) {
558 int cl = i / MOV_INDEX_CLUSTER_SIZE;
559 int id = i % MOV_INDEX_CLUSTER_SIZE;
560 if (track->cluster[cl][id].cts == ctts_entries[entries].duration) {
561 ctts_entries[entries].count++; /* compress */
562 } else {
563 entries++;
564 ctts_entries[entries].duration = track->cluster[cl][id].cts;
565 ctts_entries[entries].count = 1;
566 }
567 }
568 entries++; /* last one */
569 atom_size = 16 + (entries * 8);
570 put_be32(pb, atom_size); /* size */
571 put_tag(pb, "ctts");
572 put_be32(pb, 0); /* version & flags */
573 put_be32(pb, entries); /* entry count */
574 for (i=0; i<entries; i++) {
575 put_be32(pb, ctts_entries[i].count);
576 put_be32(pb, ctts_entries[i].duration);
577 }
578 av_free(ctts_entries);
579 return atom_size;
580 }
581
545 /* TODO: */ 582 /* TODO: */
546 /* Time to sample atom */ 583 /* Time to sample atom */
547 static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track) 584 static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track)
548 { 585 {
549 put_be32(pb, 0x18); /* size */ 586 put_be32(pb, 0x18); /* size */
578 mov_write_stsd_tag(pb, track); 615 mov_write_stsd_tag(pb, track);
579 mov_write_stts_tag(pb, track); 616 mov_write_stts_tag(pb, track);
580 if (track->enc->codec_type == CODEC_TYPE_VIDEO && 617 if (track->enc->codec_type == CODEC_TYPE_VIDEO &&
581 track->hasKeyframes) 618 track->hasKeyframes)
582 mov_write_stss_tag(pb, track); 619 mov_write_stss_tag(pb, track);
620 if (track->enc->codec_type == CODEC_TYPE_VIDEO &&
621 track->hasBframes)
622 mov_write_ctts_tag(pb, track);
583 mov_write_stsc_tag(pb, track); 623 mov_write_stsc_tag(pb, track);
584 mov_write_stsz_tag(pb, track); 624 mov_write_stsz_tag(pb, track);
585 mov_write_stco_tag(pb, track); 625 mov_write_stco_tag(pb, track);
586 return updateSize(pb, pos); 626 return updateSize(pb, pos);
587 } 627 }
1350 int i; 1390 int i;
1351 1391
1352 for(i=0; i<s->nb_streams; i++){ 1392 for(i=0; i<s->nb_streams; i++){
1353 AVCodecContext *c= s->streams[i]->codec; 1393 AVCodecContext *c= s->streams[i]->codec;
1354 1394
1355 if (c->codec_type == CODEC_TYPE_VIDEO){ 1395 if(c->codec_type == CODEC_TYPE_VIDEO){
1396 av_set_pts_info(s->streams[i], 64, 1, c->time_base.den);
1356 if (!codec_get_tag(codec_movvideo_tags, c->codec_id)){ 1397 if (!codec_get_tag(codec_movvideo_tags, c->codec_id)){
1357 if(!codec_get_tag(codec_bmp_tags, c->codec_id)) 1398 if(!codec_get_tag(codec_bmp_tags, c->codec_id))
1358 return -1; 1399 return -1;
1359 else 1400 else
1360 av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, the file may be unplayable!\n"); 1401 av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, the file may be unplayable!\n");
1361 } 1402 }
1362 }else if(c->codec_type == CODEC_TYPE_AUDIO){ 1403 }else if(c->codec_type == CODEC_TYPE_AUDIO){
1404 av_set_pts_info(s->streams[i], 64, 1, c->sample_rate);
1363 if (!codec_get_tag(codec_movaudio_tags, c->codec_id)){ 1405 if (!codec_get_tag(codec_movaudio_tags, c->codec_id)){
1364 if(!codec_get_tag(codec_wav_tags, c->codec_id)) 1406 if(!codec_get_tag(codec_wav_tags, c->codec_id))
1365 return -1; 1407 return -1;
1366 else 1408 else
1367 av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, the file may be unplayable!\n"); 1409 av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, the file may be unplayable!\n");
1470 trk->cluster[cl][id].pos = url_ftell(pb); 1512 trk->cluster[cl][id].pos = url_ftell(pb);
1471 trk->cluster[cl][id].samplesInChunk = samplesInChunk; 1513 trk->cluster[cl][id].samplesInChunk = samplesInChunk;
1472 trk->cluster[cl][id].size = size; 1514 trk->cluster[cl][id].size = size;
1473 trk->cluster[cl][id].entries = samplesInChunk; 1515 trk->cluster[cl][id].entries = samplesInChunk;
1474 if(enc->codec_type == CODEC_TYPE_VIDEO) { 1516 if(enc->codec_type == CODEC_TYPE_VIDEO) {
1517 if (pkt->dts != pkt->pts)
1518 trk->hasBframes = 1;
1519 trk->cluster[cl][id].cts = pkt->pts - pkt->dts;
1475 trk->cluster[cl][id].key_frame = !!(pkt->flags & PKT_FLAG_KEY); 1520 trk->cluster[cl][id].key_frame = !!(pkt->flags & PKT_FLAG_KEY);
1476 if(trk->cluster[cl][id].key_frame) 1521 if(trk->cluster[cl][id].key_frame)
1477 trk->hasKeyframes = 1; 1522 trk->hasKeyframes = 1;
1478 } 1523 }
1479 trk->enc = enc; 1524 trk->enc = enc;