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 "internal.h"
28 #include "libavutil/dict.h"
29 #include "libavutil/intreadwrite.h"
30 
31 //#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!!
32 #define CHECK_SUBSEQUENT_NSVS
33 //#define DISABLE_AUDIO
34 
35 /* max bytes to crawl for trying to resync
36  * stupid streaming servers don't start at chunk boundaries...
37  */
38 #define NSV_MAX_RESYNC (500*1024)
39 #define NSV_MAX_RESYNC_TRIES 300
40 
41 /*
42  * References:
43  * (1) http://www.multimedia.cx/nsv-format.txt
44  * seems someone came to the same conclusions as me, and updated it:
45  * (2) http://www.stud.ktu.lt/~vitslav/nsv/nsv-format.txt
46  * http://www.stud.ktu.lt/~vitslav/nsv/
47  * official docs
48  * (3) http://ultravox.aol.com/NSVFormat.rtf
49  * Sample files:
50  * (S1) http://www.nullsoft.com/nsv/samples/
51  * http://www.nullsoft.com/nsv/samples/faster.nsv
52  * http://streamripper.sourceforge.net/openbb/read.php?TID=492&page=4
53  */
54 
55 /*
56  * notes on the header (Francois Revol):
57  *
58  * It is followed by strings, then a table, but nothing tells
59  * where the table begins according to (1). After checking faster.nsv,
60  * I believe NVSf[16-19] gives the size of the strings data
61  * (that is the offset of the data table after the header).
62  * After checking all samples from (S1) all confirms this.
63  *
64  * Then, about NSVf[12-15], faster.nsf has 179700. When veiwing it in VLC,
65  * I noticed there was about 1 NVSs chunk/s, so I ran
66  * strings faster.nsv | grep NSVs | wc -l
67  * which gave me 180. That leads me to think that NSVf[12-15] might be the
68  * file length in milliseconds.
69  * Let's try that:
70  * 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
71  * except for nstrailer (which doesn't have an NSVf header), it repports correct time.
72  *
73  * nsvtrailer.nsv (S1) does not have any NSVf header, only NSVs chunks,
74  * so the header seems to not be mandatory. (for streaming).
75  *
76  * index slice duration check (excepts nsvtrailer.nsv):
77  * 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
78  */
79 
80 /*
81  * TODO:
82  * - handle timestamps !!!
83  * - use index
84  * - mime-type in probe()
85  * - seek
86  */
87 
88 #if 0
89 struct NSVf_header {
90  uint32_t chunk_tag; /* 'NSVf' */
91  uint32_t chunk_size;
92  uint32_t file_size; /* max 4GB ??? no one learns anything it seems :^) */
93  uint32_t file_length; //unknown1; /* what about MSB of file_size ? */
94  uint32_t info_strings_size; /* size of the info strings */ //unknown2;
95  uint32_t table_entries;
96  uint32_t table_entries_used; /* the left ones should be -1 */
97 };
98 
99 struct NSVs_header {
100  uint32_t chunk_tag; /* 'NSVs' */
101  uint32_t v4cc; /* or 'NONE' */
102  uint32_t a4cc; /* or 'NONE' */
103  uint16_t vwidth; /* av_assert(vwidth%16==0) */
104  uint16_t vheight; /* av_assert(vheight%16==0) */
105  uint8_t framerate; /* value = (framerate&0x80)?frtable[frameratex0x7f]:framerate */
106  uint16_t unknown;
107 };
108 
109 struct nsv_avchunk_header {
110  uint8_t vchunk_size_lsb;
111  uint16_t vchunk_size_msb; /* value = (vchunk_size_msb << 4) | (vchunk_size_lsb >> 4) */
112  uint16_t achunk_size;
113 };
114 
115 struct nsv_pcm_header {
116  uint8_t bits_per_sample;
117  uint8_t channel_count;
118  uint16_t sample_rate;
119 };
120 #endif
121 
122 /* variation from avi.h */
123 /*typedef struct CodecTag {
124  int id;
125  unsigned int tag;
126 } CodecTag;*/
127 
128 /* tags */
129 
130 #define T_NSVF MKTAG('N', 'S', 'V', 'f') /* file header */
131 #define T_NSVS MKTAG('N', 'S', 'V', 's') /* chunk header */
132 #define T_TOC2 MKTAG('T', 'O', 'C', '2') /* extra index marker */
133 #define T_NONE MKTAG('N', 'O', 'N', 'E') /* null a/v 4CC */
134 #define T_SUBT MKTAG('S', 'U', 'B', 'T') /* subtitle aux data */
135 #define T_ASYN MKTAG('A', 'S', 'Y', 'N') /* async a/v aux marker */
136 #define T_KEYF MKTAG('K', 'E', 'Y', 'F') /* video keyframe aux marker (addition) */
137 
138 #define TB_NSVF MKBETAG('N', 'S', 'V', 'f')
139 #define TB_NSVS MKBETAG('N', 'S', 'V', 's')
140 
141 /* hardcoded stream indexes */
142 #define NSV_ST_VIDEO 0
143 #define NSV_ST_AUDIO 1
144 #define NSV_ST_SUBT 2
145 
146 enum NSVStatus {
155 };
156 
157 typedef struct NSVStream {
158  int frame_offset; /* current frame (video) or byte (audio) counter
159  (used to compute the pts) */
160  int scale;
161  int rate;
162  int sample_size; /* audio only data */
163  int start;
164 
165  int new_frame_offset; /* temporary storage (used during seek) */
166  int cum_len; /* temporary storage (used during seek) */
167 } NSVStream;
168 
169 typedef struct {
171  int NSVf_end;
172  uint32_t *nsvs_file_offset;
175  AVPacket ahead[2]; /* [v, a] if .data is !NULL there is something */
176  /* cached */
177  int64_t duration;
178  uint32_t vtag, atag;
179  uint16_t vwidth, vheight;
180  int16_t avsync;
182  uint32_t *nsvs_timestamps;
183  //DVDemuxContext* dv_demux;
184 } NSVContext;
185 
187  { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', ' ') },
188  { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') },
189  { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') },
190  { AV_CODEC_ID_VP5, MKTAG('V', 'P', '5', ' ') },
191  { AV_CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') },
192  { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', ' ') },
193  { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') },
194  { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') },
195  { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') },
196  { AV_CODEC_ID_VP8, MKTAG('V', 'P', '8', '0') },
197 /*
198  { AV_CODEC_ID_VP4, MKTAG('V', 'P', '4', ' ') },
199  { AV_CODEC_ID_VP4, MKTAG('V', 'P', '4', '0') },
200 */
201  { AV_CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') }, /* cf sample xvid decoder from nsv_codec_sdk.zip */
202  { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', '3') },
203  { AV_CODEC_ID_NONE, 0 },
204 };
205 
207  { AV_CODEC_ID_MP3, MKTAG('M', 'P', '3', ' ') },
208  { AV_CODEC_ID_AAC, MKTAG('A', 'A', 'C', ' ') },
209  { AV_CODEC_ID_AAC, MKTAG('A', 'A', 'C', 'P') },
210  { AV_CODEC_ID_AAC, MKTAG('V', 'L', 'B', ' ') },
211  { AV_CODEC_ID_SPEEX, MKTAG('S', 'P', 'X', ' ') },
212  { AV_CODEC_ID_PCM_U16LE, MKTAG('P', 'C', 'M', ' ') },
213  { AV_CODEC_ID_NONE, 0 },
214 };
215 
216 //static int nsv_load_index(AVFormatContext *s);
217 static int nsv_read_chunk(AVFormatContext *s, int fill_header);
218 
219 #define print_tag(str, tag, size) \
220  av_dlog(NULL, "%s: tag=%c%c%c%c\n", \
221  str, tag & 0xff, \
222  (tag >> 8) & 0xff, \
223  (tag >> 16) & 0xff, \
224  (tag >> 24) & 0xff);
225 
226 /* try to find something we recognize, and set the state accordingly */
228 {
229  NSVContext *nsv = s->priv_data;
230  AVIOContext *pb = s->pb;
231  uint32_t v = 0;
232  int i;
233 
234  av_dlog(s, "%s(), offset = %"PRId64", state = %d\n", __FUNCTION__, avio_tell(pb), nsv->state);
235 
236  //nsv->state = NSV_UNSYNC;
237 
238  for (i = 0; i < NSV_MAX_RESYNC; i++) {
239  if (url_feof(pb)) {
240  av_dlog(s, "NSV EOF\n");
241  nsv->state = NSV_UNSYNC;
242  return -1;
243  }
244  v <<= 8;
245  v |= avio_r8(pb);
246  if (i < 8) {
247  av_dlog(s, "NSV resync: [%d] = %02x\n", i, v & 0x0FF);
248  }
249 
250  if ((v & 0x0000ffff) == 0xefbe) { /* BEEF */
251  av_dlog(s, "NSV resynced on BEEF after %d bytes\n", i+1);
252  nsv->state = NSV_FOUND_BEEF;
253  return 0;
254  }
255  /* we read as big-endian, thus the MK*BE* */
256  if (v == TB_NSVF) { /* NSVf */
257  av_dlog(s, "NSV resynced on NSVf after %d bytes\n", i+1);
258  nsv->state = NSV_FOUND_NSVF;
259  return 0;
260  }
261  if (v == MKBETAG('N', 'S', 'V', 's')) { /* NSVs */
262  av_dlog(s, "NSV resynced on NSVs after %d bytes\n", i+1);
263  nsv->state = NSV_FOUND_NSVS;
264  return 0;
265  }
266 
267  }
268  av_dlog(s, "NSV sync lost\n");
269  return -1;
270 }
271 
273 {
274  NSVContext *nsv = s->priv_data;
275  AVIOContext *pb = s->pb;
276  unsigned int av_unused file_size;
277  unsigned int size;
278  int64_t duration;
279  int strings_size;
280  int table_entries;
281  int table_entries_used;
282 
283  av_dlog(s, "%s()\n", __FUNCTION__);
284 
285  nsv->state = NSV_UNSYNC; /* in case we fail */
286 
287  size = avio_rl32(pb);
288  if (size < 28)
289  return -1;
290  nsv->NSVf_end = size;
291 
292  //s->file_size = (uint32_t)avio_rl32(pb);
293  file_size = (uint32_t)avio_rl32(pb);
294  av_dlog(s, "NSV NSVf chunk_size %u\n", size);
295  av_dlog(s, "NSV NSVf file_size %u\n", file_size);
296 
297  nsv->duration = duration = avio_rl32(pb); /* in ms */
298  av_dlog(s, "NSV NSVf duration %"PRId64" ms\n", duration);
299  // XXX: store it in AVStreams
300 
301  strings_size = avio_rl32(pb);
302  table_entries = avio_rl32(pb);
303  table_entries_used = avio_rl32(pb);
304  av_dlog(s, "NSV NSVf info-strings size: %d, table entries: %d, bis %d\n",
305  strings_size, table_entries, table_entries_used);
306  if (url_feof(pb))
307  return -1;
308 
309  av_dlog(s, "NSV got header; filepos %"PRId64"\n", avio_tell(pb));
310 
311  if (strings_size > 0) {
312  char *strings; /* last byte will be '\0' to play safe with str*() */
313  char *p, *endp;
314  char *token, *value;
315  char quote;
316 
317  p = strings = av_mallocz((size_t)strings_size + 1);
318  if (!p)
319  return AVERROR(ENOMEM);
320  endp = strings + strings_size;
321  avio_read(pb, strings, strings_size);
322  while (p < endp) {
323  while (*p == ' ')
324  p++; /* strip out spaces */
325  if (p >= endp-2)
326  break;
327  token = p;
328  p = strchr(p, '=');
329  if (!p || p >= endp-2)
330  break;
331  *p++ = '\0';
332  quote = *p++;
333  value = p;
334  p = strchr(p, quote);
335  if (!p || p >= endp)
336  break;
337  *p++ = '\0';
338  av_dlog(s, "NSV NSVf INFO: %s='%s'\n", token, value);
339  av_dict_set(&s->metadata, token, value, 0);
340  }
341  av_free(strings);
342  }
343  if (url_feof(pb))
344  return -1;
345 
346  av_dlog(s, "NSV got infos; filepos %"PRId64"\n", avio_tell(pb));
347 
348  if (table_entries_used > 0) {
349  int i;
350  nsv->index_entries = table_entries_used;
351  if((unsigned)table_entries_used >= UINT_MAX / sizeof(uint32_t))
352  return -1;
353  nsv->nsvs_file_offset = av_malloc((unsigned)table_entries_used * sizeof(uint32_t));
354  if (!nsv->nsvs_file_offset)
355  return AVERROR(ENOMEM);
356 
357  for(i=0;i<table_entries_used;i++)
358  nsv->nsvs_file_offset[i] = avio_rl32(pb) + size;
359 
360  if(table_entries > table_entries_used &&
361  avio_rl32(pb) == MKTAG('T','O','C','2')) {
362  nsv->nsvs_timestamps = av_malloc((unsigned)table_entries_used*sizeof(uint32_t));
363  if (!nsv->nsvs_timestamps)
364  return AVERROR(ENOMEM);
365  for(i=0;i<table_entries_used;i++) {
366  nsv->nsvs_timestamps[i] = avio_rl32(pb);
367  }
368  }
369  }
370 
371  av_dlog(s, "NSV got index; filepos %"PRId64"\n", avio_tell(pb));
372 
373 #ifdef DEBUG_DUMP_INDEX
374 #define V(v) ((v<0x20 || v > 127)?'.':v)
375  /* dump index */
376  av_dlog(s, "NSV %d INDEX ENTRIES:\n", table_entries);
377  av_dlog(s, "NSV [dataoffset][fileoffset]\n", table_entries);
378  for (i = 0; i < table_entries; i++) {
379  unsigned char b[8];
380  avio_seek(pb, size + nsv->nsvs_file_offset[i], SEEK_SET);
381  avio_read(pb, b, 8);
382  av_dlog(s, "NSV [0x%08lx][0x%08lx]: %02x %02x %02x %02x %02x %02x %02x %02x"
383  "%c%c%c%c%c%c%c%c\n",
384  nsv->nsvs_file_offset[i], size + nsv->nsvs_file_offset[i],
385  b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
386  V(b[0]), V(b[1]), V(b[2]), V(b[3]), V(b[4]), V(b[5]), V(b[6]), V(b[7]) );
387  }
388  //avio_seek(pb, size, SEEK_SET); /* go back to end of header */
389 #undef V
390 #endif
391 
392  avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */
393 
394  if (url_feof(pb))
395  return -1;
396  nsv->state = NSV_HAS_READ_NSVF;
397  return 0;
398 }
399 
401 {
402  NSVContext *nsv = s->priv_data;
403  AVIOContext *pb = s->pb;
404  uint32_t vtag, atag;
405  uint16_t vwidth, vheight;
406  AVRational framerate;
407  int i;
408  AVStream *st;
409  NSVStream *nst;
410  av_dlog(s, "%s()\n", __FUNCTION__);
411 
412  vtag = avio_rl32(pb);
413  atag = avio_rl32(pb);
414  vwidth = avio_rl16(pb);
415  vheight = avio_rl16(pb);
416  i = avio_r8(pb);
417 
418  av_dlog(s, "NSV NSVs framerate code %2x\n", i);
419  if(i&0x80) { /* odd way of giving native framerates from docs */
420  int t=(i & 0x7F)>>2;
421  if(t<16) framerate = (AVRational){1, t+1};
422  else framerate = (AVRational){t-15, 1};
423 
424  if(i&1){
425  framerate.num *= 1000;
426  framerate.den *= 1001;
427  }
428 
429  if((i&3)==3) framerate.num *= 24;
430  else if((i&3)==2) framerate.num *= 25;
431  else framerate.num *= 30;
432  }
433  else
434  framerate= (AVRational){i, 1};
435 
436  nsv->avsync = avio_rl16(pb);
437  nsv->framerate = framerate;
438 
439  print_tag("NSV NSVs vtag", vtag, 0);
440  print_tag("NSV NSVs atag", atag, 0);
441  av_dlog(s, "NSV NSVs vsize %dx%d\n", vwidth, vheight);
442 
443  /* XXX change to ap != NULL ? */
444  if (s->nb_streams == 0) { /* streams not yet published, let's do that */
445  nsv->vtag = vtag;
446  nsv->atag = atag;
447  nsv->vwidth = vwidth;
448  nsv->vheight = vwidth;
449  if (vtag != T_NONE) {
450  int i;
451  st = avformat_new_stream(s, NULL);
452  if (!st)
453  goto fail;
454 
455  st->id = NSV_ST_VIDEO;
456  nst = av_mallocz(sizeof(NSVStream));
457  if (!nst)
458  goto fail;
459  st->priv_data = nst;
461  st->codec->codec_tag = vtag;
462  st->codec->codec_id = ff_codec_get_id(nsv_codec_video_tags, vtag);
463  st->codec->width = vwidth;
464  st->codec->height = vheight;
465  st->codec->bits_per_coded_sample = 24; /* depth XXX */
466 
467  avpriv_set_pts_info(st, 64, framerate.den, framerate.num);
468  st->start_time = 0;
469  st->duration = av_rescale(nsv->duration, framerate.num, 1000*framerate.den);
470 
471  for(i=0;i<nsv->index_entries;i++) {
472  if(nsv->nsvs_timestamps) {
474  0, 0, AVINDEX_KEYFRAME);
475  } else {
476  int64_t ts = av_rescale(i*nsv->duration/nsv->index_entries, framerate.num, 1000*framerate.den);
477  av_add_index_entry(st, nsv->nsvs_file_offset[i], ts, 0, 0, AVINDEX_KEYFRAME);
478  }
479  }
480  }
481  if (atag != T_NONE) {
482 #ifndef DISABLE_AUDIO
483  st = avformat_new_stream(s, NULL);
484  if (!st)
485  goto fail;
486 
487  st->id = NSV_ST_AUDIO;
488  nst = av_mallocz(sizeof(NSVStream));
489  if (!nst)
490  goto fail;
491  st->priv_data = nst;
493  st->codec->codec_tag = atag;
494  st->codec->codec_id = ff_codec_get_id(nsv_codec_audio_tags, atag);
495 
496  st->need_parsing = AVSTREAM_PARSE_FULL; /* for PCM we will read a chunk later and put correct info */
497 
498  /* set timebase to common denominator of ms and framerate */
499  avpriv_set_pts_info(st, 64, 1, framerate.num*1000);
500  st->start_time = 0;
501  st->duration = (int64_t)nsv->duration * framerate.num;
502 #endif
503  }
504 #ifdef CHECK_SUBSEQUENT_NSVS
505  } else {
506  if (nsv->vtag != vtag || nsv->atag != atag || nsv->vwidth != vwidth || nsv->vheight != vwidth) {
507  av_dlog(s, "NSV NSVs header values differ from the first one!!!\n");
508  //return -1;
509  }
510 #endif /* CHECK_SUBSEQUENT_NSVS */
511  }
512 
513  nsv->state = NSV_HAS_READ_NSVS;
514  return 0;
515 fail:
516  /* XXX */
517  nsv->state = NSV_UNSYNC;
518  return -1;
519 }
520 
522 {
523  NSVContext *nsv = s->priv_data;
524  int i, err;
525 
526  av_dlog(s, "%s()\n", __FUNCTION__);
527  av_dlog(s, "filename '%s'\n", s->filename);
528 
529  nsv->state = NSV_UNSYNC;
530  nsv->ahead[0].data = nsv->ahead[1].data = NULL;
531 
532  for (i = 0; i < NSV_MAX_RESYNC_TRIES; i++) {
533  if (nsv_resync(s) < 0)
534  return -1;
535  if (nsv->state == NSV_FOUND_NSVF) {
536  err = nsv_parse_NSVf_header(s);
537  if (err < 0)
538  return err;
539  }
540  /* we need the first NSVs also... */
541  if (nsv->state == NSV_FOUND_NSVS) {
542  err = nsv_parse_NSVs_header(s);
543  if (err < 0)
544  return err;
545  break; /* we just want the first one */
546  }
547  }
548  if (s->nb_streams < 1) /* no luck so far */
549  return -1;
550  /* now read the first chunk, so we can attempt to decode more info */
551  err = nsv_read_chunk(s, 1);
552 
553  av_dlog(s, "parsed header\n");
554  return err;
555 }
556 
557 static int nsv_read_chunk(AVFormatContext *s, int fill_header)
558 {
559  NSVContext *nsv = s->priv_data;
560  AVIOContext *pb = s->pb;
561  AVStream *st[2] = {NULL, NULL};
562  NSVStream *nst;
563  AVPacket *pkt;
564  int i, err = 0;
565  uint8_t auxcount; /* number of aux metadata, also 4 bits of vsize */
566  uint32_t vsize;
567  uint16_t asize;
568  uint16_t auxsize;
569 
570  av_dlog(s, "%s(%d)\n", __FUNCTION__, fill_header);
571 
572  if (nsv->ahead[0].data || nsv->ahead[1].data)
573  return 0; //-1; /* hey! eat what you've in your plate first! */
574 
575 null_chunk_retry:
576  if (url_feof(pb))
577  return -1;
578 
579  for (i = 0; i < NSV_MAX_RESYNC_TRIES && nsv->state < NSV_FOUND_NSVS && !err; i++)
580  err = nsv_resync(s);
581  if (err < 0)
582  return err;
583  if (nsv->state == NSV_FOUND_NSVS)
584  err = nsv_parse_NSVs_header(s);
585  if (err < 0)
586  return err;
587  if (nsv->state != NSV_HAS_READ_NSVS && nsv->state != NSV_FOUND_BEEF)
588  return -1;
589 
590  auxcount = avio_r8(pb);
591  vsize = avio_rl16(pb);
592  asize = avio_rl16(pb);
593  vsize = (vsize << 4) | (auxcount >> 4);
594  auxcount &= 0x0f;
595  av_dlog(s, "NSV CHUNK %d aux, %u bytes video, %d bytes audio\n", auxcount, vsize, asize);
596  /* skip aux stuff */
597  for (i = 0; i < auxcount; i++) {
598  uint32_t av_unused auxtag;
599  auxsize = avio_rl16(pb);
600  auxtag = avio_rl32(pb);
601  av_dlog(s, "NSV aux data: '%c%c%c%c', %d bytes\n",
602  (auxtag & 0x0ff),
603  ((auxtag >> 8) & 0x0ff),
604  ((auxtag >> 16) & 0x0ff),
605  ((auxtag >> 24) & 0x0ff),
606  auxsize);
607  avio_skip(pb, auxsize);
608  vsize -= auxsize + sizeof(uint16_t) + sizeof(uint32_t); /* that's becoming braindead */
609  }
610 
611  if (url_feof(pb))
612  return -1;
613  if (!vsize && !asize) {
614  nsv->state = NSV_UNSYNC;
615  goto null_chunk_retry;
616  }
617 
618  /* map back streams to v,a */
619  if (s->nb_streams > 0)
620  st[s->streams[0]->id] = s->streams[0];
621  if (s->nb_streams > 1)
622  st[s->streams[1]->id] = s->streams[1];
623 
624  if (vsize && st[NSV_ST_VIDEO]) {
625  nst = st[NSV_ST_VIDEO]->priv_data;
626  pkt = &nsv->ahead[NSV_ST_VIDEO];
627  av_get_packet(pb, pkt, vsize);
628  pkt->stream_index = st[NSV_ST_VIDEO]->index;//NSV_ST_VIDEO;
629  pkt->dts = nst->frame_offset;
630  pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */
631  for (i = 0; i < FFMIN(8, vsize); i++)
632  av_dlog(s, "NSV video: [%d] = %02x\n", i, pkt->data[i]);
633  }
634  if(st[NSV_ST_VIDEO])
635  ((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset++;
636 
637  if (asize && st[NSV_ST_AUDIO]) {
638  nst = st[NSV_ST_AUDIO]->priv_data;
639  pkt = &nsv->ahead[NSV_ST_AUDIO];
640  /* read raw audio specific header on the first audio chunk... */
641  /* on ALL audio chunks ?? seems so! */
642  if (asize && st[NSV_ST_AUDIO]->codec->codec_tag == MKTAG('P', 'C', 'M', ' ')/* && fill_header*/) {
643  uint8_t bps;
644  uint8_t channels;
645  uint16_t samplerate;
646  bps = avio_r8(pb);
647  channels = avio_r8(pb);
648  samplerate = avio_rl16(pb);
649  asize-=4;
650  av_dlog(s, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate);
651  if (fill_header) {
652  st[NSV_ST_AUDIO]->need_parsing = AVSTREAM_PARSE_NONE; /* we know everything */
653  if (bps != 16) {
654  av_dlog(s, "NSV AUDIO bit/sample != 16 (%d)!!!\n", bps);
655  }
656  if(channels)
657  bps /= channels; // ???
658  else
659  av_log(s, AV_LOG_WARNING, "Channels is 0\n");
660  if (bps == 8)
662  samplerate /= 4;/* UGH ??? XXX */
663  channels = 1;
664  st[NSV_ST_AUDIO]->codec->channels = channels;
665  st[NSV_ST_AUDIO]->codec->sample_rate = samplerate;
666  av_dlog(s, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate);
667  }
668  }
669  av_get_packet(pb, pkt, asize);
670  pkt->stream_index = st[NSV_ST_AUDIO]->index;//NSV_ST_AUDIO;
671  pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */
672  if( nsv->state == NSV_HAS_READ_NSVS && st[NSV_ST_VIDEO] ) {
673  /* on a nsvs frame we have new information on a/v sync */
674  pkt->dts = (((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset-1);
675  pkt->dts *= (int64_t)1000 * nsv->framerate.den;
676  pkt->dts += (int64_t)nsv->avsync * nsv->framerate.num;
677  av_dlog(s, "NSV AUDIO: sync:%d, dts:%"PRId64, nsv->avsync, pkt->dts);
678  }
679  nst->frame_offset++;
680  }
681 
682  nsv->state = NSV_UNSYNC;
683  return 0;
684 }
685 
686 
688 {
689  NSVContext *nsv = s->priv_data;
690  int i, err = 0;
691 
692  av_dlog(s, "%s()\n", __FUNCTION__);
693 
694  /* in case we don't already have something to eat ... */
695  if (nsv->ahead[0].data == NULL && nsv->ahead[1].data == NULL)
696  err = nsv_read_chunk(s, 0);
697  if (err < 0)
698  return err;
699 
700  /* now pick one of the plates */
701  for (i = 0; i < 2; i++) {
702  if (nsv->ahead[i].data) {
703  av_dlog(s, "%s: using cached packet[%d]\n", __FUNCTION__, i);
704  /* avoid the cost of new_packet + memcpy(->data) */
705  memcpy(pkt, &nsv->ahead[i], sizeof(AVPacket));
706  nsv->ahead[i].data = NULL; /* we ate that one */
707  return pkt->size;
708  }
709  }
710 
711  /* this restaurant is not approvisionned :^] */
712  return -1;
713 }
714 
715 static int nsv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
716 {
717  NSVContext *nsv = s->priv_data;
718  AVStream *st = s->streams[stream_index];
719  NSVStream *nst = st->priv_data;
720  int index;
721 
722  index = av_index_search_timestamp(st, timestamp, flags);
723  if(index < 0)
724  return -1;
725 
726  if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0)
727  return -1;
728 
730  nsv->state = NSV_UNSYNC;
731  return 0;
732 }
733 
735 {
736 /* int i; */
737  NSVContext *nsv = s->priv_data;
738 
739  av_freep(&nsv->nsvs_file_offset);
740  av_freep(&nsv->nsvs_timestamps);
741  if (nsv->ahead[0].data)
742  av_free_packet(&nsv->ahead[0]);
743  if (nsv->ahead[1].data)
744  av_free_packet(&nsv->ahead[1]);
745 
746 #if 0
747 
748  for(i=0;i<s->nb_streams;i++) {
749  AVStream *st = s->streams[i];
750  NSVStream *ast = st->priv_data;
751  if(ast){
752  av_free(ast->index_entries);
753  av_free(ast);
754  }
755  av_free(st->codec->palctrl);
756  }
757 
758 #endif
759  return 0;
760 }
761 
762 static int nsv_probe(AVProbeData *p)
763 {
764  int i, score = 0;
765 
766  av_dlog(NULL, "nsv_probe(), buf_size %d\n", p->buf_size);
767  /* check file header */
768  /* streamed files might not have any header */
769  if (p->buf[0] == 'N' && p->buf[1] == 'S' &&
770  p->buf[2] == 'V' && (p->buf[3] == 'f' || p->buf[3] == 's'))
771  return AVPROBE_SCORE_MAX;
772  /* XXX: do streamed files always start at chunk boundary ?? */
773  /* or do we need to search NSVs in the byte stream ? */
774  /* seems the servers don't bother starting clean chunks... */
775  /* sometimes even the first header is at 9KB or something :^) */
776  for (i = 1; i < p->buf_size - 3; i++) {
777  if (AV_RL32(p->buf + i) == AV_RL32("NSVs")) {
778  /* Get the chunk size and check if at the end we are getting 0xBEEF */
779  int vsize = AV_RL24(p->buf+i+19) >> 4;
780  int asize = AV_RL16(p->buf+i+22);
781  int offset = i + 23 + asize + vsize + 1;
782  if (offset <= p->buf_size - 2 && AV_RL16(p->buf + offset) == 0xBEEF)
783  return 4*AVPROBE_SCORE_MAX/5;
784  score = AVPROBE_SCORE_MAX/5;
785  }
786  }
787  /* so we'll have more luck on extension... */
788  if (av_match_ext(p->filename, "nsv"))
789  return AVPROBE_SCORE_MAX/2;
790  /* FIXME: add mime-type check */
791  return score;
792 }
793 
795  .name = "nsv",
796  .long_name = NULL_IF_CONFIG_SMALL("Nullsoft Streaming Video"),
797  .priv_data_size = sizeof(NSVContext),
803 };
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
float v
const char * s
Definition: avisynth_c.h:668
Bytestream IO Context.
Definition: avio.h:68
void av_free_packet(AVPacket *pkt)
Free a packet.
Definition: avpacket.c:242
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.
static const AVCodecTag nsv_codec_video_tags[]
Definition: nsvdec.c:186
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
static int nsv_parse_NSVf_header(AVFormatContext *s)
Definition: nsvdec.c:272
uint32_t * nsvs_file_offset
Definition: nsvdec.c:172
uint16_t vheight
Definition: nsvdec.c:179
const char * filename
Definition: avformat.h:335
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.
uint32_t * nsvs_timestamps
Definition: nsvdec.c:182
int64_t pos
Definition: avformat.h:592
#define TB_NSVF
Definition: nsvdec.c:138
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:153
int rate
Definition: nsvdec.c:161
int num
numerator
Definition: rational.h:44
int index
stream index in AVFormatContext
Definition: avformat.h:644
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
#define AV_RL16
void * priv_data
Definition: avformat.h:663
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:256
int sample_size
Definition: nsvdec.c:162
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
#define NSV_MAX_RESYNC
Definition: nsvdec.c:38
static const AVCodecTag nsv_codec_audio_tags[]
Definition: nsvdec.c:206
Macro definitions for various function/variable attributes.
int base_offset
Definition: nsvdec.c:170
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
Format I/O context.
Definition: avformat.h:944
Public dictionary API.
#define NSV_MAX_RESYNC_TRIES
Definition: nsvdec.c:39
#define NSV_ST_AUDIO
Definition: nsvdec.c:143
uint8_t
static AVPacket pkt
Definition: demuxing.c:56
enum AVStreamParseType need_parsing
Definition: avformat.h:811
int id
Format-specific stream ID.
Definition: avformat.h:650
int frame_offset
Definition: nsvdec.c:158
#define b
Definition: input.c:42
int NSVf_end
Definition: nsvdec.c:171
int start
Definition: nsvdec.c:163
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
AVStream ** streams
Definition: avformat.h:992
int new_frame_offset
Definition: nsvdec.c:165
uint8_t * data
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
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.
static int nsv_resync(AVFormatContext *s)
Definition: nsvdec.c:227
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.
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:248
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
static int nsv_read_close(AVFormatContext *s)
Definition: nsvdec.c:734
static int64_t duration
Definition: ffplay.c:294
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:478
#define NSV_ST_VIDEO
Definition: nsvdec.c:142
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
static int nsv_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: nsvdec.c:687
int64_t duration
Definition: nsvdec.c:177
#define AVINDEX_KEYFRAME
Definition: avformat.h:599
AVPacket ahead[2]
Definition: nsvdec.c:175
AVDictionary * metadata
Definition: avformat.h:1092
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
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
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:593
uint16_t vwidth
Definition: nsvdec.c:179
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
preferred ID for decoding MPEG audio layer 1, 2 or 3
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
AVRational framerate
Definition: nsvdec.c:181
static int nsv_read_chunk(AVFormatContext *s, int fill_header)
Definition: nsvdec.c:557
int size
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
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
unsigned int nb_streams
A list of all streams in the file.
Definition: avformat.h:991
AVInputFormat ff_nsv_demuxer
Definition: nsvdec.c:794
struct AVRational AVRational
rational number numerator/denominator
#define V
static int nsv_parse_NSVs_header(AVFormatContext *s)
Definition: nsvdec.c:400
int scale
Definition: nsvdec.c:160
char filename[1024]
input or output filename
Definition: avformat.h:994
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:118
static int nsv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: nsvdec.c:715
#define FFMIN(a, b)
Definition: common.h:58
static int read_probe(AVProbeData *pd)
int width
picture width / height.
NSVStatus
Definition: nsvdec.c:146
t
Definition: genspecsines3.m:6
uint32_t vtag
Definition: nsvdec.c:178
#define AV_RL32
static int nsv_probe(AVProbeData *p)
Definition: nsvdec.c:762
int url_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
Definition: aviobuf.c:280
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:517
Stream structure.
Definition: avformat.h:643
NULL
Definition: eval.c:55
sample_rate
enum AVMediaType codec_type
enum AVCodecID codec_id
int sample_rate
samples per second
AVIOContext * pb
I/O context.
Definition: avformat.h:977
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> (&#39;D&#39;<<24) + (&#39;C&#39;<<16) + (&#39;B&#39;<<8) + &#39;A&#39;).
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
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
#define T_NONE
Definition: nsvdec.c:133
int index
Definition: gxfenc.c:89
synthesis window for stochastic i
rational number numerator/denominator
Definition: rational.h:43
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
static int nsv_read_header(AVFormatContext *s)
Definition: nsvdec.c:521
static uint32_t state
Definition: trasher.c:27
static int flags
Definition: cpu.c:23
#define AV_RL24
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:696
#define AVPROBE_SCORE_MAX
maximum score, half of that is used for file-extension-based detection
Definition: avformat.h:340
full parsing and repack
Definition: avformat.h:582
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:563
Main libavformat public API header.
int cum_len
Definition: nsvdec.c:166
enum NSVStatus state
Definition: nsvdec.c:174
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base...
Definition: avformat.h:689
uint32_t atag
Definition: nsvdec.c:178
int den
denominator
Definition: rational.h:45
struct NSVStream NSVStream
unsigned bps
Definition: movenc.c:895
#define MKBETAG(a, b, c, d)
Definition: common.h:283
int index_entries
Definition: nsvdec.c:173
int channels
number of audio channels
void * priv_data
Format private data.
Definition: avformat.h:964
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:461
int16_t avsync
Definition: nsvdec.c:180
#define MKTAG(a, b, c, d)
Definition: common.h:282
#define print_tag(str, tag, size)
Definition: nsvdec.c:219
This structure stores compressed data.
#define av_unused
Definition: attributes.h:114