nutdec.c
Go to the documentation of this file.
1 /*
2  * "NUT" Container Format demuxer
3  * Copyright (c) 2004-2006 Michael Niedermayer
4  * Copyright (c) 2003 Alex Beregszaszi
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "libavutil/avstring.h"
24 #include "libavutil/avassert.h"
25 #include "libavutil/bswap.h"
26 #include "libavutil/dict.h"
27 #include "libavutil/mathematics.h"
28 #include "libavutil/tree.h"
29 #include "avio_internal.h"
30 #include "nut.h"
31 #include "riff.h"
32 
33 #define NUT_MAX_STREAMS 256 /* arbitrary sanity check value */
34 
35 static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index,
36  int64_t *pos_arg, int64_t pos_limit);
37 
38 static int get_str(AVIOContext *bc, char *string, unsigned int maxlen)
39 {
40  unsigned int len = ffio_read_varlen(bc);
41 
42  if (len && maxlen)
43  avio_read(bc, string, FFMIN(len, maxlen));
44  while (len > maxlen) {
45  avio_r8(bc);
46  len--;
47  }
48 
49  if (maxlen)
50  string[FFMIN(len, maxlen - 1)] = 0;
51 
52  if (maxlen == len)
53  return -1;
54  else
55  return 0;
56 }
57 
58 static int64_t get_s(AVIOContext *bc)
59 {
60  int64_t v = ffio_read_varlen(bc) + 1;
61 
62  if (v & 1)
63  return -(v >> 1);
64  else
65  return (v >> 1);
66 }
67 
68 static uint64_t get_fourcc(AVIOContext *bc)
69 {
70  unsigned int len = ffio_read_varlen(bc);
71 
72  if (len == 2)
73  return avio_rl16(bc);
74  else if (len == 4)
75  return avio_rl32(bc);
76  else {
77  av_log(NULL, AV_LOG_ERROR, "Unsupported fourcc length %d\n", len);
78  return -1;
79  }
80 }
81 
82 #ifdef TRACE
83 static inline uint64_t get_v_trace(AVIOContext *bc, const char *file,
84  const char *func, int line)
85 {
86  uint64_t v = ffio_read_varlen(bc);
87 
88  av_log(NULL, AV_LOG_DEBUG, "get_v %5"PRId64" / %"PRIX64" in %s %s:%d\n",
89  v, v, file, func, line);
90  return v;
91 }
92 
93 static inline int64_t get_s_trace(AVIOContext *bc, const char *file,
94  const char *func, int line)
95 {
96  int64_t v = get_s(bc);
97 
98  av_log(NULL, AV_LOG_DEBUG, "get_s %5"PRId64" / %"PRIX64" in %s %s:%d\n",
99  v, v, file, func, line);
100  return v;
101 }
102 
103 static inline uint64_t get_4cc_trace(AVIOContext *bc, char *file,
104  char *func, int line)
105 {
106  uint64_t v = get_fourcc(bc);
107 
108  av_log(NULL, AV_LOG_DEBUG, "get_fourcc %5"PRId64" / %"PRIX64" in %s %s:%d\n",
109  v, v, file, func, line);
110  return v;
111 }
112 #define ffio_read_varlen(bc) get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
113 #define get_s(bc) get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
114 #define get_fourcc(bc) get_4cc_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
115 #endif
116 
118  int calculate_checksum, uint64_t startcode)
119 {
120  int64_t size;
121 // start = avio_tell(bc) - 8;
122 
123  startcode = av_be2ne64(startcode);
124  startcode = ff_crc04C11DB7_update(0, (uint8_t*) &startcode, 8);
125 
127  size = ffio_read_varlen(bc);
128  if (size > 4096)
129  avio_rb32(bc);
130  if (ffio_get_checksum(bc) && size > 4096)
131  return -1;
132 
133  ffio_init_checksum(bc, calculate_checksum ? ff_crc04C11DB7_update : NULL, 0);
134 
135  return size;
136 }
137 
138 static uint64_t find_any_startcode(AVIOContext *bc, int64_t pos)
139 {
140  uint64_t state = 0;
141 
142  if (pos >= 0)
143  /* Note, this may fail if the stream is not seekable, but that should
144  * not matter, as in this case we simply start where we currently are */
145  avio_seek(bc, pos, SEEK_SET);
146  while (!url_feof(bc)) {
147  state = (state << 8) | avio_r8(bc);
148  if ((state >> 56) != 'N')
149  continue;
150  switch (state) {
151  case MAIN_STARTCODE:
152  case STREAM_STARTCODE:
153  case SYNCPOINT_STARTCODE:
154  case INFO_STARTCODE:
155  case INDEX_STARTCODE:
156  return state;
157  }
158  }
159 
160  return 0;
161 }
162 
163 /**
164  * Find the given startcode.
165  * @param code the startcode
166  * @param pos the start position of the search, or -1 if the current position
167  * @return the position of the startcode or -1 if not found
168  */
169 static int64_t find_startcode(AVIOContext *bc, uint64_t code, int64_t pos)
170 {
171  for (;;) {
172  uint64_t startcode = find_any_startcode(bc, pos);
173  if (startcode == code)
174  return avio_tell(bc) - 8;
175  else if (startcode == 0)
176  return -1;
177  pos = -1;
178  }
179 }
180 
181 static int nut_probe(AVProbeData *p)
182 {
183  int i;
184  uint64_t code = 0;
185 
186  for (i = 0; i < p->buf_size; i++) {
187  code = (code << 8) | p->buf[i];
188  if (code == MAIN_STARTCODE)
189  return AVPROBE_SCORE_MAX;
190  }
191  return 0;
192 }
193 
194 #define GET_V(dst, check) \
195  do { \
196  tmp = ffio_read_varlen(bc); \
197  if (!(check)) { \
198  av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp); \
199  return -1; \
200  } \
201  dst = tmp; \
202  } while (0)
203 
204 static int skip_reserved(AVIOContext *bc, int64_t pos)
205 {
206  pos -= avio_tell(bc);
207  if (pos < 0) {
208  avio_seek(bc, pos, SEEK_CUR);
209  return -1;
210  } else {
211  while (pos--)
212  avio_r8(bc);
213  return 0;
214  }
215 }
216 
218 {
219  AVFormatContext *s = nut->avf;
220  AVIOContext *bc = s->pb;
221  uint64_t tmp, end;
222  unsigned int stream_count;
223  int i, j, count;
224  int tmp_stream, tmp_mul, tmp_pts, tmp_size, tmp_res, tmp_head_idx;
225 
226  end = get_packetheader(nut, bc, 1, MAIN_STARTCODE);
227  end += avio_tell(bc);
228 
229  GET_V(tmp, tmp >= 2 && tmp <= 3);
230  GET_V(stream_count, tmp > 0 && tmp <= NUT_MAX_STREAMS);
231 
232  nut->max_distance = ffio_read_varlen(bc);
233  if (nut->max_distance > 65536) {
234  av_log(s, AV_LOG_DEBUG, "max_distance %d\n", nut->max_distance);
235  nut->max_distance = 65536;
236  }
237 
238  GET_V(nut->time_base_count, tmp > 0 && tmp < INT_MAX / sizeof(AVRational));
239  nut->time_base = av_malloc(nut->time_base_count * sizeof(AVRational));
240 
241  for (i = 0; i < nut->time_base_count; i++) {
242  GET_V(nut->time_base[i].num, tmp > 0 && tmp < (1ULL << 31));
243  GET_V(nut->time_base[i].den, tmp > 0 && tmp < (1ULL << 31));
244  if (av_gcd(nut->time_base[i].num, nut->time_base[i].den) != 1) {
245  av_log(s, AV_LOG_ERROR, "time base invalid\n");
246  return AVERROR_INVALIDDATA;
247  }
248  }
249  tmp_pts = 0;
250  tmp_mul = 1;
251  tmp_stream = 0;
252  tmp_head_idx = 0;
253  for (i = 0; i < 256;) {
254  int tmp_flags = ffio_read_varlen(bc);
255  int tmp_fields = ffio_read_varlen(bc);
256 
257  if (tmp_fields > 0)
258  tmp_pts = get_s(bc);
259  if (tmp_fields > 1)
260  tmp_mul = ffio_read_varlen(bc);
261  if (tmp_fields > 2)
262  tmp_stream = ffio_read_varlen(bc);
263  if (tmp_fields > 3)
264  tmp_size = ffio_read_varlen(bc);
265  else
266  tmp_size = 0;
267  if (tmp_fields > 4)
268  tmp_res = ffio_read_varlen(bc);
269  else
270  tmp_res = 0;
271  if (tmp_fields > 5)
272  count = ffio_read_varlen(bc);
273  else
274  count = tmp_mul - tmp_size;
275  if (tmp_fields > 6)
276  get_s(bc);
277  if (tmp_fields > 7)
278  tmp_head_idx = ffio_read_varlen(bc);
279 
280  while (tmp_fields-- > 8)
281  ffio_read_varlen(bc);
282 
283  if (count == 0 || i + count > 256) {
284  av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i);
285  return AVERROR_INVALIDDATA;
286  }
287  if (tmp_stream >= stream_count) {
288  av_log(s, AV_LOG_ERROR, "illegal stream number\n");
289  return AVERROR_INVALIDDATA;
290  }
291 
292  for (j = 0; j < count; j++, i++) {
293  if (i == 'N') {
294  nut->frame_code[i].flags = FLAG_INVALID;
295  j--;
296  continue;
297  }
298  nut->frame_code[i].flags = tmp_flags;
299  nut->frame_code[i].pts_delta = tmp_pts;
300  nut->frame_code[i].stream_id = tmp_stream;
301  nut->frame_code[i].size_mul = tmp_mul;
302  nut->frame_code[i].size_lsb = tmp_size + j;
303  nut->frame_code[i].reserved_count = tmp_res;
304  nut->frame_code[i].header_idx = tmp_head_idx;
305  }
306  }
307  av_assert0(nut->frame_code['N'].flags == FLAG_INVALID);
308 
309  if (end > avio_tell(bc) + 4) {
310  int rem = 1024;
311  GET_V(nut->header_count, tmp < 128U);
312  nut->header_count++;
313  for (i = 1; i < nut->header_count; i++) {
314  uint8_t *hdr;
315  GET_V(nut->header_len[i], tmp > 0 && tmp < 256);
316  rem -= nut->header_len[i];
317  if (rem < 0) {
318  av_log(s, AV_LOG_ERROR, "invalid elision header\n");
319  return AVERROR_INVALIDDATA;
320  }
321  hdr = av_malloc(nut->header_len[i]);
322  if (!hdr)
323  return AVERROR(ENOMEM);
324  avio_read(bc, hdr, nut->header_len[i]);
325  nut->header[i] = hdr;
326  }
327  av_assert0(nut->header_len[0] == 0);
328  }
329 
330  if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
331  av_log(s, AV_LOG_ERROR, "main header checksum mismatch\n");
332  return AVERROR_INVALIDDATA;
333  }
334 
335  nut->stream = av_mallocz(sizeof(StreamContext) * stream_count);
336  for (i = 0; i < stream_count; i++)
338 
339  return 0;
340 }
341 
343 {
344  AVFormatContext *s = nut->avf;
345  AVIOContext *bc = s->pb;
346  StreamContext *stc;
347  int class, stream_id;
348  uint64_t tmp, end;
349  AVStream *st;
350 
351  end = get_packetheader(nut, bc, 1, STREAM_STARTCODE);
352  end += avio_tell(bc);
353 
354  GET_V(stream_id, tmp < s->nb_streams && !nut->stream[tmp].time_base);
355  stc = &nut->stream[stream_id];
356  st = s->streams[stream_id];
357  if (!st)
358  return AVERROR(ENOMEM);
359 
360  class = ffio_read_varlen(bc);
361  tmp = get_fourcc(bc);
362  st->codec->codec_tag = tmp;
363  switch (class) {
364  case 0:
366  st->codec->codec_id = av_codec_get_id((const AVCodecTag * const []) {
369  0
370  },
371  tmp);
372  break;
373  case 1:
375  st->codec->codec_id = av_codec_get_id((const AVCodecTag * const []) {
378  0
379  },
380  tmp);
381  break;
382  case 2:
385  break;
386  case 3:
389  break;
390  default:
391  av_log(s, AV_LOG_ERROR, "unknown stream class (%d)\n", class);
392  return -1;
393  }
394  if (class < 3 && st->codec->codec_id == AV_CODEC_ID_NONE)
395  av_log(s, AV_LOG_ERROR,
396  "Unknown codec tag '0x%04x' for stream number %d\n",
397  (unsigned int) tmp, stream_id);
398 
399  GET_V(stc->time_base_id, tmp < nut->time_base_count);
400  GET_V(stc->msb_pts_shift, tmp < 16);
402  GET_V(stc->decode_delay, tmp < 1000); // sanity limit, raise this if Moore's law is true
403  st->codec->has_b_frames = stc->decode_delay;
404  ffio_read_varlen(bc); // stream flags
405 
406  GET_V(st->codec->extradata_size, tmp < (1 << 30));
407  if (st->codec->extradata_size) {
410  avio_read(bc, st->codec->extradata, st->codec->extradata_size);
411  }
412 
413  if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
414  GET_V(st->codec->width, tmp > 0);
415  GET_V(st->codec->height, tmp > 0);
418  if ((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)) {
419  av_log(s, AV_LOG_ERROR, "invalid aspect ratio %d/%d\n",
421  return -1;
422  }
423  ffio_read_varlen(bc); /* csp type */
424  } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
425  GET_V(st->codec->sample_rate, tmp > 0);
426  ffio_read_varlen(bc); // samplerate_den
427  GET_V(st->codec->channels, tmp > 0);
428  }
429  if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
430  av_log(s, AV_LOG_ERROR,
431  "stream header %d checksum mismatch\n", stream_id);
432  return -1;
433  }
434  stc->time_base = &nut->time_base[stc->time_base_id];
435  avpriv_set_pts_info(s->streams[stream_id], 63, stc->time_base->num,
436  stc->time_base->den);
437  return 0;
438 }
439 
441  int stream_id)
442 {
443  int flag = 0, i;
444 
445  for (i = 0; ff_nut_dispositions[i].flag; ++i)
446  if (!strcmp(ff_nut_dispositions[i].str, value))
447  flag = ff_nut_dispositions[i].flag;
448  if (!flag)
449  av_log(avf, AV_LOG_INFO, "unknown disposition type '%s'\n", value);
450  for (i = 0; i < avf->nb_streams; ++i)
451  if (stream_id == i || stream_id == -1)
452  avf->streams[i]->disposition |= flag;
453 }
454 
456 {
457  AVFormatContext *s = nut->avf;
458  AVIOContext *bc = s->pb;
459  uint64_t tmp, chapter_start, chapter_len;
460  unsigned int stream_id_plus1, count;
461  int chapter_id, i;
462  int64_t value, end;
463  char name[256], str_value[1024], type_str[256];
464  const char *type;
465  AVChapter *chapter = NULL;
466  AVStream *st = NULL;
467  AVDictionary **metadata = NULL;
468 
469  end = get_packetheader(nut, bc, 1, INFO_STARTCODE);
470  end += avio_tell(bc);
471 
472  GET_V(stream_id_plus1, tmp <= s->nb_streams);
473  chapter_id = get_s(bc);
474  chapter_start = ffio_read_varlen(bc);
475  chapter_len = ffio_read_varlen(bc);
476  count = ffio_read_varlen(bc);
477 
478  if (chapter_id && !stream_id_plus1) {
479  int64_t start = chapter_start / nut->time_base_count;
480  chapter = avpriv_new_chapter(s, chapter_id,
481  nut->time_base[chapter_start %
482  nut->time_base_count],
483  start, start + chapter_len, NULL);
484  metadata = &chapter->metadata;
485  } else if (stream_id_plus1) {
486  st = s->streams[stream_id_plus1 - 1];
487  metadata = &st->metadata;
488  } else
489  metadata = &s->metadata;
490 
491  for (i = 0; i < count; i++) {
492  get_str(bc, name, sizeof(name));
493  value = get_s(bc);
494  if (value == -1) {
495  type = "UTF-8";
496  get_str(bc, str_value, sizeof(str_value));
497  } else if (value == -2) {
498  get_str(bc, type_str, sizeof(type_str));
499  type = type_str;
500  get_str(bc, str_value, sizeof(str_value));
501  } else if (value == -3) {
502  type = "s";
503  value = get_s(bc);
504  } else if (value == -4) {
505  type = "t";
506  value = ffio_read_varlen(bc);
507  } else if (value < -4) {
508  type = "r";
509  get_s(bc);
510  } else {
511  type = "v";
512  }
513 
514  if (stream_id_plus1 > s->nb_streams) {
515  av_log(s, AV_LOG_ERROR, "invalid stream id for info packet\n");
516  continue;
517  }
518 
519  if (!strcmp(type, "UTF-8")) {
520  if (chapter_id == 0 && !strcmp(name, "Disposition")) {
521  set_disposition_bits(s, str_value, stream_id_plus1 - 1);
522  continue;
523  }
524 
525  if (stream_id_plus1 && !strcmp(name, "r_frame_rate")) {
526  sscanf(str_value, "%d/%d", &st->r_frame_rate.num, &st->r_frame_rate.den);
527  if (st->r_frame_rate.num >= 1000LL*st->r_frame_rate.den)
528  st->r_frame_rate.num = st->r_frame_rate.den = 0;
529  continue;
530  }
531 
532  if (metadata && av_strcasecmp(name, "Uses") &&
533  av_strcasecmp(name, "Depends") && av_strcasecmp(name, "Replaces"))
534  av_dict_set(metadata, name, str_value, 0);
535  }
536  }
537 
538  if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
539  av_log(s, AV_LOG_ERROR, "info header checksum mismatch\n");
540  return -1;
541  }
542  return 0;
543 }
544 
545 static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr)
546 {
547  AVFormatContext *s = nut->avf;
548  AVIOContext *bc = s->pb;
549  int64_t end;
550  uint64_t tmp;
551 
552  nut->last_syncpoint_pos = avio_tell(bc) - 8;
553 
554  end = get_packetheader(nut, bc, 1, SYNCPOINT_STARTCODE);
555  end += avio_tell(bc);
556 
557  tmp = ffio_read_varlen(bc);
558  *back_ptr = nut->last_syncpoint_pos - 16 * ffio_read_varlen(bc);
559  if (*back_ptr < 0)
560  return AVERROR_INVALIDDATA;
561 
562  ff_nut_reset_ts(nut, nut->time_base[tmp % nut->time_base_count],
563  tmp / nut->time_base_count);
564 
565  if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
566  av_log(s, AV_LOG_ERROR, "sync point checksum mismatch\n");
567  return AVERROR_INVALIDDATA;
568  }
569 
570  *ts = tmp / nut->time_base_count *
571  av_q2d(nut->time_base[tmp % nut->time_base_count]) * AV_TIME_BASE;
572  ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts);
573 
574  return 0;
575 }
576 
577 //FIXME calculate exactly, this is just a good approximation.
578 static int64_t find_duration(NUTContext *nut, int64_t filesize)
579 {
580  AVFormatContext *s = nut->avf;
581  int64_t duration = 0;
582 
583  int64_t pos = FFMAX(0, filesize - 2*nut->max_distance);
584  for(;;){
585  int64_t ts = nut_read_timestamp(s, -1, &pos, INT64_MAX);
586  if(ts < 0)
587  break;
588  duration = FFMAX(duration, ts);
589  pos++;
590  }
591  if(duration > 0)
593  return duration;
594 }
595 
597 {
598  AVFormatContext *s = nut->avf;
599  AVIOContext *bc = s->pb;
600  uint64_t tmp, end;
601  int i, j, syncpoint_count;
602  int64_t filesize = avio_size(bc);
603  int64_t *syncpoints;
604  int8_t *has_keyframe;
605  int ret = -1;
606 
607  if(filesize <= 0)
608  return -1;
609 
610  avio_seek(bc, filesize - 12, SEEK_SET);
611  avio_seek(bc, filesize - avio_rb64(bc), SEEK_SET);
612  if (avio_rb64(bc) != INDEX_STARTCODE) {
613  av_log(s, AV_LOG_ERROR, "no index at the end\n");
614 
615  if(s->duration<=0)
616  s->duration = find_duration(nut, filesize);
617  return -1;
618  }
619 
620  end = get_packetheader(nut, bc, 1, INDEX_STARTCODE);
621  end += avio_tell(bc);
622 
623  ffio_read_varlen(bc); // max_pts
624  GET_V(syncpoint_count, tmp < INT_MAX / 8 && tmp > 0);
625  syncpoints = av_malloc(sizeof(int64_t) * syncpoint_count);
626  has_keyframe = av_malloc(sizeof(int8_t) * (syncpoint_count + 1));
627  for (i = 0; i < syncpoint_count; i++) {
628  syncpoints[i] = ffio_read_varlen(bc);
629  if (syncpoints[i] <= 0)
630  goto fail;
631  if (i)
632  syncpoints[i] += syncpoints[i - 1];
633  }
634 
635  for (i = 0; i < s->nb_streams; i++) {
636  int64_t last_pts = -1;
637  for (j = 0; j < syncpoint_count;) {
638  uint64_t x = ffio_read_varlen(bc);
639  int type = x & 1;
640  int n = j;
641  x >>= 1;
642  if (type) {
643  int flag = x & 1;
644  x >>= 1;
645  if (n + x >= syncpoint_count + 1) {
646  av_log(s, AV_LOG_ERROR, "index overflow A %d + %"PRIu64" >= %d\n", n, x, syncpoint_count + 1);
647  goto fail;
648  }
649  while (x--)
650  has_keyframe[n++] = flag;
651  has_keyframe[n++] = !flag;
652  } else {
653  while (x != 1) {
654  if (n >= syncpoint_count + 1) {
655  av_log(s, AV_LOG_ERROR, "index overflow B\n");
656  goto fail;
657  }
658  has_keyframe[n++] = x & 1;
659  x >>= 1;
660  }
661  }
662  if (has_keyframe[0]) {
663  av_log(s, AV_LOG_ERROR, "keyframe before first syncpoint in index\n");
664  goto fail;
665  }
666  av_assert0(n <= syncpoint_count + 1);
667  for (; j < n && j < syncpoint_count; j++) {
668  if (has_keyframe[j]) {
669  uint64_t B, A = ffio_read_varlen(bc);
670  if (!A) {
671  A = ffio_read_varlen(bc);
672  B = ffio_read_varlen(bc);
673  // eor_pts[j][i] = last_pts + A + B
674  } else
675  B = 0;
676  av_add_index_entry(s->streams[i], 16 * syncpoints[j - 1],
677  last_pts + A, 0, 0, AVINDEX_KEYFRAME);
678  last_pts += A + B;
679  }
680  }
681  }
682  }
683 
684  if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
685  av_log(s, AV_LOG_ERROR, "index checksum mismatch\n");
686  goto fail;
687  }
688  ret = 0;
689 
690 fail:
691  av_free(syncpoints);
692  av_free(has_keyframe);
693  return ret;
694 }
695 
697 {
698  NUTContext *nut = s->priv_data;
699  AVIOContext *bc = s->pb;
700  int64_t pos;
701  int initialized_stream_count;
702 
703  nut->avf = s;
704 
705  /* main header */
706  pos = 0;
707  do {
708  pos = find_startcode(bc, MAIN_STARTCODE, pos) + 1;
709  if (pos < 0 + 1) {
710  av_log(s, AV_LOG_ERROR, "No main startcode found.\n");
711  return AVERROR_INVALIDDATA;
712  }
713  } while (decode_main_header(nut) < 0);
714 
715  /* stream headers */
716  pos = 0;
717  for (initialized_stream_count = 0; initialized_stream_count < s->nb_streams;) {
718  pos = find_startcode(bc, STREAM_STARTCODE, pos) + 1;
719  if (pos < 0 + 1) {
720  av_log(s, AV_LOG_ERROR, "Not all stream headers found.\n");
721  return AVERROR_INVALIDDATA;
722  }
723  if (decode_stream_header(nut) >= 0)
724  initialized_stream_count++;
725  }
726 
727  /* info headers */
728  pos = 0;
729  for (;;) {
730  uint64_t startcode = find_any_startcode(bc, pos);
731  pos = avio_tell(bc);
732 
733  if (startcode == 0) {
734  av_log(s, AV_LOG_ERROR, "EOF before video frames\n");
735  return AVERROR_INVALIDDATA;
736  } else if (startcode == SYNCPOINT_STARTCODE) {
737  nut->next_startcode = startcode;
738  break;
739  } else if (startcode != INFO_STARTCODE) {
740  continue;
741  }
742 
743  decode_info_header(nut);
744  }
745 
746  s->data_offset = pos - 8;
747 
748  if (bc->seekable) {
749  int64_t orig_pos = avio_tell(bc);
751  avio_seek(bc, orig_pos, SEEK_SET);
752  }
754 
756 
757  return 0;
758 }
759 
760 static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id,
761  uint8_t *header_idx, int frame_code)
762 {
763  AVFormatContext *s = nut->avf;
764  AVIOContext *bc = s->pb;
765  StreamContext *stc;
766  int size, flags, size_mul, pts_delta, i, reserved_count;
767  uint64_t tmp;
768 
769  if (avio_tell(bc) > nut->last_syncpoint_pos + nut->max_distance) {
770  av_log(s, AV_LOG_ERROR,
771  "Last frame must have been damaged %"PRId64" > %"PRId64" + %d\n",
772  avio_tell(bc), nut->last_syncpoint_pos, nut->max_distance);
773  return AVERROR_INVALIDDATA;
774  }
775 
776  flags = nut->frame_code[frame_code].flags;
777  size_mul = nut->frame_code[frame_code].size_mul;
778  size = nut->frame_code[frame_code].size_lsb;
779  *stream_id = nut->frame_code[frame_code].stream_id;
780  pts_delta = nut->frame_code[frame_code].pts_delta;
781  reserved_count = nut->frame_code[frame_code].reserved_count;
782  *header_idx = nut->frame_code[frame_code].header_idx;
783 
784  if (flags & FLAG_INVALID)
785  return AVERROR_INVALIDDATA;
786  if (flags & FLAG_CODED)
787  flags ^= ffio_read_varlen(bc);
788  if (flags & FLAG_STREAM_ID) {
789  GET_V(*stream_id, tmp < s->nb_streams);
790  }
791  stc = &nut->stream[*stream_id];
792  if (flags & FLAG_CODED_PTS) {
793  int coded_pts = ffio_read_varlen(bc);
794  // FIXME check last_pts validity?
795  if (coded_pts < (1 << stc->msb_pts_shift)) {
796  *pts = ff_lsb2full(stc, coded_pts);
797  } else
798  *pts = coded_pts - (1LL << stc->msb_pts_shift);
799  } else
800  *pts = stc->last_pts + pts_delta;
801  if (flags & FLAG_SIZE_MSB)
802  size += size_mul * ffio_read_varlen(bc);
803  if (flags & FLAG_MATCH_TIME)
804  get_s(bc);
805  if (flags & FLAG_HEADER_IDX)
806  *header_idx = ffio_read_varlen(bc);
807  if (flags & FLAG_RESERVED)
808  reserved_count = ffio_read_varlen(bc);
809  for (i = 0; i < reserved_count; i++)
810  ffio_read_varlen(bc);
811 
812  if (*header_idx >= (unsigned)nut->header_count) {
813  av_log(s, AV_LOG_ERROR, "header_idx invalid\n");
814  return AVERROR_INVALIDDATA;
815  }
816  if (size > 4096)
817  *header_idx = 0;
818  size -= nut->header_len[*header_idx];
819 
820  if (flags & FLAG_CHECKSUM) {
821  avio_rb32(bc); // FIXME check this
822  } else if (size > 2 * nut->max_distance || FFABS(stc->last_pts - *pts) >
823  stc->max_pts_distance) {
824  av_log(s, AV_LOG_ERROR, "frame size > 2max_distance and no checksum\n");
825  return AVERROR_INVALIDDATA;
826  }
827 
828  stc->last_pts = *pts;
829  stc->last_flags = flags;
830 
831  return size;
832 }
833 
834 static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code)
835 {
836  AVFormatContext *s = nut->avf;
837  AVIOContext *bc = s->pb;
838  int size, stream_id, discard;
839  int64_t pts, last_IP_pts;
840  StreamContext *stc;
841  uint8_t header_idx;
842 
843  size = decode_frame_header(nut, &pts, &stream_id, &header_idx, frame_code);
844  if (size < 0)
845  return size;
846 
847  stc = &nut->stream[stream_id];
848 
849  if (stc->last_flags & FLAG_KEY)
850  stc->skip_until_key_frame = 0;
851 
852  discard = s->streams[stream_id]->discard;
853  last_IP_pts = s->streams[stream_id]->last_IP_pts;
854  if ((discard >= AVDISCARD_NONKEY && !(stc->last_flags & FLAG_KEY)) ||
855  (discard >= AVDISCARD_BIDIR && last_IP_pts != AV_NOPTS_VALUE &&
856  last_IP_pts > pts) ||
857  discard >= AVDISCARD_ALL ||
858  stc->skip_until_key_frame) {
859  avio_skip(bc, size);
860  return 1;
861  }
862 
863  if (av_new_packet(pkt, size + nut->header_len[header_idx]) < 0)
864  return AVERROR(ENOMEM);
865  memcpy(pkt->data, nut->header[header_idx], nut->header_len[header_idx]);
866  pkt->pos = avio_tell(bc); // FIXME
867  avio_read(bc, pkt->data + nut->header_len[header_idx], size);
868 
869  pkt->stream_index = stream_id;
870  if (stc->last_flags & FLAG_KEY)
871  pkt->flags |= AV_PKT_FLAG_KEY;
872  pkt->pts = pts;
873 
874  return 0;
875 }
876 
878 {
879  NUTContext *nut = s->priv_data;
880  AVIOContext *bc = s->pb;
881  int i, frame_code = 0, ret, skip;
882  int64_t ts, back_ptr;
883 
884  for (;;) {
885  int64_t pos = avio_tell(bc);
886  uint64_t tmp = nut->next_startcode;
887  nut->next_startcode = 0;
888 
889  if (tmp) {
890  pos -= 8;
891  } else {
892  frame_code = avio_r8(bc);
893  if (url_feof(bc))
894  return -1;
895  if (frame_code == 'N') {
896  tmp = frame_code;
897  for (i = 1; i < 8; i++)
898  tmp = (tmp << 8) + avio_r8(bc);
899  }
900  }
901  switch (tmp) {
902  case MAIN_STARTCODE:
903  case STREAM_STARTCODE:
904  case INDEX_STARTCODE:
905  skip = get_packetheader(nut, bc, 0, tmp);
906  avio_skip(bc, skip);
907  break;
908  case INFO_STARTCODE:
909  if (decode_info_header(nut) < 0)
910  goto resync;
911  break;
912  case SYNCPOINT_STARTCODE:
913  if (decode_syncpoint(nut, &ts, &back_ptr) < 0)
914  goto resync;
915  frame_code = avio_r8(bc);
916  case 0:
917  ret = decode_frame(nut, pkt, frame_code);
918  if (ret == 0)
919  return 0;
920  else if (ret == 1) // OK but discard packet
921  break;
922  default:
923 resync:
924  av_log(s, AV_LOG_DEBUG, "syncing from %"PRId64"\n", pos);
925  tmp = find_any_startcode(bc, nut->last_syncpoint_pos + 1);
926  if (tmp == 0)
927  return AVERROR_INVALIDDATA;
928  av_log(s, AV_LOG_DEBUG, "sync\n");
929  nut->next_startcode = tmp;
930  }
931  }
932 }
933 
934 static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index,
935  int64_t *pos_arg, int64_t pos_limit)
936 {
937  NUTContext *nut = s->priv_data;
938  AVIOContext *bc = s->pb;
939  int64_t pos, pts, back_ptr;
940  av_log(s, AV_LOG_DEBUG, "read_timestamp(X,%d,%"PRId64",%"PRId64")\n",
941  stream_index, *pos_arg, pos_limit);
942 
943  pos = *pos_arg;
944  do {
945  pos = find_startcode(bc, SYNCPOINT_STARTCODE, pos) + 1;
946  if (pos < 1) {
947  av_log(s, AV_LOG_ERROR, "read_timestamp failed.\n");
948  return AV_NOPTS_VALUE;
949  }
950  } while (decode_syncpoint(nut, &pts, &back_ptr) < 0);
951  *pos_arg = pos - 1;
952  av_assert0(nut->last_syncpoint_pos == *pos_arg);
953 
954  av_log(s, AV_LOG_DEBUG, "return %"PRId64" %"PRId64"\n", pts, back_ptr);
955  if (stream_index == -2)
956  return back_ptr;
957  av_assert0(stream_index == -1);
958  return pts;
959 }
960 
961 static int read_seek(AVFormatContext *s, int stream_index,
962  int64_t pts, int flags)
963 {
964  NUTContext *nut = s->priv_data;
965  AVStream *st = s->streams[stream_index];
966  Syncpoint dummy = { .ts = pts * av_q2d(st->time_base) * AV_TIME_BASE };
967  Syncpoint nopts_sp = { .ts = AV_NOPTS_VALUE, .back_ptr = AV_NOPTS_VALUE };
968  Syncpoint *sp, *next_node[2] = { &nopts_sp, &nopts_sp };
969  int64_t pos, pos2, ts;
970  int i;
971 
972  if (st->index_entries) {
973  int index = av_index_search_timestamp(st, pts, flags);
974  if (index < 0)
975  index = av_index_search_timestamp(st, pts, flags ^ AVSEEK_FLAG_BACKWARD);
976  if (index < 0)
977  return -1;
978 
979  pos2 = st->index_entries[index].pos;
980  ts = st->index_entries[index].timestamp;
981  } else {
982  av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pts_cmp,
983  (void **) next_node);
984  av_log(s, AV_LOG_DEBUG, "%"PRIu64"-%"PRIu64" %"PRId64"-%"PRId64"\n",
985  next_node[0]->pos, next_node[1]->pos, next_node[0]->ts,
986  next_node[1]->ts);
987  pos = ff_gen_search(s, -1, dummy.ts, next_node[0]->pos,
988  next_node[1]->pos, next_node[1]->pos,
989  next_node[0]->ts, next_node[1]->ts,
991 
992  if (!(flags & AVSEEK_FLAG_BACKWARD)) {
993  dummy.pos = pos + 16;
994  next_node[1] = &nopts_sp;
995  av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp,
996  (void **) next_node);
997  pos2 = ff_gen_search(s, -2, dummy.pos, next_node[0]->pos,
998  next_node[1]->pos, next_node[1]->pos,
999  next_node[0]->back_ptr, next_node[1]->back_ptr,
1000  flags, &ts, nut_read_timestamp);
1001  if (pos2 >= 0)
1002  pos = pos2;
1003  // FIXME dir but I think it does not matter
1004  }
1005  dummy.pos = pos;
1006  sp = av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp,
1007  NULL);
1008 
1009  av_assert0(sp);
1010  pos2 = sp->back_ptr - 15;
1011  }
1012  av_log(NULL, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos2);
1013  pos = find_startcode(s->pb, SYNCPOINT_STARTCODE, pos2);
1014  avio_seek(s->pb, pos, SEEK_SET);
1015  av_log(NULL, AV_LOG_DEBUG, "SP: %"PRId64"\n", pos);
1016  if (pos2 > pos || pos2 + 15 < pos)
1017  av_log(NULL, AV_LOG_ERROR, "no syncpoint at backptr pos\n");
1018  for (i = 0; i < s->nb_streams; i++)
1019  nut->stream[i].skip_until_key_frame = 1;
1020 
1021  return 0;
1022 }
1023 
1025 {
1026  NUTContext *nut = s->priv_data;
1027  int i;
1028 
1029  av_freep(&nut->time_base);
1030  av_freep(&nut->stream);
1031  ff_nut_free_sp(nut);
1032  for (i = 1; i < nut->header_count; i++)
1033  av_freep(&nut->header[i]);
1034 
1035  return 0;
1036 }
1037 
1039  .name = "nut",
1040  .long_name = NULL_IF_CONFIG_SMALL("NUT"),
1041  .flags = AVFMT_SEEK_TO_PTS,
1042  .priv_data_size = sizeof(NUTContext),
1043  .read_probe = nut_probe,
1047  .read_seek = read_seek,
1048  .extensions = "nut",
1049  .codec_tag = ff_nut_codec_tags,
1050 };
const char * name
Definition: avisynth_c.h:675
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:1743
Definition: start.py:1
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
uint8_t header_len[128]
Definition: nut.h:94
uint64_t ffio_read_varlen(AVIOContext *bc)
Definition: aviobuf.c:683
discard all frames except keyframes
float v
const char * s
Definition: avisynth_c.h:668
Bytestream IO Context.
Definition: avio.h:68
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define MAIN_STARTCODE
Definition: nut.h:32
void ff_metadata_conv_ctx(AVFormatContext *ctx, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv)
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:261
int64_t last_syncpoint_pos
Definition: nut.h:101
int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add an index entry into a sorted list.
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
enum AVDurationEstimationMethod duration_estimation_method
The duration field can be estimated through various ways, and this field can be used to know how the ...
Definition: avformat.h:1195
#define B
Definition: dsputil.c:2025
int64_t pos
byte position in stream, -1 if unknown
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
int64_t pos
Definition: avformat.h:592
static int get_str(AVIOContext *bc, char *string, unsigned int maxlen)
Definition: nutdec.c:38
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:709
int num
numerator
Definition: rational.h:44
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:199
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: avformat.h:822
Definition: nut.h:56
#define NUT_MAX_STREAMS
Definition: nutdec.c:33
int64_t ts
Definition: nut.h:60
static void set_disposition_bits(AVFormatContext *avf, char *value, int stream_id)
Definition: nutdec.c:440
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:256
int64_t data_offset
offset of the first packet
Definition: avformat.h:1242
uint8_t stream_id
Definition: nut.h:65
AVDictionary * metadata
Definition: avformat.h:922
static int decode_main_header(NUTContext *nut)
Definition: nutdec.c:217
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
const uint8_t * header[128]
Definition: nut.h:95
AVChapter * avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
initialize output if(nPeaks >3)%at least 3 peaks in spectrum for trying to find f0 nf0peaks
Format I/O context.
Definition: avformat.h:944
static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id, uint8_t *header_idx, int frame_code)
Definition: nutdec.c:760
if set, reserved_count is coded in the frame header
Definition: nut.h:49
static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit)
Definition: nutdec.c:934
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
Public dictionary API.
void * av_tree_find(const AVTreeNode *t, void *key, int(*cmp)(void *key, const void *b), void *next[2])
Definition: tree.c:38
uint8_t
AVRational * time_base
Definition: nut.h:103
Opaque data information usually continuous.
Definition: avutil.h:145
int decode_delay
Definition: nut.h:81
uint16_t flags
Definition: nut.h:64
static int nut_probe(AVProbeData *p)
Definition: nutdec.c:181
A tree container.
enum AVCodecID av_codec_get_id(const struct AVCodecTag *const *tags, unsigned int tag)
Get the AVCodecID for the given codec tag tag.
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:610
static AVPacket pkt
Definition: demuxing.c:56
if set, coded_pts is in the frame header
Definition: nut.h:45
end end
static int64_t last_pts
#define STREAM_STARTCODE
Definition: nut.h:33
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
AVStream ** streams
Definition: avformat.h:992
If set, match_time_delta is coded in the frame header.
Definition: nut.h:51
const AVMetadataConv ff_nut_metadata_conv[]
Definition: nut.c:252
static double av_q2d(AVRational a)
Convert rational to double.
Definition: rational.h:69
uint8_t * data
int last_flags
Definition: nut.h:74
static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code)
Definition: nutdec.c:834
#define sp
Definition: regdef.h:63
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
const AVCodecTag ff_nut_data_tags[]
Definition: nut.c:37
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:675
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:248
static int64_t duration
Definition: ffplay.c:294
#define A(x)
int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b)
Definition: nut.c:206
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:478
AVFormatContext * avf
Definition: nut.h:90
struct NUTContext NUTContext
int64_t last_pts
Definition: nut.h:76
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Discrete Time axis x
#define U(x)
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:73
#define AVINDEX_KEYFRAME
Definition: avformat.h:599
AVDictionary * metadata
Definition: avformat.h:1092
int has_b_frames
Size of the frame reordering buffer in the decoder.
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
void ff_nut_free_sp(NUTContext *nut)
Definition: nut.c:236
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:579
discard all bidirectional frames
uint64_t pos
Definition: nut.h:57
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:593
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: graph2dot.c:48
simple assert() macros that are a bit more flexible than ISO C assert().
int64_t av_gcd(int64_t a, int64_t b)
Return the greatest common divisor of a and b.
Definition: mathematics.c:55
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: nutdec.c:877
const AVCodecTag ff_nut_audio_tags[]
Definition: nut.c:157
int header_count
Definition: nut.h:102
AVRational * time_base
Definition: nut.h:78
static int decode_stream_header(NUTContext *nut)
Definition: nutdec.c:342
#define av_be2ne64(x)
Definition: bswap.h:94
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:334
#define FFMAX(a, b)
Definition: common.h:56
if set, frame is keyframe
Definition: nut.h:43
int size
int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b)
Definition: nut.c:210
int flags
A combination of AV_PKT_FLAG values.
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:469
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
static int nut_read_close(AVFormatContext *s)
Definition: nutdec.c:1024
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:337
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:336
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
unsigned int nb_streams
A list of all streams in the file.
Definition: avformat.h:991
void ffio_init_checksum(AVIOContext *s, unsigned long(*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), unsigned long checksum)
Definition: aviobuf.c:457
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:117
void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val)
Definition: nut.c:189
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:196
#define FFMIN(a, b)
Definition: common.h:58
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:35
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:212
uint8_t header_idx
Definition: nut.h:70
static int read_probe(AVProbeData *pd)
ret
Definition: avfilter.c:821
int width
picture width / height.
static uint64_t find_any_startcode(AVIOContext *bc, int64_t pos)
Definition: nutdec.c:138
uint16_t size_lsb
Definition: nut.h:67
FFmpeg Automated Testing Environment ************************************Table of Contents *****************FFmpeg Automated Testing Environment Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass target exec to configure or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script tests fate sh from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at doc fate_config sh template Create a configuration that suits your based on the configuration template The slot configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern< arch >< os >< compiler >< compiler version > The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the fate_recv variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration file
Definition: fate.txt:34
unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, unsigned int len)
Definition: aviobuf.c:443
int16_t pts_delta
Definition: nut.h:68
static int find_and_decode_index(NUTContext *nut)
Definition: nutdec.c:596
int64_t ff_lsb2full(StreamContext *stream, int64_t lsb)
Definition: nut.c:200
internal header for RIFF based (de)muxers do NOT include this in end user applications ...
if set, frame_code is invalid
Definition: nut.h:53
static uint64_t get_fourcc(AVIOContext *bc)
Definition: nutdec.c:68
static int get_packetheader(NUTContext *nut, AVIOContext *bc, int calculate_checksum, uint64_t startcode)
Definition: nutdec.c:117
#define FFABS(a)
Definition: common.h:53
struct AVTreeNode * syncpoints
Definition: nut.h:104
if set, data_size_msb is at frame header, otherwise data_size_msb is 0
Definition: nut.h:47
AVDictionary * metadata
Definition: avformat.h:711
static int nut_read_header(AVFormatContext *s)
Definition: nutdec.c:696
if set, the frame header contains a checksum
Definition: nut.h:48
#define INDEX_STARTCODE
Definition: nut.h:35
void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts)
Definition: nut.c:214
uint16_t size_mul
Definition: nut.h:66
int url_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
Definition: aviobuf.c:280
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:517
static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr)
Definition: nutdec.c:545
Stream structure.
Definition: avformat.h:643
int msb_pts_shift
Definition: nut.h:79
NULL
Definition: eval.c:55
or the Software in violation of any applicable export control laws in any jurisdiction Except as provided by mandatorily applicable UPF has no obligation to provide you with source code to the Software In the event Software contains any source code
enum AVMediaType codec_type
static int resync(AVIOContext *pb)
const AVCodecTag ff_nut_subtitle_tags[]
Definition: nut.c:28
enum AVCodecID codec_id
int sample_rate
samples per second
AVIOContext * pb
I/O context.
Definition: avformat.h:977
int max_pts_distance
Definition: nut.h:80
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> (&#39;D&#39;<<24) + (&#39;C&#39;<<16) + (&#39;B&#39;<<8) + &#39;A&#39;).
if set, coded_flags are stored in the frame header
Definition: nut.h:52
static int read_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition: libcdio.c:114
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:62
#define GET_V(dst, check)
Definition: nutdec.c:194
double value
Definition: eval.c:82
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
int(* func)(AVBPrint *dst, const char *in, const char *arg)
int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t(*read_timestamp)(struct AVFormatContext *, int, int64_t *, int64_t))
Perform a binary search using read_timestamp().
int index
Definition: gxfenc.c:89
synthesis window for stochastic i
rational number numerator/denominator
Definition: rational.h:43
byte swapping routines
unsigned long ffio_get_checksum(AVIOContext *s)
Definition: aviobuf.c:449
StreamContext * stream
Definition: nut.h:97
static int skip_reserved(AVIOContext *bc, int64_t pos)
Definition: nutdec.c:204
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:371
static int64_t find_startcode(AVIOContext *bc, uint64_t code, int64_t pos)
Find the given startcode.
Definition: nutdec.c:169
This structure contains the data a format has to probe a file.
Definition: avformat.h:334
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
#define type
static int read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags)
Definition: nutdec.c:961
#define INFO_STARTCODE
Definition: nut.h:36
static uint32_t state
Definition: trasher.c:27
static int flags
Definition: cpu.c:23
Duration accurately estimated from PTSes.
Definition: avformat.h:931
int skip_until_key_frame
Definition: nut.h:75
static int64_t find_duration(NUTContext *nut, int64_t filesize)
Definition: nutdec.c:578
const Dispositions ff_nut_dispositions[]
Definition: nut.c:242
#define AVPROBE_SCORE_MAX
maximum score, half of that is used for file-extension-based detection
Definition: avformat.h:340
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:563
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
uint64_t next_startcode
stores the next startcode if it has already been parsed but the stream is not seekable ...
Definition: nut.h:96
static int decode_info_header(NUTContext *nut)
Definition: nutdec.c:455
FrameCode frame_code[256]
Definition: nut.h:93
int disposition
AV_DISPOSITION_* bit field.
Definition: avformat.h:700
const AVCodecTag ff_nut_video_tags[]
Definition: nut.c:42
int den
denominator
Definition: rational.h:45
#define SYNCPOINT_STARTCODE
Definition: nut.h:34
int flag
Definition: nut.h:119
If set, header_idx is coded in the frame header.
Definition: nut.h:50
int len
AVInputFormat ff_nut_demuxer
Definition: nutdec.c:1038
int channels
number of audio channels
static int64_t get_s(AVIOContext *bc)
Definition: nutdec.c:58
void * priv_data
Format private data.
Definition: avformat.h:964
int time_base_id
Definition: nut.h:77
int64_t duration
Decoding: duration of the stream, in AV_TIME_BASE fractional seconds.
Definition: avformat.h:1009
#define AV_LOG_INFO
Definition: log.h:156
int64_t last_IP_pts
Definition: avformat.h:786
void INT64 INT64 count
Definition: avisynth_c.h:594
if set, stream_id is coded in the frame header
Definition: nut.h:46
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:461
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:679
int dummy
Definition: motion-test.c:64
uint64_t back_ptr
Definition: nut.h:58
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:702
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:738
const AVCodecTag *const ff_nut_codec_tags[]
Definition: nut.c:184
This structure stores compressed data.
unsigned int time_base_count
Definition: nut.h:100
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:190
uint8_t reserved_count
Definition: nut.h:69
unsigned int max_distance
Definition: nut.h:99