Coverage Report

Created: 2026-10-28 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/vividas.c
Line
Count
Source
1
/*
2
 * Vividas VIV format Demuxer
3
 * Copyright (c) 2012 Krzysztof Klinikowski
4
 * Copyright (c) 2010 Andrzej Szombierski
5
 * based on vivparse Copyright (c) 2007 Måns Rullgård
6
 *
7
 * This file is part of FFmpeg.
8
 *
9
 * FFmpeg is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * FFmpeg is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with FFmpeg; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 */
23
24
/**
25
 * @file
26
 * @brief Vividas VIV (.viv) file demuxer
27
 * @author Andrzej Szombierski [qq at kuku eu org] (2010-07)
28
 * @sa http://wiki.multimedia.cx/index.php?title=Vividas_VIV
29
 */
30
31
#include "libavutil/avassert.h"
32
#include "libavutil/intreadwrite.h"
33
#include "libavutil/mem.h"
34
#include "avio_internal.h"
35
#include "avformat.h"
36
#include "demux.h"
37
#include "internal.h"
38
39
5.13k
#define MAX_AUDIO_SUBPACKETS 100
40
41
typedef struct VIV_SB_block {
42
    int size, n_packets;
43
    int64_t byte_offset;
44
    int64_t packet_offset;
45
} VIV_SB_block;
46
47
typedef struct VIV_SB_entry {
48
    int size, flag;
49
} VIV_SB_entry;
50
51
typedef struct VIV_AudioSubpacket {
52
    int start, pcm_bytes;
53
} VIV_AudioSubpacket;
54
55
typedef struct VividasDemuxContext {
56
    int n_sb_blocks;
57
    VIV_SB_block *sb_blocks;
58
    int num_audio;
59
60
    uint32_t sb_key;
61
    int64_t sb_offset;
62
63
    int current_sb, current_sb_entry;
64
    uint8_t *sb_buf;
65
    AVIOContext *sb_pb;
66
    int n_sb_entries;
67
    VIV_SB_entry *sb_entries;
68
69
    int n_audio_subpackets;
70
    int current_audio_subpacket;
71
72
    int64_t audio_sample;
73
74
    VIV_AudioSubpacket audio_subpackets[MAX_AUDIO_SUBPACKETS];
75
} VividasDemuxContext;
76
77
static int viv_probe(const AVProbeData *p)
78
963k
{
79
963k
    if (memcmp(p->buf, "vividas03", 9))
80
962k
        return 0;
81
82
507
    return AVPROBE_SCORE_MAX;
83
963k
}
84
85
static const uint8_t keybits[32] = {
86
 20,  52, 111,  10,  27,  71, 142,  53,
87
 82, 138,   1,  78,  86, 121, 183,  85,
88
105, 152,  39, 140, 172,  11,  64, 144,
89
155,   6,  71, 163, 186,  49, 126,  43,
90
};
91
92
static uint32_t decode_key(uint8_t *buf)
93
6.73k
{
94
6.73k
    uint32_t key = 0;
95
96
222k
    for (int i = 0; i < 32; i++) {
97
215k
        unsigned p = keybits[i];
98
215k
        key |= ((buf[p] >> ((i*5+3)&7)) & 1u) << i;
99
215k
    }
100
101
6.73k
    return key;
102
6.73k
}
103
104
static void put_v(uint8_t *p, unsigned v)
105
570
{
106
570
    if (v>>28)
107
1
        *p++ = ((v>>28)&0x7f)|0x80;
108
570
    if (v>>21)
109
8
        *p++ = ((v>>21)&0x7f)|0x80;
110
570
    if (v>>14)
111
16
        *p++ = ((v>>14)&0x7f)|0x80;
112
570
    if (v>>7)
113
530
        *p++ =  ((v>>7)&0x7f)|0x80;
114
570
}
115
116
static unsigned recover_key(unsigned char sample[4], unsigned expected_size)
117
570
{
118
570
    unsigned char plaintext[8] = { 'S', 'B' };
119
120
570
    put_v(plaintext+2, expected_size);
121
122
570
    return AV_RL32(sample) ^ AV_RL32(plaintext);
123
570
}
124
125
static void xor_block(void *p1, void *p2, unsigned size, int key, unsigned *key_ptr)
126
11.3k
{
127
11.3k
    unsigned *d1 = p1;
128
11.3k
    unsigned *d2 = p2;
129
11.3k
    unsigned k = *key_ptr;
130
131
11.3k
    size >>= 2;
132
133
839k
    while (size > 0) {
134
828k
        AV_WN32(d2, AV_RN32(d1) ^ (HAVE_BIGENDIAN ? av_bswap32(k) : k));
135
828k
        k += key;
136
828k
        d1++;
137
828k
        d2++;
138
828k
        size--;
139
828k
    }
140
141
11.3k
    *key_ptr = k;
142
11.3k
}
143
144
static void decode_block(uint8_t *src, uint8_t *dest, unsigned size,
145
                         uint32_t key, uint32_t *key_ptr,
146
                         int align)
147
9.13k
{
148
9.13k
    unsigned s = size;
149
9.13k
    char tmp[4];
150
9.13k
    int a2;
151
152
9.13k
    if (!size)
153
24
        return;
154
155
9.10k
    align &= 3;
156
9.10k
    a2 = (4 - align) & 3;
157
158
9.10k
    if (align) {
159
302
        uint32_t tmpkey = *key_ptr - key;
160
302
        if (a2 > s) {
161
4
            a2 = s;
162
4
            avpriv_request_sample(NULL, "tiny aligned block");
163
4
        }
164
302
        memcpy(tmp + align, src, a2);
165
302
        xor_block(tmp, tmp, 4, key, &tmpkey);
166
302
        memcpy(dest, tmp + align, a2);
167
302
        s -= a2;
168
302
    }
169
170
9.10k
    if (s >= 4) {
171
8.83k
        xor_block(src + a2, dest + a2, s & ~3,
172
8.83k
                  key, key_ptr);
173
8.83k
        s &= 3;
174
8.83k
    }
175
176
9.10k
    if (s) {
177
2.25k
        size -= s;
178
2.25k
        memcpy(tmp, src + size, s);
179
2.25k
        xor_block(&tmp, &tmp, 4, key, key_ptr);
180
2.25k
        memcpy(dest + size, tmp, s);
181
2.25k
    }
182
9.10k
}
183
184
static uint32_t get_v(uint8_t *p, int len)
185
4.94k
{
186
4.94k
    uint32_t v = 0;
187
4.94k
    const uint8_t *end = p + len;
188
189
6.73k
    do {
190
6.73k
        if (p >= end || v >= UINT_MAX / 128 - *p)
191
52
            return v;
192
6.67k
        v <<= 7;
193
6.67k
        v += *p & 0x7f;
194
6.67k
    } while (*p++ & 0x80);
195
196
4.89k
    return v;
197
4.94k
}
198
199
static uint8_t *read_vblock(AVIOContext *src, uint32_t *size,
200
                            uint32_t key, uint32_t *k2, int align)
201
2.84k
{
202
2.84k
    uint8_t tmp[4];
203
2.84k
    uint8_t *buf;
204
2.84k
    unsigned n;
205
206
2.84k
    if (avio_read(src, tmp, 4) != 4)
207
48
        return NULL;
208
209
2.79k
    decode_block(tmp, tmp, 4, key, k2, align);
210
211
2.79k
    n = get_v(tmp, 4);
212
2.79k
    if (n < 4)
213
6
        return NULL;
214
215
2.78k
    buf = av_malloc(n);
216
2.78k
    if (!buf)
217
0
        return NULL;
218
219
2.78k
    *size = n;
220
2.78k
    n -= 4;
221
222
2.78k
    memcpy(buf, tmp, 4);
223
224
2.78k
    if (avio_read(src, buf + 4, n) == n) {
225
2.73k
        decode_block(buf + 4, buf + 4, n, key, k2, align);
226
2.73k
    } else {
227
57
        av_free(buf);
228
57
        buf = NULL;
229
57
    }
230
231
2.78k
    return buf;
232
2.78k
}
233
234
static uint8_t *read_sb_block(AVIOContext *src, unsigned *size,
235
                              uint32_t *key, unsigned expected_size)
236
1.71k
{
237
1.71k
    uint8_t *buf;
238
1.71k
    uint8_t ibuf[8], sbuf[8];
239
1.71k
    uint32_t k2;
240
1.71k
    unsigned n;
241
242
1.71k
    if (avio_read(src, ibuf, 8) < 8)
243
127
        return NULL;
244
245
1.58k
    k2 = *key;
246
1.58k
    decode_block(ibuf, sbuf, 8, *key, &k2, 0);
247
248
1.58k
    n = get_v(sbuf+2, 6);
249
250
1.58k
    if (sbuf[0] != 'S' || sbuf[1] != 'B' || (expected_size>0 && n != expected_size)) {
251
570
        uint32_t tmpkey = recover_key(ibuf, expected_size);
252
570
        k2 = tmpkey;
253
570
        decode_block(ibuf, sbuf, 8, tmpkey, &k2, 0);
254
570
        n = get_v(sbuf+2, 6);
255
570
        if (sbuf[0] != 'S' || sbuf[1] != 'B' || expected_size != n)
256
87
            return NULL;
257
483
        *key = tmpkey;
258
483
    }
259
260
1.49k
    if (n < 8)
261
10
        return NULL;
262
263
1.48k
    buf = av_malloc(n);
264
1.48k
    if (!buf)
265
0
        return NULL;
266
267
1.48k
    memcpy(buf, sbuf, 8);
268
269
1.48k
    *size = n;
270
1.48k
    n -= 8;
271
272
1.48k
    if (avio_read(src, buf+8, n) != n) {
273
31
        av_free(buf);
274
31
        return NULL;
275
31
    }
276
277
1.45k
    decode_block(buf + 8, buf + 8, n, *key, &k2, 0);
278
279
1.45k
    return buf;
280
1.48k
}
281
282
static int track_header(VividasDemuxContext *viv, AVFormatContext *s,
283
                        const uint8_t *buf, int size)
284
1.54k
{
285
1.54k
    int i, j, ret;
286
1.54k
    int64_t off;
287
1.54k
    int val_1;
288
1.54k
    int num_video;
289
1.54k
    FFIOContext pb0;
290
1.54k
    AVIOContext *const pb = &pb0.pub;
291
292
1.54k
    ffio_init_read_context(&pb0, buf, size);
293
294
1.54k
    ffio_read_varlen(pb); // track_header_len
295
1.54k
    avio_r8(pb); // '1'
296
297
1.54k
    val_1 = ffio_read_varlen(pb);
298
299
3.72k
    for (i=0;i<val_1;i++) {
300
2.23k
        int c = avio_r8(pb);
301
2.23k
        if (avio_feof(pb))
302
7
            return AVERROR_EOF;
303
164k
        for (j=0;j<c;j++) {
304
161k
            if (avio_feof(pb))
305
56
                return AVERROR_EOF;
306
161k
            avio_r8(pb); // val_3
307
161k
            avio_r8(pb); // val_4
308
161k
        }
309
2.22k
    }
310
311
1.48k
    avio_r8(pb); // num_streams
312
313
1.48k
    off = avio_tell(pb);
314
1.48k
    off += ffio_read_varlen(pb); // val_5
315
316
1.48k
    avio_r8(pb); // '2'
317
1.48k
    num_video = avio_r8(pb);
318
319
1.48k
    avio_seek(pb, off, SEEK_SET);
320
1.48k
    if (num_video != 1) {
321
13
        av_log(s, AV_LOG_ERROR, "number of video tracks %d is not 1\n", num_video);
322
13
        return AVERROR_PATCHWELCOME;
323
13
    }
324
325
2.94k
    for (i = 0; i < num_video; i++) {
326
1.47k
        AVStream *st = avformat_new_stream(s, NULL);
327
1.47k
        int num, den;
328
329
1.47k
        if (!st)
330
0
            return AVERROR(ENOMEM);
331
332
1.47k
        st->id = i;
333
334
1.47k
        st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
335
1.47k
        st->codecpar->codec_id = AV_CODEC_ID_VP6;
336
337
1.47k
        off = avio_tell(pb);
338
1.47k
        off += ffio_read_varlen(pb);
339
1.47k
        avio_r8(pb); // '3'
340
1.47k
        avio_r8(pb); // val_7
341
1.47k
        num = avio_rl32(pb); // frame_time
342
1.47k
        den = avio_rl32(pb); // time_base
343
1.47k
        avpriv_set_pts_info(st, 64, num, den);
344
1.47k
        st->nb_frames = avio_rl32(pb); // n frames
345
1.47k
        st->codecpar->width = avio_rl16(pb); // width
346
1.47k
        st->codecpar->height = avio_rl16(pb); // height
347
1.47k
        avio_r8(pb); // val_8
348
1.47k
        avio_rl32(pb); // val_9
349
350
1.47k
        avio_seek(pb, off, SEEK_SET);
351
1.47k
    }
352
353
1.47k
    off = avio_tell(pb);
354
1.47k
    off += ffio_read_varlen(pb); // val_10
355
1.47k
    avio_r8(pb); // '4'
356
1.47k
    viv->num_audio = avio_r8(pb);
357
1.47k
    avio_seek(pb, off, SEEK_SET);
358
359
1.47k
    if (viv->num_audio != 1)
360
734
        av_log(s, AV_LOG_WARNING, "number of audio tracks %d is not 1\n", viv->num_audio);
361
362
11.8k
    for(i=0;i<viv->num_audio;i++) {
363
10.6k
        int q;
364
10.6k
        AVStream *st = avformat_new_stream(s, NULL);
365
10.6k
        if (!st)
366
0
            return AVERROR(ENOMEM);
367
368
10.6k
        st->id = num_video + i;
369
370
10.6k
        st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
371
10.6k
        st->codecpar->codec_id = AV_CODEC_ID_VORBIS;
372
373
10.6k
        off = avio_tell(pb);
374
10.6k
        off += ffio_read_varlen(pb); // length
375
10.6k
        avio_r8(pb); // '5'
376
10.6k
        avio_r8(pb); //codec_id
377
10.6k
        avio_rl16(pb); //codec_subid
378
10.6k
        st->codecpar->ch_layout.nb_channels = avio_rl16(pb); // channels
379
10.6k
        st->codecpar->sample_rate = avio_rl32(pb); // sample_rate
380
10.6k
        if (st->codecpar->sample_rate <= 0 || st->codecpar->ch_layout.nb_channels <= 0)
381
145
            return AVERROR_INVALIDDATA;
382
10.5k
        avio_seek(pb, 10, SEEK_CUR); // data_1
383
10.5k
        q = avio_r8(pb);
384
10.5k
        avio_seek(pb, q, SEEK_CUR); // data_2
385
10.5k
        avio_r8(pb); // zeropad
386
387
10.5k
        if (avio_tell(pb) < off) {
388
1.26k
            int num_data;
389
1.26k
            int xd_size = 1;
390
1.26k
            int data_len[256];
391
1.26k
            int offset = 1;
392
1.26k
            uint8_t *p;
393
1.26k
            ffio_read_varlen(pb); // val_13
394
1.26k
            avio_r8(pb); // '19'
395
1.26k
            ffio_read_varlen(pb); // len_3
396
1.26k
            num_data = avio_r8(pb);
397
15.2k
            for (j = 0; j < num_data; j++) {
398
14.1k
                int64_t len = ffio_read_varlen(pb);
399
14.1k
                if (len < 0 || len > INT_MAX/2 - xd_size) {
400
141
                    return AVERROR_INVALIDDATA;
401
141
                }
402
13.9k
                data_len[j] = len;
403
13.9k
                xd_size += len + 1 + len/255;
404
13.9k
            }
405
406
1.12k
            ret = ff_alloc_extradata(st->codecpar, xd_size);
407
1.12k
            if (ret < 0)
408
0
                return ret;
409
410
1.12k
            p = st->codecpar->extradata;
411
1.12k
            p[0] = 2;
412
413
13.7k
            for (j = 0; j < num_data - 1; j++) {
414
12.6k
                unsigned delta = av_xiphlacing(&p[offset], data_len[j]);
415
12.6k
                av_assert0(delta <= xd_size - offset);
416
12.6k
                offset += delta;
417
12.6k
            }
418
419
3.66k
            for (j = 0; j < num_data; j++) {
420
2.66k
                ret = avio_read(pb, &p[offset], data_len[j]);
421
2.66k
                if (ret < data_len[j]) {
422
128
                    st->codecpar->extradata_size = 0;
423
128
                    av_freep(&st->codecpar->extradata);
424
128
                    break;
425
128
                }
426
2.53k
                av_assert0(data_len[j] <= xd_size - offset);
427
2.53k
                offset += data_len[j];
428
2.53k
            }
429
430
1.12k
            if (offset < st->codecpar->extradata_size)
431
776
                st->codecpar->extradata_size = offset;
432
1.12k
        }
433
10.5k
    }
434
435
1.18k
    return 0;
436
1.47k
}
437
438
static int track_index(VividasDemuxContext *viv, AVFormatContext *s,
439
                       const uint8_t *buf, unsigned size)
440
1.16k
{
441
1.16k
    int64_t off;
442
1.16k
    int64_t poff;
443
1.16k
    int maxnp=0;
444
1.16k
    FFIOContext pb0;
445
1.16k
    AVIOContext *const pb = &pb0.pub;
446
1.16k
    int i;
447
1.16k
    int64_t filesize = avio_size(s->pb);
448
1.16k
    uint64_t n_sb_blocks_tmp;
449
450
1.16k
    ffio_init_read_context(&pb0, buf, size);
451
452
1.16k
    ffio_read_varlen(pb); // track_index_len
453
1.16k
    avio_r8(pb); // 'c'
454
1.16k
    n_sb_blocks_tmp = ffio_read_varlen(pb);
455
1.16k
    if (n_sb_blocks_tmp > size / 2)
456
9
        return AVERROR_INVALIDDATA;
457
1.15k
    viv->sb_blocks = av_calloc(n_sb_blocks_tmp, sizeof(*viv->sb_blocks));
458
1.15k
    if (!viv->sb_blocks) {
459
0
        return AVERROR(ENOMEM);
460
0
    }
461
1.15k
    viv->n_sb_blocks = n_sb_blocks_tmp;
462
463
1.15k
    off = 0;
464
1.15k
    poff = 0;
465
466
6.44k
    for (i = 0; i < viv->n_sb_blocks; i++) {
467
5.32k
        uint64_t size_tmp      = ffio_read_varlen(pb);
468
5.32k
        uint64_t n_packets_tmp = ffio_read_varlen(pb);
469
470
5.32k
        if (size_tmp > INT_MAX || n_packets_tmp > INT_MAX)
471
29
            return AVERROR_INVALIDDATA;
472
473
5.29k
        viv->sb_blocks[i].byte_offset = off;
474
5.29k
        viv->sb_blocks[i].packet_offset = poff;
475
476
5.29k
        viv->sb_blocks[i].size = size_tmp;
477
5.29k
        viv->sb_blocks[i].n_packets = n_packets_tmp;
478
479
5.29k
        off += viv->sb_blocks[i].size;
480
5.29k
        poff += viv->sb_blocks[i].n_packets;
481
482
5.29k
        if (maxnp < viv->sb_blocks[i].n_packets)
483
1.97k
            maxnp = viv->sb_blocks[i].n_packets;
484
5.29k
    }
485
486
1.12k
    if (filesize > 0 && poff > filesize)
487
4
        return AVERROR_INVALIDDATA;
488
489
1.12k
    viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry));
490
1.12k
    if (!viv->sb_entries)
491
8
        return AVERROR(ENOMEM);
492
493
1.11k
    return 0;
494
1.12k
}
495
496
static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
497
1.71k
{
498
1.71k
    uint32_t size = 0;
499
1.71k
    int i;
500
1.71k
    AVIOContext *pb = 0;
501
502
1.71k
    if (viv->sb_pb) {
503
615
        av_free(viv->sb_pb);
504
615
        viv->sb_pb = NULL;
505
615
    }
506
507
1.71k
    if (viv->sb_buf)
508
615
        av_free(viv->sb_buf);
509
510
1.71k
    viv->sb_buf = read_sb_block(s->pb, &size, &viv->sb_key, expected_size);
511
1.71k
    if (!viv->sb_buf) {
512
255
        return;
513
255
    }
514
515
1.45k
    pb = avio_alloc_context(viv->sb_buf, size, 0, NULL, NULL, NULL, NULL);
516
1.45k
    if (!pb)
517
0
        return;
518
519
1.45k
    viv->sb_pb = pb;
520
521
1.45k
    avio_r8(pb); //  'S'
522
1.45k
    avio_r8(pb); //  'B'
523
1.45k
    ffio_read_varlen(pb); //  size
524
1.45k
    avio_r8(pb); //  junk
525
1.45k
    ffio_read_varlen(pb); // first packet
526
527
1.45k
    viv->n_sb_entries = viv->sb_blocks[viv->current_sb].n_packets;
528
529
198M
    for (i = 0; i < viv->n_sb_entries; i++) {
530
198M
        viv->sb_entries[i].size = ffio_read_varlen(pb);
531
198M
        viv->sb_entries[i].flag = avio_r8(pb);
532
198M
    }
533
534
1.45k
    ffio_read_varlen(pb);
535
1.45k
    avio_r8(pb);
536
537
1.45k
    viv->current_sb_entry = 0;
538
1.45k
}
539
540
static int viv_read_header(AVFormatContext *s)
541
1.97k
{
542
1.97k
    VividasDemuxContext *viv = s->priv_data;
543
1.97k
    AVIOContext *pb = s->pb;
544
1.97k
    int64_t header_end;
545
1.97k
    int num_tracks;
546
1.97k
    uint32_t key, k2;
547
1.97k
    uint32_t v;
548
1.97k
    uint8_t keybuffer[187];
549
1.97k
    uint32_t b22_size = 0;
550
1.97k
    uint32_t b22_key = 0;
551
1.97k
    uint8_t *buf = 0;
552
1.97k
    int ret;
553
554
1.97k
    avio_skip(pb, 9);
555
556
1.97k
    header_end = avio_tell(pb);
557
558
1.97k
    header_end += ffio_read_varlen(pb);
559
560
1.97k
    num_tracks = avio_r8(pb);
561
562
1.97k
    if (num_tracks != 1) {
563
114
        av_log(s, AV_LOG_ERROR, "number of tracks %d is not 1\n", num_tracks);
564
114
        return AVERROR(EINVAL);
565
114
    }
566
567
1.86k
    v = avio_r8(pb);
568
1.86k
    avio_seek(pb, v, SEEK_CUR);
569
570
1.86k
    ret = ffio_read_size(pb, keybuffer, 187);
571
1.86k
    if (ret < 0)
572
22
        return ret;
573
1.84k
    key = decode_key(keybuffer);
574
1.84k
    viv->sb_key = key;
575
576
1.84k
    avio_rl32(pb);
577
578
21.8k
    for (;;) {
579
21.8k
        int64_t here = avio_tell(pb);
580
21.8k
        int block_len, block_type;
581
582
21.8k
        if (here >= header_end)
583
1.64k
            break;
584
585
20.2k
        block_len = ffio_read_varlen(pb);
586
20.2k
        if (avio_feof(pb) || block_len <= 0)
587
149
            return AVERROR_INVALIDDATA;
588
589
20.0k
        block_type = avio_r8(pb);
590
591
20.0k
        if (block_type == 22) {
592
4.94k
            ret = ffio_read_size(pb, keybuffer, 187);
593
4.94k
            if (ret < 0)
594
51
                return ret;
595
4.89k
            b22_key = decode_key(keybuffer);
596
4.89k
            b22_size = avio_rl32(pb);
597
4.89k
        }
598
599
20.0k
        avio_seek(pb, here + block_len, SEEK_SET);
600
20.0k
    }
601
602
1.64k
    if (b22_size) {
603
26
        k2 = b22_key;
604
26
        buf = read_vblock(pb, &v, b22_key, &k2, 0);
605
26
        if (!buf)
606
12
            return AVERROR_INVALIDDATA;
607
608
14
        av_free(buf);
609
14
    }
610
611
1.62k
    k2 = key;
612
1.62k
    buf = read_vblock(pb, &v, key, &k2, 0);
613
1.62k
    if (!buf)
614
79
        return AVERROR_INVALIDDATA;
615
1.54k
    ret = track_header(viv, s, buf, v);
616
1.54k
    av_free(buf);
617
1.54k
    if (ret < 0)
618
362
        return ret;
619
620
1.18k
    buf = read_vblock(pb, &v, key, &k2, v);
621
1.18k
    if (!buf)
622
20
        return AVERROR_INVALIDDATA;
623
1.16k
    ret = track_index(viv, s, buf, v);
624
1.16k
    av_free(buf);
625
1.16k
    if (ret < 0)
626
50
        return ret;
627
628
1.11k
    viv->sb_offset = avio_tell(pb);
629
1.11k
    if (viv->n_sb_blocks > 0) {
630
1.09k
        viv->current_sb = 0;
631
1.09k
        load_sb_block(s, viv, viv->sb_blocks[0].size);
632
1.09k
    } else {
633
22
        viv->current_sb = -1;
634
22
    }
635
636
1.11k
    return 0;
637
1.16k
}
638
639
static int viv_read_packet(AVFormatContext *s,
640
                           AVPacket *pkt)
641
13.3k
{
642
13.3k
    VividasDemuxContext *viv = s->priv_data;
643
13.3k
    AVIOContext *pb;
644
13.3k
    int64_t off;
645
13.3k
    int ret;
646
647
13.3k
    if (!viv->sb_pb)
648
430
        return AVERROR_INVALIDDATA;
649
12.9k
    if (avio_feof(viv->sb_pb))
650
943
        return AVERROR_EOF;
651
652
12.0k
    if (viv->current_audio_subpacket < viv->n_audio_subpackets) {
653
4.17k
        AVStream *astream;
654
4.17k
        int size = viv->audio_subpackets[viv->current_audio_subpacket+1].start - viv->audio_subpackets[viv->current_audio_subpacket].start;
655
656
4.17k
        pb = viv->sb_pb;
657
4.17k
        ret = av_get_packet(pb, pkt, size);
658
4.17k
        if (ret < 0)
659
82
            return ret;
660
4.09k
        pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
661
662
4.09k
        pkt->stream_index = 1;
663
4.09k
        astream = s->streams[pkt->stream_index];
664
665
4.09k
        pkt->pts = av_rescale_q(viv->audio_sample, av_make_q(1, astream->codecpar->sample_rate), astream->time_base);
666
4.09k
        viv->audio_sample += viv->audio_subpackets[viv->current_audio_subpacket].pcm_bytes / 2 /
667
4.09k
                             astream->codecpar->ch_layout.nb_channels;
668
4.09k
        pkt->flags |= AV_PKT_FLAG_KEY;
669
4.09k
        viv->current_audio_subpacket++;
670
4.09k
        return 0;
671
4.17k
    }
672
673
7.83k
    if (viv->current_sb_entry >= viv->n_sb_entries) {
674
648
        if (viv->current_sb+1 >= viv->n_sb_blocks)
675
33
            return AVERROR_INVALIDDATA;
676
615
        viv->current_sb++;
677
678
615
        load_sb_block(s, viv, 0);
679
615
        viv->current_sb_entry = 0;
680
615
    }
681
682
7.79k
    pb = viv->sb_pb;
683
7.79k
    if (!pb)
684
84
        return AVERROR_INVALIDDATA;
685
7.71k
    off = avio_tell(pb);
686
687
7.71k
    if (viv->current_sb_entry >= viv->n_sb_entries)
688
15
        return AVERROR_INVALIDDATA;
689
690
7.70k
    off += viv->sb_entries[viv->current_sb_entry].size;
691
692
7.70k
    if (viv->sb_entries[viv->current_sb_entry].flag == 0) {
693
532
        uint64_t v_size = ffio_read_varlen(pb);
694
532
        int last = 0, last_start;
695
696
532
        if (!viv->num_audio)
697
11
            return AVERROR_INVALIDDATA;
698
699
521
        ffio_read_varlen(pb);
700
521
        if (v_size > INT_MAX || !v_size)
701
66
            return AVERROR_INVALIDDATA;
702
455
        ret = av_get_packet(pb, pkt, v_size);
703
455
        if (ret < 0)
704
24
            return ret;
705
431
        pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
706
707
431
        pkt->pts = viv->sb_blocks[viv->current_sb].packet_offset + viv->current_sb_entry;
708
431
        pkt->flags |= (pkt->data[0]&0x80)?0:AV_PKT_FLAG_KEY;
709
431
        pkt->stream_index = 0;
710
711
5.13k
        for (int i = 0; i < MAX_AUDIO_SUBPACKETS - 1; i++) {
712
5.13k
            int start, pcm_bytes;
713
5.13k
            start = ffio_read_varlen(pb);
714
5.13k
            pcm_bytes = ffio_read_varlen(pb);
715
716
5.13k
            if (i > 0 && start == 0)
717
284
                break;
718
4.84k
            if (start < last)
719
145
                return AVERROR_INVALIDDATA;
720
721
4.70k
            viv->n_audio_subpackets = i + 1;
722
4.70k
            last =
723
4.70k
            viv->audio_subpackets[i].start = start;
724
4.70k
            viv->audio_subpackets[i].pcm_bytes = pcm_bytes;
725
4.70k
        }
726
286
        last_start =
727
286
        viv->audio_subpackets[viv->n_audio_subpackets].start = (int)(off - avio_tell(pb));
728
286
        if (last_start < last) {
729
42
            viv->n_audio_subpackets = 0;
730
42
            return AVERROR_INVALIDDATA;
731
42
        }
732
244
        viv->current_audio_subpacket = 0;
733
734
7.16k
    } else {
735
7.16k
        uint64_t v_size = ffio_read_varlen(pb);
736
737
7.16k
        if (v_size > INT_MAX || !v_size)
738
192
            return AVERROR_INVALIDDATA;
739
6.97k
        ret = av_get_packet(pb, pkt, v_size);
740
6.97k
        if (ret < 0)
741
16
            return ret;
742
6.96k
        pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
743
6.96k
        pkt->pts = viv->sb_blocks[viv->current_sb].packet_offset + viv->current_sb_entry;
744
6.96k
        pkt->flags |= (pkt->data[0] & 0x80) ? 0 : AV_PKT_FLAG_KEY;
745
6.96k
        pkt->stream_index = 0;
746
6.96k
    }
747
748
7.20k
    viv->current_sb_entry++;
749
750
7.20k
    return 0;
751
7.70k
}
752
753
static int viv_read_close(AVFormatContext *s)
754
1.97k
{
755
1.97k
    VividasDemuxContext *viv = s->priv_data;
756
757
1.97k
    av_freep(&viv->sb_pb);
758
1.97k
    av_freep(&viv->sb_buf);
759
1.97k
    av_freep(&viv->sb_blocks);
760
1.97k
    av_freep(&viv->sb_entries);
761
762
1.97k
    return 0;
763
1.97k
}
764
765
static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
766
0
{
767
0
    VividasDemuxContext *viv = s->priv_data;
768
0
    int64_t frame;
769
770
0
    if (stream_index == 0)
771
0
        frame = timestamp;
772
0
    else
773
0
        frame = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[stream_index]->time_base);
774
775
0
    for (int i = 0; i < viv->n_sb_blocks; i++) {
776
0
        if (frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) {
777
0
            viv->current_sb = i;
778
            // seek to ith sb block
779
0
            avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET);
780
            // load the block
781
0
            load_sb_block(s, viv, 0);
782
0
            if (viv->num_audio) {
783
0
                const AVCodecParameters *par = s->streams[1]->codecpar;
784
                // flush audio packet queue
785
0
                viv->current_audio_subpacket = 0;
786
0
                viv->n_audio_subpackets      = 0;
787
                // most problematic part: guess audio offset
788
0
                viv->audio_sample = av_rescale_q(viv->sb_blocks[i].packet_offset,
789
0
                                                 av_make_q(par->sample_rate, 1),
790
0
                                                 av_inv_q(s->streams[0]->time_base));
791
                // hand-tuned 1.s a/v offset
792
0
                viv->audio_sample += par->sample_rate;
793
0
            }
794
0
            viv->current_sb_entry = 0;
795
0
            return 1;
796
0
        }
797
0
    }
798
0
    return 0;
799
0
}
800
801
const FFInputFormat ff_vividas_demuxer = {
802
    .p.name         = "vividas",
803
    .p.long_name    = NULL_IF_CONFIG_SMALL("Vividas VIV"),
804
    .priv_data_size = sizeof(VividasDemuxContext),
805
    .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
806
    .read_probe     = viv_probe,
807
    .read_header    = viv_read_header,
808
    .read_packet    = viv_read_packet,
809
    .read_close     = viv_read_close,
810
    .read_seek      = viv_read_seek,
811
};