X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fidcin.c;h=eb2cb8bf55f672a835202ca67a05350823de3e5c;hb=f985113075b0c571b1b1b166fe28f87f0f291be5;hp=3b7662766973a638774a878acc4b882b83e40578;hpb=769e10f0684c63aefb6fe36788f3e543312e185d;p=ffmpeg diff --git a/libavformat/idcin.c b/libavformat/idcin.c index 3b766276697..eb2cb8bf55f 100644 --- a/libavformat/idcin.c +++ b/libavformat/idcin.c @@ -1,28 +1,28 @@ /* - * Id Quake II CIN File Demuxer + * id Quake II CIN File Demuxer * Copyright (c) 2003 The ffmpeg Project * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * 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.1 of the License, or (at your option) any later version. * - * FFmpeg 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 FFmpeg; if not, write to the Free Software + * 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 @@ -53,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 @@ -68,10 +68,12 @@ * transmitting them to the video decoder */ +#include "libavutil/intreadwrite.h" #include "avformat.h" +#include "internal.h" #define HUFFMAN_TABLE_SIZE (64 * 1024) -#define FRAME_PTS_INC (90000 / 14) +#define IDCIN_FPS 14 typedef struct IdcinDemuxContext { int video_stream_index; @@ -85,8 +87,6 @@ typedef struct IdcinDemuxContext { int audio_present; int64_t pts; - - AVPaletteControl palctrl; } IdcinDemuxContext; static int idcin_probe(AVProbeData *p) @@ -94,7 +94,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 @@ -104,6 +104,11 @@ static int idcin_probe(AVProbeData *p) * audio channels: 0 for no audio, or 1 or 2 */ + /* 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 = AV_RL32(&p->buf[0]); if ((number == 0) || (number > 1024)) @@ -133,28 +138,27 @@ static int idcin_probe(AVProbeData *p) return AVPROBE_SCORE_MAX / 2; } -static int idcin_read_header(AVFormatContext *s, - AVFormatParameters *ap) +static int idcin_read_header(AVFormatContext *s) { - ByteIOContext *pb = &s->pb; + 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); + st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, 90000); + avpriv_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; @@ -163,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); + st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, 90000); + avpriv_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) @@ -215,24 +217,24 @@ static int idcin_read_packet(AVFormatContext *s, unsigned int command; unsigned int chunk_size; IdcinDemuxContext *idcin = s->priv_data; - ByteIOContext *pb = &s->pb; + 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++) @@ -245,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; + 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 { @@ -265,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) @@ -280,18 +291,11 @@ static int idcin_read_packet(AVFormatContext *s, return ret; } -static int idcin_read_close(AVFormatContext *s) -{ - - return 0; -} - -AVInputFormat idcin_demuxer = { - "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, };