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 {
52 
53 typedef struct VividasDemuxContext {
56  int num_audio;
57 
58  uint32_t sb_key;
59  int64_t sb_offset;
60 
62  uint8_t *sb_buf;
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 
232 static uint8_t *read_sb_block(AVIOContext *src, unsigned *size,
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 
280 static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *buf, int size)
281 {
282  int i, j, ret;
283  int64_t off;
284  int val_1;
285  int num_video;
286  FFIOContext pb0;
287  AVIOContext *const pb = &pb0.pub;
288 
289  ffio_init_context(&pb0, buf, size, 0, NULL, NULL, NULL, NULL);
290 
291  ffio_read_varlen(pb); // track_header_len
292  avio_r8(pb); // '1'
293 
294  val_1 = ffio_read_varlen(pb);
295 
296  for (i=0;i<val_1;i++) {
297  int c = avio_r8(pb);
298  if (avio_feof(pb))
299  return AVERROR_EOF;
300  for (j=0;j<c;j++) {
301  if (avio_feof(pb))
302  return AVERROR_EOF;
303  avio_r8(pb); // val_3
304  avio_r8(pb); // val_4
305  }
306  }
307 
308  avio_r8(pb); // num_streams
309 
310  off = avio_tell(pb);
311  off += ffio_read_varlen(pb); // val_5
312 
313  avio_r8(pb); // '2'
314  num_video = avio_r8(pb);
315 
316  avio_seek(pb, off, SEEK_SET);
317  if (num_video != 1) {
318  av_log(s, AV_LOG_ERROR, "number of video tracks %d is not 1\n", num_video);
319  return AVERROR_PATCHWELCOME;
320  }
321 
322  for (i = 0; i < num_video; i++) {
324  int num, den;
325 
326  if (!st)
327  return AVERROR(ENOMEM);
328 
329  st->id = i;
330 
333 
334  off = avio_tell(pb);
335  off += ffio_read_varlen(pb);
336  avio_r8(pb); // '3'
337  avio_r8(pb); // val_7
338  num = avio_rl32(pb); // frame_time
339  den = avio_rl32(pb); // time_base
340  avpriv_set_pts_info(st, 64, num, den);
341  st->nb_frames = avio_rl32(pb); // n frames
342  st->codecpar->width = avio_rl16(pb); // width
343  st->codecpar->height = avio_rl16(pb); // height
344  avio_r8(pb); // val_8
345  avio_rl32(pb); // val_9
346 
347  avio_seek(pb, off, SEEK_SET);
348  }
349 
350  off = avio_tell(pb);
351  off += ffio_read_varlen(pb); // val_10
352  avio_r8(pb); // '4'
353  viv->num_audio = avio_r8(pb);
354  avio_seek(pb, off, SEEK_SET);
355 
356  if (viv->num_audio != 1)
357  av_log(s, AV_LOG_WARNING, "number of audio tracks %d is not 1\n", viv->num_audio);
358 
359  for(i=0;i<viv->num_audio;i++) {
360  int q;
362  if (!st)
363  return AVERROR(ENOMEM);
364 
365  st->id = num_video + i;
366 
369 
370  off = avio_tell(pb);
371  off += ffio_read_varlen(pb); // length
372  avio_r8(pb); // '5'
373  avio_r8(pb); //codec_id
374  avio_rl16(pb); //codec_subid
375  st->codecpar->ch_layout.nb_channels = avio_rl16(pb); // channels
376  st->codecpar->sample_rate = avio_rl32(pb); // sample_rate
377  if (st->codecpar->sample_rate <= 0 || st->codecpar->ch_layout.nb_channels <= 0)
378  return AVERROR_INVALIDDATA;
379  avio_seek(pb, 10, SEEK_CUR); // data_1
380  q = avio_r8(pb);
381  avio_seek(pb, q, SEEK_CUR); // data_2
382  avio_r8(pb); // zeropad
383 
384  if (avio_tell(pb) < off) {
385  int num_data;
386  int xd_size = 1;
387  int data_len[256];
388  int offset = 1;
389  uint8_t *p;
390  ffio_read_varlen(pb); // val_13
391  avio_r8(pb); // '19'
392  ffio_read_varlen(pb); // len_3
393  num_data = avio_r8(pb);
394  for (j = 0; j < num_data; j++) {
395  int64_t len = ffio_read_varlen(pb);
396  if (len < 0 || len > INT_MAX/2 - xd_size) {
397  return AVERROR_INVALIDDATA;
398  }
399  data_len[j] = len;
400  xd_size += len + 1 + len/255;
401  }
402 
403  ret = ff_alloc_extradata(st->codecpar, xd_size);
404  if (ret < 0)
405  return ret;
406 
407  p = st->codecpar->extradata;
408  p[0] = 2;
409 
410  for (j = 0; j < num_data - 1; j++) {
411  unsigned delta = av_xiphlacing(&p[offset], data_len[j]);
412  av_assert0(delta <= xd_size - offset);
413  offset += delta;
414  }
415 
416  for (j = 0; j < num_data; j++) {
417  int ret = avio_read(pb, &p[offset], data_len[j]);
418  if (ret < data_len[j]) {
419  st->codecpar->extradata_size = 0;
420  av_freep(&st->codecpar->extradata);
421  break;
422  }
423  av_assert0(data_len[j] <= xd_size - offset);
424  offset += data_len[j];
425  }
426 
427  if (offset < st->codecpar->extradata_size)
429  }
430  }
431 
432  return 0;
433 }
434 
435 static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *buf, unsigned size)
436 {
437  int64_t off;
438  int64_t poff;
439  int maxnp=0;
440  FFIOContext pb0;
441  AVIOContext *const pb = &pb0.pub;
442  int i;
443  int64_t filesize = avio_size(s->pb);
444  uint64_t n_sb_blocks_tmp;
445 
446  ffio_init_context(&pb0, buf, size, 0, NULL, NULL, NULL, NULL);
447 
448  ffio_read_varlen(pb); // track_index_len
449  avio_r8(pb); // 'c'
450  n_sb_blocks_tmp = ffio_read_varlen(pb);
451  if (n_sb_blocks_tmp > size / 2)
452  return AVERROR_INVALIDDATA;
453  viv->sb_blocks = av_calloc(n_sb_blocks_tmp, sizeof(*viv->sb_blocks));
454  if (!viv->sb_blocks) {
455  return AVERROR(ENOMEM);
456  }
457  viv->n_sb_blocks = n_sb_blocks_tmp;
458 
459  off = 0;
460  poff = 0;
461 
462  for (i = 0; i < viv->n_sb_blocks; i++) {
463  uint64_t size_tmp = ffio_read_varlen(pb);
464  uint64_t n_packets_tmp = ffio_read_varlen(pb);
465 
466  if (size_tmp > INT_MAX || n_packets_tmp > INT_MAX)
467  return AVERROR_INVALIDDATA;
468 
469  viv->sb_blocks[i].byte_offset = off;
470  viv->sb_blocks[i].packet_offset = poff;
471 
472  viv->sb_blocks[i].size = size_tmp;
473  viv->sb_blocks[i].n_packets = n_packets_tmp;
474 
475  off += viv->sb_blocks[i].size;
476  poff += viv->sb_blocks[i].n_packets;
477 
478  if (maxnp < viv->sb_blocks[i].n_packets)
479  maxnp = viv->sb_blocks[i].n_packets;
480  }
481 
482  if (filesize > 0 && poff > filesize)
483  return AVERROR_INVALIDDATA;
484 
485  viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry));
486  if (!viv->sb_entries)
487  return AVERROR(ENOMEM);
488 
489  return 0;
490 }
491 
492 static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
493 {
494  uint32_t size = 0;
495  int i;
496  AVIOContext *pb = 0;
497 
498  if (viv->sb_pb) {
499  av_free(viv->sb_pb);
500  viv->sb_pb = NULL;
501  }
502 
503  if (viv->sb_buf)
504  av_free(viv->sb_buf);
505 
506  viv->sb_buf = read_sb_block(s->pb, &size, &viv->sb_key, expected_size);
507  if (!viv->sb_buf) {
508  return;
509  }
510 
511  pb = avio_alloc_context(viv->sb_buf, size, 0, NULL, NULL, NULL, NULL);
512  if (!pb)
513  return;
514 
515  viv->sb_pb = pb;
516 
517  avio_r8(pb); // 'S'
518  avio_r8(pb); // 'B'
519  ffio_read_varlen(pb); // size
520  avio_r8(pb); // junk
521  ffio_read_varlen(pb); // first packet
522 
523  viv->n_sb_entries = viv->sb_blocks[viv->current_sb].n_packets;
524 
525  for (i = 0; i < viv->n_sb_entries; i++) {
526  viv->sb_entries[i].size = ffio_read_varlen(pb);
527  viv->sb_entries[i].flag = avio_r8(pb);
528  }
529 
530  ffio_read_varlen(pb);
531  avio_r8(pb);
532 
533  viv->current_sb_entry = 0;
534 }
535 
537 {
538  VividasDemuxContext *viv = s->priv_data;
539  AVIOContext *pb = s->pb;
540  int64_t header_end;
541  int num_tracks;
542  uint32_t key, k2;
543  uint32_t v;
544  uint8_t keybuffer[187];
545  uint32_t b22_size = 0;
546  uint32_t b22_key = 0;
547  uint8_t *buf = 0;
548  int ret;
549 
550  avio_skip(pb, 9);
551 
552  header_end = avio_tell(pb);
553 
554  header_end += ffio_read_varlen(pb);
555 
556  num_tracks = avio_r8(pb);
557 
558  if (num_tracks != 1) {
559  av_log(s, AV_LOG_ERROR, "number of tracks %d is not 1\n", num_tracks);
560  return AVERROR(EINVAL);
561  }
562 
563  v = avio_r8(pb);
564  avio_seek(pb, v, SEEK_CUR);
565 
566  avio_read(pb, keybuffer, 187);
567  key = decode_key(keybuffer);
568  viv->sb_key = key;
569 
570  avio_rl32(pb);
571 
572  for (;;) {
573  int64_t here = avio_tell(pb);
574  int block_len, block_type;
575 
576  if (here >= header_end)
577  break;
578 
579  block_len = ffio_read_varlen(pb);
580  if (avio_feof(pb) || block_len <= 0)
581  return AVERROR_INVALIDDATA;
582 
583  block_type = avio_r8(pb);
584 
585  if (block_type == 22) {
586  avio_read(pb, keybuffer, 187);
587  b22_key = decode_key(keybuffer);
588  b22_size = avio_rl32(pb);
589  }
590 
591  avio_seek(pb, here + block_len, SEEK_SET);
592  }
593 
594  if (b22_size) {
595  k2 = b22_key;
596  buf = read_vblock(pb, &v, b22_key, &k2, 0);
597  if (!buf)
598  return AVERROR(EIO);
599 
600  av_free(buf);
601  }
602 
603  k2 = key;
604  buf = read_vblock(pb, &v, key, &k2, 0);
605  if (!buf)
606  return AVERROR(EIO);
607  ret = track_header(viv, s, buf, v);
608  av_free(buf);
609  if (ret < 0)
610  return ret;
611 
612  buf = read_vblock(pb, &v, key, &k2, v);
613  if (!buf)
614  return AVERROR(EIO);
615  ret = track_index(viv, s, buf, v);
616  av_free(buf);
617  if (ret < 0)
618  return ret;
619 
620  viv->sb_offset = avio_tell(pb);
621  if (viv->n_sb_blocks > 0) {
622  viv->current_sb = 0;
623  load_sb_block(s, viv, viv->sb_blocks[0].size);
624  } else {
625  viv->current_sb = -1;
626  }
627 
628  return 0;
629 }
630 
632  AVPacket *pkt)
633 {
634  VividasDemuxContext *viv = s->priv_data;
635  AVIOContext *pb;
636  int64_t off;
637  int ret;
638 
639  if (!viv->sb_pb)
640  return AVERROR(EIO);
641  if (avio_feof(viv->sb_pb))
642  return AVERROR_EOF;
643 
645  AVStream *astream;
647 
648  pb = viv->sb_pb;
649  ret = av_get_packet(pb, pkt, size);
650  if (ret < 0)
651  return ret;
652  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
653 
654  pkt->stream_index = 1;
655  astream = s->streams[pkt->stream_index];
656 
657  pkt->pts = av_rescale_q(viv->audio_sample, av_make_q(1, astream->codecpar->sample_rate), astream->time_base);
659  astream->codecpar->ch_layout.nb_channels;
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  int last = 0, last_start;
687 
688  if (!viv->num_audio)
689  return AVERROR_INVALIDDATA;
690 
691  ffio_read_varlen(pb);
692  if (v_size > INT_MAX || !v_size)
693  return AVERROR_INVALIDDATA;
694  ret = av_get_packet(pb, pkt, v_size);
695  if (ret < 0)
696  return ret;
697  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
698 
700  pkt->flags |= (pkt->data[0]&0x80)?0:AV_PKT_FLAG_KEY;
701  pkt->stream_index = 0;
702 
703  for (int i = 0; i < MAX_AUDIO_SUBPACKETS - 1; i++) {
704  int start, pcm_bytes;
705  start = ffio_read_varlen(pb);
706  pcm_bytes = ffio_read_varlen(pb);
707 
708  if (i > 0 && start == 0)
709  break;
710  if (start < last)
711  return AVERROR_INVALIDDATA;
712 
713  viv->n_audio_subpackets = i + 1;
714  last =
715  viv->audio_subpackets[i].start = start;
716  viv->audio_subpackets[i].pcm_bytes = pcm_bytes;
717  }
718  last_start =
719  viv->audio_subpackets[viv->n_audio_subpackets].start = (int)(off - avio_tell(pb));
720  if (last_start < last)
721  return AVERROR_INVALIDDATA;
722  viv->current_audio_subpacket = 0;
723 
724  } else {
725  uint64_t v_size = ffio_read_varlen(pb);
726 
727  if (v_size > INT_MAX || !v_size)
728  return AVERROR_INVALIDDATA;
729  ret = av_get_packet(pb, pkt, v_size);
730  if (ret < 0)
731  return ret;
732  pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
734  pkt->flags |= (pkt->data[0] & 0x80) ? 0 : AV_PKT_FLAG_KEY;
735  pkt->stream_index = 0;
736  }
737 
738  viv->current_sb_entry++;
739 
740  return 0;
741 }
742 
744 {
745  VividasDemuxContext *viv = s->priv_data;
746 
747  av_freep(&viv->sb_pb);
748  av_freep(&viv->sb_buf);
749  av_freep(&viv->sb_blocks);
750  av_freep(&viv->sb_entries);
751 
752  return 0;
753 }
754 
755 static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
756 {
757  VividasDemuxContext *viv = s->priv_data;
758  int64_t frame;
759 
760  if (stream_index == 0)
761  frame = timestamp;
762  else
763  frame = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[stream_index]->time_base);
764 
765  for (int i = 0; i < viv->n_sb_blocks; i++) {
766  if (frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) {
767  viv->current_sb = i;
768  // seek to ith sb block
769  avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET);
770  // load the block
771  load_sb_block(s, viv, 0);
772  if (viv->num_audio) {
773  const AVCodecParameters *par = s->streams[1]->codecpar;
774  // flush audio packet queue
775  viv->current_audio_subpacket = 0;
776  viv->n_audio_subpackets = 0;
777  // most problematic part: guess audio offset
779  av_make_q(par->sample_rate, 1),
780  av_inv_q(s->streams[0]->time_base));
781  // hand-tuned 1.s a/v offset
782  viv->audio_sample += par->sample_rate;
783  }
784  viv->current_sb_entry = 0;
785  return 1;
786  }
787  }
788  return 0;
789 }
790 
792  .name = "vividas",
793  .long_name = NULL_IF_CONFIG_SMALL("Vividas VIV"),
794  .priv_data_size = sizeof(VividasDemuxContext),
795  .flags_internal = FF_FMT_INIT_CLEANUP,
801 };
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:102
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:76
FF_FMT_INIT_CLEANUP
#define FF_FMT_INIT_CLEANUP
For an AVInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition: internal.h:47
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
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: options.c:243
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:58
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:54
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:262
track_index
static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *buf, unsigned size)
Definition: vividas.c:435
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:62
AVPacket::data
uint8_t * data
Definition: packet.h:374
AV_CODEC_ID_VP6
@ AV_CODEC_ID_VP6
Definition: codec_id.h:143
VividasDemuxContext::current_sb_entry
int current_sb_entry
Definition: vividas.c:61
VIV_SB_block
Definition: vividas.c:39
VividasDemuxContext::audio_sample
int64_t audio_sample
Definition: vividas.c:70
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:311
VIV_SB_block::byte_offset
int64_t byte_offset
Definition: vividas.c:41
VividasDemuxContext::current_audio_subpacket
int current_audio_subpacket
Definition: vividas.c:68
get_v
static uint32_t get_v(uint8_t *p, int len)
Definition: vividas.c:182
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:344
FFIOContext
Definition: avio_internal.h:29
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:429
VividasDemuxContext::n_sb_blocks
int n_sb_blocks
Definition: vividas.c:54
read_vblock
static uint8_t * read_vblock(AVIOContext *src, uint32_t *size, uint32_t key, uint32_t *k2, int align)
Definition: vividas.c:197
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:114
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:142
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:771
VIV_AudioSubpacket::start
int start
Definition: vividas.c:50
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:536
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:500
VividasDemuxContext::num_audio
int num_audio
Definition: vividas.c:56
VividasDemuxContext::current_sb
int current_sb
Definition: vividas.c:61
avio_rl16
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:735
av_bswap32
#define av_bswap32
Definition: bswap.h:33
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AVInputFormat
Definition: avformat.h:546
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:41
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:256
viv_read_seek
static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: vividas.c:755
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:551
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:128
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
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:45
key
const char * key
Definition: hwcontext_opencl.c:174
AVFormatContext
Format I/O context.
Definition: avformat.h:1104
VIV_SB_entry::size
int size
Definition: vividas.c:46
internal.h
VividasDemuxContext::audio_subpackets
VIV_AudioSubpacket audio_subpackets[MAX_AUDIO_SUBPACKETS]
Definition: vividas.c:72
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:861
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:545
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:877
NULL
#define NULL
Definition: coverity.c:32
VIV_AudioSubpacket
Definition: vividas.c:49
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:232
VIV_SB_block::n_packets
int n_packets
Definition: vividas.c:40
xor_block
static void xor_block(void *p1, void *p2, unsigned size, int key, unsigned *key_ptr)
Definition: vividas.c:123
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:213
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:178
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:899
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:80
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:751
AVIOContext
Bytestream IO Context.
Definition: avio.h:166
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:115
FFIOContext::pub
AVIOContext pub
Definition: avio_internal.h:30
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:863
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:624
VIV_SB_entry::flag
int flag
Definition: vividas.c:46
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:380
ffio_read_varlen
uint64_t ffio_read_varlen(AVIOContext *bc)
Definition: aviobuf.c:937
VIV_SB_block::size
int size
Definition: vividas.c:40
MAX_AUDIO_SUBPACKETS
#define MAX_AUDIO_SUBPACKETS
Definition: vividas.c:37
filesize
static int64_t filesize(AVIOContext *pb)
Definition: ffmpeg_mux.c:48
load_sb_block
static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
Definition: vividas.c:492
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:367
VividasDemuxContext::sb_key
uint32_t sb_key
Definition: vividas.c:58
avio_internal.h
AVCodecParameters::height
int height
Definition: codec_par.h:129
decode_key
static uint32_t decode_key(uint8_t *buf)
Definition: vividas.c:90
VividasDemuxContext
Definition: vividas.c:53
ffio_init_context
void ffio_init_context(FFIOContext *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:81
VIV_SB_block::packet_offset
int64_t packet_offset
Definition: vividas.c:42
a2
#define a2
Definition: regdef.h:48
delta
float delta
Definition: vorbis_enc_data.h:430
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, 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:130
viv_probe
static int viv_probe(const AVProbeData *p)
Definition: vividas.c:75
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
track_header
static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *buf, int size)
Definition: vividas.c:280
len
int len
Definition: vorbis_enc_data.h:426
ff_vividas_demuxer
const AVInputFormat ff_vividas_demuxer
Definition: vividas.c:791
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:102
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:850
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:838
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:252
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:83
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:631
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:633
VividasDemuxContext::n_audio_subpackets
int n_audio_subpackets
Definition: vividas.c:67
AVPacket::stream_index
int stream_index
Definition: packet.h:376
VividasDemuxContext::n_sb_entries
int n_sb_entries
Definition: vividas.c:64
VividasDemuxContext::sb_pb
AVIOContext * sb_pb
Definition: vividas.c:63
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:339
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:29
VividasDemuxContext::sb_offset
int64_t sb_offset
Definition: vividas.c:59
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:36
VIV_AudioSubpacket::pcm_bytes
int pcm_bytes
Definition: vividas.c:50
VividasDemuxContext::sb_entries
VIV_SB_entry * sb_entries
Definition: vividas.c:65
viv_read_close
static int viv_read_close(AVFormatContext *s)
Definition: vividas.c:743
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
VividasDemuxContext::sb_blocks
VIV_SB_block * sb_blocks
Definition: vividas.c:55
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:62
AVPacket
This structure stores compressed data.
Definition: packet.h:351
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:394
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
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:443
int
int
Definition: ffmpeg_filter.c:156
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:238
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:367