summaryrefslogtreecommitdiff
path: root/ffmpeg/libavformat/wtvdec.c
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2013-12-29 12:19:38 +0000
committerTim Redfern <tim@eclectronics.org>2013-12-29 12:19:38 +0000
commitf7813a5324be39d13ab536c245d15dfc602a7849 (patch)
treefad99148b88823d34a5df2f0a25881a002eb291b /ffmpeg/libavformat/wtvdec.c
parentb7a5a477b8ff4d4e3028b9dfb9a9df0a41463f92 (diff)
basic type mechanism working
Diffstat (limited to 'ffmpeg/libavformat/wtvdec.c')
-rw-r--r--ffmpeg/libavformat/wtvdec.c55
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;