Mercurial > libavformat.hg
annotate flic.c @ 5200:cd884511ec8b libavformat
Make packet interleaving in the muxer not scan through the whole
buffer when simply appending at the end works.
Much faster if one stream ends prematurely.
Fixes issue1379.
author | michael |
---|---|
date | Wed, 16 Sep 2009 00:59:15 +0000 |
parents | 49c1d3b27727 |
children | 536e5527c1e0 |
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 /** | |
4331
49c1d3b27727
Use full internal pathname in doxygen @file directives.
diego
parents:
4201
diff
changeset
|
23 * @file libavformat/flic.c |
315 | 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 | |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
3583
diff
changeset
|
34 #include "libavutil/intreadwrite.h" |
315 | 35 #include "avformat.h" |
36 | |
37 #define FLIC_FILE_MAGIC_1 0xAF11 | |
38 #define FLIC_FILE_MAGIC_2 0xAF12 | |
885 | 39 #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
|
40 originated in Dave's Targa Animator (DTA) */ |
315 | 41 #define FLIC_CHUNK_MAGIC_1 0xF1FA |
42 #define FLIC_CHUNK_MAGIC_2 0xF5FA | |
2423 | 43 #define FLIC_MC_SPEED 5 /* speed for Magic Carpet game FLIs */ |
44 #define FLIC_DEFAULT_SPEED 5 /* for FLIs that have 0 speed */ | |
315 | 45 |
46 #define FLIC_HEADER_SIZE 128 | |
47 #define FLIC_PREAMBLE_SIZE 6 | |
48 | |
49 typedef struct FlicDemuxContext { | |
50 int video_stream_index; | |
2423 | 51 int frame_number; |
315 | 52 } FlicDemuxContext; |
53 | |
54 static int flic_probe(AVProbeData *p) | |
55 { | |
56 int magic_number; | |
57 | |
3583 | 58 if(p->buf_size < FLIC_HEADER_SIZE) |
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 | |
3583 | 67 if(AV_RL16(&p->buf[0x10]) != FLIC_CHUNK_MAGIC_1){ |
68 if(AV_RL32(&p->buf[0x10]) > 2000) | |
69 return 0; | |
70 } | |
71 | |
72 if( AV_RL16(&p->buf[0x08]) > 4096 | |
73 || AV_RL16(&p->buf[0x0A]) > 4096) | |
74 return 0; | |
75 | |
76 | |
315 | 77 return AVPROBE_SCORE_MAX; |
78 } | |
79 | |
80 static int flic_read_header(AVFormatContext *s, | |
81 AVFormatParameters *ap) | |
82 { | |
2006 | 83 FlicDemuxContext *flic = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2423
diff
changeset
|
84 ByteIOContext *pb = s->pb; |
315 | 85 unsigned char header[FLIC_HEADER_SIZE]; |
86 AVStream *st; | |
87 int speed; | |
88 int magic_number; | |
89 | |
2423 | 90 flic->frame_number = 0; |
315 | 91 |
92 /* load the whole header and pull out the width and height */ | |
93 if (get_buffer(pb, header, FLIC_HEADER_SIZE) != FLIC_HEADER_SIZE) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
94 return AVERROR(EIO); |
315 | 95 |
1673 | 96 magic_number = AV_RL16(&header[4]); |
97 speed = AV_RL32(&header[0x10]); | |
2423 | 98 if (speed == 0) |
99 speed = FLIC_DEFAULT_SPEED; | |
315 | 100 |
101 /* initialize the decoder streams */ | |
102 st = av_new_stream(s, 0); | |
103 if (!st) | |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2006
diff
changeset
|
104 return AVERROR(ENOMEM); |
315 | 105 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
|
106 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
|
107 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
|
108 st->codec->codec_tag = 0; /* no fourcc */ |
1673 | 109 st->codec->width = AV_RL16(&header[0x08]); |
110 st->codec->height = AV_RL16(&header[0x0A]); | |
315 | 111 |
2385
8a7b2fac0a98
Try size 640x480 for FLC files which don't specify their size.
aurel
parents:
2274
diff
changeset
|
112 if (!st->codec->width || !st->codec->height) { |
8a7b2fac0a98
Try size 640x480 for FLC files which don't specify their size.
aurel
parents:
2274
diff
changeset
|
113 /* Ugly hack needed for the following sample: */ |
8a7b2fac0a98
Try size 640x480 for FLC files which don't specify their size.
aurel
parents:
2274
diff
changeset
|
114 /* http://samples.mplayerhq.hu/fli-flc/fli-bugs/specular.flc */ |
8a7b2fac0a98
Try size 640x480 for FLC files which don't specify their size.
aurel
parents:
2274
diff
changeset
|
115 av_log(s, AV_LOG_WARNING, |
8a7b2fac0a98
Try size 640x480 for FLC files which don't specify their size.
aurel
parents:
2274
diff
changeset
|
116 "File with no specified width/height. Trying 640x480.\n"); |
8a7b2fac0a98
Try size 640x480 for FLC files which don't specify their size.
aurel
parents:
2274
diff
changeset
|
117 st->codec->width = 640; |
8a7b2fac0a98
Try size 640x480 for FLC files which don't specify their size.
aurel
parents:
2274
diff
changeset
|
118 st->codec->height = 480; |
8a7b2fac0a98
Try size 640x480 for FLC files which don't specify their size.
aurel
parents:
2274
diff
changeset
|
119 } |
315 | 120 |
121 /* 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
|
122 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
|
123 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
|
124 memcpy(st->codec->extradata, header, FLIC_HEADER_SIZE); |
315 | 125 |
126 /* Time to figure out the framerate: If there is a FLIC chunk magic | |
127 * number at offset 0x10, assume this is from the Bullfrog game, | |
128 * Magic Carpet. */ | |
1673 | 129 if (AV_RL16(&header[0x10]) == FLIC_CHUNK_MAGIC_1) { |
315 | 130 |
2423 | 131 av_set_pts_info(st, 64, FLIC_MC_SPEED, 70); |
315 | 132 |
133 /* rewind the stream since the first chunk is at offset 12 */ | |
134 url_fseek(pb, 12, SEEK_SET); | |
135 | |
136 /* 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
|
137 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
|
138 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
|
139 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
|
140 memcpy(st->codec->extradata, header, 12); |
315 | 141 |
142 } else if (magic_number == FLIC_FILE_MAGIC_1) { | |
2423 | 143 av_set_pts_info(st, 64, speed, 70); |
864
00a3ba030166
support for FLX and DTA extensions in the FLIC format, courtesy of
melanson
parents:
820
diff
changeset
|
144 } 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
|
145 (magic_number == FLIC_FILE_MAGIC_3)) { |
2423 | 146 av_set_pts_info(st, 64, speed, 1000); |
1801 | 147 } else { |
148 av_log(s, AV_LOG_INFO, "Invalid or unsupported magic chunk in file\n"); | |
315 | 149 return AVERROR_INVALIDDATA; |
1801 | 150 } |
315 | 151 |
152 return 0; | |
153 } | |
154 | |
155 static int flic_read_packet(AVFormatContext *s, | |
156 AVPacket *pkt) | |
157 { | |
2006 | 158 FlicDemuxContext *flic = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2423
diff
changeset
|
159 ByteIOContext *pb = s->pb; |
315 | 160 int packet_read = 0; |
161 unsigned int size; | |
162 int magic; | |
163 int ret = 0; | |
164 unsigned char preamble[FLIC_PREAMBLE_SIZE]; | |
165 | |
166 while (!packet_read) { | |
167 | |
168 if ((ret = get_buffer(pb, preamble, FLIC_PREAMBLE_SIZE)) != | |
169 FLIC_PREAMBLE_SIZE) { | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
170 ret = AVERROR(EIO); |
315 | 171 break; |
172 } | |
173 | |
1673 | 174 size = AV_RL32(&preamble[0]); |
175 magic = AV_RL16(&preamble[4]); | |
315 | 176 |
643 | 177 if (((magic == FLIC_CHUNK_MAGIC_1) || (magic == FLIC_CHUNK_MAGIC_2)) && size > FLIC_PREAMBLE_SIZE) { |
315 | 178 if (av_new_packet(pkt, size)) { |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
179 ret = AVERROR(EIO); |
315 | 180 break; |
181 } | |
182 pkt->stream_index = flic->video_stream_index; | |
2423 | 183 pkt->pts = flic->frame_number++; |
885 | 184 pkt->pos = url_ftell(pb); |
315 | 185 memcpy(pkt->data, preamble, FLIC_PREAMBLE_SIZE); |
885 | 186 ret = get_buffer(pb, pkt->data + FLIC_PREAMBLE_SIZE, |
315 | 187 size - FLIC_PREAMBLE_SIZE); |
188 if (ret != size - FLIC_PREAMBLE_SIZE) { | |
189 av_free_packet(pkt); | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
190 ret = AVERROR(EIO); |
315 | 191 } |
192 packet_read = 1; | |
193 } else { | |
194 /* not interested in this chunk */ | |
195 url_fseek(pb, size - 6, SEEK_CUR); | |
196 } | |
197 } | |
198 | |
199 return ret; | |
200 } | |
201 | |
1169 | 202 AVInputFormat flic_demuxer = { |
315 | 203 "flic", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
2771
diff
changeset
|
204 NULL_IF_CONFIG_SMALL("FLI/FLC/FLX animation format"), |
315 | 205 sizeof(FlicDemuxContext), |
206 flic_probe, | |
207 flic_read_header, | |
208 flic_read_packet, | |
209 }; |