FFmpeg
vividas.c
Go to the documentation of this file.
1 /*
2  * Vividas VIV format Demuxer
3  * Copyright (c) 2012 Krzysztof Klinikowski
4  * Copyright (c) 2010 Andrzej Szombierski
5  * based on vivparse Copyright (c) 2007 Måns Rullgård
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 /**
25  * @file
26  * @brief Vividas VIV (.viv) file demuxer
27  * @author Andrzej Szombierski [qq at kuku eu org] (2010-07)
28  * @sa http://wiki.multimedia.cx/index.php?title=Vividas_VIV
29  */
30 
31 #include "libavutil/avassert.h"
32 #include "libavutil/intreadwrite.h"
33 #include "avio_internal.h"
34 #include "avformat.h"
35 #include "demux.h"
36 #include "internal.h"
37 
38 #define MAX_AUDIO_SUBPACKETS 100
39 
40 typedef struct VIV_SB_block {
44 } VIV_SB_block;
45 
46 typedef struct VIV_SB_entry {
47  int size, flag;
48 } VIV_SB_entry;
49 
50 typedef struct VIV_AudioSubpacket {
53 
54 typedef struct VividasDemuxContext {
57  int num_audio;
58 
59  uint32_t sb_key;
61 
63  uint8_t *sb_buf;
67 
70 
72 
75 
76 static int viv_probe(const AVProbeData *p)
77 {
78  if (memcmp(p->buf, "vividas03", 9))
79  return 0;
80 
81  return AVPROBE_SCORE_MAX;
82 }
83 
84 static const uint8_t keybits[32] = {
85  20, 52, 111, 10, 27, 71, 142, 53,
86  82, 138, 1, 78, 86, 121, 183, 85,
87 105, 152, 39, 140, 172, 11, 64, 144,
88 155, 6, 71, 163, 186, 49, 126, 43,
89 };
90 
91 static uint32_t decode_key(uint8_t *buf)
92 {
93  uint32_t key = 0;
94 
95  for (int i = 0; i < 32; i++) {
96  unsigned p = keybits[i];
97  key |= ((buf[p] >> ((i*5+3)&7)) & 1u) << i;
98  }
99 
100  return key;
101 }
102 
103 static void put_v(uint8_t *p, unsigned v)
104 {
105  if (v>>28)
106  *p++ = ((v>>28)&0x7f)|0x80;
107  if (v>>21)
108  *p++ = ((v>>21)&0x7f)|0x80;
109  if (v>>14)
110  *p++ = ((v>>14)&0x7f)|0x80;
111  if (v>>7)
112  *p++ = ((v>>7)&0x7f)|0x80;
113 }
114 
115 static unsigned recover_key(unsigned char sample[4], unsigned expected_size)
116 {
117  unsigned char plaintext[8] = { 'S', 'B' };
118 
119  put_v(plaintext+2, expected_size);
120 
121  return AV_RL32(sample) ^ AV_RL32(plaintext);
122 }
123 
124 static void xor_block(void *p1, void *p2, unsigned size, int key, unsigned *key_ptr)
125 {
126  unsigned *d1 = p1;
127  unsigned *d2 = p2;
128  unsigned k = *key_ptr;
129 
130  size >>= 2;
131 
132  while (size > 0) {
133  *d2 = *d1 ^ (HAVE_BIGENDIAN ? av_bswap32(k) : k);
134  k += key;
135  d1++;
136  d2++;
137  size--;
138  }
139 
140  *key_ptr = k;
141 }
142 
143 static void decode_block(uint8_t *src, uint8_t *dest, unsigned size,
144  uint32_t key, uint32_t *key_ptr,
145  int align)
146 {
147  unsigned s = size;
148  char tmp[4];
149  int a2;
150 
151  if (!size)
152  return;
153 
154  align &= 3;
155  a2 = (4 - align) & 3;
156 
157  if (align) {
158  uint32_t tmpkey = *key_ptr - key;
159  if (a2 > s) {
160  a2 = s;
161  avpriv_request_sample(NULL, "tiny aligned block");
162  }
163  memcpy(tmp + align, src, a2);
164  xor_block(tmp, tmp, 4, key, &tmpkey);
165  memcpy(dest, tmp + align, a2);
166  s -= a2;
167  }
168 
169  if (s >= 4) {
170  xor_block(src + a2, dest + a2, s & ~3,
171  key, key_ptr);
172  s &= 3;
173  }
174 
175  if (s) {
176  size -= s;
177  memcpy(tmp, src + size, s);
178  xor_block(&tmp, &tmp, 4, key, key_ptr);
179  memcpy(dest + size, tmp, s);
180  }
181 }
182 
183 static uint32_t get_v(uint8_t *p, int len)
184 {
185  uint32_t v = 0;
186  const uint8_t *end = p + len;
187 
188  do {
189  if (p >= end || v >= UINT_MAX / 128 - *p)
190  return v;
191  v <<= 7;
192  v += *p & 0x7f;
193  } while (*p++ & 0x80);
194 
195  return v;
196 }
197 
198 static uint8_t *read_vblock(AVIOContext *src, uint32_t *size,
199  uint32_t key, uint32_t *k2, int align)
200 {
201  uint8_t tmp[4];
202  uint8_t *buf;
203  unsigned n;
204 
205  if (avio_read(src, tmp, 4) != 4)
206  return NULL;
207 
208  decode_block(tmp, tmp, 4, key, k2, align);
209 
210  n = get_v(tmp, 4);
211  if (n < 4)
212  return NULL;
213 
214  buf = av_malloc(n);
215  if (!buf)
216  return NULL;
217 
218  *size = n;
219  n -= 4;
220 
221  memcpy(buf, tmp, 4);
222 
223  if (avio_read(src, buf + 4, n) == n) {
224  decode_block(buf + 4, buf + 4, n, key, k2, align);
225  } else {
226  av_free(buf);
227  buf = NULL;
228  }
229 
230  return buf;
231 }
232 
233 static uint8_t *read_sb_block(AVIOContext *src, unsigned *size,
234  uint32_t *key, unsigned expected_size)
235 {
236  uint8_t *buf;
237  uint8_t ibuf[8], sbuf[8];
238  uint32_t k2;
239  unsigned n;
240 
241  if (avio_read(src, ibuf, 8) < 8)
242  return NULL;
243 
244  k2 = *key;
245  decode_block(ibuf, sbuf, 8, *key, &k2, 0);
246 
247  n = get_v(sbuf+2, 6);
248 
249  if (sbuf[0] != 'S' || sbuf[1] != 'B' || (expected_size>0 && n != expected_size)) {
250  uint32_t tmpkey = recover_key(ibuf, expected_size);
251  k2 = tmpkey;
252  decode_block(ibuf, sbuf, 8, tmpkey, &k2, 0);
253  n = get_v(sbuf+2, 6);
254  if (sbuf[0] != 'S' || sbuf[1] != 'B' || expected_size != n)
255  return NULL;
256  *key = tmpkey;
257  }
258 
259  if (n < 8)
260  return NULL;
261 
262  buf = av_malloc(n);
263  if (!buf)
264  return NULL;
265 
266  memcpy(buf, sbuf, 8);
267 
268  *size = n;
269  n -= 8;
270 
271  if (avio_read(src, buf+8, n) != n) {
272  av_free(buf);
273  return NULL;
274  }
275 
276  decode_block(buf + 8, buf + 8, n, *key, &k2, 0);
277 
278  return buf;
279 }
280 
282  const uint8_t *buf, int size)
283 {
284  int i, j, ret;
285  int64_t off;
286  int val_1;
287  int num_video;
288  FFIOContext pb0;
289  AVIOContext *const pb = &pb0.pub;
290 
291  ffio_init_read_context(&pb0, buf, size);
292 
293  ffio_read_varlen(pb); // track_header_len
294  avio_r8(pb); // '1'
295 
296  val_1 = ffio_read_varlen(pb);
297 
298  for (i=0;i<val_1;i++) {
299  int c = avio_r8(pb);
300  if (avio_feof(pb))
301  return AVERROR_EOF;
302  for (j=0;j<c;j++) {
303  if (avio_feof(pb))
304  return AVERROR_EOF;
305  avio_r8(pb); // val_3
306  avio_r8(pb); // val_4
307  }
308  }
309 
310  avio_r8(pb); // num_streams
311 
312  off = avio_tell(pb);
313  off += ffio_read_varlen(pb); // val_5
314 
315  avio_r8(pb); // '2'
316  num_video = avio_r8(pb);
317 
318  avio_seek(pb, off, SEEK_SET);
319  if (num_video != 1) {
320  av_log(s, AV_LOG_ERROR, "number of video tracks %d is not 1\n", num_video);
321  return AVERROR_PATCHWELCOME;
322  }
323 
324  for (i = 0; i < num_video; i++) {
326  int num, den;
327 
328  if (!st)
329  return AVERROR(ENOMEM);
330 
331  st->id = i;
332 
335 
336  off = avio_tell(pb);
337  off += ffio_read_varlen(pb);
338  avio_r8(pb); // '3'
339  avio_r8(pb); // val_7
340  num = avio_rl32(pb); // frame_time
341  den = avio_rl32(pb); // time_base
342  avpriv_set_pts_info(st, 64, num, den);
343  st->nb_frames = avio_rl32(pb); // n frames
344  st->codecpar->width = avio_rl16(pb); // width
345  st->codecpar->height = avio_rl16(pb); // height
346  avio_r8(pb); // val_8
347  avio_rl32(pb); // val_9
348 
349  avio_seek(pb, off, SEEK_SET);
350  }
351 
352  off = avio_tell(pb);
353  off += ffio_read_varlen(pb); // val_10
354  avio_r8(pb); // '4'
355  viv->num_audio = avio_r8(pb);
356  avio_seek(pb, off, SEEK_SET);
357 
358  if (viv->num_audio != 1)
359  av_log(s, AV_LOG_WARNING, "number of audio tracks %d is not 1\n", viv->num_audio);
360 
361  for(i=0;i<viv->num_audio;i++) {
362  int q;
364  if (!st)
365  return AVERROR(ENOMEM);
366 
367  st->id = num_video + i;
368 
371 
372  off = avio_tell(pb);
373  off += ffio_read_varlen(pb); // length
374  avio_r8(pb); // '5'
375  avio_r8(pb); //codec_id
376  avio_rl16(pb); //codec_subid
377  st->codecpar->ch_layout.nb_channels = avio_rl16(pb); // channels
378  st->codecpar->sample_rate = avio_rl32(pb); // sample_rate
379  if (st->codecpar->sample_rate <= 0 || st->codecpar->ch_layout.nb_channels <= 0)
380  return AVERROR_INVALIDDATA;
381  avio_seek(pb, 10, SEEK_CUR); // data_1
382  q = avio_r8(pb);
383  avio_seek(pb, q, SEEK_CUR); // data_2
384  avio_r8(pb); // zeropad
385 
386  if (avio_tell(pb) < off) {
387  int num_data;
388  int xd_size = 1;
389  int data_len[256];
390  int offset = 1;
391  uint8_t *p;
392  ffio_read_varlen(pb); // val_13
393  avio_r8(pb); // '19'
394  ffio_read_varlen(pb); // len_3
395  num_data = avio_r8(pb);
396  for (j = 0; j < num_data; j++) {
398  if (len < 0 || len > INT_MAX/2 - xd_size) {
399  return AVERROR_INVALIDDATA;
400  }
401  data_len[j] = len;
402  xd_size += len + 1 + len/255;
403  }
404 
405  ret = ff_alloc_extradata(st->codecpar, xd_size);
406  if (ret < 0)
407  return ret;
408 
409  p = st->codecpar->extradata;
410  p[0] = 2;
411 
412  for (j = 0; j < num_data - 1; j++) {
413  unsigned delta = av_xiphlacing(&p[offset], data_len[j]);
414  av_assert0(delta <= xd_size - offset);
415  offset += delta;
416  }
417 
418  for (j = 0; j < num_data; j++) {
419  int ret = avio_read(pb, &p[offset], data_len[j]);
420  if (ret < data_len[j]) {
421  st->codecpar->extradata_size = 0;
422  av_freep(&st->codecpar->extradata);
423  break;
424  }
425  av_assert0(data_len[j] <= xd_size - offset);
426  offset += data_len[j];
427  }
428 
429  if (offset < st->codecpar->extradata_size)
431  }
432  }
433 
434  return 0;
435 }
436 
438  const uint8_t *buf, unsigned size)
439 {
440  int64_t off;
441  int64_t poff;
442  int maxnp=0;
443  FFIOContext pb0;
444  AVIOContext *const pb = &pb0.pub;
445  int i;
446  int64_t filesize = avio_size(s->pb);
447  uint64_t n_sb_blocks_tmp;
448 
449  ffio_init_read_context(&pb0, buf, size);
450 
451  ffio_read_varlen(pb); // track_index_len
452  avio_r8(pb); // 'c'
453  n_sb_blocks_tmp = ffio_read_varlen(pb);
454  if (n_sb_blocks_tmp > size / 2)
455  return AVERROR_INVALIDDATA;
456  viv->sb_blocks = av_calloc(n_sb_blocks_tmp, sizeof(*viv->sb_blocks));
457  if (!viv->sb_blocks) {
458  return AVERROR(ENOMEM);
459  }
460  viv->n_sb_blocks = n_sb_blocks_tmp;
461 
462  off = 0;
463  poff = 0;
464 
465  for (i = 0; i < viv->n_sb_blocks; i++) {
466  uint64_t size_tmp = ffio_read_varlen(pb);
467  uint64_t n_packets_tmp = ffio_read_varlen(pb);
468 
469  if (size_tmp > INT_MAX || n_packets_tmp > INT_MAX)
470  return AVERROR_INVALIDDATA;
471 
472  viv->sb_blocks[i].byte_offset = off;
473  viv->sb_blocks[i].packet_offset = poff;
474 
475  viv->sb_blocks[i].size = size_tmp;
476  viv->sb_blocks[i].n_packets = n_packets_tmp;
477 
478  off += viv->sb_blocks[i].size;
479  poff += viv->sb_blocks[i].n_packets;
480 
481  if (maxnp < viv->sb_blocks[i].n_packets)
482  maxnp = viv->sb_blocks[i].n_packets;
483  }
484 
485  if (filesize > 0 && poff > filesize)
486  return AVERROR_INVALIDDATA;
487 
488  viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry));
489  if (!viv->sb_entries)
490  return AVERROR(ENOMEM);
491 
492  return 0;
493 }
494 
495 static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
496 {
497  uint32_t size = 0;
498  int i;
499  AVIOContext *pb = 0;
500 
501  if (viv->sb_pb) {
502  av_free(viv->sb_pb);
503  viv->sb_pb = NULL;
504  }
505 
506  if (viv->sb_buf)
507  av_free(viv->sb_buf);
508 
509  viv->sb_buf = read_sb_block(s->pb, &size, &viv->sb_key, expected_size);
510  if (!viv->sb_buf) {
511  return;
512  }
513 
514  pb = avio_alloc_context(viv->sb_buf, size, 0, NULL, NULL, NULL, NULL);
515  if (!pb)
516  return;
517 
518  viv->sb_pb = pb;
519 
520  avio_r8(pb); // 'S'
521  avio_r8(pb); // 'B'
522  ffio_read_varlen(pb); // size
523  avio_r8(pb); // junk
524  ffio_read_varlen(pb); // first packet
525 
526  viv->n_sb_entries = viv->sb_blocks[viv->current_sb].n_packets;
527 
528  for (i = 0; i < viv->n_sb_entries; i++) {
529  viv->sb_entries[i].size = ffio_read_varlen(pb);
530  viv->sb_entries[i].flag = avio_r8(pb);
531  }
532 
533  ffio_read_varlen(pb);
534  avio_r8(pb);
535 
536  viv->current_sb_entry = 0;
537 }
538 
540 {
541  VividasDemuxContext *viv = s->priv_data;
542  AVIOContext *pb = s->pb;
543  int64_t header_end;
544  int num_tracks;
545  uint32_t key, k2;
546  uint32_t v;
547  uint8_t keybuffer[187];
548  uint32_t b22_size = 0;
549  uint32_t b22_key = 0;
550  uint8_t *buf = 0;
551  int ret;
552 
553  avio_skip(pb, 9);
554 
555  header_end = avio_tell(pb);
556 
557  header_end += ffio_read_varlen(pb);
558 
559  num_tracks = avio_r8(pb);
560 
561  if (num_tracks != 1) {
562  av_log(s, AV_LOG_ERROR, "number of tracks %d is not 1\n", num_tracks);
563  return AVERROR(EINVAL);
564  }
565 
566  v = avio_r8(pb);
567  avio_seek(pb, v, SEEK_CUR);
568 
569  avio_read(pb, keybuffer, 187);
570  key = decode_key(keybuffer);
571  viv->sb_key = key;
572 
573  avio_rl32(pb);
574 
575  for (;;) {
576  int64_t here = avio_tell(pb);
577  int block_len, block_type;
578 
579  if (here >= header_end)
580  break;
581 
582  block_len = ffio_read_varlen(pb);
583  if (avio_feof(pb) || block_len <= 0)
584  return AVERROR_INVALIDDATA;
585 
586  block_type = avio_r8(pb);
587 
588  if (block_type == 22) {
589  avio_read(pb, keybuffer, 187);
590  b22_key = decode_key(keybuffer);
591  b22_size = avio_rl32(pb);
592  }
593 
594  avio_seek(pb, here + block_len, SEEK_SET);
595  }
596 
597  if (b22_size) {
598  k2 = b22_key;
599  buf = read_vblock(pb, &v, b22_key, &k2, 0);
600  if (!buf)
601  return AVERROR(EIO);
602 
603  av_free(buf);
604  }
605 
606  k2 = key;
607  buf = read_vblock(pb, &v, key, &k2, 0);
608  if (!buf)
609  return AVERROR(EIO);
610  ret = track_header(viv, s, buf, v);
611  av_free(buf);
612  if (ret < 0)
613  return ret;
614 
615  buf = read_vblock(pb, &v, key, &k2, v);
616  if (!buf)
617  return AVERROR(EIO);
618  ret = track_index(viv, s, buf, v);
619  av_free(buf);
620  if (ret < 0)
621  return ret;
622 
623  viv->sb_offset = avio_tell(pb);
624  if (viv->n_sb_blocks > 0) {
625  viv->current_sb = 0;
626  load_sb_block(s, viv, viv->sb_blocks[0].size);
627  } else {
628  viv->current_sb = -1;
629  }
630 
631  return 0;
632 }
633 
635  AVPacket *pkt)
636 {
637  VividasDemuxContext *viv = s->priv_data;
638  AVIOContext *pb;
639  int64_t off;
640  int ret;
641 
642  if (!viv->sb_pb)
643  return AVERROR(EIO);
644  if (avio_feof(viv->sb_pb))
645  return AVERROR_EOF;
646 
648  AVStream *astream;
650 
651  pb = viv->sb_pb;
652  ret = av_get_packet(pb, pkt, size);
653  if (ret < 0)
654  return ret;
655  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
656 
657  pkt->stream_index = 1;
658  astream = s->streams[pkt->stream_index];
659 
660  pkt->pts = av_rescale_q(viv->audio_sample, av_make_q(1, astream->codecpar->sample_rate), astream->time_base);
662  astream->codecpar->ch_layout.nb_channels;
665  return 0;
666  }
667 
668  if (viv->current_sb_entry >= viv->n_sb_entries) {
669  if (viv->current_sb+1 >= viv->n_sb_blocks)
670  return AVERROR(EIO);
671  viv->current_sb++;
672 
673  load_sb_block(s, viv, 0);
674  viv->current_sb_entry = 0;
675  }
676 
677  pb = viv->sb_pb;
678  if (!pb)
679  return AVERROR(EIO);
680  off = avio_tell(pb);
681 
682  if (viv->current_sb_entry >= viv->n_sb_entries)
683  return AVERROR_INVALIDDATA;
684 
685  off += viv->sb_entries[viv->current_sb_entry].size;
686 
687  if (viv->sb_entries[viv->current_sb_entry].flag == 0) {
688  uint64_t v_size = ffio_read_varlen(pb);
689  int last = 0, last_start;
690 
691  if (!viv->num_audio)
692  return AVERROR_INVALIDDATA;
693 
694  ffio_read_varlen(pb);
695  if (v_size > INT_MAX || !v_size)
696  return AVERROR_INVALIDDATA;
697  ret = av_get_packet(pb, pkt, v_size);
698  if (ret < 0)
699  return ret;
700  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
701 
703  pkt->flags |= (pkt->data[0]&0x80)?0:AV_PKT_FLAG_KEY;
704  pkt->stream_index = 0;
705 
706  for (int i = 0; i < MAX_AUDIO_SUBPACKETS - 1; i++) {
707  int start, pcm_bytes;
708  start = ffio_read_varlen(pb);
709  pcm_bytes = ffio_read_varlen(pb);
710 
711  if (i > 0 && start == 0)
712  break;
713  if (start < last)
714  return AVERROR_INVALIDDATA;
715 
716  viv->n_audio_subpackets = i + 1;
717  last =
718  viv->audio_subpackets[i].start = start;
719  viv->audio_subpackets[i].pcm_bytes = pcm_bytes;
720  }
721  last_start =
722  viv->audio_subpackets[viv->n_audio_subpackets].start = (int)(off - avio_tell(pb));
723  if (last_start < last)
724  return AVERROR_INVALIDDATA;
725  viv->current_audio_subpacket = 0;
726 
727  } else {
728  uint64_t v_size = ffio_read_varlen(pb);
729 
730  if (v_size > INT_MAX || !v_size)
731  return AVERROR_INVALIDDATA;
732  ret = av_get_packet(pb, pkt, v_size);
733  if (ret < 0)
734  return ret;
735  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
737  pkt->flags |= (pkt->data[0] & 0x80) ? 0 : AV_PKT_FLAG_KEY;
738  pkt->stream_index = 0;
739  }
740 
741  viv->current_sb_entry++;
742 
743  return 0;
744 }
745 
747 {
748  VividasDemuxContext *viv = s->priv_data;
749 
750  av_freep(&viv->sb_pb);
751  av_freep(&viv->sb_buf);
752  av_freep(&viv->sb_blocks);
753  av_freep(&viv->sb_entries);
754 
755  return 0;
756 }
757 
758 static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
759 {
760  VividasDemuxContext *viv = s->priv_data;
761  int64_t frame;
762 
763  if (stream_index == 0)
764  frame = timestamp;
765  else
766  frame = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[stream_index]->time_base);
767 
768  for (int i = 0; i < viv->n_sb_blocks; i++) {
769  if (frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) {
770  viv->current_sb = i;
771  // seek to ith sb block
772  avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET);
773  // load the block
774  load_sb_block(s, viv, 0);
775  if (viv->num_audio) {
776  const AVCodecParameters *par = s->streams[1]->codecpar;
777  // flush audio packet queue
778  viv->current_audio_subpacket = 0;
779  viv->n_audio_subpackets = 0;
780  // most problematic part: guess audio offset
782  av_make_q(par->sample_rate, 1),
783  av_inv_q(s->streams[0]->time_base));
784  // hand-tuned 1.s a/v offset
785  viv->audio_sample += par->sample_rate;
786  }
787  viv->current_sb_entry = 0;
788  return 1;
789  }
790  }
791  return 0;
792 }
793 
795  .p.name = "vividas",
796  .p.long_name = NULL_IF_CONFIG_SMALL("Vividas VIV"),
797  .priv_data_size = sizeof(VividasDemuxContext),
798  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
804 };
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
put_v
static void put_v(uint8_t *p, unsigned v)
Definition: vividas.c:103
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
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
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:250
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
int64_t
long long int64_t
Definition: coverity.c:34
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
VividasDemuxContext::sb_buf
uint8_t * sb_buf
Definition: vividas.c:63
AVPacket::data
uint8_t * data
Definition: packet.h:522
avio_alloc_context
AVIOContext * avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, const uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Allocate and initialize an AVIOContext for buffered I/O.
Definition: aviobuf.c:108
AV_CODEC_ID_VP6
@ AV_CODEC_ID_VP6
Definition: codec_id.h:143
VividasDemuxContext::current_sb_entry
int current_sb_entry
Definition: vividas.c:62
VIV_SB_block
Definition: vividas.c:40
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:98
VividasDemuxContext::audio_sample
int64_t audio_sample
Definition: vividas.c:71
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
VIV_SB_block::byte_offset
int64_t byte_offset
Definition: vividas.c:42
VividasDemuxContext::current_audio_subpacket
int current_audio_subpacket
Definition: vividas.c:69
get_v
static uint32_t get_v(uint8_t *p, int len)
Definition: vividas.c:183
track_index
static int track_index(VividasDemuxContext *viv, AVFormatContext *s, const uint8_t *buf, unsigned size)
Definition: vividas.c:437
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:322
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:577
VividasDemuxContext::n_sb_blocks
int n_sb_blocks
Definition: vividas.c:55
read_vblock
static uint8_t * read_vblock(AVIOContext *src, uint32_t *size, uint32_t key, uint32_t *k2, int align)
Definition: vividas.c:198
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
recover_key
static unsigned recover_key(unsigned char sample[4], unsigned expected_size)
Definition: vividas.c:115
decode_block
static void decode_block(uint8_t *src, uint8_t *dest, unsigned size, uint32_t key, uint32_t *key_ptr, int align)
Definition: vividas.c:143
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
VIV_AudioSubpacket::start
int start
Definition: vividas.c:51
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
viv_read_header
static int viv_read_header(AVFormatContext *s)
Definition: vividas.c:539
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
VividasDemuxContext::num_audio
int num_audio
Definition: vividas.c:57
VividasDemuxContext::current_sb
int current_sb
Definition: vividas.c:62
avio_rl16
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:713
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
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
viv_read_seek
static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: vividas.c:758
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
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
VIV_SB_entry
Definition: vividas.c:46
key
const char * key
Definition: hwcontext_opencl.c:189
frame
static AVFrame * frame
Definition: demux_decode.c:54
FF_INFMT_FLAG_INIT_CLEANUP
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition: demux.h:35
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
VIV_SB_entry::size
int size
Definition: vividas.c:47
internal.h
VividasDemuxContext::audio_subpackets
VIV_AudioSubpacket audio_subpackets[MAX_AUDIO_SUBPACKETS]
Definition: vividas.c:73
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:550
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:782
NULL
#define NULL
Definition: coverity.c:32
VIV_AudioSubpacket
Definition: vividas.c:50
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
read_sb_block
static uint8_t * read_sb_block(AVIOContext *src, unsigned *size, uint32_t *key, unsigned expected_size)
Definition: vividas.c:233
VIV_SB_block::n_packets
int n_packets
Definition: vividas.c:41
xor_block
static void xor_block(void *p1, void *p2, unsigned size, int key, unsigned *key_ptr)
Definition: vividas.c:124
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:804
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
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
av_bswap32
#define av_bswap32
Definition: bswap.h:28
FFIOContext::pub
AVIOContext pub
Definition: avio_internal.h:29
plaintext
static const uint8_t plaintext[8]
Definition: blowfish.c:112
sample
#define sample
Definition: flacdsp_template.c:44
size
int size
Definition: twinvq_data.h:10344
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
av_xiphlacing
unsigned int av_xiphlacing(unsigned char *s, unsigned int v)
Encode extradata length to a buffer.
Definition: utils.c:820
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:41
align
static const uint8_t *BS_FUNC() align(BSCTX *bc)
Skip bits to a byte boundary.
Definition: bitstream_template.h:411
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:602
VIV_SB_entry::flag
int flag
Definition: vividas.c:47
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
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:528
ffio_read_varlen
uint64_t ffio_read_varlen(AVIOContext *bc)
Definition: aviobuf.c:915
VIV_SB_block::size
int size
Definition: vividas.c:41
MAX_AUDIO_SUBPACKETS
#define MAX_AUDIO_SUBPACKETS
Definition: vividas.c:38
filesize
static int64_t filesize(AVIOContext *pb)
Definition: ffmpeg_mux.c:51
load_sb_block
static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
Definition: vividas.c:495
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:515
VividasDemuxContext::sb_key
uint32_t sb_key
Definition: vividas.c:59
avio_internal.h
AVCodecParameters::height
int height
Definition: codec_par.h:135
decode_key
static uint32_t decode_key(uint8_t *buf)
Definition: vividas.c:91
VividasDemuxContext
Definition: vividas.c:54
VIV_SB_block::packet_offset
int64_t packet_offset
Definition: vividas.c:43
a2
#define a2
Definition: regdef.h:48
delta
float delta
Definition: vorbis_enc_data.h:430
viv_probe
static int viv_probe(const AVProbeData *p)
Definition: vividas.c:76
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
demux.h
len
int len
Definition: vorbis_enc_data.h:426
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
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
keybits
static const uint8_t keybits[32]
Definition: vividas.c:84
avformat.h
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
viv_read_packet
static int viv_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: vividas.c:634
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:611
VividasDemuxContext::n_audio_subpackets
int n_audio_subpackets
Definition: vividas.c:68
AVPacket::stream_index
int stream_index
Definition: packet.h:524
VividasDemuxContext::n_sb_entries
int n_sb_entries
Definition: vividas.c:65
VividasDemuxContext::sb_pb
AVIOContext * sb_pb
Definition: vividas.c:64
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:317
track_header
static int track_header(VividasDemuxContext *viv, AVFormatContext *s, const uint8_t *buf, int size)
Definition: vividas.c:281
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
VividasDemuxContext::sb_offset
int64_t sb_offset
Definition: vividas.c:60
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:36
VIV_AudioSubpacket::pcm_bytes
int pcm_bytes
Definition: vividas.c:51
VividasDemuxContext::sb_entries
VIV_SB_entry * sb_entries
Definition: vividas.c:66
viv_read_close
static int viv_read_close(AVFormatContext *s)
Definition: vividas.c:746
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
VividasDemuxContext::sb_blocks
VIV_SB_block * sb_blocks
Definition: vividas.c:56
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
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:542
FFInputFormat
Definition: demux.h:37
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:445
int
int
Definition: ffmpeg_filter.c:409
ff_vividas_demuxer
const FFInputFormat ff_vividas_demuxer
Definition: vividas.c:794
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