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  avio_seek(pb, 10, SEEK_CUR); // data_1
377  q = avio_r8(pb);
378  avio_seek(pb, q, SEEK_CUR); // data_2
379  avio_r8(pb); // zeropad
380 
381  if (avio_tell(pb) < off) {
382  int num_data;
383  int xd_size = 1;
384  int data_len[256];
385  int offset = 1;
386  uint8_t *p;
387  ffio_read_varlen(pb); // val_13
388  avio_r8(pb); // '19'
389  ffio_read_varlen(pb); // len_3
390  num_data = avio_r8(pb);
391  for (j = 0; j < num_data; j++) {
392  uint64_t len = ffio_read_varlen(pb);
393  if (len > INT_MAX/2 - xd_size) {
394  return AVERROR_INVALIDDATA;
395  }
396  data_len[j] = len;
397  xd_size += len + 1 + len/255;
398  }
399 
400  ret = ff_alloc_extradata(st->codecpar, xd_size);
401  if (ret < 0)
402  return ret;
403 
404  p = st->codecpar->extradata;
405  p[0] = 2;
406 
407  for (j = 0; j < num_data - 1; j++) {
408  unsigned delta = av_xiphlacing(&p[offset], data_len[j]);
409  av_assert0(delta <= xd_size - offset);
410  offset += delta;
411  }
412 
413  for (j = 0; j < num_data; j++) {
414  int ret = avio_read(pb, &p[offset], data_len[j]);
415  if (ret < data_len[j]) {
416  st->codecpar->extradata_size = 0;
417  av_freep(&st->codecpar->extradata);
418  break;
419  }
420  av_assert0(data_len[j] <= xd_size - offset);
421  offset += data_len[j];
422  }
423 
424  if (offset < st->codecpar->extradata_size)
426  }
427  }
428 
429  return 0;
430 }
431 
432 static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *buf, unsigned size)
433 {
434  int64_t off;
435  int64_t poff;
436  int maxnp=0;
437  AVIOContext pb0, *pb = &pb0;
438  int i;
439  int64_t filesize = avio_size(s->pb);
440  uint64_t n_sb_blocks_tmp;
441 
442  ffio_init_context(pb, buf, size, 0, NULL, NULL, NULL, NULL);
443 
444  ffio_read_varlen(pb); // track_index_len
445  avio_r8(pb); // 'c'
446  n_sb_blocks_tmp = ffio_read_varlen(pb);
447  if (n_sb_blocks_tmp > size / 2)
448  return AVERROR_INVALIDDATA;
449  viv->sb_blocks = av_calloc(n_sb_blocks_tmp, sizeof(*viv->sb_blocks));
450  if (!viv->sb_blocks) {
451  return AVERROR(ENOMEM);
452  }
453  viv->n_sb_blocks = n_sb_blocks_tmp;
454 
455  off = 0;
456  poff = 0;
457 
458  for (i = 0; i < viv->n_sb_blocks; i++) {
459  uint64_t size_tmp = ffio_read_varlen(pb);
460  uint64_t n_packets_tmp = ffio_read_varlen(pb);
461 
462  if (size_tmp > INT_MAX || n_packets_tmp > INT_MAX)
463  return AVERROR_INVALIDDATA;
464 
465  viv->sb_blocks[i].byte_offset = off;
466  viv->sb_blocks[i].packet_offset = poff;
467 
468  viv->sb_blocks[i].size = size_tmp;
469  viv->sb_blocks[i].n_packets = n_packets_tmp;
470 
471  off += viv->sb_blocks[i].size;
472  poff += viv->sb_blocks[i].n_packets;
473 
474  if (maxnp < viv->sb_blocks[i].n_packets)
475  maxnp = viv->sb_blocks[i].n_packets;
476  }
477 
478  if (filesize > 0 && poff > filesize)
479  return AVERROR_INVALIDDATA;
480 
481  viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry));
482  if (!viv->sb_entries)
483  return AVERROR(ENOMEM);
484 
485  return 0;
486 }
487 
488 static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
489 {
490  uint32_t size = 0;
491  int i;
492  AVIOContext *pb = 0;
493 
494  if (viv->sb_pb) {
495  av_free(viv->sb_pb);
496  viv->sb_pb = NULL;
497  }
498 
499  if (viv->sb_buf)
500  av_free(viv->sb_buf);
501 
502  viv->sb_buf = read_sb_block(s->pb, &size, &viv->sb_key, expected_size);
503  if (!viv->sb_buf) {
504  return;
505  }
506 
507  pb = avio_alloc_context(viv->sb_buf, size, 0, NULL, NULL, NULL, NULL);
508  if (!pb)
509  return;
510 
511  viv->sb_pb = pb;
512 
513  avio_r8(pb); // 'S'
514  avio_r8(pb); // 'B'
515  ffio_read_varlen(pb); // size
516  avio_r8(pb); // junk
517  ffio_read_varlen(pb); // first packet
518 
519  viv->n_sb_entries = viv->sb_blocks[viv->current_sb].n_packets;
520 
521  for (i = 0; i < viv->n_sb_entries; i++) {
522  viv->sb_entries[i].size = ffio_read_varlen(pb);
523  viv->sb_entries[i].flag = avio_r8(pb);
524  }
525 
526  ffio_read_varlen(pb);
527  avio_r8(pb);
528 
529  viv->current_sb_entry = 0;
530 }
531 
533 {
534  VividasDemuxContext *viv = s->priv_data;
535  AVIOContext *pb = s->pb;
536  int64_t header_end;
537  int num_tracks;
538  uint32_t key, k2;
539  uint32_t v;
540  uint8_t keybuffer[187];
541  uint32_t b22_size = 0;
542  uint32_t b22_key = 0;
543  uint8_t *buf = 0;
544  int ret;
545 
546  avio_skip(pb, 9);
547 
548  header_end = avio_tell(pb);
549 
550  header_end += ffio_read_varlen(pb);
551 
552  num_tracks = avio_r8(pb);
553 
554  if (num_tracks != 1) {
555  av_log(s, AV_LOG_ERROR, "number of tracks %d is not 1\n", num_tracks);
556  return AVERROR(EINVAL);
557  }
558 
559  v = avio_r8(pb);
560  avio_seek(pb, v, SEEK_CUR);
561 
562  avio_read(pb, keybuffer, 187);
563  key = decode_key(keybuffer);
564  viv->sb_key = key;
565 
566  avio_rl32(pb);
567 
568  for (;;) {
569  int64_t here = avio_tell(pb);
570  int block_len, block_type;
571 
572  if (here >= header_end)
573  break;
574 
575  block_len = ffio_read_varlen(pb);
576  if (avio_feof(pb) || block_len <= 0)
577  return AVERROR_INVALIDDATA;
578 
579  block_type = avio_r8(pb);
580 
581  if (block_type == 22) {
582  avio_read(pb, keybuffer, 187);
583  b22_key = decode_key(keybuffer);
584  b22_size = avio_rl32(pb);
585  }
586 
587  avio_seek(pb, here + block_len, SEEK_SET);
588  }
589 
590  if (b22_size) {
591  k2 = b22_key;
592  buf = read_vblock(pb, &v, b22_key, &k2, 0);
593  if (!buf)
594  return AVERROR(EIO);
595 
596  av_free(buf);
597  }
598 
599  k2 = key;
600  buf = read_vblock(pb, &v, key, &k2, 0);
601  if (!buf)
602  return AVERROR(EIO);
603  ret = track_header(viv, s, buf, v);
604  av_free(buf);
605  if (ret < 0)
606  return ret;
607 
608  buf = read_vblock(pb, &v, key, &k2, v);
609  if (!buf)
610  return AVERROR(EIO);
611  ret = track_index(viv, s, buf, v);
612  av_free(buf);
613  if (ret < 0)
614  goto fail;
615 
616  viv->sb_offset = avio_tell(pb);
617  if (viv->n_sb_blocks > 0) {
618  viv->current_sb = 0;
619  load_sb_block(s, viv, viv->sb_blocks[0].size);
620  } else {
621  viv->current_sb = -1;
622  }
623 
624  return 0;
625 fail:
626  av_freep(&viv->sb_blocks);
627  return ret;
628 }
629 
631  AVPacket *pkt)
632 {
633  VividasDemuxContext *viv = s->priv_data;
634  AVIOContext *pb;
635  int64_t off;
636  int ret;
637 
638  if (!viv->sb_pb)
639  return AVERROR(EIO);
640  if (avio_feof(viv->sb_pb))
641  return AVERROR_EOF;
642 
644  AVStream *astream;
646 
647  pb = viv->sb_pb;
648  ret = av_get_packet(pb, pkt, size);
649  if (ret < 0)
650  return ret;
651  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
652 
653  pkt->stream_index = 1;
654  astream = s->streams[pkt->stream_index];
655 
656  pkt->pts = av_rescale_q(viv->audio_sample, av_make_q(1, astream->codecpar->sample_rate), astream->time_base);
658  pkt->flags |= AV_PKT_FLAG_KEY;
660  return 0;
661  }
662 
663  if (viv->current_sb_entry >= viv->n_sb_entries) {
664  if (viv->current_sb+1 >= viv->n_sb_blocks)
665  return AVERROR(EIO);
666  viv->current_sb++;
667 
668  load_sb_block(s, viv, 0);
669  viv->current_sb_entry = 0;
670  }
671 
672  pb = viv->sb_pb;
673  if (!pb)
674  return AVERROR(EIO);
675  off = avio_tell(pb);
676 
677  if (viv->current_sb_entry >= viv->n_sb_entries)
678  return AVERROR_INVALIDDATA;
679 
680  off += viv->sb_entries[viv->current_sb_entry].size;
681 
682  if (viv->sb_entries[viv->current_sb_entry].flag == 0) {
683  uint64_t v_size = ffio_read_varlen(pb);
684 
685  if (!viv->num_audio)
686  return AVERROR_INVALIDDATA;
687 
688  ffio_read_varlen(pb);
689  if (v_size > INT_MAX || !v_size)
690  return AVERROR_INVALIDDATA;
691  ret = av_get_packet(pb, pkt, v_size);
692  if (ret < 0)
693  return ret;
694  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
695 
696  pkt->pts = viv->sb_blocks[viv->current_sb].packet_offset + viv->current_sb_entry;
697  pkt->flags |= (pkt->data[0]&0x80)?0:AV_PKT_FLAG_KEY;
698  pkt->stream_index = 0;
699 
700  for (int i = 0; i < MAX_AUDIO_SUBPACKETS - 1; i++) {
701  int start, pcm_bytes;
702  start = ffio_read_varlen(pb);
703  pcm_bytes = ffio_read_varlen(pb);
704 
705  if (i > 0 && start == 0)
706  break;
707 
708  viv->n_audio_subpackets = i + 1;
709  viv->audio_subpackets[i].start = start;
710  viv->audio_subpackets[i].pcm_bytes = pcm_bytes;
711  }
712  viv->audio_subpackets[viv->n_audio_subpackets].start = (int)(off - avio_tell(pb));
713  viv->current_audio_subpacket = 0;
714 
715  } else {
716  uint64_t v_size = ffio_read_varlen(pb);
717 
718  if (v_size > INT_MAX || !v_size)
719  return AVERROR_INVALIDDATA;
720  ret = av_get_packet(pb, pkt, v_size);
721  if (ret < 0)
722  return ret;
723  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
724  pkt->pts = viv->sb_blocks[viv->current_sb].packet_offset + viv->current_sb_entry;
725  pkt->flags |= (pkt->data[0] & 0x80) ? 0 : AV_PKT_FLAG_KEY;
726  pkt->stream_index = 0;
727  }
728 
729  viv->current_sb_entry++;
730 
731  return 0;
732 }
733 
735 {
736  VividasDemuxContext *viv = s->priv_data;
737 
738  av_freep(&viv->sb_pb);
739  av_freep(&viv->sb_buf);
740  av_freep(&viv->sb_blocks);
741  av_freep(&viv->sb_entries);
742 
743  return 0;
744 }
745 
746 static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
747 {
748  VividasDemuxContext *viv = s->priv_data;
749  int64_t frame;
750 
751  if (stream_index == 0)
752  frame = timestamp;
753  else
754  frame = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[stream_index]->time_base);
755 
756  for (int i = 0; i < viv->n_sb_blocks; i++) {
757  if (frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) {
758  // flush audio packet queue
759  viv->current_audio_subpacket = 0;
760  viv->n_audio_subpackets = 0;
761  viv->current_sb = i;
762  // seek to ith sb block
763  avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET);
764  // load the block
765  load_sb_block(s, viv, 0);
766  // most problematic part: guess audio offset
768  // hand-tuned 1.s a/v offset
769  viv->audio_sample += s->streams[1]->codecpar->sample_rate;
770  viv->current_sb_entry = 0;
771  return 1;
772  }
773  }
774  return 0;
775 }
776 
778  .name = "vividas",
779  .long_name = NULL_IF_CONFIG_SMALL("Vividas VIV"),
780  .priv_data_size = sizeof(VividasDemuxContext),
786 };
#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:4871
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:4453
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:262
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:305
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:254
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:153
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:532
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:746
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:3260
AVInputFormat ff_vividas_demuxer
Definition: vividas.c:777
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:1831
int n_packets
Definition: vividas.c:40
static int viv_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: vividas.c:630
This structure contains the data a format has to probe a file.
Definition: avformat.h:441
#define flags(name, subs,...)
Definition: cbs_av1.c:560
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:488
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:552
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:734
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:432
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:26