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 }