Commit 2a5f4c1e authored by Michael Niedermayer's avatar Michael Niedermayer

Merge remote-tracking branch 'qatar/master'

* qatar/master:
  wtv: Seek by sector properly

Conflicts:
	libavformat/wtvdec.c

See: a0d13d84Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 5d2a8357 2b72f8ac
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "riff.h" #include "riff.h"
#include "asf.h" #include "asf.h"
#define WTV_SECTOR_BITS INT64_C(12) #define WTV_SECTOR_BITS 12
#define WTV_SECTOR_SIZE (1 << WTV_SECTOR_BITS) #define WTV_SECTOR_SIZE (1 << WTV_SECTOR_BITS)
#define WTV_BIGSECTOR_BITS 18 #define WTV_BIGSECTOR_BITS 18
#define WTV_PAD8(x) (((x) + 7) & ~7) #define WTV_PAD8(x) (((x) + 7) & ~7)
......
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
* *
*/ */
#define SHIFT_SECTOR_BITS(a) ((int64_t)(a) << WTV_SECTOR_BITS)
typedef struct { typedef struct {
AVIOContext *pb_filesystem; /**< file system (AVFormatContext->pb) */ AVIOContext *pb_filesystem; /**< file system (AVFormatContext->pb) */
...@@ -58,6 +60,11 @@ typedef struct { ...@@ -58,6 +60,11 @@ typedef struct {
int64_t length; int64_t length;
} WtvFile; } WtvFile;
static int64_t seek_by_sector(AVIOContext *pb, int64_t sector, int64_t offset)
{
return avio_seek(pb, SHIFT_SECTOR_BITS(sector) + offset, SEEK_SET);
}
/** /**
* @return bytes read, 0 on end of file, or <0 on error * @return bytes read, 0 on end of file, or <0 on error
*/ */
...@@ -88,7 +95,7 @@ static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size) ...@@ -88,7 +95,7 @@ static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size)
int i = wf->position >> wf->sector_bits; int i = wf->position >> wf->sector_bits;
if (i >= wf->nb_sectors || if (i >= wf->nb_sectors ||
(wf->sectors[i] != wf->sectors[i - 1] + (1 << (wf->sector_bits - WTV_SECTOR_BITS)) && (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; wf->error = 1;
break; break;
} }
...@@ -113,8 +120,8 @@ static int64_t wtvfile_seek(void *opaque, int64_t offset, int whence) ...@@ -113,8 +120,8 @@ static int64_t wtvfile_seek(void *opaque, int64_t offset, int whence)
offset = wf->length; offset = wf->length;
wf->error = offset < 0 || offset >= wf->length || wf->error = offset < 0 || offset >= wf->length ||
avio_seek(pb, ((int64_t)wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS) seek_by_sector(pb, wf->sectors[offset >> wf->sector_bits],
+ (offset & ((1 << wf->sector_bits) - 1)), SEEK_SET) < 0; offset & ((1 << wf->sector_bits) - 1)) < 0;
wf->position = offset; wf->position = offset;
return offset; return offset;
} }
...@@ -149,7 +156,7 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int ...@@ -149,7 +156,7 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int
WtvFile *wf; WtvFile *wf;
uint8_t *buffer; uint8_t *buffer;
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; return NULL;
wf = av_mallocz(sizeof(WtvFile)); wf = av_mallocz(sizeof(WtvFile));
...@@ -176,14 +183,14 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int ...@@ -176,14 +183,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 nb_sectors1 = read_ints(s->pb, sectors1, WTV_SECTOR_SIZE / 4);
int i; int i;
wf->sectors = av_malloc(nb_sectors1 << WTV_SECTOR_BITS); wf->sectors = av_malloc(SHIFT_SECTOR_BITS(nb_sectors1));
if (!wf->sectors) { if (!wf->sectors) {
av_free(wf); av_free(wf);
return NULL; return NULL;
} }
wf->nb_sectors = 0; wf->nb_sectors = 0;
for (i = 0; i < nb_sectors1; i++) { 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; break;
wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4); wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4);
} }
...@@ -213,7 +220,7 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int ...@@ -213,7 +220,7 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int
/* seek to initial sector */ /* seek to initial sector */
wf->position = 0; 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->sectors);
av_free(wf); av_free(wf);
return NULL; return NULL;
...@@ -941,7 +948,7 @@ static int read_header(AVFormatContext *s) ...@@ -941,7 +948,7 @@ static int read_header(AVFormatContext *s)
avio_skip(s->pb, 4); avio_skip(s->pb, 4);
root_sector = avio_rl32(s->pb); 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); root_size = avio_read(s->pb, root, root_size);
if (root_size < 0) if (root_size < 0)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment