FFmpeg
nsvdec.c
Go to the documentation of this file.
1 /*
2  * NSV demuxer
3  * Copyright (c) 2004 The FFmpeg Project
4  *
5  * first version by Francois Revol <revol@free.fr>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "libavutil/attributes.h"
25 #include "libavutil/mathematics.h"
26 #include "avformat.h"
27 #include "demux.h"
28 #include "internal.h"
29 #include "libavutil/dict.h"
30 #include "libavutil/intreadwrite.h"
31 
32 /* max bytes to crawl for trying to resync
33  * stupid streaming servers don't start at chunk boundaries...
34  */
35 #define NSV_MAX_RESYNC (500*1024)
36 #define NSV_MAX_RESYNC_TRIES 300
37 
38 /*
39  * References:
40  * (1) http://www.multimedia.cx/nsv-format.txt
41  * seems someone came to the same conclusions as me, and updated it:
42  * (2) http://www.stud.ktu.lt/~vitslav/nsv/nsv-format.txt
43  * http://www.stud.ktu.lt/~vitslav/nsv/
44  * official docs
45  * (3) http://ultravox.aol.com/NSVFormat.rtf
46  * Sample files:
47  * (S1) http://www.nullsoft.com/nsv/samples/
48  * http://www.nullsoft.com/nsv/samples/faster.nsv
49  * http://streamripper.sourceforge.net/openbb/read.php?TID=492&page=4
50  */
51 
52 /*
53  * notes on the header (Francois Revol):
54  *
55  * It is followed by strings, then a table, but nothing tells
56  * where the table begins according to (1). After checking faster.nsv,
57  * I believe NVSf[16-19] gives the size of the strings data
58  * (that is the offset of the data table after the header).
59  * After checking all samples from (S1) all confirms this.
60  *
61  * Then, about NSVf[12-15], faster.nsf has 179700. When viewing it in VLC,
62  * I noticed there was about 1 NVSs chunk/s, so I ran
63  * strings faster.nsv | grep NSVs | wc -l
64  * which gave me 180. That leads me to think that NSVf[12-15] might be the
65  * file length in milliseconds.
66  * Let's try that:
67  * for f in *.nsv; do HTIME="$(od -t x4 "$f" | head -1 | sed 's/.* //')"; echo "'$f' $((0x$HTIME))s = $((0x$HTIME/1000/60)):$((0x$HTIME/1000%60))"; done
68  * except for nsvtrailer (which doesn't have an NSVf header), it reports correct time.
69  *
70  * nsvtrailer.nsv (S1) does not have any NSVf header, only NSVs chunks,
71  * so the header seems to not be mandatory. (for streaming).
72  *
73  * index slice duration check (excepts nsvtrailer.nsv):
74  * for f in [^n]*.nsv; do DUR="$(ffmpeg -i "$f" 2>/dev/null | grep 'NSVf duration' | cut -d ' ' -f 4)"; IC="$(ffmpeg -i "$f" 2>/dev/null | grep 'INDEX ENTRIES' | cut -d ' ' -f 2)"; echo "duration $DUR, slite time $(($DUR/$IC))"; done
75  */
76 
77 /*
78  * TODO:
79  * - handle timestamps !!!
80  * - use index
81  * - mime-type in probe()
82  * - seek
83  */
84 
85 #if 0
86 struct NSVf_header {
87  uint32_t chunk_tag; /* 'NSVf' */
88  uint32_t chunk_size;
89  uint32_t file_size; /* max 4GB ??? no one learns anything it seems :^) */
90  uint32_t file_length; //unknown1; /* what about MSB of file_size ? */
91  uint32_t info_strings_size; /* size of the info strings */ //unknown2;
92  uint32_t table_entries;
93  uint32_t table_entries_used; /* the left ones should be -1 */
94 };
95 
96 struct NSVs_header {
97  uint32_t chunk_tag; /* 'NSVs' */
98  uint32_t v4cc; /* or 'NONE' */
99  uint32_t a4cc; /* or 'NONE' */
100  uint16_t vwidth; /* av_assert0(vwidth%16==0) */
101  uint16_t vheight; /* av_assert0(vheight%16==0) */
102  uint8_t framerate; /* value = (framerate&0x80)?frtable[frameratex0x7f]:framerate */
103  uint16_t unknown;
104 };
105 
106 struct nsv_avchunk_header {
107  uint8_t vchunk_size_lsb;
108  uint16_t vchunk_size_msb; /* value = (vchunk_size_msb << 4) | (vchunk_size_lsb >> 4) */
109  uint16_t achunk_size;
110 };
111 
112 struct nsv_pcm_header {
113  uint8_t bits_per_sample;
114  uint8_t channel_count;
115  uint16_t sample_rate;
116 };
117 #endif
118 
119 /* variation from avi.h */
120 /*typedef struct CodecTag {
121  int id;
122  unsigned int tag;
123 } CodecTag;*/
124 
125 /* tags */
126 
127 #define T_NSVF MKTAG('N', 'S', 'V', 'f') /* file header */
128 #define T_NSVS MKTAG('N', 'S', 'V', 's') /* chunk header */
129 #define T_TOC2 MKTAG('T', 'O', 'C', '2') /* extra index marker */
130 #define T_NONE MKTAG('N', 'O', 'N', 'E') /* null a/v 4CC */
131 #define T_SUBT MKTAG('S', 'U', 'B', 'T') /* subtitle aux data */
132 #define T_ASYN MKTAG('A', 'S', 'Y', 'N') /* async a/v aux marker */
133 #define T_KEYF MKTAG('K', 'E', 'Y', 'F') /* video keyframe aux marker (addition) */
134 
135 #define TB_NSVF MKBETAG('N', 'S', 'V', 'f')
136 #define TB_NSVS MKBETAG('N', 'S', 'V', 's')
137 
138 /* hardcoded stream indexes */
139 #define NSV_ST_VIDEO 0
140 #define NSV_ST_AUDIO 1
141 #define NSV_ST_SUBT 2
142 
143 enum NSVStatus {
152 };
153 
154 typedef struct NSVStream {
155  int frame_offset; /* current frame (video) or byte (audio) counter
156  (used to compute the pts) */
157  int scale;
158  int rate;
159  int sample_size; /* audio only data */
160  int start;
161 
162  int new_frame_offset; /* temporary storage (used during seek) */
163  int cum_len; /* temporary storage (used during seek) */
164 } NSVStream;
165 
166 typedef struct NSVContext {
168  int NSVf_end;
169  uint32_t *nsvs_file_offset;
172  AVPacket ahead[2]; /* [v, a] if .data is !NULL there is something */
173  /* cached */
174  int64_t duration;
175  uint32_t vtag, atag;
176  uint16_t vwidth, vheight;
177  int16_t avsync;
179  uint32_t *nsvs_timestamps;
180  int nsvf;
181 } NSVContext;
182 
184  { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', ' ') },
185  { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') },
186  { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') },
187  { AV_CODEC_ID_VP5, MKTAG('V', 'P', '5', ' ') },
188  { AV_CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') },
189  { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', ' ') },
190  { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') },
191  { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') },
192  { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') },
193  { AV_CODEC_ID_VP8, MKTAG('V', 'P', '8', '0') },
194 /*
195  { AV_CODEC_ID_VP4, MKTAG('V', 'P', '4', ' ') },
196  { AV_CODEC_ID_VP4, MKTAG('V', 'P', '4', '0') },
197 */
198  { AV_CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') }, /* cf sample xvid decoder from nsv_codec_sdk.zip */
199  { AV_CODEC_ID_H264, MKTAG('H', '2', '6', '4') },
200  { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', '3') },
201  { AV_CODEC_ID_NONE, 0 },
202 };
203 
205  { AV_CODEC_ID_MP3, MKTAG('M', 'P', '3', ' ') },
206  { AV_CODEC_ID_AAC, MKTAG('A', 'A', 'C', ' ') },
207  { AV_CODEC_ID_AAC, MKTAG('A', 'A', 'C', 'P') },
208  { AV_CODEC_ID_AAC, MKTAG('A', 'A', 'V', ' ') },
209  { AV_CODEC_ID_AAC, MKTAG('V', 'L', 'B', ' ') },
210  { AV_CODEC_ID_SPEEX, MKTAG('S', 'P', 'X', ' ') },
211  { AV_CODEC_ID_PCM_U16LE, MKTAG('P', 'C', 'M', ' ') },
212  { AV_CODEC_ID_NONE, 0 },
213 };
214 
215 //static int nsv_load_index(AVFormatContext *s);
216 static int nsv_read_chunk(AVFormatContext *s, int fill_header);
217 
218 /* try to find something we recognize, and set the state accordingly */
220 {
221  NSVContext *nsv = s->priv_data;
222  AVIOContext *pb = s->pb;
223  uint32_t v = 0;
224  int i;
225 
226  for (i = 0; i < NSV_MAX_RESYNC; i++) {
227  if (avio_feof(pb)) {
228  av_log(s, AV_LOG_TRACE, "NSV EOF\n");
229  nsv->state = NSV_UNSYNC;
230  return -1;
231  }
232  v <<= 8;
233  v |= avio_r8(pb);
234  if (i < 8) {
235  av_log(s, AV_LOG_TRACE, "NSV resync: [%d] = %02"PRIx32"\n", i, v & 0x0FF);
236  }
237 
238  if ((v & 0x0000ffff) == 0xefbe) { /* BEEF */
239  av_log(s, AV_LOG_TRACE, "NSV resynced on BEEF after %d bytes\n", i+1);
240  nsv->state = NSV_FOUND_BEEF;
241  return 0;
242  }
243  /* we read as big-endian, thus the MK*BE* */
244  if (v == TB_NSVF) { /* NSVf */
245  av_log(s, AV_LOG_TRACE, "NSV resynced on NSVf after %d bytes\n", i+1);
246  nsv->state = NSV_FOUND_NSVF;
247  return 0;
248  }
249  if (v == MKBETAG('N', 'S', 'V', 's')) { /* NSVs */
250  av_log(s, AV_LOG_TRACE, "NSV resynced on NSVs after %d bytes\n", i+1);
251  nsv->state = NSV_FOUND_NSVS;
252  return 0;
253  }
254 
255  }
256  av_log(s, AV_LOG_TRACE, "NSV sync lost\n");
257  return -1;
258 }
259 
261 {
262  NSVContext *nsv = s->priv_data;
263  AVIOContext *pb = s->pb;
264  unsigned int av_unused file_size;
265  unsigned int size;
266  int64_t duration;
267  int strings_size;
268  int table_entries;
269  int table_entries_used;
270 
271  nsv->state = NSV_UNSYNC; /* in case we fail */
272 
273  if (nsv->nsvf) {
274  av_log(s, AV_LOG_TRACE, "Multiple NSVf\n");
275  return 0;
276  }
277  nsv->nsvf = 1;
278 
279  size = avio_rl32(pb);
280  if (size < 28)
281  return -1;
282  nsv->NSVf_end = size;
283 
284  file_size = (uint32_t)avio_rl32(pb);
285  av_log(s, AV_LOG_TRACE, "NSV NSVf chunk_size %u\n", size);
286  av_log(s, AV_LOG_TRACE, "NSV NSVf file_size %u\n", file_size);
287 
288  nsv->duration = duration = avio_rl32(pb); /* in ms */
289  av_log(s, AV_LOG_TRACE, "NSV NSVf duration %"PRId64" ms\n", duration);
290  // XXX: store it in AVStreams
291 
292  strings_size = avio_rl32(pb);
293  table_entries = avio_rl32(pb);
294  table_entries_used = avio_rl32(pb);
295  av_log(s, AV_LOG_TRACE, "NSV NSVf info-strings size: %d, table entries: %d, bis %d\n",
296  strings_size, table_entries, table_entries_used);
297  if (avio_feof(pb))
298  return -1;
299 
300  av_log(s, AV_LOG_TRACE, "NSV got header; filepos %"PRId64"\n", avio_tell(pb));
301 
302  if (strings_size > 0) {
303  char *strings; /* last byte will be '\0' to play safe with str*() */
304  char *p, *endp;
305  char *token, *value;
306  char quote;
307 
308  p = strings = av_mallocz((size_t)strings_size + 1);
309  if (!p)
310  return AVERROR(ENOMEM);
311  endp = strings + strings_size;
312  avio_read(pb, strings, strings_size);
313  while (p < endp) {
314  while (*p == ' ')
315  p++; /* strip out spaces */
316  if (p >= endp-2)
317  break;
318  token = p;
319  p = strchr(p, '=');
320  if (!p || p >= endp-2)
321  break;
322  *p++ = '\0';
323  quote = *p++;
324  value = p;
325  p = strchr(p, quote);
326  if (!p || p >= endp)
327  break;
328  *p++ = '\0';
329  av_log(s, AV_LOG_TRACE, "NSV NSVf INFO: %s='%s'\n", token, value);
330  av_dict_set(&s->metadata, token, value, 0);
331  }
332  av_free(strings);
333  }
334  if (avio_feof(pb))
335  return -1;
336 
337  av_log(s, AV_LOG_TRACE, "NSV got infos; filepos %"PRId64"\n", avio_tell(pb));
338 
339  if (table_entries_used > 0) {
340  int i;
341  nsv->index_entries = table_entries_used;
342  if((unsigned)table_entries_used >= UINT_MAX / sizeof(uint32_t))
343  return -1;
344  nsv->nsvs_file_offset = av_malloc_array((unsigned)table_entries_used, sizeof(uint32_t));
345  if (!nsv->nsvs_file_offset)
346  return AVERROR(ENOMEM);
347 
348  for(i=0;i<table_entries_used;i++) {
349  if (avio_feof(pb))
350  return AVERROR_INVALIDDATA;
351  nsv->nsvs_file_offset[i] = avio_rl32(pb) + size;
352  }
353 
354  if(table_entries > table_entries_used &&
355  avio_rl32(pb) == MKTAG('T','O','C','2')) {
356  nsv->nsvs_timestamps = av_malloc_array((unsigned)table_entries_used, sizeof(uint32_t));
357  if (!nsv->nsvs_timestamps)
358  return AVERROR(ENOMEM);
359  for(i=0;i<table_entries_used;i++) {
360  nsv->nsvs_timestamps[i] = avio_rl32(pb);
361  }
362  }
363  }
364 
365  av_log(s, AV_LOG_TRACE, "NSV got index; filepos %"PRId64"\n", avio_tell(pb));
366 
367  avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */
368 
369  if (avio_feof(pb))
370  return -1;
371  nsv->state = NSV_HAS_READ_NSVF;
372  return 0;
373 }
374 
376 {
377  NSVContext *nsv = s->priv_data;
378  AVIOContext *pb = s->pb;
379  uint32_t vtag, atag;
380  uint16_t vwidth, vheight;
382  int i;
383  AVStream *st;
384  NSVStream *nst;
385 
386  vtag = avio_rl32(pb);
387  atag = avio_rl32(pb);
388  vwidth = avio_rl16(pb);
389  vheight = avio_rl16(pb);
390  i = avio_r8(pb);
391 
392  av_log(s, AV_LOG_TRACE, "NSV NSVs framerate code %2x\n", i);
393  if(i&0x80) { /* odd way of giving native framerates from docs */
394  int t=(i & 0x7F)>>2;
395  if(t<16) framerate = (AVRational){1, t+1};
396  else framerate = (AVRational){t-15, 1};
397 
398  if(i&1){
399  framerate.num *= 1000;
400  framerate.den *= 1001;
401  }
402 
403  if((i&3)==3) framerate.num *= 24;
404  else if((i&3)==2) framerate.num *= 25;
405  else framerate.num *= 30;
406  }
407  else
408  framerate= (AVRational){i, 1};
409 
410  nsv->avsync = avio_rl16(pb);
411  nsv->framerate = framerate;
412 
413  av_log(s, AV_LOG_TRACE, "NSV NSVs vsize %dx%d\n", vwidth, vheight);
414 
415  /* XXX change to ap != NULL ? */
416  if (s->nb_streams == 0) { /* streams not yet published, let's do that */
417  nsv->vtag = vtag;
418  nsv->atag = atag;
419  nsv->vwidth = vwidth;
420  nsv->vheight = vwidth;
421  if (vtag != T_NONE) {
422  int i;
423  st = avformat_new_stream(s, NULL);
424  if (!st)
425  goto fail;
426 
427  st->id = NSV_ST_VIDEO;
428  nst = av_mallocz(sizeof(NSVStream));
429  if (!nst)
430  goto fail;
431  st->priv_data = nst;
433  st->codecpar->codec_tag = vtag;
435  st->codecpar->width = vwidth;
436  st->codecpar->height = vheight;
437  st->codecpar->bits_per_coded_sample = 24; /* depth XXX */
438 
439  avpriv_set_pts_info(st, 64, framerate.den, framerate.num);
440  st->start_time = 0;
441  st->duration = av_rescale(nsv->duration, framerate.num, 1000*framerate.den);
442 
443  for(i=0;i<nsv->index_entries;i++) {
444  if(nsv->nsvs_timestamps) {
446  0, 0, AVINDEX_KEYFRAME);
447  } else {
448  int64_t ts = av_rescale(i*nsv->duration/nsv->index_entries, framerate.num, 1000*framerate.den);
450  }
451  }
452  }
453  if (atag != T_NONE) {
454  st = avformat_new_stream(s, NULL);
455  if (!st)
456  goto fail;
457 
458  st->id = NSV_ST_AUDIO;
459  nst = av_mallocz(sizeof(NSVStream));
460  if (!nst)
461  goto fail;
462  st->priv_data = nst;
464  st->codecpar->codec_tag = atag;
466 
467  if (atag == MKTAG('A', 'A', 'V', ' ')) {
468  static const uint8_t aav_pce[] = {
469  0x12, 0x00, 0x05, 0x08, 0x48, 0x00,
470  0x20, 0x00, 0xC6, 0x40, 0x04, 0x4C,
471  0x61, 0x76, 0x63, 0x56, 0xE5, 0x00,
472  0x00, 0x00,
473  };
474  int ret;
475 
476  if ((ret = ff_alloc_extradata(st->codecpar, sizeof(aav_pce))) < 0)
477  return ret;
478 
479  st->codecpar->sample_rate = 44100;
480  memcpy(st->codecpar->extradata, aav_pce, sizeof(aav_pce));
481  }
482 
483  ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL; /* for PCM we will read a chunk later and put correct info */
484 
485  /* set timebase to common denominator of ms and framerate */
486  avpriv_set_pts_info(st, 64, 1, framerate.num*1000);
487  st->start_time = 0;
488  st->duration = (int64_t)nsv->duration * framerate.num;
489  }
490  } else {
491  if (nsv->vtag != vtag || nsv->atag != atag || nsv->vwidth != vwidth || nsv->vheight != vwidth) {
492  av_log(s, AV_LOG_TRACE, "NSV NSVs header values differ from the first one!!!\n");
493  //return -1;
494  }
495  }
496 
497  nsv->state = NSV_HAS_READ_NSVS;
498  return 0;
499 fail:
500  /* XXX */
501  nsv->state = NSV_UNSYNC;
502  return -1;
503 }
504 
506 {
507  NSVContext *nsv = s->priv_data;
508  int i, err;
509 
510  nsv->state = NSV_UNSYNC;
511  nsv->ahead[0].data = nsv->ahead[1].data = NULL;
512 
513  for (i = 0; i < NSV_MAX_RESYNC_TRIES; i++) {
514  err = nsv_resync(s);
515  if (err < 0)
516  return err;
517  if (nsv->state == NSV_FOUND_NSVF) {
518  err = nsv_parse_NSVf_header(s);
519  if (err < 0)
520  return err;
521  }
522  /* we need the first NSVs also... */
523  if (nsv->state == NSV_FOUND_NSVS) {
524  err = nsv_parse_NSVs_header(s);
525  if (err < 0)
526  return err;
527  break; /* we just want the first one */
528  }
529  }
530  if (s->nb_streams < 1) /* no luck so far */
531  return AVERROR_INVALIDDATA;
532 
533  /* now read the first chunk, so we can attempt to decode more info */
534  err = nsv_read_chunk(s, 1);
535 
536  av_log(s, AV_LOG_TRACE, "parsed header\n");
537  return err;
538 }
539 
540 static int nsv_read_chunk(AVFormatContext *s, int fill_header)
541 {
542  NSVContext *nsv = s->priv_data;
543  AVIOContext *pb = s->pb;
544  AVStream *st[2] = {NULL, NULL};
545  NSVStream *nst;
546  AVPacket *pkt;
547  int i, err = 0;
548  uint8_t auxcount; /* number of aux metadata, also 4 bits of vsize */
549  uint32_t vsize;
550  uint16_t asize;
551  uint16_t auxsize;
552  int ret;
553 
554  if (nsv->ahead[0].data || nsv->ahead[1].data)
555  return 0; //-1; /* hey! eat what you've in your plate first! */
556 
557 null_chunk_retry:
558  if (avio_feof(pb))
559  return -1;
560 
561  for (i = 0; i < NSV_MAX_RESYNC_TRIES && nsv->state < NSV_FOUND_NSVS && !err; i++)
562  err = nsv_resync(s);
563  if (err < 0)
564  return err;
565  if (nsv->state == NSV_FOUND_NSVS)
566  err = nsv_parse_NSVs_header(s);
567  if (err < 0)
568  return err;
569  if (nsv->state != NSV_HAS_READ_NSVS && nsv->state != NSV_FOUND_BEEF)
570  return -1;
571 
572  auxcount = avio_r8(pb);
573  vsize = avio_rl16(pb);
574  asize = avio_rl16(pb);
575  vsize = (vsize << 4) | (auxcount >> 4);
576  auxcount &= 0x0f;
577  av_log(s, AV_LOG_TRACE, "NSV CHUNK %d aux, %"PRIu32" bytes video, %d bytes audio\n", auxcount, vsize, asize);
578  /* skip aux stuff */
579  for (i = 0; i < auxcount; i++) {
580  uint32_t av_unused auxtag;
581  auxsize = avio_rl16(pb);
582  auxtag = avio_rl32(pb);
583  avio_skip(pb, auxsize);
584  vsize -= auxsize + sizeof(uint16_t) + sizeof(uint32_t); /* that's becoming brain-dead */
585  }
586 
587  if (avio_feof(pb))
588  return -1;
589  if (!vsize && !asize) {
590  nsv->state = NSV_UNSYNC;
591  goto null_chunk_retry;
592  }
593 
594  /* map back streams to v,a */
595  if (s->nb_streams > 0)
596  st[s->streams[0]->id] = s->streams[0];
597  if (s->nb_streams > 1)
598  st[s->streams[1]->id] = s->streams[1];
599 
600  if (vsize && st[NSV_ST_VIDEO]) {
601  nst = st[NSV_ST_VIDEO]->priv_data;
602  pkt = &nsv->ahead[NSV_ST_VIDEO];
603  if ((ret = av_get_packet(pb, pkt, vsize)) < 0)
604  return ret;
605  pkt->stream_index = st[NSV_ST_VIDEO]->index;//NSV_ST_VIDEO;
606  pkt->dts = nst->frame_offset;
607  pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */
608  for (i = 0; i < FFMIN(8, vsize); i++)
609  av_log(s, AV_LOG_TRACE, "NSV video: [%d] = %02x\n", i, pkt->data[i]);
610  }
611  if(st[NSV_ST_VIDEO])
612  ((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset++;
613 
614  if (asize && st[NSV_ST_AUDIO]) {
615  nst = st[NSV_ST_AUDIO]->priv_data;
616  pkt = &nsv->ahead[NSV_ST_AUDIO];
617  /* read raw audio specific header on the first audio chunk... */
618  /* on ALL audio chunks ?? seems so! */
619  if (asize && st[NSV_ST_AUDIO]->codecpar->codec_tag == MKTAG('P', 'C', 'M', ' ')/* && fill_header*/) {
620  uint8_t bps;
621  uint8_t channels;
622  uint16_t samplerate;
623  bps = avio_r8(pb);
624  channels = avio_r8(pb);
625  samplerate = avio_rl16(pb);
626  if (!channels || !samplerate)
627  return AVERROR_INVALIDDATA;
628  asize-=4;
629  av_log(s, AV_LOG_TRACE, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate);
630  if (fill_header) {
631  ffstream(st[NSV_ST_AUDIO])->need_parsing = AVSTREAM_PARSE_NONE; /* we know everything */
632  if (bps != 16) {
633  av_log(s, AV_LOG_TRACE, "NSV AUDIO bit/sample != 16 (%d)!!!\n", bps);
634  }
635  bps /= channels; // ???
636  if (bps == 8)
638  samplerate /= 4;/* UGH ??? XXX */
639  channels = 1;
641  st[NSV_ST_AUDIO]->codecpar->sample_rate = samplerate;
642  av_log(s, AV_LOG_TRACE, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate);
643  }
644  }
645  if ((ret = av_get_packet(pb, pkt, asize)) < 0)
646  return ret;
647  pkt->stream_index = st[NSV_ST_AUDIO]->index;//NSV_ST_AUDIO;
648  pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */
649  if( nsv->state == NSV_HAS_READ_NSVS && st[NSV_ST_VIDEO] ) {
650  /* on a nsvs frame we have new information on a/v sync */
651  pkt->dts = (((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset-1);
652  pkt->dts *= (int64_t)1000 * nsv->framerate.den;
653  pkt->dts += (int64_t)nsv->avsync * nsv->framerate.num;
654  av_log(s, AV_LOG_TRACE, "NSV AUDIO: sync:%d, dts:%"PRId64, nsv->avsync, pkt->dts);
655  }
656  nst->frame_offset++;
657  }
658 
659  nsv->state = NSV_UNSYNC;
660  return 0;
661 }
662 
663 
665 {
666  NSVContext *nsv = s->priv_data;
667  int i, err = 0;
668 
669  /* in case we don't already have something to eat ... */
670  if (!nsv->ahead[0].data && !nsv->ahead[1].data)
671  err = nsv_read_chunk(s, 0);
672  if (err < 0)
673  return err;
674 
675  /* now pick one of the plates */
676  for (i = 0; i < 2; i++) {
677  if (nsv->ahead[i].data) {
678  av_packet_move_ref(pkt, &nsv->ahead[i]);
679  return 0;
680  }
681  }
682 
683  /* this restaurant is not provisioned :^] */
684  return -1;
685 }
686 
687 static int nsv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
688 {
689  NSVContext *nsv = s->priv_data;
690  AVStream *st = s->streams[stream_index];
691  FFStream *const sti = ffstream(st);
692  NSVStream *nst = st->priv_data;
693  int index;
694 
695  index = av_index_search_timestamp(st, timestamp, flags);
696  if(index < 0)
697  return -1;
698 
699  if (avio_seek(s->pb, sti->index_entries[index].pos, SEEK_SET) < 0)
700  return -1;
701 
703  nsv->state = NSV_UNSYNC;
704  return 0;
705 }
706 
708 {
709  NSVContext *nsv = s->priv_data;
710 
711  av_freep(&nsv->nsvs_file_offset);
712  av_freep(&nsv->nsvs_timestamps);
713  if (nsv->ahead[0].data)
714  av_packet_unref(&nsv->ahead[0]);
715  if (nsv->ahead[1].data)
716  av_packet_unref(&nsv->ahead[1]);
717  return 0;
718 }
719 
720 static int nsv_probe(const AVProbeData *p)
721 {
722  int i, score = 0;
723 
724  /* check file header */
725  /* streamed files might not have any header */
726  if (p->buf[0] == 'N' && p->buf[1] == 'S' &&
727  p->buf[2] == 'V' && (p->buf[3] == 'f' || p->buf[3] == 's'))
728  return AVPROBE_SCORE_MAX;
729  /* XXX: do streamed files always start at chunk boundary ?? */
730  /* or do we need to search NSVs in the byte stream ? */
731  /* seems the servers don't bother starting clean chunks... */
732  /* sometimes even the first header is at 9KB or something :^) */
733  for (i = 1; i < p->buf_size - 3; i++) {
734  if (AV_RL32(p->buf + i) == AV_RL32("NSVs")) {
735  /* Get the chunk size and check if at the end we are getting 0xBEEF */
736  int vsize = AV_RL24(p->buf+i+19) >> 4;
737  int asize = AV_RL16(p->buf+i+22);
738  int offset = i + 23 + asize + vsize + 1;
739  if (offset <= p->buf_size - 2 && AV_RL16(p->buf + offset) == 0xBEEF)
740  return 4*AVPROBE_SCORE_MAX/5;
741  score = AVPROBE_SCORE_MAX/5;
742  }
743  }
744  /* so we'll have more luck on extension... */
745  if (av_match_ext(p->filename, "nsv"))
747  /* FIXME: add mime-type check */
748  return score;
749 }
750 
752  .p.name = "nsv",
753  .p.long_name = NULL_IF_CONFIG_SMALL("Nullsoft Streaming Video"),
754  .priv_data_size = sizeof(NSVContext),
755  .flags_internal = FF_FMT_INIT_CLEANUP,
761 };
nsv_read_chunk
static int nsv_read_chunk(AVFormatContext *s, int fill_header)
Definition: nsvdec.c:540
NSVContext::nsvs_timestamps
uint32_t * nsvs_timestamps
Definition: nsvdec.c:179
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:427
NSV_FOUND_NSVF
@ NSV_FOUND_NSVF
Definition: nsvdec.c:145
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
FF_FMT_INIT_CLEANUP
#define FF_FMT_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition: internal.h:46
NSV_HAS_READ_NSVS
@ NSV_HAS_READ_NSVS
Definition: nsvdec.c:148
NSV_HAS_READ_NSVF
@ NSV_HAS_READ_NSVF
Definition: nsvdec.c:146
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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. Frame references ownership and permissions
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
NSVContext::base_offset
int base_offset
Definition: nsvdec.c:167
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AVStream::priv_data
void * priv_data
Definition: avformat.h:768
NSVContext::avsync
int16_t avsync
Definition: nsvdec.c:177
NSVStatus
NSVStatus
Definition: nsvdec.c:143
NSV_ST_VIDEO
#define NSV_ST_VIDEO
Definition: nsvdec.c:139
NSVStream
Definition: nsvdec.c:154
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:65
av_unused
#define av_unused
Definition: attributes.h:131
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
AVPacket::data
uint8_t * data
Definition: packet.h:522
AV_CODEC_ID_VP6
@ AV_CODEC_ID_VP6
Definition: codec_id.h:143
NSVStream::scale
int scale
Definition: nsvdec.c:157
NSVContext::NSVf_end
int NSVf_end
Definition: nsvdec.c:168
nsv_read_seek
static int nsv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: nsvdec.c:687
NSVStream::cum_len
int cum_len
Definition: nsvdec.c:163
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
mathematics.h
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:454
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:577
sample_rate
sample_rate
Definition: ffmpeg_filter.c:425
NSVContext::vheight
uint16_t vheight
Definition: nsvdec.c:176
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:610
NSVContext
Definition: nsvdec.c:166
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:853
nsv_parse_NSVs_header
static int nsv_parse_NSVs_header(AVFormatContext *s)
Definition: nsvdec.c:375
T_NONE
#define T_NONE
Definition: nsvdec.c:130
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:475
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:423
fail
#define fail()
Definition: checkasm.h:179
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
av_add_index_entry
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.
Definition: seek.c:120
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
NSVContext::vwidth
uint16_t vwidth
Definition: nsvdec.c:176
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:441
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:802
avio_rl16
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:713
AVRational::num
int num
Numerator.
Definition: rational.h:59
nsv_read_header
static int nsv_read_header(AVFormatContext *s)
Definition: nsvdec.c:505
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:206
pkt
AVPacket * pkt
Definition: movenc.c:59
NSVContext::framerate
AVRational framerate
Definition: nsvdec.c:178
AVCodecTag
Definition: internal.h:48
duration
int64_t duration
Definition: movenc.c:64
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:41
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
NSVStream::rate
int rate
Definition: nsvdec.c:158
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
NSV_GOT_AUDIO
@ NSV_GOT_AUDIO
Definition: nsvdec.c:151
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
AVProbeData::filename
const char * filename
Definition: avformat.h:452
av_match_ext
int av_match_ext(const char *filename, const char *extensions)
Return a positive value if the given filename has one of the given extensions, 0 otherwise.
Definition: format.c:42
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:604
channels
channels
Definition: aptx.h:31
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
NSV_FOUND_BEEF
@ NSV_FOUND_BEEF
Definition: nsvdec.c:149
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:392
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
framerate
float framerate
Definition: av1_levels.c:29
NSVContext::duration
int64_t duration
Definition: nsvdec.c:174
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:550
NULL
#define NULL
Definition: coverity.c:32
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVSTREAM_PARSE_NONE
@ AVSTREAM_PARSE_NONE
Definition: avformat.h:592
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
NSVContext::ahead
AVPacket ahead[2]
Definition: nsvdec.c:172
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
av_packet_move_ref
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: avpacket.c:484
NSVStream::frame_offset
int frame_offset
Definition: nsvdec.c:155
index
int index
Definition: gxfenc.c:89
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:461
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:442
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:729
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:145
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:303
FFStream
Definition: internal.h:199
bps
unsigned bps
Definition: movenc.c:1787
size
int size
Definition: twinvq_data.h:10344
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
nsv_codec_video_tags
static const AVCodecTag nsv_codec_video_tags[]
Definition: nsvdec.c:183
AV_RL24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_RL24
Definition: bytestream.h:93
nsv_read_packet
static int nsv_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: nsvdec.c:664
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:35
nsv_probe
static int nsv_probe(const AVProbeData *p)
Definition: nsvdec.c:720
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:521
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:602
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
attributes.h
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:528
AV_CODEC_ID_VP5
@ AV_CODEC_ID_VP5
Definition: codec_id.h:142
AV_CODEC_ID_VP3
@ AV_CODEC_ID_VP3
Definition: codec_id.h:81
NSVContext::vtag
uint32_t vtag
Definition: nsvdec.c:175
nsv_resync
static int nsv_resync(AVFormatContext *s)
Definition: nsvdec.c:219
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVCodecParameters::height
int height
Definition: codec_par.h:135
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
nsv_parse_NSVf_header
static int nsv_parse_NSVf_header(AVFormatContext *s)
Definition: nsvdec.c:260
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
demux.h
NSV_MAX_RESYNC
#define NSV_MAX_RESYNC
Definition: nsvdec.c:35
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:103
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:755
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:230
NSV_ST_AUDIO
#define NSV_ST_AUDIO
Definition: nsvdec.c:140
avformat.h
dict.h
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:749
NSV_GOT_VIDEO
@ NSV_GOT_VIDEO
Definition: nsvdec.c:150
AVRational::den
int den
Denominator.
Definition: rational.h:60
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:611
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:603
AVPacket::stream_index
int stream_index
Definition: packet.h:524
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:317
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:255
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:110
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:333
NSV_FOUND_NSVS
@ NSV_FOUND_NSVS
Definition: nsvdec.c:147
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:378
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:499
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
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:88
FFInputFormat
Definition: demux.h:31
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:593
NSVContext::atag
uint32_t atag
Definition: nsvdec.c:175
AV_CODEC_ID_PCM_U16LE
@ AV_CODEC_ID_PCM_U16LE
Definition: codec_id.h:330
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
TB_NSVF
#define TB_NSVF
Definition: nsvdec.c:135
NSVStream::start
int start
Definition: nsvdec.c:160
NSVContext::state
enum NSVStatus state
Definition: nsvdec.c:171
nsv_codec_audio_tags
static const AVCodecTag nsv_codec_audio_tags[]
Definition: nsvdec.c:204
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
NSVStream::new_frame_offset
int new_frame_offset
Definition: nsvdec.c:162
ff_nsv_demuxer
const FFInputFormat ff_nsv_demuxer
Definition: nsvdec.c:751
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:792
NSVContext::nsvf
int nsvf
Definition: nsvdec.c:180
NSV_MAX_RESYNC_TRIES
#define NSV_MAX_RESYNC_TRIES
Definition: nsvdec.c:36
nsv_read_close
static int nsv_read_close(AVFormatContext *s)
Definition: nsvdec.c:707
NSVStream::sample_size
int sample_size
Definition: nsvdec.c:159
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:243
NSV_UNSYNC
@ NSV_UNSYNC
Definition: nsvdec.c:144
NSVContext::nsvs_file_offset
uint32_t * nsvs_file_offset
Definition: nsvdec.c:169
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:239
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:345
NSVContext::index_entries
int index_entries
Definition: nsvdec.c:170