Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

FFMPEG 1.0.3 vividas patch

By: a guest on Jan 31st, 2013  |  syntax: C++  |  size: 22.66 KB  |  hits: 99  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. diff -Naur ffmpeg-1.0.3.old/libavformat/allformats.c ffmpeg-1.0.3/libavformat/allformats.c
  2. --- ffmpeg-1.0.3.old/libavformat/allformats.c   2013-01-31 13:25:30.076977988 +0100
  3. +++ ffmpeg-1.0.3/libavformat/allformats.c       2013-01-31 13:26:27.280976325 +0100
  4. @@ -245,6 +245,7 @@
  5.      REGISTER_DEMUXER  (TTY, tty);
  6.      REGISTER_DEMUXER  (VC1, vc1);
  7.      REGISTER_MUXDEMUX (VC1T, vc1t);
  8. +    REGISTER_DEMUXER  (VIVIDAS, vividas);
  9.      REGISTER_DEMUXER  (VMD, vmd);
  10.      REGISTER_MUXDEMUX (VOC, voc);
  11.      REGISTER_DEMUXER  (VQF, vqf);
  12. diff -Naur ffmpeg-1.0.3.old/libavformat/Makefile ffmpeg-1.0.3/libavformat/Makefile
  13. --- ffmpeg-1.0.3.old/libavformat/Makefile       2013-01-31 13:25:30.063977989 +0100
  14. +++ ffmpeg-1.0.3/libavformat/Makefile   2013-01-31 13:26:55.569975502 +0100
  15. @@ -344,6 +344,7 @@
  16.  OBJS-$(CONFIG_VC1_DEMUXER)               += rawdec.o
  17.  OBJS-$(CONFIG_VC1T_DEMUXER)              += vc1test.o
  18.  OBJS-$(CONFIG_VC1T_MUXER)                += vc1testenc.o
  19. +OBJS-$(CONFIG_VIVIDAS_DEMUXER)           += vividas.o
  20.  OBJS-$(CONFIG_VMD_DEMUXER)               += sierravmd.o
  21.  OBJS-$(CONFIG_VOC_DEMUXER)               += vocdec.o voc.o
  22.  OBJS-$(CONFIG_VOC_MUXER)                 += vocenc.o voc.o
  23. diff -Naur ffmpeg-1.0.3.old/libavformat/vividas.c ffmpeg-1.0.3/libavformat/vividas.c
  24. --- ffmpeg-1.0.3.old/libavformat/vividas.c      1970-01-01 01:00:00.000000000 +0100
  25. +++ ffmpeg-1.0.3/libavformat/vividas.c  2013-01-31 13:28:01.641973581 +0100
  26. @@ -0,0 +1,739 @@
  27. +/*
  28. + * Vividas VIV format Demuxer
  29. + * Copyright (c) 2012 Krzysztof Klinikowski
  30. + * Copyright (c) 2010 Andrzej Szombierski
  31. + * based on vivparse Copyright (c) 2007 Måns Rullgård
  32. + *
  33. + * This file is part of FFmpeg.
  34. + *
  35. + * FFmpeg is free software; you can redistribute it and/or
  36. + * modify it under the terms of the GNU Lesser General Public
  37. + * License as published by the Free Software Foundation; either
  38. + * version 2.1 of the License, or (at your option) any later version.
  39. + *
  40. + * FFmpeg is distributed in the hope that it will be useful,
  41. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  42. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  43. + * Lesser General Public License for more details.
  44. + *
  45. + * You should have received a copy of the GNU Lesser General Public
  46. + * License along with FFmpeg; if not, write to the Free Software
  47. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  48. + */
  49. +
  50. +/**
  51. + * @file
  52. + * @brief Vividas VIV (.viv) file demuxer
  53. + * @author Andrzej Szombierski [qq at kuku eu org] (2010-07)
  54. + * @sa http://wiki.multimedia.cx/index.php?title=Vividas_VIV
  55. + */
  56. +
  57. +#define AV_PKT_FLAG_KEY   0x0001
  58. +
  59. +#include "libavutil/intreadwrite.h"
  60. +#include "avio_internal.h"
  61. +#include "avformat.h"
  62. +
  63. +#define MAX_AUDIO_SUBPACKETS 100
  64. +#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
  65. +#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
  66. +
  67. +typedef struct VIV_SB_block {
  68. +    int size, n_packets;
  69. +    int64_t byte_offset;
  70. +    int packet_offset;
  71. +} VIV_SB_block;
  72. +
  73. +typedef struct VIV_SB_entry {
  74. +    int size, flag;
  75. +} VIV_SB_entry;
  76. +
  77. +typedef struct VIV_AudioSubpacket {
  78. +    int start, pcm_bytes;
  79. +} VIV_AudioSubpacket;
  80. +
  81. +typedef struct VIV_DemuxContext
  82. +{
  83. +    int n_sb_blocks;
  84. +    VIV_SB_block *sb_blocks;
  85. +
  86. +    uint32_t sb_key;
  87. +    int64_t sb_offset;
  88. +
  89. +    int current_sb, current_sb_entry;
  90. +    uint8_t *sb_buf;
  91. +    AVIOContext *sb_pb;
  92. +    int n_sb_entries;
  93. +    VIV_SB_entry *sb_entries;
  94. +
  95. +    int n_audio_subpackets;
  96. +    int current_audio_subpacket;
  97. +
  98. +    int audio_sample;
  99. +
  100. +    VIV_AudioSubpacket audio_subpackets[MAX_AUDIO_SUBPACKETS];
  101. +} VIV_DemuxContext;
  102. +
  103. +static int viv_probe(AVProbeData *p)
  104. +{
  105. +    if(strncmp((char*)p->buf, "vividas03", 9))
  106. +        return 0;
  107. +
  108. +    return AVPROBE_SCORE_MAX;
  109. +}
  110. +
  111. +const unsigned short keybits[32] = {
  112. +     163,  416,  893,   82,  223,  572, 1137,  430,
  113. +     659, 1104,   13,  626,  695,  972, 1465,  686,
  114. +     843, 1216,  317, 1122, 1383,   92,  513, 1158,
  115. +    1243,   48,  573, 1306, 1495,  396, 1009,  350,
  116. +};
  117. +
  118. +static uint32_t decode_key(uint8_t  *buf)
  119. +{
  120. +    uint32_t key = 0;
  121. +    int i;
  122. +
  123. +    for (i = 0; i < 32; i++) {
  124. +        unsigned p = keybits[i];
  125. +        key |= !!(buf[p>>3] & (1<<(p&7))) << i;
  126. +    }
  127. +
  128. +    return key;
  129. +}
  130. +
  131. +static void put_v(uint8_t *p, int v)
  132. +{
  133. +       if(v>>28)
  134. +               *p++ = ((v>>28)&0x7f)|0x80;
  135. +       if(v>>21)
  136. +               *p++ = ((v>>21)&0x7f)|0x80;
  137. +       if(v>>14)
  138. +               *p++ = ((v>>14)&0x7f)|0x80;
  139. +       if(v>>7)
  140. +               *p++ = ((v>>7)&0x7f)|0x80;
  141. +}
  142. +
  143. +static unsigned int recover_key(unsigned char sample[4], int expected_size)
  144. +{
  145. +       unsigned char plaintext[8] = { 'S', 'B' };
  146. +       put_v(plaintext+2, expected_size);
  147. +
  148. +       return (sample[0]^plaintext[0])|
  149. +               ((sample[1]^plaintext[1])<<8)|
  150. +               ((sample[2]^plaintext[2])<<16)|
  151. +               ((sample[3]^plaintext[3])<<24);
  152. +}
  153. +
  154. +static void xor_block(void *p1, void *p2, int size, int key, int *key_ptr)
  155. +{
  156. +       int *d1 = p1;
  157. +       int *d2 = p2;
  158. +       int k = *key_ptr;
  159. +
  160. +       size >>= 2;
  161. +
  162. +       while (size--) {
  163. +               *d2 = *d1 ^ k;
  164. +               k += key;
  165. +               d1++;
  166. +               d2++;
  167. +       }
  168. +
  169. +       *key_ptr = k;
  170. +}
  171. +
  172. +static void decode_block(uint8_t *src, uint8_t *dest, int size,
  173. +                                 uint32_t key, uint32_t *key_ptr,
  174. +                                 int align)
  175. +{
  176. +       int s = size;
  177. +       char tmp[4];
  178. +       int a2;
  179. +
  180. +       if (!size)
  181. +               return;
  182. +
  183. +       align &= 3;
  184. +       a2 = (4 - align) & 3;
  185. +
  186. +       if (align) {
  187. +               uint32_t tmpkey = *key_ptr - key;
  188. +               memcpy(tmp + align, src, a2);
  189. +               xor_block(tmp, tmp, 4, key, &tmpkey);
  190. +               memcpy(dest, tmp + align, a2);
  191. +               s -= a2;
  192. +       }
  193. +
  194. +       if (s >= 4) {
  195. +               if (!align)
  196. +                       align = 4;
  197. +               xor_block(src + a2, dest + a2, s & ~3,
  198. +                                 key, key_ptr);
  199. +               s &= 3;
  200. +       }
  201. +
  202. +       if (s) {
  203. +               size -= s;
  204. +               memcpy(tmp, src + size, s);
  205. +               xor_block(&tmp, &tmp, 4, key, key_ptr);
  206. +               memcpy(dest + size, tmp, s);
  207. +       }
  208. +}
  209. +
  210. +static uint32_t get_v(uint8_t *p)
  211. +{
  212. +       uint32_t v = 0;
  213. +
  214. +       do {
  215. +               v <<= 7;
  216. +               v += *p & 0x7f;
  217. +       } while (*p++ & 0x80);
  218. +
  219. +       return v;
  220. +}
  221. +
  222. +static uint8_t *read_vblock(AVIOContext *src, uint32_t *size, uint32_t key, uint32_t *k2, int align)
  223. +{
  224. +       uint8_t tmp[4];
  225. +       uint8_t *buf;
  226. +       unsigned n;
  227. +
  228. +       if(avio_read(src, tmp, 4) != 4)
  229. +        return NULL;
  230. +
  231. +       decode_block(tmp, tmp, 4, key, k2, align);
  232. +
  233. +       n = get_v(tmp);
  234. +
  235. +       buf = av_malloc(n);
  236. +       if (!buf)
  237. +               return NULL;
  238. +
  239. +       *size = n;
  240. +       n -= 4;
  241. +
  242. +       memcpy(buf, tmp, 4);
  243. +
  244. +       if (avio_read(src, buf + 4, n) == n) {
  245. +               decode_block(buf + 4, buf + 4, n, key, k2, align + 4);
  246. +       } else {
  247. +               av_free(buf);
  248. +               buf = NULL;
  249. +       }
  250. +
  251. +       return buf;
  252. +}
  253. +
  254. +static uint8_t *read_sb_block(AVIOContext *src, unsigned *size, uint32_t *key, int expected_size)
  255. +{
  256. +       uint8_t *buf;
  257. +       uint8_t ibuf[8], sbuf[8];
  258. +       uint32_t k2;
  259. +       int n;
  260. +
  261. +       if (avio_read(src, ibuf, 8) < 8)
  262. +               return NULL;
  263. +
  264. +       k2 = *key;
  265. +       decode_block(ibuf, sbuf, 8, *key, &k2, 0);
  266. +
  267. +       n = get_v(sbuf+2);
  268. +
  269. +       if (sbuf[0] != 'S' || sbuf[1] != 'B' || (expected_size>0 && n != expected_size)) {
  270. +        uint32_t tmpkey = recover_key(ibuf, expected_size);
  271. +        k2 = tmpkey;
  272. +           decode_block(ibuf, sbuf, 8, tmpkey, &k2, 0);
  273. +           n = get_v(sbuf+2);
  274. +        if(sbuf[0] != 'S' || sbuf[1] != 'B' || expected_size != n)
  275. +            return NULL;
  276. +        *key = tmpkey;
  277. +       }
  278. +
  279. +       buf = av_malloc(n);
  280. +       if (!buf)
  281. +               return NULL;
  282. +
  283. +       memcpy(buf, sbuf, 8);
  284. +
  285. +       *size = n;
  286. +       n -= 8;
  287. +
  288. +       if (avio_read(src, buf+8, n) < n) {
  289. +               av_free(buf);
  290. +               return NULL;
  291. +       }
  292. +
  293. +       decode_block(buf + 8, buf + 8, n, *key, &k2, 0);
  294. +
  295. +       return buf;
  296. +}
  297. +
  298. +static void track_header(VIV_DemuxContext *viv, AVFormatContext *s,  uint8_t *buf, int size)
  299. +{
  300. +    int i,j;
  301. +    int64_t off;
  302. +    int val_1;
  303. +    int num_video, num_audio;
  304. +    AVIOContext *pb=0;
  305. +
  306. +    pb = avio_alloc_context(buf, size, 0, NULL, NULL, NULL, NULL);
  307. +    //ff_get_v(pb); // track_header_len
  308. +    avio_r8(pb); // '1'
  309. +
  310. +    //val_1 = ff_get_v(pb);
  311. +    val_1 = ffio_read_varlen(pb);
  312. +
  313. +    for(i=0;i<val_1;i++) {
  314. +        int c = avio_r8(pb);
  315. +        for(j=0;j<c;j++) {
  316. +            avio_r8(pb); // val_3
  317. +            avio_r8(pb); // val_4
  318. +        }
  319. +    }
  320. +
  321. +    avio_r8(pb); // num_streams
  322. +
  323. +    off = avio_tell(pb);
  324. +    //off += ff_get_v(pb); // val_5
  325. +    off += ffio_read_varlen(pb); // val_5
  326. +
  327. +    avio_r8(pb); // '2'
  328. +    num_video = avio_r8(pb);
  329. +    
  330. +    avio_seek(pb, off, SEEK_SET);
  331. +    if(num_video != 1)
  332. +        av_log(s, AV_LOG_WARNING, "viv: number of video tracks %d is not 1\n", num_video);
  333. +
  334. +    for(i=0;i<num_video;i++) {
  335. +        AVStream *st = avformat_new_stream(s, NULL);
  336. +        AVCodecContext *vcodec = st->codec;
  337. +
  338. +        st->id = i;
  339. +
  340. +        vcodec->codec_type = CODEC_TYPE_VIDEO;
  341. +               vcodec->codec_id = CODEC_ID_VP6;
  342. +
  343. +        off = avio_tell(pb);
  344. +        //off += ff_get_v(pb);
  345. +        off += ffio_read_varlen(pb);
  346. +        avio_r8(pb); // '3'
  347. +        avio_r8(pb); // val_7
  348. +        st->time_base.num = avio_rl32(pb); // frame_time
  349. +        st->time_base.den = avio_rl32(pb); // time_base
  350. +        st->nb_frames = avio_rl32(pb); // n frames
  351. +        vcodec->width = avio_rl16(pb); // width
  352. +        vcodec->height = avio_rl16(pb); // height
  353. +        avio_r8(pb); // val_8
  354. +        avio_rl32(pb); // val_9
  355. +
  356. +               vcodec->flags |= CODEC_FLAG_GLOBAL_HEADER; // ?
  357. +
  358. +        avio_seek(pb, off, SEEK_SET);
  359. +    }
  360. +
  361. +    off = avio_tell(pb);
  362. +    //off += ff_get_v(pb); // val_10
  363. +    off += ffio_read_varlen(pb); // val_10
  364. +    avio_r8(pb); // '4'
  365. +    num_audio = avio_r8(pb);
  366. +    avio_seek(pb, off, SEEK_SET);
  367. +
  368. +    if(num_audio != 1)
  369. +        av_log(s, AV_LOG_WARNING, "viv: number of audio tracks %d is not 1\n", num_audio);
  370. +
  371. +    for(i=0;i<num_audio;i++) {
  372. +        int q;
  373. +        AVStream *st = avformat_new_stream(s, NULL);
  374. +        AVCodecContext *acodec = st->codec;
  375. +
  376. +        st->id = num_video + i;
  377. +        
  378. +        acodec->codec_type = CODEC_TYPE_AUDIO;
  379. +               acodec->codec_id = CODEC_ID_VORBIS;
  380. +               acodec->flags |= CODEC_FLAG_GLOBAL_HEADER; // ?
  381. +
  382. +        off = avio_tell(pb);
  383. +        //off += ff_get_v(pb); // length
  384. +        off += ffio_read_varlen(pb); // length
  385. +        avio_r8(pb); // '5'
  386. +        avio_r8(pb); //codec_id
  387. +        avio_rl16(pb); //codec_subid
  388. +        acodec->channels = avio_rl16(pb); // channels
  389. +        acodec->sample_rate = avio_rl32(pb); // sample_rate
  390. +        avio_seek(pb, 10, SEEK_CUR); // data_1
  391. +        q = avio_r8(pb);
  392. +        avio_seek(pb, q, SEEK_CUR); // data_2
  393. +        avio_r8(pb); // zeropad
  394. +
  395. +        if(avio_tell(pb) < off) {
  396. +            int num_data;
  397. +                   int xd_size = 0;
  398. +            int data_len[256];
  399. +                   uint8_t * p;
  400. +            int offset = 1;
  401. +            //ff_get_v(pb); // val_13
  402. +            ffio_read_varlen(pb); // val_13
  403. +            avio_r8(pb); // '19'
  404. +            //ff_get_v(pb); // len_3
  405. +            ffio_read_varlen(pb); // len_3
  406. +            num_data = avio_r8(pb);
  407. +            for(j=0;j<num_data;j++) {
  408. +                //data_len[j] = ff_get_v(pb);
  409. +                data_len[j] = ffio_read_varlen(pb);
  410. +                xd_size += data_len[j];
  411. +            }
  412. +
  413. +            acodec->extradata_size = 64 + xd_size + xd_size / 255;
  414. +            acodec->extradata = (uint8_t*)av_mallocz(acodec->extradata_size);
  415. +            
  416. +            p = acodec->extradata;
  417. +                   p[0] = 2;
  418. +
  419. +            for(j=0;j<num_data-1;j++)
  420. +                           offset += av_xiphlacing(&p[offset], data_len[j]);
  421. +
  422. +            for(j=0;j<num_data;j++) {
  423. +                avio_read(pb, &p[offset], data_len[j]);
  424. +                       offset += data_len[j];
  425. +            }
  426. +
  427. +                   acodec->extradata_size = offset;
  428. +        }
  429. +    }
  430. +
  431. +    av_free(pb);
  432. +}
  433. +
  434. +static void track_index(VIV_DemuxContext *viv, AVFormatContext *s, uint8_t *buf, int size)
  435. +{
  436. +    int i;
  437. +    int64_t off;
  438. +    int poff;
  439. +    int maxnp=0;
  440. +    AVIOContext *pb=0;
  441. +
  442. +    pb = avio_alloc_context(buf, size, 0, NULL, NULL, NULL, NULL);
  443. +    //ff_get_v(pb); // track_index_len
  444. +    ffio_read_varlen(pb); // track_index_len
  445. +    avio_r8(pb); // 'c'
  446. +    //viv->n_sb_blocks = ff_get_v(pb);
  447. +    viv->n_sb_blocks = ffio_read_varlen(pb);
  448. +    viv->sb_blocks = av_mallocz(sizeof(VIV_SB_block) * viv->n_sb_blocks);
  449. +    if(!viv->sb_blocks) {
  450. +        viv->n_sb_blocks = 0;
  451. +        av_free(pb);
  452. +        return;
  453. +    }
  454. +
  455. +    off = 0;
  456. +    poff = 0;
  457. +
  458. +    for(i=0;i<viv->n_sb_blocks;i++) {
  459. +        viv->sb_blocks[i].byte_offset = off;
  460. +        viv->sb_blocks[i].packet_offset = poff;
  461. +
  462. +        //viv->sb_blocks[i].size = ff_get_v(pb);
  463. +        //viv->sb_blocks[i].n_packets = ff_get_v(pb);
  464. +        viv->sb_blocks[i].size = ffio_read_varlen(pb);
  465. +        viv->sb_blocks[i].n_packets = ffio_read_varlen(pb);
  466. +
  467. +        off += viv->sb_blocks[i].size;
  468. +        poff += viv->sb_blocks[i].n_packets;
  469. +
  470. +
  471. +        if(maxnp < viv->sb_blocks[i].n_packets)
  472. +            maxnp = viv->sb_blocks[i].n_packets;
  473. +    }
  474. +
  475. +    viv->sb_entries = av_mallocz(maxnp * sizeof(VIV_SB_entry));
  476. +    av_free(pb);
  477. +}
  478. +
  479. +static void load_sb_block(AVFormatContext *s, VIV_DemuxContext *viv, int expected_size)
  480. +{
  481. +    uint32_t size=0;
  482. +    int i;
  483. +    AVIOContext *pb = 0;
  484. +    if(viv->sb_pb) {
  485. +        av_free(viv->sb_pb);
  486. +        viv->sb_pb = NULL;
  487. +    }
  488. +    
  489. +    if(viv->sb_buf)
  490. +        av_free(viv->sb_buf);
  491. +
  492. +    viv->sb_buf = read_sb_block(s->pb, &size, &viv->sb_key, expected_size);
  493. +    if(!viv->sb_buf) {
  494. +        return;
  495. +    }
  496. +
  497. +    pb = avio_alloc_context(viv->sb_buf, size, 0, NULL, NULL, NULL, NULL);
  498. +    viv->sb_pb = pb;
  499. +    
  500. +    avio_r8(pb); //  'S'
  501. +    avio_r8(pb); //  'B'
  502. +    //ff_get_v(pb); //  size
  503. +    ffio_read_varlen(pb); //  size
  504. +    avio_r8(pb); //  junk
  505. +    //ff_get_v(pb); // first packet
  506. +    ffio_read_varlen(pb); // first packet
  507. +
  508. +    viv->n_sb_entries = viv->sb_blocks[viv->current_sb].n_packets;
  509. +
  510. +    for(i=0;i<viv->n_sb_entries;i++) {
  511. +        //viv->sb_entries[i].size = ff_get_v(pb);
  512. +        viv->sb_entries[i].size = ffio_read_varlen(pb);
  513. +        viv->sb_entries[i].flag = avio_r8(pb);
  514. +    }
  515. +
  516. +    //ff_get_v(pb); // 0
  517. +    ffio_read_varlen(pb); // 0
  518. +    avio_r8(pb); // 0
  519. +
  520. +    viv->current_sb_entry = 0;
  521. +}
  522. +
  523. +static int viv_read_header(AVFormatContext *s)
  524. +{
  525. +    VIV_DemuxContext *viv = s->priv_data;
  526. +    AVIOContext *pb = s->pb;
  527. +    int64_t header_end;
  528. +    int num_tracks;
  529. +    uint32_t key, k2;
  530. +    uint32_t v;
  531. +    uint8_t keybuffer[187];
  532. +    uint32_t b22_size = 0;
  533. +       uint32_t b22_key = 0;
  534. +    uint8_t *buf = 0;
  535. +
  536. +    // string "vividas03"
  537. +    avio_seek(pb, 9, SEEK_CUR);
  538. +
  539. +    header_end = avio_tell(pb);
  540. +
  541. +    // v: header size
  542. +    //header_end += ff_get_v(pb);
  543. +    header_end += ffio_read_varlen(pb);
  544. +
  545. +    // u8: n tracks
  546. +    num_tracks = avio_r8(pb);
  547. +
  548. +    if(num_tracks != 1) {
  549. +        av_log(s, AV_LOG_ERROR, "number of tracks %d is not 1\n", num_tracks);
  550. +        return AVERROR(EINVAL);
  551. +    }
  552. +
  553. +    v = avio_r8(pb);
  554. +    avio_seek(pb, v, SEEK_CUR);
  555. +
  556. +    avio_read(pb, keybuffer, 187);
  557. +    key = decode_key(keybuffer);
  558. +    viv->sb_key = key;
  559. +
  560. +    avio_rl32(pb); // track_header_len
  561. +      
  562. +    for(;;) {
  563. +        int64_t here = avio_tell(pb);
  564. +        int block_len, block_type;
  565. +
  566. +        if(here >= header_end)
  567. +            break;
  568. +
  569. +        //block_len = ff_get_v(pb);
  570. +        block_len = ffio_read_varlen(pb);
  571. +        block_type = avio_r8(pb);
  572. +
  573. +        if(block_type == 22) {
  574. +            avio_read(pb, keybuffer, 187);
  575. +            b22_key = decode_key(keybuffer);
  576. +            b22_size = avio_rl32(pb);
  577. +        }
  578. +
  579. +        avio_seek(pb, here + block_len, SEEK_SET);
  580. +    }
  581. +
  582. +    if(b22_size) {
  583. +        k2 = b22_key;
  584. +        buf = read_vblock(pb, &v, b22_key, &k2, 0);
  585. +        if(!buf)
  586. +            return AVERROR(EIO);
  587. +
  588. +        av_free(buf);
  589. +    }
  590. +
  591. +    k2 = key;
  592. +    buf = read_vblock(pb, &v, key, &k2, 0);
  593. +    if(!buf)
  594. +        return AVERROR(EIO);
  595. +    track_header(viv, s, buf, v);
  596. +    av_free(buf);
  597. +
  598. +    buf = read_vblock(pb, &v, key, &k2, v);
  599. +    if(!buf)
  600. +        return AVERROR(EIO);
  601. +    track_index(viv, s, buf, v);
  602. +    av_free(buf);
  603. +
  604. +    viv->sb_offset = avio_tell(pb);
  605. +    if(viv->n_sb_blocks > 0) {
  606. +        viv->current_sb = 0;
  607. +        load_sb_block(s, viv, viv->sb_blocks[0].size);
  608. +    } else {
  609. +        viv->current_sb = -1;
  610. +    }
  611. +
  612. +    return 0;
  613. +}
  614. +
  615. +static int viv_read_packet(AVFormatContext *s,
  616. +                           AVPacket *pkt)
  617. +{
  618. +    VIV_DemuxContext *viv = s->priv_data;
  619. +    AVIOContext *pb;
  620. +    int64_t off;
  621. +
  622. +    if(viv->current_audio_subpacket < viv->n_audio_subpackets) {
  623. +        // audio packets
  624. +        AVStream *astream;
  625. +        int size = viv->audio_subpackets[viv->current_audio_subpacket+1].start - viv->audio_subpackets[viv->current_audio_subpacket].start;
  626. +        pb = viv->sb_pb;
  627. +        av_get_packet(pb, pkt, size);
  628. +        pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
  629. +
  630. +        pkt->stream_index = 1;
  631. +        astream = s->streams[pkt->stream_index];
  632. +
  633. +        pkt->pts = viv->audio_sample * (long long)astream->time_base.den / (long long)astream->time_base.num / (long long)astream->codec->sample_rate;
  634. +        viv->audio_sample += viv->audio_subpackets[viv->current_audio_subpacket].pcm_bytes / 2 / astream->codec->channels;
  635. +        pkt->flags |= AV_PKT_FLAG_KEY;
  636. +        viv->current_audio_subpacket++;
  637. +        return 0;
  638. +    }
  639. +
  640. +    if(viv->current_sb_entry >= viv->n_sb_entries) {
  641. +        if(viv->current_sb+1 >= viv->n_sb_blocks)
  642. +            return AVERROR(EIO);
  643. +        viv->current_sb++;
  644. +
  645. +        load_sb_block(s, viv, 0);
  646. +        viv->current_sb_entry = 0;
  647. +    }
  648. +  
  649. +    pb = viv->sb_pb;
  650. +    off = avio_tell(pb);
  651. +    off += viv->sb_entries[viv->current_sb_entry].size;
  652. +
  653. +    if(viv->sb_entries[viv->current_sb_entry].flag == 0) {
  654. +        // A/V packet
  655. +        int i;
  656. +        //int v_size = ff_get_v(pb);
  657. +        int v_size = ffio_read_varlen(pb);
  658. +        ///*int a_size = */ff_get_v(pb);
  659. +        /*int a_size = */ffio_read_varlen(pb);
  660. +        av_get_packet(pb, pkt, v_size);
  661. +        pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
  662. +    
  663. +        pkt->pts = viv->sb_blocks[viv->current_sb].packet_offset + viv->current_sb_entry;
  664. +        pkt->flags |= (pkt->data[0]&0x80)?0:AV_PKT_FLAG_KEY;
  665. +        pkt->stream_index = 0;
  666. +
  667. +        for(i=0;i<MAX_AUDIO_SUBPACKETS-1;i++) {
  668. +            int start, pcm_bytes;
  669. +            //start = ff_get_v(pb);
  670. +            //pcm_bytes = ff_get_v(pb);
  671. +            start = ffio_read_varlen(pb);
  672. +            pcm_bytes = ffio_read_varlen(pb);
  673. +
  674. +            if(i > 0 && start == 0)
  675. +                break;
  676. +
  677. +            viv->n_audio_subpackets = i+1;
  678. +            viv->audio_subpackets[i].start = start;
  679. +            viv->audio_subpackets[i].pcm_bytes = pcm_bytes;
  680. +        }
  681. +        viv->audio_subpackets[viv->n_audio_subpackets].start = (int)(off - avio_tell(pb));
  682. +        viv->current_audio_subpacket = 0;
  683. +        //viv->n_audio_subpackets = 0;
  684. +        //avio_seek(pb, off, SEEK_SET);
  685. +        
  686. +    } else {
  687. +        // V packet
  688. +        //int v_size = ff_get_v(pb);
  689. +        int v_size = ffio_read_varlen(pb);
  690. +        av_get_packet(pb, pkt, v_size);
  691. +        pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
  692. +        pkt->pts = viv->sb_blocks[viv->current_sb].packet_offset + viv->current_sb_entry;
  693. +        pkt->flags |= (pkt->data[0]&0x80)?0:AV_PKT_FLAG_KEY;
  694. +        pkt->stream_index = 0;
  695. +    }
  696. +
  697. +    viv->current_sb_entry++;
  698. +
  699. +//    avio_seek(pb, off, SEEK_SET);
  700. +
  701. +    return 0;
  702. +}
  703. +
  704. +static int viv_read_close(AVFormatContext *s)
  705. +{
  706. +    VIV_DemuxContext *viv = s->priv_data;
  707. +    if(viv->sb_pb)
  708. +        av_free(viv->sb_pb);
  709. +    
  710. +    if(viv->sb_buf)
  711. +        av_free(viv->sb_buf);
  712. +
  713. +    if(viv->sb_blocks)
  714. +        av_free(viv->sb_blocks);
  715. +  
  716. +    if(viv->sb_entries)
  717. +        av_free(viv->sb_entries);
  718. +
  719. +    return 0;
  720. +}
  721. +
  722. +static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
  723. +{
  724. +    VIV_DemuxContext *viv = s->priv_data;
  725. +    int frame = 0;
  726. +    int i;
  727. +
  728. +    if(stream_index == 0)
  729. +        frame = (int)timestamp;
  730. +    else
  731. +        frame = (int)timestamp * s->streams[stream_index]->time_base.den * s->streams[0]->time_base.num / s->streams[stream_index]->time_base.num / s->streams[0]->time_base.den;
  732. +
  733. +    for(i=0;i<viv->n_sb_blocks;i++) {
  734. +        if(frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) {
  735. +            // flush audio packet queue
  736. +            viv->current_audio_subpacket = 0;
  737. +            viv->n_audio_subpackets = 0;
  738. +            viv->current_sb = i;
  739. +            // seek to ith sb block
  740. +            avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET);
  741. +            // load the block
  742. +            load_sb_block(s, viv, 0);
  743. +            // most problematic part: guess audio offset
  744. +            viv->audio_sample = (int64_t)viv->sb_blocks[i].packet_offset * (int64_t)s->streams[1]->codec->sample_rate * s->streams[0]->time_base.num / s->streams[0]->time_base.den;
  745. +            // hand-tuned 1.3s a/v offset
  746. +            viv->audio_sample += 1300 * s->streams[1]->codec->sample_rate / 1000;
  747. +            viv->current_sb_entry = 0;
  748. +            return 1;
  749. +        }
  750. +    }
  751. +    return 0;
  752. +}
  753. +
  754. +AVInputFormat ff_vividas_demuxer = {
  755. +    .name           = "vividas",
  756. +    .long_name      = NULL_IF_CONFIG_SMALL("Vividas VIV format"),
  757. +    .priv_data_size = sizeof(VIV_DemuxContext),
  758. +    .read_probe     = viv_probe,
  759. +    .read_header    = viv_read_header,
  760. +    .read_packet    = viv_read_packet,
  761. +    .read_close     = viv_read_close,
  762. +    .read_seek      = viv_read_seek
  763. +};