Mercurial > libavformat.hg
comparison mov.c @ 928:2244fbe4a883 libavformat
simplify timebase if possible
ignore edit lists instead of always failing
author | michael |
---|---|
date | Thu, 02 Feb 2006 20:56:35 +0000 |
parents | 97a083dcfb7b |
children | 4e7a66723f1d |
comparison
equal
deleted
inserted
replaced
927:a28b47d5238a | 928:2244fbe4a883 |
---|---|
60 #include <fcntl.h> | 60 #include <fcntl.h> |
61 #endif | 61 #endif |
62 | 62 |
63 #include "qtpalette.h" | 63 #include "qtpalette.h" |
64 | 64 |
65 | |
66 #undef NDEBUG | |
67 #include <assert.h> | |
65 | 68 |
66 /* Allows seeking (MOV_SPLIT_CHUNKS should also be defined) */ | 69 /* Allows seeking (MOV_SPLIT_CHUNKS should also be defined) */ |
67 #define MOV_SEEK | 70 #define MOV_SEEK |
68 | 71 |
69 /* allows chunk splitting - should work now... */ | 72 /* allows chunk splitting - should work now... */ |
277 long sample_count; | 280 long sample_count; |
278 long *sample_sizes; | 281 long *sample_sizes; |
279 long keyframe_count; | 282 long keyframe_count; |
280 long *keyframes; | 283 long *keyframes; |
281 int time_scale; | 284 int time_scale; |
285 int time_rate; | |
282 long current_sample; | 286 long current_sample; |
283 long left_in_chunk; /* how many samples before next chunk */ | 287 long left_in_chunk; /* how many samples before next chunk */ |
284 MOV_esds_t esds; | 288 MOV_esds_t esds; |
285 } MOVStreamContext; | 289 } MOVStreamContext; |
286 | 290 |
718 | 722 |
719 (version==1)?get_be64(pb):get_be32(pb); /* creation time */ | 723 (version==1)?get_be64(pb):get_be32(pb); /* creation time */ |
720 (version==1)?get_be64(pb):get_be32(pb); /* modification time */ | 724 (version==1)?get_be64(pb):get_be32(pb); /* modification time */ |
721 | 725 |
722 c->streams[c->fc->nb_streams-1]->time_scale = get_be32(pb); | 726 c->streams[c->fc->nb_streams-1]->time_scale = get_be32(pb); |
723 av_set_pts_info(c->fc->streams[c->fc->nb_streams-1], 64, 1, c->streams[c->fc->nb_streams-1]->time_scale); | |
724 | 727 |
725 #ifdef DEBUG | 728 #ifdef DEBUG |
726 av_log(NULL, AV_LOG_DEBUG, "track[%i].time_scale = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->time_scale); /* time scale */ | 729 av_log(NULL, AV_LOG_DEBUG, "track[%i].time_scale = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->time_scale); /* time scale */ |
727 #endif | 730 #endif |
728 c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */ | 731 c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */ |
1413 } | 1416 } |
1414 | 1417 |
1415 static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) | 1418 static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) |
1416 { | 1419 { |
1417 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; | 1420 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; |
1418 //MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; | 1421 MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; |
1419 unsigned int i, entries; | 1422 unsigned int i, entries; |
1420 int64_t duration=0; | 1423 int64_t duration=0; |
1421 int64_t total_sample_count=0; | 1424 int64_t total_sample_count=0; |
1422 | 1425 |
1423 print_atom("stts", atom); | 1426 print_atom("stts", atom); |
1426 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ | 1429 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ |
1427 entries = get_be32(pb); | 1430 entries = get_be32(pb); |
1428 if(entries >= UINT_MAX / sizeof(Time2Sample)) | 1431 if(entries >= UINT_MAX / sizeof(Time2Sample)) |
1429 return -1; | 1432 return -1; |
1430 | 1433 |
1431 c->streams[c->fc->nb_streams-1]->stts_count = entries; | 1434 sc->stts_count = entries; |
1432 c->streams[c->fc->nb_streams-1]->stts_data = av_malloc(entries * sizeof(Time2Sample)); | 1435 sc->stts_data = av_malloc(entries * sizeof(Time2Sample)); |
1433 | 1436 |
1434 #ifdef DEBUG | 1437 #ifdef DEBUG |
1435 av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries); | 1438 av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries); |
1436 #endif | 1439 #endif |
1440 | |
1441 sc->time_rate=0; | |
1442 | |
1437 for(i=0; i<entries; i++) { | 1443 for(i=0; i<entries; i++) { |
1438 int sample_duration; | 1444 int sample_duration; |
1439 int sample_count; | 1445 int sample_count; |
1440 | 1446 |
1441 sample_count=get_be32(pb); | 1447 sample_count=get_be32(pb); |
1442 sample_duration = get_be32(pb); | 1448 sample_duration = get_be32(pb); |
1443 c->streams[c->fc->nb_streams - 1]->stts_data[i].count= sample_count; | 1449 sc->stts_data[i].count= sample_count; |
1444 c->streams[c->fc->nb_streams - 1]->stts_data[i].duration= sample_duration; | 1450 sc->stts_data[i].duration= sample_duration; |
1451 | |
1452 sc->time_rate= ff_gcd(sc->time_rate, sample_duration); | |
1445 | 1453 |
1446 #ifdef DEBUG | 1454 #ifdef DEBUG |
1447 av_log(NULL, AV_LOG_DEBUG, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration); | 1455 av_log(NULL, AV_LOG_DEBUG, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration); |
1448 #endif | 1456 #endif |
1449 duration+=sample_duration*sample_count; | 1457 duration+=sample_duration*sample_count; |
1862 s->nb_streams--; | 1870 s->nb_streams--; |
1863 } else | 1871 } else |
1864 i++; | 1872 i++; |
1865 } | 1873 } |
1866 for(i=0; i<s->nb_streams;i++) { | 1874 for(i=0; i<s->nb_streams;i++) { |
1867 MOVStreamContext *sc; | 1875 MOVStreamContext *sc = (MOVStreamContext *)s->streams[i]->priv_data; |
1868 sc = (MOVStreamContext *)s->streams[i]->priv_data; | 1876 |
1877 if(!sc->time_rate) | |
1878 sc->time_rate=1; | |
1879 av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale); | |
1880 | |
1881 assert(s->streams[i]->duration % sc->time_rate == 0); | |
1882 s->streams[i]->duration /= sc->time_rate; | |
1883 | |
1869 sc->ffindex = i; | 1884 sc->ffindex = i; |
1870 sc->is_ff_stream = 1; | 1885 sc->is_ff_stream = 1; |
1871 } | 1886 } |
1872 #endif | 1887 #endif |
1873 #ifdef DEBUG | 1888 #ifdef DEBUG |
1880 /* XXX:remove useless commented code sometime */ | 1895 /* XXX:remove useless commented code sometime */ |
1881 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) | 1896 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) |
1882 { | 1897 { |
1883 MOVContext *mov = (MOVContext *) s->priv_data; | 1898 MOVContext *mov = (MOVContext *) s->priv_data; |
1884 MOVStreamContext *sc; | 1899 MOVStreamContext *sc; |
1900 AVStream *st; | |
1885 int64_t offset = INT64_MAX; | 1901 int64_t offset = INT64_MAX; |
1886 int64_t best_dts = INT64_MAX; | 1902 int64_t best_dts = INT64_MAX; |
1887 int i, a, b, m; | 1903 int i, a, b, m; |
1888 int size; | 1904 int size; |
1889 int idx; | 1905 int idx; |
2107 duration = sc->ctts_data[sc->sample_to_ctime_index].duration; | 2123 duration = sc->ctts_data[sc->sample_to_ctime_index].duration; |
2108 } | 2124 } |
2109 pts = dts + duration; | 2125 pts = dts + duration; |
2110 }else | 2126 }else |
2111 pts = dts; | 2127 pts = dts; |
2112 pkt->pts = pts; | 2128 |
2113 pkt->dts = dts; | 2129 st= s->streams[ sc->ffindex ]; |
2130 assert(pts % st->time_base.num == 0); | |
2131 assert(dts % st->time_base.num == 0); | |
2132 | |
2133 pkt->pts = pts / st->time_base.num; | |
2134 pkt->dts = dts / st->time_base.num; | |
2114 #ifdef DEBUG | 2135 #ifdef DEBUG |
2115 av_log(NULL, AV_LOG_DEBUG, "stream #%d smp #%ld dts = %lld pts = %lld (smp:%ld time:%lld idx:%d ent:%d count:%d dur:%d)\n" | 2136 av_log(NULL, AV_LOG_DEBUG, "stream #%d smp #%ld dts = %lld pts = %lld (smp:%ld time:%lld idx:%d ent:%d count:%d dur:%d)\n" |
2116 , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts | 2137 , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts |
2117 , sc->sample_to_time_sample | 2138 , sc->sample_to_time_sample |
2118 , sc->sample_to_time_time | 2139 , sc->sample_to_time_time |
2158 av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index); | 2179 av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index); |
2159 return -1; | 2180 return -1; |
2160 } | 2181 } |
2161 sc = mov->streams[mov_idx]; | 2182 sc = mov->streams[mov_idx]; |
2162 | 2183 |
2184 sample_time *= s->streams[stream_index]->time_base.num; | |
2185 | |
2163 // Step 1. Find the edit that contains the requested time (elst) | 2186 // Step 1. Find the edit that contains the requested time (elst) |
2164 if (sc->edit_count) { | 2187 if (sc->edit_count && 0) { |
2165 // FIXME should handle edit list | 2188 // FIXME should handle edit list |
2166 av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count); | 2189 av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count); |
2167 return -1; | 2190 return -1; |
2168 } | 2191 } |
2169 | 2192 |