Mercurial > libavformat.hg
comparison flic.c @ 2423:91b61b76eb8c libavformat
simplify PTS handling
author | melanson |
---|---|
date | Tue, 04 Sep 2007 17:33:35 +0000 |
parents | 8a7b2fac0a98 |
children | d52c718e83f9 |
comparison
equal
deleted
inserted
replaced
2422:f3a8f7d55bd1 | 2423:91b61b76eb8c |
---|---|
37 #define FLIC_FILE_MAGIC_2 0xAF12 | 37 #define FLIC_FILE_MAGIC_2 0xAF12 |
38 #define FLIC_FILE_MAGIC_3 0xAF44 /* Flic Type for Extended FLX Format which | 38 #define FLIC_FILE_MAGIC_3 0xAF44 /* Flic Type for Extended FLX Format which |
39 originated in Dave's Targa Animator (DTA) */ | 39 originated in Dave's Targa Animator (DTA) */ |
40 #define FLIC_CHUNK_MAGIC_1 0xF1FA | 40 #define FLIC_CHUNK_MAGIC_1 0xF1FA |
41 #define FLIC_CHUNK_MAGIC_2 0xF5FA | 41 #define FLIC_CHUNK_MAGIC_2 0xF5FA |
42 #define FLIC_MC_PTS_INC 6000 /* pts increment for Magic Carpet game FLIs */ | 42 #define FLIC_MC_SPEED 5 /* speed for Magic Carpet game FLIs */ |
43 #define FLIC_DEFAULT_PTS_INC 6000 /* for FLIs that have 0 speed */ | 43 #define FLIC_DEFAULT_SPEED 5 /* for FLIs that have 0 speed */ |
44 | 44 |
45 #define FLIC_HEADER_SIZE 128 | 45 #define FLIC_HEADER_SIZE 128 |
46 #define FLIC_PREAMBLE_SIZE 6 | 46 #define FLIC_PREAMBLE_SIZE 6 |
47 | 47 |
48 typedef struct FlicDemuxContext { | 48 typedef struct FlicDemuxContext { |
49 int frame_pts_inc; | |
50 int64_t pts; | |
51 int video_stream_index; | 49 int video_stream_index; |
50 int frame_number; | |
52 } FlicDemuxContext; | 51 } FlicDemuxContext; |
53 | 52 |
54 static int flic_probe(AVProbeData *p) | 53 static int flic_probe(AVProbeData *p) |
55 { | 54 { |
56 int magic_number; | 55 int magic_number; |
72 unsigned char header[FLIC_HEADER_SIZE]; | 71 unsigned char header[FLIC_HEADER_SIZE]; |
73 AVStream *st; | 72 AVStream *st; |
74 int speed; | 73 int speed; |
75 int magic_number; | 74 int magic_number; |
76 | 75 |
77 flic->pts = 0; | 76 flic->frame_number = 0; |
78 | 77 |
79 /* load the whole header and pull out the width and height */ | 78 /* load the whole header and pull out the width and height */ |
80 if (get_buffer(pb, header, FLIC_HEADER_SIZE) != FLIC_HEADER_SIZE) | 79 if (get_buffer(pb, header, FLIC_HEADER_SIZE) != FLIC_HEADER_SIZE) |
81 return AVERROR(EIO); | 80 return AVERROR(EIO); |
82 | 81 |
83 magic_number = AV_RL16(&header[4]); | 82 magic_number = AV_RL16(&header[4]); |
84 speed = AV_RL32(&header[0x10]); | 83 speed = AV_RL32(&header[0x10]); |
84 if (speed == 0) | |
85 speed = FLIC_DEFAULT_SPEED; | |
85 | 86 |
86 /* initialize the decoder streams */ | 87 /* initialize the decoder streams */ |
87 st = av_new_stream(s, 0); | 88 st = av_new_stream(s, 0); |
88 if (!st) | 89 if (!st) |
89 return AVERROR(ENOMEM); | 90 return AVERROR(ENOMEM); |
106 /* send over the whole 128-byte FLIC header */ | 107 /* send over the whole 128-byte FLIC header */ |
107 st->codec->extradata_size = FLIC_HEADER_SIZE; | 108 st->codec->extradata_size = FLIC_HEADER_SIZE; |
108 st->codec->extradata = av_malloc(FLIC_HEADER_SIZE); | 109 st->codec->extradata = av_malloc(FLIC_HEADER_SIZE); |
109 memcpy(st->codec->extradata, header, FLIC_HEADER_SIZE); | 110 memcpy(st->codec->extradata, header, FLIC_HEADER_SIZE); |
110 | 111 |
111 av_set_pts_info(st, 33, 1, 90000); | |
112 | |
113 /* Time to figure out the framerate: If there is a FLIC chunk magic | 112 /* Time to figure out the framerate: If there is a FLIC chunk magic |
114 * number at offset 0x10, assume this is from the Bullfrog game, | 113 * number at offset 0x10, assume this is from the Bullfrog game, |
115 * Magic Carpet. */ | 114 * Magic Carpet. */ |
116 if (AV_RL16(&header[0x10]) == FLIC_CHUNK_MAGIC_1) { | 115 if (AV_RL16(&header[0x10]) == FLIC_CHUNK_MAGIC_1) { |
117 | 116 |
118 flic->frame_pts_inc = FLIC_MC_PTS_INC; | 117 av_set_pts_info(st, 64, FLIC_MC_SPEED, 70); |
119 | 118 |
120 /* rewind the stream since the first chunk is at offset 12 */ | 119 /* rewind the stream since the first chunk is at offset 12 */ |
121 url_fseek(pb, 12, SEEK_SET); | 120 url_fseek(pb, 12, SEEK_SET); |
122 | 121 |
123 /* send over abbreviated FLIC header chunk */ | 122 /* send over abbreviated FLIC header chunk */ |
125 st->codec->extradata_size = 12; | 124 st->codec->extradata_size = 12; |
126 st->codec->extradata = av_malloc(12); | 125 st->codec->extradata = av_malloc(12); |
127 memcpy(st->codec->extradata, header, 12); | 126 memcpy(st->codec->extradata, header, 12); |
128 | 127 |
129 } else if (magic_number == FLIC_FILE_MAGIC_1) { | 128 } else if (magic_number == FLIC_FILE_MAGIC_1) { |
130 /* | 129 av_set_pts_info(st, 64, speed, 70); |
131 * in this case, the speed (n) is number of 1/70s ticks between frames: | |
132 * | |
133 * pts n * frame # | |
134 * -------- = ----------- => pts = n * (90000/70) * frame # | |
135 * 90000 70 | |
136 * | |
137 * therefore, the frame pts increment = n * 1285.7 | |
138 */ | |
139 flic->frame_pts_inc = speed * 1285.7; | |
140 } else if ((magic_number == FLIC_FILE_MAGIC_2) || | 130 } else if ((magic_number == FLIC_FILE_MAGIC_2) || |
141 (magic_number == FLIC_FILE_MAGIC_3)) { | 131 (magic_number == FLIC_FILE_MAGIC_3)) { |
142 /* | 132 av_set_pts_info(st, 64, speed, 1000); |
143 * in this case, the speed (n) is number of milliseconds between frames: | |
144 * | |
145 * pts n * frame # | |
146 * -------- = ----------- => pts = n * 90 * frame # | |
147 * 90000 1000 | |
148 * | |
149 * therefore, the frame pts increment = n * 90 | |
150 */ | |
151 flic->frame_pts_inc = speed * 90; | |
152 } else { | 133 } else { |
153 av_log(s, AV_LOG_INFO, "Invalid or unsupported magic chunk in file\n"); | 134 av_log(s, AV_LOG_INFO, "Invalid or unsupported magic chunk in file\n"); |
154 return AVERROR_INVALIDDATA; | 135 return AVERROR_INVALIDDATA; |
155 } | 136 } |
156 | |
157 if (flic->frame_pts_inc == 0) | |
158 flic->frame_pts_inc = FLIC_DEFAULT_PTS_INC; | |
159 | 137 |
160 return 0; | 138 return 0; |
161 } | 139 } |
162 | 140 |
163 static int flic_read_packet(AVFormatContext *s, | 141 static int flic_read_packet(AVFormatContext *s, |
186 if (av_new_packet(pkt, size)) { | 164 if (av_new_packet(pkt, size)) { |
187 ret = AVERROR(EIO); | 165 ret = AVERROR(EIO); |
188 break; | 166 break; |
189 } | 167 } |
190 pkt->stream_index = flic->video_stream_index; | 168 pkt->stream_index = flic->video_stream_index; |
191 pkt->pts = flic->pts; | 169 pkt->pts = flic->frame_number++; |
192 pkt->pos = url_ftell(pb); | 170 pkt->pos = url_ftell(pb); |
193 memcpy(pkt->data, preamble, FLIC_PREAMBLE_SIZE); | 171 memcpy(pkt->data, preamble, FLIC_PREAMBLE_SIZE); |
194 ret = get_buffer(pb, pkt->data + FLIC_PREAMBLE_SIZE, | 172 ret = get_buffer(pb, pkt->data + FLIC_PREAMBLE_SIZE, |
195 size - FLIC_PREAMBLE_SIZE); | 173 size - FLIC_PREAMBLE_SIZE); |
196 if (ret != size - FLIC_PREAMBLE_SIZE) { | 174 if (ret != size - FLIC_PREAMBLE_SIZE) { |
197 av_free_packet(pkt); | 175 av_free_packet(pkt); |
198 ret = AVERROR(EIO); | 176 ret = AVERROR(EIO); |
199 } | 177 } |
200 flic->pts += flic->frame_pts_inc; | |
201 packet_read = 1; | 178 packet_read = 1; |
202 } else { | 179 } else { |
203 /* not interested in this chunk */ | 180 /* not interested in this chunk */ |
204 url_fseek(pb, size - 6, SEEK_CUR); | 181 url_fseek(pb, size - 6, SEEK_CUR); |
205 } | 182 } |