return -1;
}
-#ifdef TRACE
-static inline uint64_t get_v_trace(AVIOContext *bc, const char *file,
- const char *func, int line)
-{
- uint64_t v = ffio_read_varlen(bc);
-
- av_log(NULL, AV_LOG_DEBUG, "get_v %5"PRId64" / %"PRIX64" in %s %s:%d\n",
- v, v, file, func, line);
- return v;
-}
-
-static inline int64_t get_s_trace(AVIOContext *bc, const char *file,
- const char *func, int line)
-{
- int64_t v = get_s(bc);
-
- av_log(NULL, AV_LOG_DEBUG, "get_s %5"PRId64" / %"PRIX64" in %s %s:%d\n",
- v, v, file, func, line);
- return v;
-}
-
-#define ffio_read_varlen(bc) get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_s(bc) get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#endif
-
static int get_packetheader(NUTContext *nut, AVIOContext *bc,
int calculate_checksum, uint64_t startcode)
{
int64_t size;
-// start = avio_tell(bc) - 8;
startcode = av_be2ne64(startcode);
startcode = ff_crc04C11DB7_update(0, (uint8_t*) &startcode, 8);
GET_V(nut->time_base[i].num, tmp > 0 && tmp < (1ULL << 31));
GET_V(nut->time_base[i].den, tmp > 0 && tmp < (1ULL << 31));
if (av_gcd(nut->time_base[i].num, nut->time_base[i].den) != 1) {
- av_log(s, AV_LOG_ERROR, "time base invalid\n");
+ av_log(s, AV_LOG_ERROR, "invalid time base %d/%d\n",
+ nut->time_base[i].num,
+ nut->time_base[i].den);
return AVERROR_INVALIDDATA;
}
}
return AVERROR_INVALIDDATA;
}
if (tmp_stream >= stream_count) {
- av_log(s, AV_LOG_ERROR, "illegal stream number\n");
+ av_log(s, AV_LOG_ERROR, "illegal stream number %d >= %d\n",
+ tmp_stream, stream_count);
return AVERROR_INVALIDDATA;
}
for (i = 1; i < nut->header_count; i++) {
uint8_t *hdr;
GET_V(nut->header_len[i], tmp > 0 && tmp < 256);
- rem -= nut->header_len[i];
- if (rem < 0) {
- av_log(s, AV_LOG_ERROR, "invalid elision header\n");
+ if (rem < nut->header_len[i]) {
+ av_log(s, AV_LOG_ERROR,
+ "invalid elision header %d : %d > %d\n",
+ i, nut->header_len[i], rem);
return AVERROR_INVALIDDATA;
}
+ rem -= nut->header_len[i];
hdr = av_malloc(nut->header_len[i]);
if (!hdr)
return AVERROR(ENOMEM);
class = ffio_read_varlen(bc);
tmp = get_fourcc(bc);
- st->codec->codec_tag = tmp;
+ st->codecpar->codec_tag = tmp;
switch (class) {
case 0:
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = av_codec_get_id((const AVCodecTag * const []) {
+ st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codecpar->codec_id = av_codec_get_id((const AVCodecTag * const []) {
ff_nut_video_tags,
ff_codec_bmp_tags,
0
tmp);
break;
case 1:
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_id = av_codec_get_id((const AVCodecTag * const []) {
+ st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codecpar->codec_id = av_codec_get_id((const AVCodecTag * const []) {
ff_nut_audio_tags,
ff_codec_wav_tags,
0
tmp);
break;
case 2:
- st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
- st->codec->codec_id = ff_codec_get_id(ff_nut_subtitle_tags, tmp);
+ st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ st->codecpar->codec_id = ff_codec_get_id(ff_nut_subtitle_tags, tmp);
break;
case 3:
- st->codec->codec_type = AVMEDIA_TYPE_DATA;
- st->codec->codec_id = ff_codec_get_id(ff_nut_data_tags, tmp);
+ st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
+ st->codecpar->codec_id = ff_codec_get_id(ff_nut_data_tags, tmp);
break;
default:
av_log(s, AV_LOG_ERROR, "unknown stream class (%d)\n", class);
return AVERROR(ENOSYS);
}
- if (class < 3 && st->codec->codec_id == AV_CODEC_ID_NONE)
+ if (class < 3 && st->codecpar->codec_id == AV_CODEC_ID_NONE)
av_log(s, AV_LOG_ERROR,
"Unknown codec tag '0x%04x' for stream number %d\n",
(unsigned int) tmp, stream_id);
GET_V(stc->decode_delay, tmp < 1000); // sanity limit, raise this if Moore's law is true
ffio_read_varlen(bc); // stream flags
- GET_V(st->codec->extradata_size, tmp < (1 << 30));
- if (st->codec->extradata_size) {
- st->codec->extradata = av_mallocz(st->codec->extradata_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
- if (!st->codec->extradata)
+ GET_V(st->codecpar->extradata_size, tmp < (1 << 30));
+ if (st->codecpar->extradata_size) {
+ st->codecpar->extradata = av_mallocz(st->codecpar->extradata_size +
+ AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codecpar->extradata)
return AVERROR(ENOMEM);
- avio_read(bc, st->codec->extradata, st->codec->extradata_size);
+ avio_read(bc, st->codecpar->extradata, st->codecpar->extradata_size);
}
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- GET_V(st->codec->width, tmp > 0);
- GET_V(st->codec->height, tmp > 0);
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+ GET_V(st->codecpar->width, tmp > 0);
+ GET_V(st->codecpar->height, tmp > 0);
st->sample_aspect_ratio.num = ffio_read_varlen(bc);
st->sample_aspect_ratio.den = ffio_read_varlen(bc);
if ((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)) {
return AVERROR_INVALIDDATA;
}
ffio_read_varlen(bc); /* csp type */
- } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- GET_V(st->codec->sample_rate, tmp > 0);
+ } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+ GET_V(st->codecpar->sample_rate, tmp > 0);
ffio_read_varlen(bc); // samplerate_den
- GET_V(st->codec->channels, tmp > 0);
+ GET_V(st->codecpar->channels, tmp > 0);
}
if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
av_log(s, AV_LOG_ERROR,
nut->time_base[chapter_start %
nut->time_base_count],
start, start + chapter_len, NULL);
+ if (!chapter) {
+ av_log(s, AV_LOG_ERROR, "Could not create chapter.\n");
+ return AVERROR(ENOMEM);
+ }
metadata = &chapter->metadata;
} else if (stream_id_plus1) {
st = s->streams[stream_id_plus1 - 1];
}
if (stream_id_plus1 > s->nb_streams) {
- av_log(s, AV_LOG_ERROR, "invalid stream id for info packet\n");
+ av_log(s, AV_LOG_WARNING,
+ "invalid stream id %d for info packet\n",
+ stream_id_plus1);
continue;
}
avio_seek(bc, filesize - 12, SEEK_SET);
avio_seek(bc, filesize - avio_rb64(bc), SEEK_SET);
if (avio_rb64(bc) != INDEX_STARTCODE) {
- av_log(s, AV_LOG_ERROR, "no index at the end\n");
+ av_log(s, AV_LOG_WARNING, "no index at the end\n");
return ret;
}
return ret;
}
+static int nut_read_close(AVFormatContext *s)
+{
+ NUTContext *nut = s->priv_data;
+ int i;
+
+ av_freep(&nut->time_base);
+ av_freep(&nut->stream);
+ ff_nut_free_sp(nut);
+ for (i = 1; i < nut->header_count; i++)
+ av_freep(&nut->header[i]);
+
+ return 0;
+}
+
static int nut_read_header(AVFormatContext *s)
{
NUTContext *nut = s->priv_data;
pos = find_startcode(bc, MAIN_STARTCODE, pos) + 1;
if (pos < 0 + 1) {
av_log(s, AV_LOG_ERROR, "No main startcode found.\n");
- return AVERROR_INVALIDDATA;
+ goto fail;
}
} while (decode_main_header(nut) < 0);
pos = find_startcode(bc, STREAM_STARTCODE, pos) + 1;
if (pos < 0 + 1) {
av_log(s, AV_LOG_ERROR, "Not all stream headers found.\n");
- return AVERROR_INVALIDDATA;
+ goto fail;
}
if (decode_stream_header(nut) >= 0)
initialized_stream_count++;
if (startcode == 0) {
av_log(s, AV_LOG_ERROR, "EOF before video frames\n");
- return AVERROR_INVALIDDATA;
+ goto fail;
} else if (startcode == SYNCPOINT_STARTCODE) {
nut->next_startcode = startcode;
break;
s->internal->data_offset = pos - 8;
- if (bc->seekable) {
+ if (bc->seekable & AVIO_SEEKABLE_NORMAL) {
int64_t orig_pos = avio_tell(bc);
find_and_decode_index(nut);
avio_seek(bc, orig_pos, SEEK_SET);
ff_metadata_conv_ctx(s, NULL, ff_nut_metadata_conv);
return 0;
+
+fail:
+ nut_read_close(s);
+
+ return AVERROR_INVALIDDATA;
}
static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id,
ret = av_new_packet(pkt, size + nut->header_len[header_idx]);
if (ret < 0)
return ret;
- memcpy(pkt->data, nut->header[header_idx], nut->header_len[header_idx]);
+ if (nut->header[header_idx])
+ memcpy(pkt->data, nut->header[header_idx], nut->header_len[header_idx]);
pkt->pos = avio_tell(bc); // FIXME
avio_read(bc, pkt->data + nut->header_len[header_idx], size);
pos2 = st->index_entries[index].pos;
ts = st->index_entries[index].timestamp;
} else {
- av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pts_cmp,
+ av_tree_find(nut->syncpoints, &dummy,
+ (int (*)(void *, const void *)) ff_nut_sp_pts_cmp,
(void **) next_node);
av_log(s, AV_LOG_DEBUG, "%"PRIu64"-%"PRIu64" %"PRId64"-%"PRId64"\n",
next_node[0]->pos, next_node[1]->pos, next_node[0]->ts,
if (!(flags & AVSEEK_FLAG_BACKWARD)) {
dummy.pos = pos + 16;
next_node[1] = &nopts_sp;
- av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp,
+ av_tree_find(nut->syncpoints, &dummy,
+ (int (*)(void *, const void *)) ff_nut_sp_pos_cmp,
(void **) next_node);
pos2 = ff_gen_search(s, -2, dummy.pos, next_node[0]->pos,
next_node[1]->pos, next_node[1]->pos,
// FIXME dir but I think it does not matter
}
dummy.pos = pos;
- sp = av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp,
+ sp = av_tree_find(nut->syncpoints, &dummy,
+ (int (*)(void *, const void *)) ff_nut_sp_pos_cmp,
NULL);
assert(sp);
return 0;
}
-static int nut_read_close(AVFormatContext *s)
-{
- NUTContext *nut = s->priv_data;
- int i;
-
- av_freep(&nut->time_base);
- av_freep(&nut->stream);
- ff_nut_free_sp(nut);
- for (i = 1; i < nut->header_count; i++)
- av_freep(&nut->header[i]);
-
- return 0;
-}
-
AVInputFormat ff_nut_demuxer = {
.name = "nut",
.long_name = NULL_IF_CONFIG_SMALL("NUT"),