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 "internal.h"
36 
37 #define MAX_AUDIO_SUBPACKETS 100
38 
39 typedef struct VIV_SB_block {
41  int64_t byte_offset;
42  int64_t packet_offset;
43 } VIV_SB_block;
44 
45 typedef struct VIV_SB_entry {
46  int size, flag;
47 } VIV_SB_entry;
48 
49 typedef struct VIV_AudioSubpacket {
50  int start, pcm_bytes;
52 
53 typedef struct VividasDemuxContext {
56  int num_audio;
57 
58  uint32_t sb_key;
59  int64_t sb_offset;
60 
61  int current_sb, current_sb_entry;
66 
69 
70  int64_t audio_sample;
71 
74 
75 static int viv_probe(const AVProbeData *p)
76 {
77  if (memcmp(p->buf, "vividas03", 9))
78  return 0;
79 
80  return AVPROBE_SCORE_MAX;
81 }
82 
83 static const uint8_t keybits[32] = {
84  20, 52, 111, 10, 27, 71, 142, 53,
85  82, 138, 1, 78, 86, 121, 183, 85,
86 105, 152, 39, 140, 172, 11, 64, 144,
87 155, 6, 71, 163, 186, 49, 126, 43,
88 };
89 
90 static uint32_t decode_key(uint8_t *buf)
91 {
92  uint32_t key = 0;
93 
94  for (int i = 0; i < 32; i++) {
95  unsigned p = keybits[i];
96  key |= ((buf[p] >> ((i*5+3)&7)) & 1u) << i;
97  }
98 
99  return key;
100 }
101 
102 static void put_v(uint8_t *p, unsigned v)
103 {
104  if (v>>28)
105  *p++ = ((v>>28)&0x7f)|0x80;
106  if (v>>21)
107  *p++ = ((v>>21)&0x7f)|0x80;
108  if (v>>14)
109  *p++ = ((v>>14)&0x7f)|0x80;
110  if (v>>7)
111  *p++ = ((v>>7)&0x7f)|0x80;
112 }
113 
114 static unsigned recover_key(unsigned char sample[4], unsigned expected_size)
115 {
116  unsigned char plaintext[8] = { 'S', 'B' };
117 
118  put_v(plaintext+2, expected_size);
119 
120  return AV_RL32(sample) ^ AV_RL32(plaintext);
121 }
122 
123 static void xor_block(void *p1, void *p2, unsigned size, int key, unsigned *key_ptr)
124 {
125  unsigned *d1 = p1;
126  unsigned *d2 = p2;
127  unsigned k = *key_ptr;
128 
129  size >>= 2;
130 
131  while (size > 0) {
132  *d2 = *d1 ^ (HAVE_BIGENDIAN ? av_bswap32(k) : k);
133  k += key;
134  d1++;
135  d2++;
136  size--;
137  }
138 
139  *key_ptr = k;
140 }
141 
142 static void decode_block(uint8_t *src, uint8_t *dest, unsigned size,
143  uint32_t key, uint32_t *key_ptr,
144  int align)
145 {
146  unsigned s = size;
147  char tmp[4];
148  int a2;
149 
150  if (!size)
151  return;
152 
153  align &= 3;
154  a2 = (4 - align) & 3;
155 
156  if (align) {
157  uint32_t tmpkey = *key_ptr - key;
158  if (a2 > s) {
159  a2 = s;
160  avpriv_request_sample(NULL, "tiny aligned block");
161  }
162  memcpy(tmp + align, src, a2);
163  xor_block(tmp, tmp, 4, key, &tmpkey);
164  memcpy(dest, tmp + align, a2);
165  s -= a2;
166  }
167 
168  if (s >= 4) {
169  xor_block(src + a2, dest + a2, s & ~3,
170  key, key_ptr);
171  s &= 3;
172  }
173 
174  if (s) {
175  size -= s;
176  memcpy(tmp, src + size, s);
177  xor_block(&tmp, &tmp, 4, key, key_ptr);
178  memcpy(dest + size, tmp, s);
179  }
180 }
181 
182 static uint32_t get_v(uint8_t *p, int len)
183 {
184  uint32_t v = 0;
185  const uint8_t *end = p + len;
186 
187  do {
188  if (p >= end || v >= UINT_MAX / 128 - *p)
189  return v;
190  v <<= 7;
191  v += *p & 0x7f;
192  } while (*p++ & 0x80);
193 
194  return v;
195 }
196 
197 static uint8_t *read_vblock(AVIOContext *src, uint32_t *size,
198  uint32_t key, uint32_t *k2, int align)
199 {
200  uint8_t tmp[4];
201  uint8_t *buf;
202  unsigned n;
203 
204  if (avio_read(src, tmp, 4) != 4)
205  return NULL;
206 
207  decode_block(tmp, tmp, 4, key, k2, align);
208 
209  n = get_v(tmp, 4);
210  if (n < 4)
211  return NULL;
212 
213  buf = av_malloc(n);
214  if (!buf)
215  return NULL;
216 
217  *size = n;
218  n -= 4;
219 
220  memcpy(buf, tmp, 4);
221 
222  if (avio_read(src, buf + 4, n) == n) {
223  decode_block(buf + 4, buf + 4, n, key, k2, align);
224  } else {
225  av_free(buf);
226  buf = NULL;
227  }
228 
229  return buf;
230 }
231 
233  uint32_t *key, unsigned expected_size)
234 {
235  uint8_t *buf;
236  uint8_t ibuf[8], sbuf[8];
237  uint32_t k2;
238  unsigned n;
239 
240  if (avio_read(src, ibuf, 8) < 8)
241  return NULL;
242 
243  k2 = *key;
244  decode_block(ibuf, sbuf, 8, *key, &k2, 0);
245 
246  n = get_v(sbuf+2, 6);
247 
248  if (sbuf[0] != 'S' || sbuf[1] != 'B' || (expected_size>0 && n != expected_size)) {
249  uint32_t tmpkey = recover_key(ibuf, expected_size);
250  k2 = tmpkey;
251  decode_block(ibuf, sbuf, 8, tmpkey, &k2, 0);
252  n = get_v(sbuf+2, 6);
253  if (sbuf[0] != 'S' || sbuf[1] != 'B' || expected_size != n)
254  return NULL;
255  *key = tmpkey;
256  }
257 
258  if (n < 8)
259  return NULL;
260 
261  buf = av_malloc(n);
262  if (!buf)
263  return NULL;
264 
265  memcpy(buf, sbuf, 8);
266 
267  *size = n;
268  n -= 8;
269 
270  if (avio_read(src, buf+8, n) < n) {
271  av_free(buf);
272  return NULL;
273  }
274 
275  decode_block(buf + 8, buf + 8, n, *key, &k2, 0);
276 
277  return buf;
278 }
279 
281 {
282  int i, j, ret;
283  int64_t off;
284  int val_1;
285  int num_video;
286  AVIOContext pb0, *pb = &pb0;
287 
288  ffio_init_context(pb, buf, size, 0, NULL, NULL, NULL, NULL);
289 
290  ffio_read_varlen(pb); // track_header_len
291  avio_r8(pb); // '1'
292 
293  val_1 = ffio_read_varlen(pb);
294 
295  for (i=0;i<val_1;i++) {
296  int c = avio_r8(pb);
297  if (avio_feof(pb))
298  return AVERROR_EOF;
299  for (j=0;j<c;j++) {
300  if (avio_feof(pb))
301  return AVERROR_EOF;
302  avio_r8(pb); // val_3
303  avio_r8(pb); // val_4
304  }
305  }
306 
307  avio_r8(pb); // num_streams
308 
309  off = avio_tell(pb);
310  off += ffio_read_varlen(pb); // val_5
311 
312  avio_r8(pb); // '2'
313  num_video = avio_r8(pb);
314 
315  avio_seek(pb, off, SEEK_SET);
316  if (num_video != 1) {
317  av_log(s, AV_LOG_ERROR, "number of video tracks %d is not 1\n", num_video);
318  return AVERROR_PATCHWELCOME;
319  }
320 
321  for (i = 0; i < num_video; i++) {
323  int num, den;
324 
325  if (!st)
326  return AVERROR(ENOMEM);
327 
328  st->id = i;
329 
332 
333  off = avio_tell(pb);
334  off += ffio_read_varlen(pb);
335  avio_r8(pb); // '3'
336  avio_r8(pb); // val_7
337  num = avio_rl32(pb); // frame_time
338  den = avio_rl32(pb); // time_base
339  avpriv_set_pts_info(st, 64, num, den);
340  st->nb_frames = avio_rl32(pb); // n frames
341  st->codecpar->width = avio_rl16(pb); // width
342  st->codecpar->height = avio_rl16(pb); // height
343  avio_r8(pb); // val_8
344  avio_rl32(pb); // val_9
345 
346  avio_seek(pb, off, SEEK_SET);
347  }
348 
349  off = avio_tell(pb);
350  off += ffio_read_varlen(pb); // val_10
351  avio_r8(pb); // '4'
352  viv->num_audio = avio_r8(pb);
353  avio_seek(pb, off, SEEK_SET);
354 
355  if (viv->num_audio != 1)
356  av_log(s, AV_LOG_WARNING, "number of audio tracks %d is not 1\n", viv->num_audio);
357 
358  for(i=0;i<viv->num_audio;i++) {
359  int q;
361  if (!st)
362  return AVERROR(ENOMEM);
363 
364  st->id = num_video + i;
365 
368 
369  off = avio_tell(pb);
370  off += ffio_read_varlen(pb); // length
371  avio_r8(pb); // '5'
372  avio_r8(pb); //codec_id
373  avio_rl16(pb); //codec_subid
374  st->codecpar->channels = avio_rl16(pb); // channels
375  st->codecpar->sample_rate = avio_rl32(pb); // sample_rate
376  if (st->codecpar->sample_rate <= 0 || st->codecpar->channels <= 0)
377  return AVERROR_INVALIDDATA;
378  avio_seek(pb, 10, SEEK_CUR); // data_1
379  q = avio_r8(pb);
380  avio_seek(pb, q, SEEK_CUR); // data_2
381  avio_r8(pb); // zeropad
382 
383  if (avio_tell(pb) < off) {
384  int num_data;
385  int xd_size = 1;
386  int data_len[256];
387  int offset = 1;
388  uint8_t *p;
389  ffio_read_varlen(pb); // val_13
390  avio_r8(pb); // '19'
391  ffio_read_varlen(pb); // len_3
392  num_data = avio_r8(pb);
393  for (j = 0; j < num_data; j++) {
394  int64_t len = ffio_read_varlen(pb);
395  if (len < 0 || len > INT_MAX/2 - xd_size) {
396  return AVERROR_INVALIDDATA;
397  }
398  data_len[j] = len;
399  xd_size += len + 1 + len/255;
400  }
401 
402  ret = ff_alloc_extradata(st->codecpar, xd_size);
403  if (ret < 0)
404  return ret;
405 
406  p = st->codecpar->extradata;
407  p[0] = 2;
408 
409  for (j = 0; j < num_data - 1; j++) {
410  unsigned delta = av_xiphlacing(&p[offset], data_len[j]);
411  av_assert0(delta <= xd_size - offset);
412  offset += delta;
413  }
414 
415  for (j = 0; j < num_data; j++) {
416  int ret = avio_read(pb, &p[offset], data_len[j]);
417  if (ret < data_len[j]) {
418  st->codecpar->extradata_size = 0;
419  av_freep(&st->codecpar->extradata);
420  break;
421  }
422  av_assert0(data_len[j] <= xd_size - offset);
423  offset += data_len[j];
424  }
425 
426  if (offset < st->codecpar->extradata_size)
428  }
429  }
430 
431  return 0;
432 }
433 
434 static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *buf, unsigned size)
435 {
436  int64_t off;
437  int64_t poff;
438  int maxnp=0;
439  AVIOContext pb0, *pb = &pb0;
440  int i;
441  int64_t filesize = avio_size(s->pb);
442  uint64_t n_sb_blocks_tmp;
443 
444  ffio_init_context(pb, buf, size, 0, NULL, NULL, NULL, NULL);
445 
446  ffio_read_varlen(pb); // track_index_len
447  avio_r8(pb); // 'c'
448  n_sb_blocks_tmp = ffio_read_varlen(pb);
449  if (n_sb_blocks_tmp > size / 2)
450  return AVERROR_INVALIDDATA;
451  viv->sb_blocks = av_calloc(n_sb_blocks_tmp, sizeof(*viv->sb_blocks));
452  if (!viv->sb_blocks) {
453  return AVERROR(ENOMEM);
454  }
455  viv->n_sb_blocks = n_sb_blocks_tmp;
456 
457  off = 0;
458  poff = 0;
459 
460  for (i = 0; i < viv->n_sb_blocks; i++) {
461  uint64_t size_tmp = ffio_read_varlen(pb);
462  uint64_t n_packets_tmp = ffio_read_varlen(pb);
463 
464  if (size_tmp > INT_MAX || n_packets_tmp > INT_MAX)
465  return AVERROR_INVALIDDATA;
466 
467  viv->sb_blocks[i].byte_offset = off;
468  viv->sb_blocks[i].packet_offset = poff;
469 
470  viv->sb_blocks[i].size = size_tmp;
471  viv->sb_blocks[i].n_packets = n_packets_tmp;
472 
473  off += viv->sb_blocks[i].size;
474  poff += viv->sb_blocks[i].n_packets;
475 
476  if (maxnp < viv->sb_blocks[i].n_packets)
477  maxnp = viv->sb_blocks[i].n_packets;
478  }
479 
480  if (filesize > 0 && poff > filesize)
481  return AVERROR_INVALIDDATA;
482 
483  viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry));
484  if (!viv->sb_entries)
485  return AVERROR(ENOMEM);
486 
487  return 0;
488 }
489 
490 static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
491 {
492  uint32_t size = 0;
493  int i;
494  AVIOContext *pb = 0;
495 
496  if (viv->sb_pb) {
497  av_free(viv->sb_pb);
498  viv->sb_pb = NULL;
499  }
500 
501  if (viv->sb_buf)
502  av_free(viv->sb_buf);
503 
504  viv->sb_buf = read_sb_block(s->pb, &size, &viv->sb_key, expected_size);
505  if (!viv->sb_buf) {
506  return;
507  }
508 
509  pb = avio_alloc_context(viv->sb_buf, size, 0, NULL, NULL, NULL, NULL);
510  if (!pb)
511  return;
512 
513  viv->sb_pb = pb;
514 
515  avio_r8(pb); // 'S'
516  avio_r8(pb); // 'B'
517  ffio_read_varlen(pb); // size
518  avio_r8(pb); // junk
519  ffio_read_varlen(pb); // first packet
520 
521  viv->n_sb_entries = viv->sb_blocks[viv->current_sb].n_packets;
522 
523  for (i = 0; i < viv->n_sb_entries; i++) {
524  viv->sb_entries[i].size = ffio_read_varlen(pb);
525  viv->sb_entries[i].flag = avio_r8(pb);
526  }
527 
528  ffio_read_varlen(pb);
529  avio_r8(pb);
530 
531  viv->current_sb_entry = 0;
532 }
533 
535 {
536  VividasDemuxContext *viv = s->priv_data;
537  AVIOContext *pb = s->pb;
538  int64_t header_end;
539  int num_tracks;
540  uint32_t key, k2;
541  uint32_t v;
542  uint8_t keybuffer[187];
543  uint32_t b22_size = 0;
544  uint32_t b22_key = 0;
545  uint8_t *buf = 0;
546  int ret;
547 
548  avio_skip(pb, 9);
549 
550  header_end = avio_tell(pb);
551 
552  header_end += ffio_read_varlen(pb);
553 
554  num_tracks = avio_r8(pb);
555 
556  if (num_tracks != 1) {
557  av_log(s, AV_LOG_ERROR, "number of tracks %d is not 1\n", num_tracks);
558  return AVERROR(EINVAL);
559  }
560 
561  v = avio_r8(pb);
562  avio_seek(pb, v, SEEK_CUR);
563 
564  avio_read(pb, keybuffer, 187);
565  key = decode_key(keybuffer);
566  viv->sb_key = key;
567 
568  avio_rl32(pb);
569 
570  for (;;) {
571  int64_t here = avio_tell(pb);
572  int block_len, block_type;
573 
574  if (here >= header_end)
575  break;
576 
577  block_len = ffio_read_varlen(pb);
578  if (avio_feof(pb) || block_len <= 0)
579  return AVERROR_INVALIDDATA;
580 
581  block_type = avio_r8(pb);
582 
583  if (block_type == 22) {
584  avio_read(pb, keybuffer, 187);
585  b22_key = decode_key(keybuffer);
586  b22_size = avio_rl32(pb);
587  }
588 
589  avio_seek(pb, here + block_len, SEEK_SET);
590  }
591 
592  if (b22_size) {
593  k2 = b22_key;
594  buf = read_vblock(pb, &v, b22_key, &k2, 0);
595  if (!buf)
596  return AVERROR(EIO);
597 
598  av_free(buf);
599  }
600 
601  k2 = key;
602  buf = read_vblock(pb, &v, key, &k2, 0);
603  if (!buf)
604  return AVERROR(EIO);
605  ret = track_header(viv, s, buf, v);
606  av_free(buf);
607  if (ret < 0)
608  return ret;
609 
610  buf = read_vblock(pb, &v, key, &k2, v);
611  if (!buf)
612  return AVERROR(EIO);
613  ret = track_index(viv, s, buf, v);
614  av_free(buf);
615  if (ret < 0)
616  goto fail;
617 
618  viv->sb_offset = avio_tell(pb);
619  if (viv->n_sb_blocks > 0) {
620  viv->current_sb = 0;
621  load_sb_block(s, viv, viv->sb_blocks[0].size);
622  } else {
623  viv->current_sb = -1;
624  }
625 
626  return 0;
627 fail:
628  av_freep(&viv->sb_blocks);
629  return ret;
630 }
631 
633  AVPacket *pkt)
634 {
635  VividasDemuxContext *viv = s->priv_data;
636  AVIOContext *pb;
637  int64_t off;
638  int ret;
639 
640  if (!viv->sb_pb)
641  return AVERROR(EIO);
642  if (avio_feof(viv->sb_pb))
643  return AVERROR_EOF;
644 
646  AVStream *astream;
648 
649  pb = viv->sb_pb;
650  ret = av_get_packet(pb, pkt, size);
651  if (ret < 0)
652  return ret;
653  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
654 
655  pkt->stream_index = 1;
656  astream = s->streams[pkt->stream_index];
657 
658  pkt->pts = av_rescale_q(viv->audio_sample, av_make_q(1, astream->codecpar->sample_rate), astream->time_base);
660  pkt->flags |= AV_PKT_FLAG_KEY;
662  return 0;
663  }
664 
665  if (viv->current_sb_entry >= viv->n_sb_entries) {
666  if (viv->current_sb+1 >= viv->n_sb_blocks)
667  return AVERROR(EIO);
668  viv->current_sb++;
669 
670  load_sb_block(s, viv, 0);
671  viv->current_sb_entry = 0;
672  }
673 
674  pb = viv->sb_pb;
675  if (!pb)
676  return AVERROR(EIO);
677  off = avio_tell(pb);
678 
679  if (viv->current_sb_entry >= viv->n_sb_entries)
680  return AVERROR_INVALIDDATA;
681 
682  off += viv->sb_entries[viv->current_sb_entry].size;
683 
684  if (viv->sb_entries[viv->current_sb_entry].flag == 0) {
685  uint64_t v_size = ffio_read_varlen(pb);
686 
687  if (!viv->num_audio)
688  return AVERROR_INVALIDDATA;
689 
690  ffio_read_varlen(pb);
691  if (v_size > INT_MAX || !v_size)
692  return AVERROR_INVALIDDATA;
693  ret = av_get_packet(pb, pkt, v_size);
694  if (ret < 0)
695  return ret;
696  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
697 
698  pkt->pts = viv->sb_blocks[viv->current_sb].packet_offset + viv->current_sb_entry;
699  pkt->flags |= (pkt->data[0]&0x80)?0:AV_PKT_FLAG_KEY;
700  pkt->stream_index = 0;
701 
702  for (int i = 0; i < MAX_AUDIO_SUBPACKETS - 1; i++) {
703  int start, pcm_bytes;
704  start = ffio_read_varlen(pb);
705  pcm_bytes = ffio_read_varlen(pb);
706 
707  if (i > 0 && start == 0)
708  break;
709 
710  viv->n_audio_subpackets = i + 1;
711  viv->audio_subpackets[i].start = start;
712  viv->audio_subpackets[i].pcm_bytes = pcm_bytes;
713  }
714  viv->audio_subpackets[viv->n_audio_subpackets].start = (int)(off - avio_tell(pb));
715  viv->current_audio_subpacket = 0;
716 
717  } else {
718  uint64_t v_size = ffio_read_varlen(pb);
719 
720  if (v_size > INT_MAX || !v_size)
721  return AVERROR_INVALIDDATA;
722  ret = av_get_packet(pb, pkt, v_size);
723  if (ret < 0)
724  return ret;
725  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
726  pkt->pts = viv->sb_blocks[viv->current_sb].packet_offset + viv->current_sb_entry;
727  pkt->flags |= (pkt->data[0] & 0x80) ? 0 : AV_PKT_FLAG_KEY;
728  pkt->stream_index = 0;
729  }
730 
731  viv->current_sb_entry++;
732 
733  return 0;
734 }
735 
737 {
738  VividasDemuxContext *viv = s->priv_data;
739 
740  av_freep(&viv->sb_pb);
741  av_freep(&viv->sb_buf);
742  av_freep(&viv->sb_blocks);
743  av_freep(&viv->sb_entries);
744 
745  return 0;
746 }
747 
748 static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
749 {
750  VividasDemuxContext *viv = s->priv_data;
751  int64_t frame;
752 
753  if (stream_index == 0)
754  frame = timestamp;
755  else
756  frame = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[stream_index]->time_base);
757 
758  for (int i = 0; i < viv->n_sb_blocks; i++) {
759  if (frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) {
760  // flush audio packet queue
761  viv->current_audio_subpacket = 0;
762  viv->n_audio_subpackets = 0;
763  viv->current_sb = i;
764  // seek to ith sb block
765  avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET);
766  // load the block
767  load_sb_block(s, viv, 0);
768  // most problematic part: guess audio offset
770  // hand-tuned 1.s a/v offset
771  viv->audio_sample += s->streams[1]->codecpar->sample_rate;
772  viv->current_sb_entry = 0;
773  return 1;
774  }
775  }
776  return 0;
777 }
778 
780  .name = "vividas",
781  .long_name = NULL_IF_CONFIG_SMALL("Vividas VIV"),
782  .priv_data_size = sizeof(VividasDemuxContext),
788 };
#define NULL
Definition: coverity.c:32
uint64_t ffio_read_varlen(AVIOContext *bc)
Definition: aviobuf.c:914
static uint8_t * read_vblock(AVIOContext *src, uint32_t *size, uint32_t key, uint32_t *k2, int align)
Definition: vividas.c:197
Bytestream IO Context.
Definition: avio.h:161
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:346
static uint32_t get_v(uint8_t *p, int len)
Definition: vividas.c:182
static void decode_block(uint8_t *src, uint8_t *dest, unsigned size, uint32_t key, uint32_t *key_ptr, int align)
Definition: vividas.c:142
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:383
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.
Definition: utils.c:4899
int64_t packet_offset
Definition: vividas.c:42
#define avpriv_request_sample(...)
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:153
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:253
int n_audio_subpackets
Definition: vividas.c:67
static unsigned recover_key(unsigned char sample[4], unsigned expected_size)
Definition: vividas.c:114
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:341
int size
Definition: vividas.c:46
const char * key
static AVPacket pkt
#define sample
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
Format I/O context.
Definition: avformat.h:1239
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
Definition: vividas.c:45
uint8_t
#define av_malloc(s)
int width
Video only.
Definition: codec_par.h:126
float delta
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
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
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
int id
Format-specific stream ID.
Definition: avformat.h:887
VIV_SB_block * sb_blocks
Definition: vividas.c:55
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4480
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:264
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1307
int flag
Definition: vividas.c:46
uint8_t * data
Definition: packet.h:363
#define AVERROR_EOF
End of file.
Definition: error.h:55
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
uint32_t sb_key
Definition: vividas.c:58
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:310
ptrdiff_t size
Definition: opengl_enc.c:100
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
#define av_log(a,...)
AVIOContext * sb_pb
Definition: vividas.c:63
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:637
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:401
static const uint8_t plaintext[8]
Definition: blowfish.c:112
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
#define src
Definition: vp8dsp.c:255
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, 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:138
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
static uint8_t * read_sb_block(AVIOContext *src, unsigned *size, uint32_t *key, unsigned expected_size)
Definition: vividas.c:232
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:754
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:115
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:56
static int viv_read_header(AVFormatContext *s)
Definition: vividas.c:534
simple assert() macros that are a bit more flexible than ISO C assert().
#define fail()
Definition: checkasm.h:123
int64_t sb_offset
Definition: vividas.c:59
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:369
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:78
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:628
VIV_SB_entry * sb_entries
Definition: vividas.c:65
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:443
static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: vividas.c:748
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:3285
AVInputFormat ff_vividas_demuxer
Definition: vividas.c:779
static void xor_block(void *p1, void *p2, unsigned size, int key, unsigned *key_ptr)
Definition: vividas.c:123
#define a2
Definition: regdef.h:48
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
#define s(width, name)
Definition: cbs_vp9.c:257
#define MAX_AUDIO_SUBPACKETS
Definition: vividas.c:37
int current_audio_subpacket
Definition: vividas.c:68
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:527
Stream structure.
Definition: avformat.h:880
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
#define av_bswap32
Definition: bswap.h:33
AVIOContext * pb
I/O context.
Definition: avformat.h:1281
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
static uint32_t decode_key(uint8_t *buf)
Definition: vividas.c:90
int64_t audio_sample
Definition: vividas.c:70
unsigned int av_xiphlacing(unsigned char *s, unsigned int v)
Encode extradata length to a buffer.
Definition: utils.c:1838
int n_packets
Definition: vividas.c:40
static int viv_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: vividas.c:632
This structure contains the data a format has to probe a file.
Definition: avformat.h:441
#define flags(name, subs,...)
Definition: cbs_av1.c:561
static int read_probe(const AVProbeData *pd)
Definition: jvdec.c:55
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
int sample_rate
Audio only.
Definition: codec_par.h:170
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:453
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:738
Main libavformat public API header.
int
static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
Definition: vividas.c:490
int ffio_init_context(AVIOContext *s, 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, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Definition: aviobuf.c:88
#define flag(name)
Definition: cbs_av1.c:553
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:931
uint8_t * sb_buf
Definition: vividas.c:62
static int viv_read_close(AVFormatContext *s)
Definition: vividas.c:736
static int viv_probe(const AVProbeData *p)
Definition: vividas.c:75
#define av_free(p)
int len
void * priv_data
Format private data.
Definition: avformat.h:1267
static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *buf, int size)
Definition: vividas.c:280
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:74
int channels
Audio only.
Definition: codec_par.h:166
static const uint8_t keybits[32]
Definition: vividas.c:83
#define av_freep(p)
VIV_AudioSubpacket audio_subpackets[MAX_AUDIO_SUBPACKETS]
Definition: vividas.c:72
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:652
static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *buf, unsigned size)
Definition: vividas.c:434
int size
Definition: vividas.c:40
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1045
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:368
int stream_index
Definition: packet.h:365
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:909
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
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:91
This structure stores compressed data.
Definition: packet.h:340
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:356
int i
Definition: input.c:407
static void put_v(uint8_t *p, unsigned v)
Definition: vividas.c:102
int64_t byte_offset
Definition: vividas.c:41
static uint8_t tmp[11]
Definition: aes_ctr.c:27