Mercurial > libavformat.hg
annotate flic.c @ 1779:de2cf54eb68f libavformat
mxf aes decryption support, patch by Reimar, simplified to only look for first crypto context, will be extended once we get files with multiple cryptocontext, and hope that they won't have broken container ul
author | bcoudurier |
---|---|
date | Sun, 11 Feb 2007 12:50:33 +0000 |
parents | a782462e2497 |
children | 9cd35d039830 |
rev | line source |
---|---|
315 | 1 /* |
2 * FLI/FLC Animation File Demuxer | |
3 * Copyright (c) 2003 The ffmpeg Project | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
315 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
315 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
315 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
885
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
315 | 20 */ |
21 | |
22 /** | |
23 * @file flic.c | |
24 * FLI/FLC file demuxer | |
25 * by Mike Melanson (melanson@pcisys.net) | |
26 * for more information on the .fli/.flc file format and all of its many | |
27 * variations, visit: | |
28 * http://www.compuphase.com/flic.htm | |
29 * | |
30 * This demuxer handles standard 0xAF11- and 0xAF12-type FLIs. It also | |
31 * handles special FLIs from the PC game "Magic Carpet". | |
32 */ | |
33 | |
34 #include "avformat.h" | |
35 | |
36 #define FLIC_FILE_MAGIC_1 0xAF11 | |
37 #define FLIC_FILE_MAGIC_2 0xAF12 | |
885 | 38 #define FLIC_FILE_MAGIC_3 0xAF44 /* Flic Type for Extended FLX Format which |
864
00a3ba030166
support for FLX and DTA extensions in the FLIC format, courtesy of
melanson
parents:
820
diff
changeset
|
39 originated in Dave's Targa Animator (DTA) */ |
315 | 40 #define FLIC_CHUNK_MAGIC_1 0xF1FA |
41 #define FLIC_CHUNK_MAGIC_2 0xF5FA | |
42 #define FLIC_MC_PTS_INC 6000 /* pts increment for Magic Carpet game FLIs */ | |
43 #define FLIC_DEFAULT_PTS_INC 6000 /* for FLIs that have 0 speed */ | |
44 | |
45 #define FLIC_HEADER_SIZE 128 | |
46 #define FLIC_PREAMBLE_SIZE 6 | |
47 | |
48 typedef struct FlicDemuxContext { | |
49 int frame_pts_inc; | |
50 int64_t pts; | |
51 int video_stream_index; | |
52 } FlicDemuxContext; | |
53 | |
54 static int flic_probe(AVProbeData *p) | |
55 { | |
56 int magic_number; | |
57 | |
58 if (p->buf_size < 6) | |
59 return 0; | |
60 | |
1673 | 61 magic_number = AV_RL16(&p->buf[4]); |
315 | 62 if ((magic_number != FLIC_FILE_MAGIC_1) && |
864
00a3ba030166
support for FLX and DTA extensions in the FLIC format, courtesy of
melanson
parents:
820
diff
changeset
|
63 (magic_number != FLIC_FILE_MAGIC_2) && |
00a3ba030166
support for FLX and DTA extensions in the FLIC format, courtesy of
melanson
parents:
820
diff
changeset
|
64 (magic_number != FLIC_FILE_MAGIC_3)) |
315 | 65 return 0; |
66 | |
67 return AVPROBE_SCORE_MAX; | |
68 } | |
69 | |
70 static int flic_read_header(AVFormatContext *s, | |
71 AVFormatParameters *ap) | |
72 { | |
73 FlicDemuxContext *flic = (FlicDemuxContext *)s->priv_data; | |
74 ByteIOContext *pb = &s->pb; | |
75 unsigned char header[FLIC_HEADER_SIZE]; | |
76 AVStream *st; | |
77 int speed; | |
78 int magic_number; | |
79 | |
80 flic->pts = 0; | |
81 | |
82 /* load the whole header and pull out the width and height */ | |
83 if (get_buffer(pb, header, FLIC_HEADER_SIZE) != FLIC_HEADER_SIZE) | |
482 | 84 return AVERROR_IO; |
315 | 85 |
1673 | 86 magic_number = AV_RL16(&header[4]); |
87 speed = AV_RL32(&header[0x10]); | |
315 | 88 |
89 /* initialize the decoder streams */ | |
90 st = av_new_stream(s, 0); | |
91 if (!st) | |
92 return AVERROR_NOMEM; | |
93 flic->video_stream_index = st->index; | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
94 st->codec->codec_type = CODEC_TYPE_VIDEO; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
95 st->codec->codec_id = CODEC_ID_FLIC; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
96 st->codec->codec_tag = 0; /* no fourcc */ |
1673 | 97 st->codec->width = AV_RL16(&header[0x08]); |
98 st->codec->height = AV_RL16(&header[0x0A]); | |
315 | 99 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
100 if (!st->codec->width || !st->codec->height) |
315 | 101 return AVERROR_INVALIDDATA; |
102 | |
103 /* send over the whole 128-byte FLIC header */ | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
104 st->codec->extradata_size = FLIC_HEADER_SIZE; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
105 st->codec->extradata = av_malloc(FLIC_HEADER_SIZE); |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
106 memcpy(st->codec->extradata, header, FLIC_HEADER_SIZE); |
315 | 107 |
462
b69898ffc92a
move time_base (pts_num/pts_den) from AVFormatContext -> AVStream
michael
parents:
386
diff
changeset
|
108 av_set_pts_info(st, 33, 1, 90000); |
315 | 109 |
110 /* Time to figure out the framerate: If there is a FLIC chunk magic | |
111 * number at offset 0x10, assume this is from the Bullfrog game, | |
112 * Magic Carpet. */ | |
1673 | 113 if (AV_RL16(&header[0x10]) == FLIC_CHUNK_MAGIC_1) { |
315 | 114 |
115 flic->frame_pts_inc = FLIC_MC_PTS_INC; | |
116 | |
117 /* rewind the stream since the first chunk is at offset 12 */ | |
118 url_fseek(pb, 12, SEEK_SET); | |
119 | |
120 /* send over abbreviated FLIC header chunk */ | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
121 av_free(st->codec->extradata); |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
122 st->codec->extradata_size = 12; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
123 st->codec->extradata = av_malloc(12); |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
124 memcpy(st->codec->extradata, header, 12); |
315 | 125 |
126 } else if (magic_number == FLIC_FILE_MAGIC_1) { | |
127 /* | |
128 * in this case, the speed (n) is number of 1/70s ticks between frames: | |
129 * | |
130 * pts n * frame # | |
131 * -------- = ----------- => pts = n * (90000/70) * frame # | |
132 * 90000 70 | |
133 * | |
134 * therefore, the frame pts increment = n * 1285.7 | |
135 */ | |
136 flic->frame_pts_inc = speed * 1285.7; | |
864
00a3ba030166
support for FLX and DTA extensions in the FLIC format, courtesy of
melanson
parents:
820
diff
changeset
|
137 } else if ((magic_number == FLIC_FILE_MAGIC_2) || |
00a3ba030166
support for FLX and DTA extensions in the FLIC format, courtesy of
melanson
parents:
820
diff
changeset
|
138 (magic_number == FLIC_FILE_MAGIC_3)) { |
315 | 139 /* |
140 * in this case, the speed (n) is number of milliseconds between frames: | |
141 * | |
142 * pts n * frame # | |
143 * -------- = ----------- => pts = n * 90 * frame # | |
144 * 90000 1000 | |
145 * | |
146 * therefore, the frame pts increment = n * 90 | |
147 */ | |
148 flic->frame_pts_inc = speed * 90; | |
149 } else | |
150 return AVERROR_INVALIDDATA; | |
151 | |
152 if (flic->frame_pts_inc == 0) | |
153 flic->frame_pts_inc = FLIC_DEFAULT_PTS_INC; | |
154 | |
155 return 0; | |
156 } | |
157 | |
158 static int flic_read_packet(AVFormatContext *s, | |
159 AVPacket *pkt) | |
160 { | |
161 FlicDemuxContext *flic = (FlicDemuxContext *)s->priv_data; | |
162 ByteIOContext *pb = &s->pb; | |
163 int packet_read = 0; | |
164 unsigned int size; | |
165 int magic; | |
166 int ret = 0; | |
167 unsigned char preamble[FLIC_PREAMBLE_SIZE]; | |
168 | |
169 while (!packet_read) { | |
170 | |
171 if ((ret = get_buffer(pb, preamble, FLIC_PREAMBLE_SIZE)) != | |
172 FLIC_PREAMBLE_SIZE) { | |
482 | 173 ret = AVERROR_IO; |
315 | 174 break; |
175 } | |
176 | |
1673 | 177 size = AV_RL32(&preamble[0]); |
178 magic = AV_RL16(&preamble[4]); | |
315 | 179 |
643 | 180 if (((magic == FLIC_CHUNK_MAGIC_1) || (magic == FLIC_CHUNK_MAGIC_2)) && size > FLIC_PREAMBLE_SIZE) { |
315 | 181 if (av_new_packet(pkt, size)) { |
482 | 182 ret = AVERROR_IO; |
315 | 183 break; |
184 } | |
185 pkt->stream_index = flic->video_stream_index; | |
186 pkt->pts = flic->pts; | |
885 | 187 pkt->pos = url_ftell(pb); |
315 | 188 memcpy(pkt->data, preamble, FLIC_PREAMBLE_SIZE); |
885 | 189 ret = get_buffer(pb, pkt->data + FLIC_PREAMBLE_SIZE, |
315 | 190 size - FLIC_PREAMBLE_SIZE); |
191 if (ret != size - FLIC_PREAMBLE_SIZE) { | |
192 av_free_packet(pkt); | |
482 | 193 ret = AVERROR_IO; |
315 | 194 } |
195 flic->pts += flic->frame_pts_inc; | |
196 packet_read = 1; | |
197 } else { | |
198 /* not interested in this chunk */ | |
199 url_fseek(pb, size - 6, SEEK_CUR); | |
200 } | |
201 } | |
202 | |
203 return ret; | |
204 } | |
205 | |
206 static int flic_read_close(AVFormatContext *s) | |
207 { | |
208 // FlicDemuxContext *flic = (FlicDemuxContext *)s->priv_data; | |
209 | |
210 return 0; | |
211 } | |
212 | |
1169 | 213 AVInputFormat flic_demuxer = { |
315 | 214 "flic", |
864
00a3ba030166
support for FLX and DTA extensions in the FLIC format, courtesy of
melanson
parents:
820
diff
changeset
|
215 "FLI/FLC/FLX animation format", |
315 | 216 sizeof(FlicDemuxContext), |
217 flic_probe, | |
218 flic_read_header, | |
219 flic_read_packet, | |
220 flic_read_close, | |
221 }; |