X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fidcin.c;h=ca67e69101c1f04c85bad6051f727a4f147e019c;hb=5a9ee3152b6e69166c7819f07a4992bd22052917;hp=ce56d2a8a5716628dbc0419d2b4434bcf39c5925;hpb=01f4895c682a1752bf6d138ffb0628470e16b85a;p=ffmpeg diff --git a/libavformat/idcin.c b/libavformat/idcin.c index ce56d2a8a57..ca67e69101c 100644 --- a/libavformat/idcin.c +++ b/libavformat/idcin.c @@ -1,26 +1,28 @@ /* - * Id Quake II CIN File Demuxer + * id Quake II CIN File Demuxer * Copyright (c) 2003 The ffmpeg Project * - * This library is free software; you can redistribute it and/or + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file idcin.c - * Id Quake II CIN file demuxer by Mike Melanson (melanson@pcisys.net) - * For more information about the Id CIN format, visit: + * @file + * id Quake II CIN file demuxer by Mike Melanson (melanson@pcisys.net) + * For more information about the id CIN format, visit: * http://www.csse.monash.edu.au/~timf/ * * CIN is a somewhat quirky and ill-defined format. Here are some notes @@ -51,7 +53,7 @@ * audio frame #2: 787 * (bytes/sample) * (# channels) bytes in frame * audio frame #3: 788 * (bytes/sample) * (# channels) bytes in frame * - * Finally, not all Id CIN creation tools agree on the resolution of the + * Finally, not all id CIN creation tools agree on the resolution of the * color palette, apparently. Some creation tools specify red, green, and * blue palette components in terms of 6-bit VGA color DAC values which * range from 0..63. Other tools specify the RGB components as full 8-bit @@ -66,10 +68,11 @@ * transmitting them to the video decoder */ +#include "libavutil/intreadwrite.h" #include "avformat.h" #define HUFFMAN_TABLE_SIZE (64 * 1024) -#define FRAME_PTS_INC (90000 / 14) +#define IDCIN_FPS 14 typedef struct IdcinDemuxContext { int video_stream_index; @@ -83,8 +86,6 @@ typedef struct IdcinDemuxContext { int audio_present; int64_t pts; - - AVPaletteControl palctrl; } IdcinDemuxContext; static int idcin_probe(AVProbeData *p) @@ -92,7 +93,7 @@ static int idcin_probe(AVProbeData *p) unsigned int number; /* - * This is what you could call a "probabilistic" file check: Id CIN + * This is what you could call a "probabilistic" file check: id CIN * files don't have a definite file signature. In lieu of such a marker, * perform sanity checks on the 5 32-bit header fields: * width, height: greater than 0, less than or equal to 1024 @@ -102,32 +103,33 @@ static int idcin_probe(AVProbeData *p) * audio channels: 0 for no audio, or 1 or 2 */ - /* cannot proceed without 20 bytes */ + /* check we have enough data to do all checks, otherwise the + 0-padding may cause a wrong recognition */ if (p->buf_size < 20) return 0; /* check the video width */ - number = LE_32(&p->buf[0]); + number = AV_RL32(&p->buf[0]); if ((number == 0) || (number > 1024)) return 0; /* check the video height */ - number = LE_32(&p->buf[4]); + number = AV_RL32(&p->buf[4]); if ((number == 0) || (number > 1024)) return 0; /* check the audio sample rate */ - number = LE_32(&p->buf[8]); + number = AV_RL32(&p->buf[8]); if ((number != 0) && ((number < 8000) | (number > 48000))) return 0; /* check the audio bytes/sample */ - number = LE_32(&p->buf[12]); + number = AV_RL32(&p->buf[12]); if (number > 2) return 0; /* check the audio channels */ - number = LE_32(&p->buf[16]); + number = AV_RL32(&p->buf[16]); if (number > 2) return 0; @@ -138,25 +140,25 @@ static int idcin_probe(AVProbeData *p) static int idcin_read_header(AVFormatContext *s, AVFormatParameters *ap) { - ByteIOContext *pb = &s->pb; - IdcinDemuxContext *idcin = (IdcinDemuxContext *)s->priv_data; + AVIOContext *pb = s->pb; + IdcinDemuxContext *idcin = s->priv_data; AVStream *st; unsigned int width, height; unsigned int sample_rate, bytes_per_sample, channels; /* get the 5 header parameters */ - width = get_le32(pb); - height = get_le32(pb); - sample_rate = get_le32(pb); - bytes_per_sample = get_le32(pb); - channels = get_le32(pb); + width = avio_rl32(pb); + height = avio_rl32(pb); + sample_rate = avio_rl32(pb); + bytes_per_sample = avio_rl32(pb); + channels = avio_rl32(pb); st = av_new_stream(s, 0); if (!st) - return AVERROR_NOMEM; - av_set_pts_info(st, 33, 1, 90000); + return AVERROR(ENOMEM); + av_set_pts_info(st, 33, 1, IDCIN_FPS); idcin->video_stream_index = st->index; - st->codec->codec_type = CODEC_TYPE_VIDEO; + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_IDCIN; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = width; @@ -165,25 +167,23 @@ static int idcin_read_header(AVFormatContext *s, /* load up the Huffman tables into extradata */ st->codec->extradata_size = HUFFMAN_TABLE_SIZE; st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE); - if (get_buffer(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) != + if (avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) != HUFFMAN_TABLE_SIZE) - return AVERROR_IO; - /* save a reference in order to transport the palette */ - st->codec->palctrl = &idcin->palctrl; + return AVERROR(EIO); /* if sample rate is 0, assume no audio */ if (sample_rate) { idcin->audio_present = 1; st = av_new_stream(s, 0); if (!st) - return AVERROR_NOMEM; - av_set_pts_info(st, 33, 1, 90000); + return AVERROR(ENOMEM); + av_set_pts_info(st, 33, 1, IDCIN_FPS); idcin->audio_stream_index = st->index; - st->codec->codec_type = CODEC_TYPE_AUDIO; + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = 1; st->codec->channels = channels; st->codec->sample_rate = sample_rate; - st->codec->bits_per_sample = bytes_per_sample * 8; + st->codec->bits_per_coded_sample = bytes_per_sample * 8; st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels; st->codec->block_align = bytes_per_sample * channels; if (bytes_per_sample == 1) @@ -216,25 +216,25 @@ static int idcin_read_packet(AVFormatContext *s, int ret; unsigned int command; unsigned int chunk_size; - IdcinDemuxContext *idcin = (IdcinDemuxContext *)s->priv_data; - ByteIOContext *pb = &s->pb; + IdcinDemuxContext *idcin = s->priv_data; + AVIOContext *pb = s->pb; int i; int palette_scale; unsigned char r, g, b; unsigned char palette_buffer[768]; + uint32_t palette[256]; - if (url_feof(&s->pb)) - return AVERROR_IO; + if (s->pb->eof_reached) + return AVERROR(EIO); if (idcin->next_chunk_is_video) { - command = get_le32(pb); + command = avio_rl32(pb); if (command == 2) { - return AVERROR_IO; + return AVERROR(EIO); } else if (command == 1) { /* trigger a palette change */ - idcin->palctrl.palette_changed = 1; - if (get_buffer(pb, palette_buffer, 768) != 768) - return AVERROR_IO; + if (avio_read(pb, palette_buffer, 768) != 768) + return AVERROR(EIO); /* scale the palette as necessary */ palette_scale = 2; for (i = 0; i < 768; i++) @@ -247,17 +247,26 @@ static int idcin_read_packet(AVFormatContext *s, r = palette_buffer[i * 3 ] << palette_scale; g = palette_buffer[i * 3 + 1] << palette_scale; b = palette_buffer[i * 3 + 2] << palette_scale; - idcin->palctrl.palette[i] = (r << 16) | (g << 8) | (b); + palette[i] = (r << 16) | (g << 8) | (b); } } - chunk_size = get_le32(pb); + chunk_size = avio_rl32(pb); /* skip the number of decoded bytes (always equal to width * height) */ - url_fseek(pb, 4, SEEK_CUR); + avio_skip(pb, 4); chunk_size -= 4; - ret= av_get_packet(pb, pkt, chunk_size); - if (ret != chunk_size) - return AVERROR_IO; + ret= av_get_packet(pb, pkt, chunk_size); + if (ret < 0) + return ret; + if (command == 1) { + uint8_t *pal; + + pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, + AVPALETTE_SIZE); + if (ret < 0) + return ret; + memcpy(pal, palette, AVPALETTE_SIZE); + } pkt->stream_index = idcin->video_stream_index; pkt->pts = idcin->pts; } else { @@ -267,13 +276,13 @@ static int idcin_read_packet(AVFormatContext *s, else chunk_size = idcin->audio_chunk_size1; ret= av_get_packet(pb, pkt, chunk_size); - if (ret != chunk_size) - return AVERROR_IO; + if (ret < 0) + return ret; pkt->stream_index = idcin->audio_stream_index; pkt->pts = idcin->pts; idcin->current_audio_chunk ^= 1; - idcin->pts += FRAME_PTS_INC; + idcin->pts++; } if (idcin->audio_present) @@ -282,24 +291,11 @@ static int idcin_read_packet(AVFormatContext *s, return ret; } -static int idcin_read_close(AVFormatContext *s) -{ - - return 0; -} - -static AVInputFormat idcin_iformat = { - "idcin", - "Id CIN format", - sizeof(IdcinDemuxContext), - idcin_probe, - idcin_read_header, - idcin_read_packet, - idcin_read_close, +AVInputFormat ff_idcin_demuxer = { + .name = "idcin", + .long_name = NULL_IF_CONFIG_SMALL("id Cinematic format"), + .priv_data_size = sizeof(IdcinDemuxContext), + .read_probe = idcin_probe, + .read_header = idcin_read_header, + .read_packet = idcin_read_packet, }; - -int idcin_init(void) -{ - av_register_input_format(&idcin_iformat); - return 0; -}