Mercurial > libavformat.hg
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; |