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 "libavutil/mem.h"
34 #include "avio_internal.h"
35 #include "avformat.h"
36 #include "demux.h"
37 #include "internal.h"
38 
39 #define MAX_AUDIO_SUBPACKETS 100
40 
41 typedef struct VIV_SB_block {
43  int64_t byte_offset;
44  int64_t packet_offset;
45 } VIV_SB_block;
46 
47 typedef struct VIV_SB_entry {
48  int size, flag;
49 } VIV_SB_entry;
50 
51 typedef struct VIV_AudioSubpacket {
54 
55 typedef struct VividasDemuxContext {
58  int num_audio;
59 
60  uint32_t sb_key;
61  int64_t sb_offset;
62 
64  uint8_t *sb_buf;
68 
71 
72  int64_t audio_sample;
73 
76 
77 static int viv_probe(const AVProbeData *p)
78 {
79  if (memcmp(p->buf, "vividas03", 9))
80  return 0;
81 
82  return AVPROBE_SCORE_MAX;
83 }
84 
85 static const uint8_t keybits[32] = {
86  20, 52, 111, 10, 27, 71, 142, 53,
87  82, 138, 1, 78, 86, 121, 183, 85,
88 105, 152, 39, 140, 172, 11, 64, 144,
89 155, 6, 71, 163, 186, 49, 126, 43,
90 };
91 
92 static uint32_t decode_key(uint8_t *buf)
93 {
94  uint32_t key = 0;
95 
96  for (int i = 0; i < 32; i++) {
97  unsigned p = keybits[i];
98  key |= ((buf[p] >> ((i*5+3)&7)) & 1u) << i;
99  }
100 
101  return key;
102 }
103 
104 static void put_v(uint8_t *p, unsigned v)
105 {
106  if (v>>28)
107  *p++ = ((v>>28)&0x7f)|0x80;
108  if (v>>21)
109  *p++ = ((v>>21)&0x7f)|0x80;
110  if (v>>14)
111  *p++ = ((v>>14)&0x7f)|0x80;
112  if (v>>7)
113  *p++ = ((v>>7)&0x7f)|0x80;
114 }
115 
116 static unsigned recover_key(unsigned char sample[4], unsigned expected_size)
117 {
118  unsigned char plaintext[8] = { 'S', 'B' };
119 
120  put_v(plaintext+2, expected_size);
121 
122  return AV_RL32(sample) ^ AV_RL32(plaintext);
123 }
124 
125 static void xor_block(void *p1, void *p2, unsigned size, int key, unsigned *key_ptr)
126 {
127  unsigned *d1 = p1;
128  unsigned *d2 = p2;
129  unsigned k = *key_ptr;
130 
131  size >>= 2;
132 
133  while (size > 0) {
134  *d2 = *d1 ^ (HAVE_BIGENDIAN ? av_bswap32(k) : k);
135  k += key;
136  d1++;
137  d2++;
138  size--;
139  }
140 
141  *key_ptr = k;
142 }
143 
144 static void decode_block(uint8_t *src, uint8_t *dest, unsigned size,
145  uint32_t key, uint32_t *key_ptr,
146  int align)
147 {
148  unsigned s = size;
149  char tmp[4];
150  int a2;
151 
152  if (!size)
153  return;
154 
155  align &= 3;
156  a2 = (4 - align) & 3;
157 
158  if (align) {
159  uint32_t tmpkey = *key_ptr - key;
160  if (a2 > s) {
161  a2 = s;
162  avpriv_request_sample(NULL, "tiny aligned block");
163  }
164  memcpy(tmp + align, src, a2);
165  xor_block(tmp, tmp, 4, key, &tmpkey);
166  memcpy(dest, tmp + align, a2);
167  s -= a2;
168  }
169 
170  if (s >= 4) {
171  xor_block(src + a2, dest + a2, s & ~3,
172  key, key_ptr);
173  s &= 3;
174  }
175 
176  if (s) {
177  size -= s;
178  memcpy(tmp, src + size, s);
179  xor_block(&tmp, &tmp, 4, key, key_ptr);
180  memcpy(dest + size, tmp, s);
181  }
182 }
183 
184 static uint32_t get_v(uint8_t *p, int len)
185 {
186  uint32_t v = 0;
187  const uint8_t *end = p + len;
188 
189  do {
190  if (p >= end || v >= UINT_MAX / 128 - *p)
191  return v;
192  v <<= 7;
193  v += *p & 0x7f;
194  } while (*p++ & 0x80);
195 
196  return v;
197 }
198 
199 static uint8_t *read_vblock(AVIOContext *src, uint32_t *size,
200  uint32_t key, uint32_t *k2, int align)
201 {
202  uint8_t tmp[4];
203  uint8_t *buf;
204  unsigned n;
205 
206  if (avio_read(src, tmp, 4) != 4)
207  return NULL;
208 
209  decode_block(tmp, tmp, 4, key, k2, align);
210 
211  n = get_v(tmp, 4);
212  if (n < 4)
213  return NULL;
214 
215  buf = av_malloc(n);
216  if (!buf)
217  return NULL;
218 
219  *size = n;
220  n -= 4;
221 
222  memcpy(buf, tmp, 4);
223 
224  if (avio_read(src, buf + 4, n) == n) {
225  decode_block(buf + 4, buf + 4, n, key, k2, align);
226  } else {
227  av_free(buf);
228  buf = NULL;
229  }
230 
231  return buf;
232 }
233 
234 static uint8_t *read_sb_block(AVIOContext *src, unsigned *size,
235  uint32_t *key, unsigned expected_size)
236 {
237  uint8_t *buf;
238  uint8_t ibuf[8], sbuf[8];
239  uint32_t k2;
240  unsigned n;
241 
242  if (avio_read(src, ibuf, 8) < 8)
243  return NULL;
244 
245  k2 = *key;
246  decode_block(ibuf, sbuf, 8, *key, &k2, 0);
247 
248  n = get_v(sbuf+2, 6);
249 
250  if (sbuf[0] != 'S' || sbuf[1] != 'B' || (expected_size>0 && n != expected_size)) {
251  uint32_t tmpkey = recover_key(ibuf, expected_size);
252  k2 = tmpkey;
253  decode_block(ibuf, sbuf, 8, tmpkey, &k2, 0);
254  n = get_v(sbuf+2, 6);
255  if (sbuf[0] != 'S' || sbuf[1] != 'B' || expected_size != n)
256  return NULL;
257  *key = tmpkey;
258  }
259 
260  if (n < 8)
261  return NULL;
262 
263  buf = av_malloc(n);
264  if (!buf)
265  return NULL;
266 
267  memcpy(buf, sbuf, 8);
268 
269  *size = n;
270  n -= 8;
271 
272  if (avio_read(src, buf+8, n) != n) {
273  av_free(buf);
274  return NULL;
275  }
276 
277  decode_block(buf + 8, buf + 8, n, *key, &k2, 0);
278 
279  return buf;
280 }
281 
283  const uint8_t *buf, int size)
284 {
285  int i, j, ret;
286  int64_t off;
287  int val_1;
288  int num_video;
289  FFIOContext pb0;
290  AVIOContext *const pb = &pb0.pub;
291 
292  ffio_init_read_context(&pb0, buf, size);
293 
294  ffio_read_varlen(pb); // track_header_len
295  avio_r8(pb); // '1'
296 
297  val_1 = ffio_read_varlen(pb);
298 
299  for (i=0;i<val_1;i++) {
300  int c = avio_r8(pb);
301  if (avio_feof(pb))
302  return AVERROR_EOF;
303  for (j=0;j<c;j++) {
304  if (avio_feof(pb))
305  return AVERROR_EOF;
306  avio_r8(pb); // val_3
307  avio_r8(pb); // val_4
308  }
309  }
310 
311  avio_r8(pb); // num_streams
312 
313  off = avio_tell(pb);
314  off += ffio_read_varlen(pb); // val_5
315 
316  avio_r8(pb); // '2'
317  num_video = avio_r8(pb);
318 
319  avio_seek(pb, off, SEEK_SET);
320  if (num_video != 1) {
321  av_log(s, AV_LOG_ERROR, "number of video tracks %d is not 1\n", num_video);
322  return AVERROR_PATCHWELCOME;
323  }
324 
325  for (i = 0; i < num_video; i++) {
327  int num, den;
328 
329  if (!st)
330  return AVERROR(ENOMEM);
331 
332  st->id = i;
333 
336 
337  off = avio_tell(pb);
338  off += ffio_read_varlen(pb);
339  avio_r8(pb); // '3'
340  avio_r8(pb); // val_7
341  num = avio_rl32(pb); // frame_time
342  den = avio_rl32(pb); // time_base
343  avpriv_set_pts_info(st, 64, num, den);
344  st->nb_frames = avio_rl32(pb); // n frames
345  st->codecpar->width = avio_rl16(pb); // width
346  st->codecpar->height = avio_rl16(pb); // height
347  avio_r8(pb); // val_8
348  avio_rl32(pb); // val_9
349 
350  avio_seek(pb, off, SEEK_SET);
351  }
352 
353  off = avio_tell(pb);
354  off += ffio_read_varlen(pb); // val_10
355  avio_r8(pb); // '4'
356  viv->num_audio = avio_r8(pb);
357  avio_seek(pb, off, SEEK_SET);
358 
359  if (viv->num_audio != 1)
360  av_log(s, AV_LOG_WARNING, "number of audio tracks %d is not 1\n", viv->num_audio);
361 
362  for(i=0;i<viv->num_audio;i++) {
363  int q;
365  if (!st)
366  return AVERROR(ENOMEM);
367 
368  st->id = num_video + i;
369 
372 
373  off = avio_tell(pb);
374  off += ffio_read_varlen(pb); // length
375  avio_r8(pb); // '5'
376  avio_r8(pb); //codec_id
377  avio_rl16(pb); //codec_subid
378  st->codecpar->ch_layout.nb_channels = avio_rl16(pb); // channels
379  st->codecpar->sample_rate = avio_rl32(pb); // sample_rate
380  if (st->codecpar->sample_rate <= 0 || st->codecpar->ch_layout.nb_channels <= 0)
381  return AVERROR_INVALIDDATA;
382  avio_seek(pb, 10, SEEK_CUR); // data_1
383  q = avio_r8(pb);
384  avio_seek(pb, q, SEEK_CUR); // data_2
385  avio_r8(pb); // zeropad
386 
387  if (avio_tell(pb) < off) {
388  int num_data;
389  int xd_size = 1;
390  int data_len[256];
391  int offset = 1;
392  uint8_t *p;
393  ffio_read_varlen(pb); // val_13
394  avio_r8(pb); // '19'
395  ffio_read_varlen(pb); // len_3
396  num_data = avio_r8(pb);
397  for (j = 0; j < num_data; j++) {
398  int64_t len = ffio_read_varlen(pb);
399  if (len < 0 || len > INT_MAX/2 - xd_size) {
400  return AVERROR_INVALIDDATA;
401  }
402  data_len[j] = len;
403  xd_size += len + 1 + len/255;
404  }
405 
406  ret = ff_alloc_extradata(st->codecpar, xd_size);
407  if (ret < 0)
408  return ret;
409 
410  p = st->codecpar->extradata;
411  p[0] = 2;
412 
413  for (j = 0; j < num_data - 1; j++) {
414  unsigned delta = av_xiphlacing(&p[offset], data_len[j]);
415  av_assert0(delta <= xd_size - offset);
416  offset += delta;
417  }
418 
419  for (j = 0; j < num_data; j++) {
420  int ret = avio_read(pb, &p[offset], data_len[j]);
421  if (ret < data_len[j]) {
422  st->codecpar->extradata_size = 0;
423  av_freep(&st->codecpar->extradata);
424  break;
425  }
426  av_assert0(data_len[j] <= xd_size - offset);
427  offset += data_len[j];
428  }
429 
430  if (offset < st->codecpar->extradata_size)
432  }
433  }
434 
435  return 0;
436 }
437 
439  const uint8_t *buf, unsigned size)
440 {
441  int64_t off;
442  int64_t poff;
443  int maxnp=0;
444  FFIOContext pb0;
445  AVIOContext *const pb = &pb0.pub;
446  int i;
447  int64_t filesize = avio_size(s->pb);
448  uint64_t n_sb_blocks_tmp;
449 
450  ffio_init_read_context(&pb0, buf, size);
451 
452  ffio_read_varlen(pb); // track_index_len
453  avio_r8(pb); // 'c'
454  n_sb_blocks_tmp = ffio_read_varlen(pb);
455  if (n_sb_blocks_tmp > size / 2)
456  return AVERROR_INVALIDDATA;
457  viv->sb_blocks = av_calloc(n_sb_blocks_tmp, sizeof(*viv->sb_blocks));
458  if (!viv->sb_blocks) {
459  return AVERROR(ENOMEM);
460  }
461  viv->n_sb_blocks = n_sb_blocks_tmp;
462 
463  off = 0;
464  poff = 0;
465 
466  for (i = 0; i < viv->n_sb_blocks; i++) {
467  uint64_t size_tmp = ffio_read_varlen(pb);
468  uint64_t n_packets_tmp = ffio_read_varlen(pb);
469 
470  if (size_tmp > INT_MAX || n_packets_tmp > INT_MAX)
471  return AVERROR_INVALIDDATA;
472 
473  viv->sb_blocks[i].byte_offset = off;
474  viv->sb_blocks[i].packet_offset = poff;
475 
476  viv->sb_blocks[i].size = size_tmp;
477  viv->sb_blocks[i].n_packets = n_packets_tmp;
478 
479  off += viv->sb_blocks[i].size;
480  poff += viv->sb_blocks[i].n_packets;
481 
482  if (maxnp < viv->sb_blocks[i].n_packets)
483  maxnp = viv->sb_blocks[i].n_packets;
484  }
485 
486  if (filesize > 0 && poff > filesize)
487  return AVERROR_INVALIDDATA;
488 
489  viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry));
490  if (!viv->sb_entries)
491  return AVERROR(ENOMEM);
492 
493  return 0;
494 }
495 
496 static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
497 {
498  uint32_t size = 0;
499  int i;
500  AVIOContext *pb = 0;
501 
502  if (viv->sb_pb) {
503  av_free(viv->sb_pb);
504  viv->sb_pb = NULL;
505  }
506 
507  if (viv->sb_buf)
508  av_free(viv->sb_buf);
509 
510  viv->sb_buf = read_sb_block(s->pb, &size, &viv->sb_key, expected_size);
511  if (!viv->sb_buf) {
512  return;
513  }
514 
515  pb = avio_alloc_context(viv->sb_buf, size, 0, NULL, NULL, NULL, NULL);
516  if (!pb)
517  return;
518 
519  viv->sb_pb = pb;
520 
521  avio_r8(pb); // 'S'
522  avio_r8(pb); // 'B'
523  ffio_read_varlen(pb); // size
524  avio_r8(pb); // junk
525  ffio_read_varlen(pb); // first packet
526 
527  viv->n_sb_entries = viv->sb_blocks[viv->current_sb].n_packets;
528 
529  for (i = 0; i < viv->n_sb_entries; i++) {
530  viv->sb_entries[i].size = ffio_read_varlen(pb);
531  viv->sb_entries[i].flag = avio_r8(pb);
532  }
533 
534  ffio_read_varlen(pb);
535  avio_r8(pb);
536 
537  viv->current_sb_entry = 0;
538 }
539 
541 {
542  VividasDemuxContext *viv = s->priv_data;
543  AVIOContext *pb = s->pb;
544  int64_t header_end;
545  int num_tracks;
546  uint32_t key, k2;
547  uint32_t v;
548  uint8_t keybuffer[187];
549  uint32_t b22_size = 0;
550  uint32_t b22_key = 0;
551  uint8_t *buf = 0;
552  int ret;
553 
554  avio_skip(pb, 9);
555 
556  header_end = avio_tell(pb);
557 
558  header_end += ffio_read_varlen(pb);
559 
560  num_tracks = avio_r8(pb);
561 
562  if (num_tracks != 1) {
563  av_log(s, AV_LOG_ERROR, "number of tracks %d is not 1\n", num_tracks);
564  return AVERROR(EINVAL);
565  }
566 
567  v = avio_r8(pb);
568  avio_seek(pb, v, SEEK_CUR);
569 
570  avio_read(pb, keybuffer, 187);
571  key = decode_key(keybuffer);
572  viv->sb_key = key;
573 
574  avio_rl32(pb);
575 
576  for (;;) {
577  int64_t here = avio_tell(pb);
578  int block_len, block_type;
579 
580  if (here >= header_end)
581  break;
582 
583  block_len = ffio_read_varlen(pb);
584  if (avio_feof(pb) || block_len <= 0)
585  return AVERROR_INVALIDDATA;
586 
587  block_type = avio_r8(pb);
588 
589  if (block_type == 22) {
590  avio_read(pb, keybuffer, 187);
591  b22_key = decode_key(keybuffer);
592  b22_size = avio_rl32(pb);
593  }
594 
595  avio_seek(pb, here + block_len, SEEK_SET);
596  }
597 
598  if (b22_size) {
599  k2 = b22_key;
600  buf = read_vblock(pb, &v, b22_key, &k2, 0);
601  if (!buf)
602  return AVERROR(EIO);
603 
604  av_free(buf);
605  }
606 
607  k2 = key;
608  buf = read_vblock(pb, &v, key, &k2, 0);
609  if (!buf)
610  return AVERROR(EIO);
611  ret = track_header(viv, s, buf, v);
612  av_free(buf);
613  if (ret < 0)
614  return ret;
615 
616  buf = read_vblock(pb, &v, key, &k2, v);
617  if (!buf)
618  return AVERROR(EIO);
619  ret = track_index(viv, s, buf, v);
620  av_free(buf);
621  if (ret < 0)
622  return ret;
623 
624  viv->sb_offset = avio_tell(pb);
625  if (viv->n_sb_blocks > 0) {
626  viv->current_sb = 0;
627  load_sb_block(s, viv, viv->sb_blocks[0].size);
628  } else {
629  viv->current_sb = -1;
630  }
631 
632  return 0;
633 }
634 
636  AVPacket *pkt)
637 {
638  VividasDemuxContext *viv = s->priv_data;
639  AVIOContext *pb;
640  int64_t off;
641  int ret;
642 
643  if (!viv->sb_pb)
644  return AVERROR(EIO);
645  if (avio_feof(viv->sb_pb))
646  return AVERROR_EOF;
647 
649  AVStream *astream;
651 
652  pb = viv->sb_pb;
653  ret = av_get_packet(pb, pkt, size);
654  if (ret < 0)
655  return ret;
656  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
657 
658  pkt->stream_index = 1;
659  astream = s->streams[pkt->stream_index];
660 
661  pkt->pts = av_rescale_q(viv->audio_sample, av_make_q(1, astream->codecpar->sample_rate), astream->time_base);
663  astream->codecpar->ch_layout.nb_channels;
666  return 0;
667  }
668 
669  if (viv->current_sb_entry >= viv->n_sb_entries) {
670  if (viv->current_sb+1 >= viv->n_sb_blocks)
671  return AVERROR(EIO);
672  viv->current_sb++;
673 
674  load_sb_block(s, viv, 0);
675  viv->current_sb_entry = 0;
676  }
677 
678  pb = viv->sb_pb;
679  if (!pb)
680  return AVERROR(EIO);
681  off = avio_tell(pb);
682 
683  if (viv->current_sb_entry >= viv->n_sb_entries)
684  return AVERROR_INVALIDDATA;
685 
686  off += viv->sb_entries[viv->current_sb_entry].size;
687 
688  if (viv->sb_entries[viv->current_sb_entry].flag == 0) {
689  uint64_t v_size = ffio_read_varlen(pb);
690  int last = 0, last_start;
691 
692  if (!viv->num_audio)
693  return AVERROR_INVALIDDATA;
694 
695  ffio_read_varlen(pb);
696  if (v_size > INT_MAX || !v_size)
697  return AVERROR_INVALIDDATA;
698  ret = av_get_packet(pb, pkt, v_size);
699  if (ret < 0)
700  return ret;
701  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
702 
704  pkt->flags |= (pkt->data[0]&0x80)?0:AV_PKT_FLAG_KEY;
705  pkt->stream_index = 0;
706 
707  for (int i = 0; i < MAX_AUDIO_SUBPACKETS - 1; i++) {
708  int start, pcm_bytes;
709  start = ffio_read_varlen(pb);
710  pcm_bytes = ffio_read_varlen(pb);
711 
712  if (i > 0 && start == 0)
713  break;
714  if (start < last)
715  return AVERROR_INVALIDDATA;
716 
717  viv->n_audio_subpackets = i + 1;
718  last =
719  viv->audio_subpackets[i].start = start;
720  viv->audio_subpackets[i].pcm_bytes = pcm_bytes;
721  }
722  last_start =
723  viv->audio_subpackets[viv->n_audio_subpackets].start = (int)(off - avio_tell(pb));
724  if (last_start < last)
725  return AVERROR_INVALIDDATA;
726  viv->current_audio_subpacket = 0;
727 
728  } else {
729  uint64_t v_size = ffio_read_varlen(pb);
730 
731  if (v_size > INT_MAX || !v_size)
732  return AVERROR_INVALIDDATA;
733  ret = av_get_packet(pb, pkt, v_size);
734  if (ret < 0)
735  return ret;
736  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
738  pkt->flags |= (pkt->data[0] & 0x80) ? 0 : AV_PKT_FLAG_KEY;
739  pkt->stream_index = 0;
740  }
741 
742  viv->current_sb_entry++;
743 
744  return 0;
745 }
746 
748 {
749  VividasDemuxContext *viv = s->priv_data;
750 
751  av_freep(&viv->sb_pb);
752  av_freep(&viv->sb_buf);
753  av_freep(&viv->sb_blocks);
754  av_freep(&viv->sb_entries);
755 
756  return 0;
757 }
758 
759 static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
760 {
761  VividasDemuxContext *viv = s->priv_data;
762  int64_t frame;
763 
764  if (stream_index == 0)
765  frame = timestamp;
766  else
767  frame = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[stream_index]->time_base);
768 
769  for (int i = 0; i < viv->n_sb_blocks; i++) {
770  if (frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) {
771  viv->current_sb = i;
772  // seek to ith sb block
773  avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET);
774  // load the block
775  load_sb_block(s, viv, 0);
776  if (viv->num_audio) {
777  const AVCodecParameters *par = s->streams[1]->codecpar;
778  // flush audio packet queue
779  viv->current_audio_subpacket = 0;
780  viv->n_audio_subpackets = 0;
781  // most problematic part: guess audio offset
783  av_make_q(par->sample_rate, 1),
784  av_inv_q(s->streams[0]->time_base));
785  // hand-tuned 1.s a/v offset
786  viv->audio_sample += par->sample_rate;
787  }
788  viv->current_sb_entry = 0;
789  return 1;
790  }
791  }
792  return 0;
793 }
794 
796  .p.name = "vividas",
797  .p.long_name = NULL_IF_CONFIG_SMALL("Vividas VIV"),
798  .priv_data_size = sizeof(VividasDemuxContext),
799  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
805 };
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:104
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:251
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
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
VividasDemuxContext::sb_buf
uint8_t * sb_buf
Definition: vividas.c:64
AVPacket::data
uint8_t * data
Definition: packet.h:520
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:109
AV_CODEC_ID_VP6
@ AV_CODEC_ID_VP6
Definition: codec_id.h:143
VividasDemuxContext::current_sb_entry
int current_sb_entry
Definition: vividas.c:63
VIV_SB_block
Definition: vividas.c:41
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:99
VividasDemuxContext::audio_sample
int64_t audio_sample
Definition: vividas.c:72
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:321
VIV_SB_block::byte_offset
int64_t byte_offset
Definition: vividas.c:43
VividasDemuxContext::current_audio_subpacket
int current_audio_subpacket
Definition: vividas.c:70
get_v
static uint32_t get_v(uint8_t *p, int len)
Definition: vividas.c:184
track_index
static int track_index(VividasDemuxContext *viv, AVFormatContext *s, const uint8_t *buf, unsigned size)
Definition: vividas.c:438
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:323
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:575
VividasDemuxContext::n_sb_blocks
int n_sb_blocks
Definition: vividas.c:56
read_vblock
static uint8_t * read_vblock(AVIOContext *src, uint32_t *size, uint32_t key, uint32_t *k2, int align)
Definition: vividas.c:199
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:116
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:144
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:52
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:540
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:58
a2
static double a2(void *priv, double x, double y)
Definition: vf_xfade.c:2031
VividasDemuxContext::current_sb
int current_sb
Definition: vividas.c:63
avio_rl16
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:714
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:60
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:42
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:759
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:47
key
const char * key
Definition: hwcontext_opencl.c:189
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:48
internal.h
VividasDemuxContext::audio_subpackets
VIV_AudioSubpacket audio_subpackets[MAX_AUDIO_SUBPACKETS]
Definition: vividas.c:74
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:51
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:234
VIV_SB_block::n_packets
int n_packets
Definition: vividas.c:42
xor_block
static void xor_block(void *p1, void *p2, unsigned size, int key, unsigned *key_ptr)
Definition: vividas.c:125
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:730
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:94
av_bswap32
#define av_bswap32
Definition: bswap.h:47
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:817
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:603
VIV_SB_entry::flag
int flag
Definition: vividas.c:48
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:526
ffio_read_varlen
uint64_t ffio_read_varlen(AVIOContext *bc)
Definition: aviobuf.c:916
VIV_SB_block::size
int size
Definition: vividas.c:42
MAX_AUDIO_SUBPACKETS
#define MAX_AUDIO_SUBPACKETS
Definition: vividas.c:39
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:496
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:513
VividasDemuxContext::sb_key
uint32_t sb_key
Definition: vividas.c:60
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:92
VividasDemuxContext
Definition: vividas.c:55
VIV_SB_block::packet_offset
int64_t packet_offset
Definition: vividas.c:44
delta
float delta
Definition: vorbis_enc_data.h:430
viv_probe
static int viv_probe(const AVProbeData *p)
Definition: vividas.c:77
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:264
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:91
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:231
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
keybits
static const uint8_t keybits[32]
Definition: vividas.c:85
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:635
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:612
VividasDemuxContext::n_audio_subpackets
int n_audio_subpackets
Definition: vividas.c:69
AVPacket::stream_index
int stream_index
Definition: packet.h:522
VividasDemuxContext::n_sb_entries
int n_sb_entries
Definition: vividas.c:66
VividasDemuxContext::sb_pb
AVIOContext * sb_pb
Definition: vividas.c:65
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:318
track_header
static int track_header(VividasDemuxContext *viv, AVFormatContext *s, const uint8_t *buf, int size)
Definition: vividas.c:282
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
mem.h
VividasDemuxContext::sb_offset
int64_t sb_offset
Definition: vividas.c:61
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:36
VIV_AudioSubpacket::pcm_bytes
int pcm_bytes
Definition: vividas.c:52
VividasDemuxContext::sb_entries
VIV_SB_entry * sb_entries
Definition: vividas.c:67
viv_read_close
static int viv_read_close(AVFormatContext *s)
Definition: vividas.c:747
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
VividasDemuxContext::sb_blocks
VIV_SB_block * sb_blocks
Definition: vividas.c:57
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:497
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:540
FFInputFormat
Definition: demux.h:37
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
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:424
ff_vividas_demuxer
const FFInputFormat ff_vividas_demuxer
Definition: vividas.c:795
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:227
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:346