diff options
Diffstat (limited to 'ffmpeg/libavformat/wtvdec.c')
| -rw-r--r-- | ffmpeg/libavformat/wtvdec.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/ffmpeg/libavformat/wtvdec.c b/ffmpeg/libavformat/wtvdec.c index e423370..21236fa 100644 --- a/ffmpeg/libavformat/wtvdec.c +++ b/ffmpeg/libavformat/wtvdec.c @@ -47,17 +47,22 @@ */ typedef struct { - AVIOContext *pb_filesystem; /** file system (AVFormatContext->pb) */ + AVIOContext *pb_filesystem; /**< file system (AVFormatContext->pb) */ - int sector_bits; /** sector shift bits; used to convert sector number into pb_filesystem offset */ - uint32_t *sectors; /** file allocation table */ - int nb_sectors; /** number of sectors */ + int sector_bits; /**< sector shift bits; used to convert sector number into pb_filesystem offset */ + uint32_t *sectors; /**< file allocation table */ + int nb_sectors; /**< number of sectors */ int error; int64_t position; int64_t length; } WtvFile; +static int64_t seek_by_sector(AVIOContext *pb, int64_t sector, int64_t offset) +{ + return avio_seek(pb, (sector << WTV_SECTOR_BITS) + offset, SEEK_SET); +} + /** * @return bytes read, 0 on end of file, or <0 on error */ @@ -88,7 +93,7 @@ static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size) int i = wf->position >> wf->sector_bits; if (i >= wf->nb_sectors || (wf->sectors[i] != wf->sectors[i - 1] + (1 << (wf->sector_bits - WTV_SECTOR_BITS)) && - avio_seek(pb, (int64_t)wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) { + seek_by_sector(pb, wf->sectors[i], 0) < 0)) { wf->error = 1; break; } @@ -113,8 +118,8 @@ static int64_t wtvfile_seek(void *opaque, int64_t offset, int whence) offset = wf->length; wf->error = offset < 0 || offset >= wf->length || - avio_seek(pb, ((int64_t)wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS) - + (offset & ((1 << wf->sector_bits) - 1)), SEEK_SET) < 0; + seek_by_sector(pb, wf->sectors[offset >> wf->sector_bits], + offset & ((1 << wf->sector_bits) - 1)) < 0; wf->position = offset; return offset; } @@ -148,8 +153,9 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int AVIOContext *pb; WtvFile *wf; uint8_t *buffer; + int64_t size; - if (avio_seek(s->pb, (int64_t)first_sector << WTV_SECTOR_BITS, SEEK_SET) < 0) + if (seek_by_sector(s->pb, first_sector, 0) < 0) return NULL; wf = av_mallocz(sizeof(WtvFile)); @@ -176,14 +182,14 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int int nb_sectors1 = read_ints(s->pb, sectors1, WTV_SECTOR_SIZE / 4); int i; - wf->sectors = av_malloc(nb_sectors1 << WTV_SECTOR_BITS); + wf->sectors = av_malloc_array(nb_sectors1, 1 << WTV_SECTOR_BITS); if (!wf->sectors) { av_free(wf); return NULL; } wf->nb_sectors = 0; for (i = 0; i < nb_sectors1; i++) { - if (avio_seek(s->pb, (int64_t)sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0) + if (seek_by_sector(s->pb, sectors1[i], 0) < 0) break; wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4); } @@ -200,7 +206,8 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int return NULL; } - if ((int64_t)wf->sectors[wf->nb_sectors - 1] << WTV_SECTOR_BITS > avio_tell(s->pb)) + size = avio_size(s->pb); + if (size >= 0 && (int64_t)wf->sectors[wf->nb_sectors - 1] << WTV_SECTOR_BITS > size) av_log(s, AV_LOG_WARNING, "truncated file\n"); /* check length */ @@ -213,7 +220,7 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int /* seek to initial sector */ wf->position = 0; - if (avio_seek(s->pb, (int64_t)wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) { + if (seek_by_sector(s->pb, wf->sectors[0], 0) < 0) { av_free(wf->sectors); av_free(wf); return NULL; @@ -261,7 +268,12 @@ static AVIOContext * wtvfile_open2(AVFormatContext *s, const uint8_t *buf, int b dir_length = AV_RL16(buf + 16); file_length = AV_RL64(buf + 24); name_size = 2 * AV_RL32(buf + 32); - if (buf + 48 + (int64_t)name_size > buf_end || name_size<0) { + if (name_size < 0) { + av_log(s, AV_LOG_ERROR, + "bad filename length, remaining directory entries ignored\n"); + break; + } + if (48 + (int64_t)name_size > buf_end - buf) { av_log(s, AV_LOG_ERROR, "filename exceeds buffer size; remaining directory entries ignored\n"); break; } @@ -306,10 +318,10 @@ typedef struct { } WtvStream; typedef struct { - AVIOContext *pb; /** timeline file */ + AVIOContext *pb; /**< timeline file */ int64_t epoch; - int64_t pts; /** pts for next data chunk */ - int64_t last_valid_pts; /** latest valid pts, used for interative seeking */ + int64_t pts; /**< pts for next data chunk */ + int64_t last_valid_pts; /**< latest valid pts, used for interative seeking */ /* maintain private seek index, as the AVIndexEntry->pos is relative to the start of the 'timeline' file, not the file system (AVFormatContext->pb) */ @@ -360,10 +372,6 @@ static const ff_asf_guid mediasubtype_dtvccdata = static const ff_asf_guid mediasubtype_mpeg2_sections = {0x79,0x85,0x9F,0x4A,0xF8,0x6B,0x92,0x43,0x8A,0x6D,0xD2,0xDD,0x09,0xFA,0x78,0x61}; -/* Formats */ -static const ff_asf_guid format_videoinfo2 = - {0xA0,0x76,0x2A,0xF7,0x0A,0xEB,0xD0,0x11,0xAC,0xE4,0x00,0x00,0xC0,0xCC,0x16,0xBA}; - static int read_probe(AVProbeData *p) { return ff_guidcmp(p->buf, ff_wtv_guid) ? 0 : AVPROBE_SCORE_MAX; @@ -436,6 +444,7 @@ static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length) av_dict_set(&st->metadata, "title", description, 0); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_MJPEG; + st->id = -1; ret = av_get_packet(pb, &st->attached_pic, filesize); if (ret < 0) goto done; @@ -495,7 +504,7 @@ static void get_tag(AVFormatContext *s, AVIOContext *pb, const char *key, int ty else snprintf(buf, buf_size, "%"PRIi64, num); } else if (type == 5 && length == 2) { - snprintf(buf, buf_size, "%"PRIi16, avio_rl16(pb)); + snprintf(buf, buf_size, "%u", avio_rl16(pb)); } else if (type == 6 && length == 16) { ff_asf_guid guid; avio_read(pb, guid, 16); @@ -678,7 +687,7 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid, st = new_stream(s, st, sid, AVMEDIA_TYPE_VIDEO); if (!st) return NULL; - if (!ff_guidcmp(formattype, format_videoinfo2)) { + if (!ff_guidcmp(formattype, ff_format_videoinfo2)) { int consumed = parse_videoinfoheader2(s, st); avio_skip(pb, FFMAX(size - consumed, 0)); } else if (!ff_guidcmp(formattype, ff_format_mpeg2_video)) { @@ -935,7 +944,7 @@ static int read_header(AVFormatContext *s) avio_skip(s->pb, 4); root_sector = avio_rl32(s->pb); - avio_seek(s->pb, (int64_t)root_sector << WTV_SECTOR_BITS, SEEK_SET); + seek_by_sector(s->pb, root_sector, 0); root_size = avio_read(s->pb, root, root_size); if (root_size < 0) return AVERROR_INVALIDDATA; |
