Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -Naur ffmpeg-1.0.3.old/libavformat/allformats.c ffmpeg-1.0.3/libavformat/allformats.c
- --- ffmpeg-1.0.3.old/libavformat/allformats.c 2013-01-31 13:25:30.076977988 +0100
- +++ ffmpeg-1.0.3/libavformat/allformats.c 2013-01-31 13:26:27.280976325 +0100
- @@ -245,6 +245,7 @@
- REGISTER_DEMUXER (TTY, tty);
- REGISTER_DEMUXER (VC1, vc1);
- REGISTER_MUXDEMUX (VC1T, vc1t);
- + REGISTER_DEMUXER (VIVIDAS, vividas);
- REGISTER_DEMUXER (VMD, vmd);
- REGISTER_MUXDEMUX (VOC, voc);
- REGISTER_DEMUXER (VQF, vqf);
- diff -Naur ffmpeg-1.0.3.old/libavformat/Makefile ffmpeg-1.0.3/libavformat/Makefile
- --- ffmpeg-1.0.3.old/libavformat/Makefile 2013-01-31 13:25:30.063977989 +0100
- +++ ffmpeg-1.0.3/libavformat/Makefile 2013-01-31 13:26:55.569975502 +0100
- @@ -344,6 +344,7 @@
- OBJS-$(CONFIG_VC1_DEMUXER) += rawdec.o
- OBJS-$(CONFIG_VC1T_DEMUXER) += vc1test.o
- OBJS-$(CONFIG_VC1T_MUXER) += vc1testenc.o
- +OBJS-$(CONFIG_VIVIDAS_DEMUXER) += vividas.o
- OBJS-$(CONFIG_VMD_DEMUXER) += sierravmd.o
- OBJS-$(CONFIG_VOC_DEMUXER) += vocdec.o voc.o
- OBJS-$(CONFIG_VOC_MUXER) += vocenc.o voc.o
- diff -Naur ffmpeg-1.0.3.old/libavformat/vividas.c ffmpeg-1.0.3/libavformat/vividas.c
- --- ffmpeg-1.0.3.old/libavformat/vividas.c 1970-01-01 01:00:00.000000000 +0100
- +++ ffmpeg-1.0.3/libavformat/vividas.c 2013-01-31 13:28:01.641973581 +0100
- @@ -0,0 +1,739 @@
- +/*
- + * Vividas VIV format Demuxer
- + * Copyright (c) 2012 Krzysztof Klinikowski
- + * Copyright (c) 2010 Andrzej Szombierski
- + * based on vivparse Copyright (c) 2007 Måns Rullgård
- + *
- + * This file is part of FFmpeg.
- + *
- + * FFmpeg is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU Lesser General Public
- + * License as published by the Free Software Foundation; either
- + * version 2.1 of the License, or (at your option) any later version.
- + *
- + * FFmpeg is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- + * Lesser General Public License for more details.
- + *
- + * You should have received a copy of the GNU Lesser General Public
- + * License along with FFmpeg; if not, write to the Free Software
- + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- + */
- +
- +/**
- + * @file
- + * @brief Vividas VIV (.viv) file demuxer
- + * @author Andrzej Szombierski [qq at kuku eu org] (2010-07)
- + * @sa http://wiki.multimedia.cx/index.php?title=Vividas_VIV
- + */
- +
- +#define AV_PKT_FLAG_KEY 0x0001
- +
- +#include "libavutil/intreadwrite.h"
- +#include "avio_internal.h"
- +#include "avformat.h"
- +
- +#define MAX_AUDIO_SUBPACKETS 100
- +#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
- +#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
- +
- +typedef struct VIV_SB_block {
- + int size, n_packets;
- + int64_t byte_offset;
- + int packet_offset;
- +} VIV_SB_block;
- +
- +typedef struct VIV_SB_entry {
- + int size, flag;
- +} VIV_SB_entry;
- +
- +typedef struct VIV_AudioSubpacket {
- + int start, pcm_bytes;
- +} VIV_AudioSubpacket;
- +
- +typedef struct VIV_DemuxContext
- +{
- + int n_sb_blocks;
- + VIV_SB_block *sb_blocks;
- +
- + uint32_t sb_key;
- + int64_t sb_offset;
- +
- + int current_sb, current_sb_entry;
- + uint8_t *sb_buf;
- + AVIOContext *sb_pb;
- + int n_sb_entries;
- + VIV_SB_entry *sb_entries;
- +
- + int n_audio_subpackets;
- + int current_audio_subpacket;
- +
- + int audio_sample;
- +
- + VIV_AudioSubpacket audio_subpackets[MAX_AUDIO_SUBPACKETS];
- +} VIV_DemuxContext;
- +
- +static int viv_probe(AVProbeData *p)
- +{
- + if(strncmp((char*)p->buf, "vividas03", 9))
- + return 0;
- +
- + return AVPROBE_SCORE_MAX;
- +}
- +
- +const unsigned short keybits[32] = {
- + 163, 416, 893, 82, 223, 572, 1137, 430,
- + 659, 1104, 13, 626, 695, 972, 1465, 686,
- + 843, 1216, 317, 1122, 1383, 92, 513, 1158,
- + 1243, 48, 573, 1306, 1495, 396, 1009, 350,
- +};
- +
- +static uint32_t decode_key(uint8_t *buf)
- +{
- + uint32_t key = 0;
- + int i;
- +
- + for (i = 0; i < 32; i++) {
- + unsigned p = keybits[i];
- + key |= !!(buf[p>>3] & (1<<(p&7))) << i;
- + }
- +
- + return key;
- +}
- +
- +static void put_v(uint8_t *p, int v)
- +{
- + if(v>>28)
- + *p++ = ((v>>28)&0x7f)|0x80;
- + if(v>>21)
- + *p++ = ((v>>21)&0x7f)|0x80;
- + if(v>>14)
- + *p++ = ((v>>14)&0x7f)|0x80;
- + if(v>>7)
- + *p++ = ((v>>7)&0x7f)|0x80;
- +}
- +
- +static unsigned int recover_key(unsigned char sample[4], int expected_size)
- +{
- + unsigned char plaintext[8] = { 'S', 'B' };
- + put_v(plaintext+2, expected_size);
- +
- + return (sample[0]^plaintext[0])|
- + ((sample[1]^plaintext[1])<<8)|
- + ((sample[2]^plaintext[2])<<16)|
- + ((sample[3]^plaintext[3])<<24);
- +}
- +
- +static void xor_block(void *p1, void *p2, int size, int key, int *key_ptr)
- +{
- + int *d1 = p1;
- + int *d2 = p2;
- + int k = *key_ptr;
- +
- + size >>= 2;
- +
- + while (size--) {
- + *d2 = *d1 ^ k;
- + k += key;
- + d1++;
- + d2++;
- + }
- +
- + *key_ptr = k;
- +}
- +
- +static void decode_block(uint8_t *src, uint8_t *dest, int size,
- + uint32_t key, uint32_t *key_ptr,
- + int align)
- +{
- + int s = size;
- + char tmp[4];
- + int a2;
- +
- + if (!size)
- + return;
- +
- + align &= 3;
- + a2 = (4 - align) & 3;
- +
- + if (align) {
- + uint32_t tmpkey = *key_ptr - key;
- + memcpy(tmp + align, src, a2);
- + xor_block(tmp, tmp, 4, key, &tmpkey);
- + memcpy(dest, tmp + align, a2);
- + s -= a2;
- + }
- +
- + if (s >= 4) {
- + if (!align)
- + align = 4;
- + xor_block(src + a2, dest + a2, s & ~3,
- + key, key_ptr);
- + s &= 3;
- + }
- +
- + if (s) {
- + size -= s;
- + memcpy(tmp, src + size, s);
- + xor_block(&tmp, &tmp, 4, key, key_ptr);
- + memcpy(dest + size, tmp, s);
- + }
- +}
- +
- +static uint32_t get_v(uint8_t *p)
- +{
- + uint32_t v = 0;
- +
- + do {
- + v <<= 7;
- + v += *p & 0x7f;
- + } while (*p++ & 0x80);
- +
- + return v;
- +}
- +
- +static uint8_t *read_vblock(AVIOContext *src, uint32_t *size, uint32_t key, uint32_t *k2, int align)
- +{
- + uint8_t tmp[4];
- + uint8_t *buf;
- + unsigned n;
- +
- + if(avio_read(src, tmp, 4) != 4)
- + return NULL;
- +
- + decode_block(tmp, tmp, 4, key, k2, align);
- +
- + n = get_v(tmp);
- +
- + buf = av_malloc(n);
- + if (!buf)
- + return NULL;
- +
- + *size = n;
- + n -= 4;
- +
- + memcpy(buf, tmp, 4);
- +
- + if (avio_read(src, buf + 4, n) == n) {
- + decode_block(buf + 4, buf + 4, n, key, k2, align + 4);
- + } else {
- + av_free(buf);
- + buf = NULL;
- + }
- +
- + return buf;
- +}
- +
- +static uint8_t *read_sb_block(AVIOContext *src, unsigned *size, uint32_t *key, int expected_size)
- +{
- + uint8_t *buf;
- + uint8_t ibuf[8], sbuf[8];
- + uint32_t k2;
- + int n;
- +
- + if (avio_read(src, ibuf, 8) < 8)
- + return NULL;
- +
- + k2 = *key;
- + decode_block(ibuf, sbuf, 8, *key, &k2, 0);
- +
- + n = get_v(sbuf+2);
- +
- + if (sbuf[0] != 'S' || sbuf[1] != 'B' || (expected_size>0 && n != expected_size)) {
- + uint32_t tmpkey = recover_key(ibuf, expected_size);
- + k2 = tmpkey;
- + decode_block(ibuf, sbuf, 8, tmpkey, &k2, 0);
- + n = get_v(sbuf+2);
- + if(sbuf[0] != 'S' || sbuf[1] != 'B' || expected_size != n)
- + return NULL;
- + *key = tmpkey;
- + }
- +
- + buf = av_malloc(n);
- + if (!buf)
- + return NULL;
- +
- + memcpy(buf, sbuf, 8);
- +
- + *size = n;
- + n -= 8;
- +
- + if (avio_read(src, buf+8, n) < n) {
- + av_free(buf);
- + return NULL;
- + }
- +
- + decode_block(buf + 8, buf + 8, n, *key, &k2, 0);
- +
- + return buf;
- +}
- +
- +static void track_header(VIV_DemuxContext *viv, AVFormatContext *s, uint8_t *buf, int size)
- +{
- + int i,j;
- + int64_t off;
- + int val_1;
- + int num_video, num_audio;
- + AVIOContext *pb=0;
- +
- + pb = avio_alloc_context(buf, size, 0, NULL, NULL, NULL, NULL);
- + //ff_get_v(pb); // track_header_len
- + avio_r8(pb); // '1'
- +
- + //val_1 = ff_get_v(pb);
- + val_1 = ffio_read_varlen(pb);
- +
- + for(i=0;i<val_1;i++) {
- + int c = avio_r8(pb);
- + for(j=0;j<c;j++) {
- + avio_r8(pb); // val_3
- + avio_r8(pb); // val_4
- + }
- + }
- +
- + avio_r8(pb); // num_streams
- +
- + off = avio_tell(pb);
- + //off += ff_get_v(pb); // val_5
- + off += ffio_read_varlen(pb); // val_5
- +
- + avio_r8(pb); // '2'
- + num_video = avio_r8(pb);
- +
- + avio_seek(pb, off, SEEK_SET);
- + if(num_video != 1)
- + av_log(s, AV_LOG_WARNING, "viv: number of video tracks %d is not 1\n", num_video);
- +
- + for(i=0;i<num_video;i++) {
- + AVStream *st = avformat_new_stream(s, NULL);
- + AVCodecContext *vcodec = st->codec;
- +
- + st->id = i;
- +
- + vcodec->codec_type = CODEC_TYPE_VIDEO;
- + vcodec->codec_id = CODEC_ID_VP6;
- +
- + off = avio_tell(pb);
- + //off += ff_get_v(pb);
- + off += ffio_read_varlen(pb);
- + avio_r8(pb); // '3'
- + avio_r8(pb); // val_7
- + st->time_base.num = avio_rl32(pb); // frame_time
- + st->time_base.den = avio_rl32(pb); // time_base
- + st->nb_frames = avio_rl32(pb); // n frames
- + vcodec->width = avio_rl16(pb); // width
- + vcodec->height = avio_rl16(pb); // height
- + avio_r8(pb); // val_8
- + avio_rl32(pb); // val_9
- +
- + vcodec->flags |= CODEC_FLAG_GLOBAL_HEADER; // ?
- +
- + avio_seek(pb, off, SEEK_SET);
- + }
- +
- + off = avio_tell(pb);
- + //off += ff_get_v(pb); // val_10
- + off += ffio_read_varlen(pb); // val_10
- + avio_r8(pb); // '4'
- + num_audio = avio_r8(pb);
- + avio_seek(pb, off, SEEK_SET);
- +
- + if(num_audio != 1)
- + av_log(s, AV_LOG_WARNING, "viv: number of audio tracks %d is not 1\n", num_audio);
- +
- + for(i=0;i<num_audio;i++) {
- + int q;
- + AVStream *st = avformat_new_stream(s, NULL);
- + AVCodecContext *acodec = st->codec;
- +
- + st->id = num_video + i;
- +
- + acodec->codec_type = CODEC_TYPE_AUDIO;
- + acodec->codec_id = CODEC_ID_VORBIS;
- + acodec->flags |= CODEC_FLAG_GLOBAL_HEADER; // ?
- +
- + off = avio_tell(pb);
- + //off += ff_get_v(pb); // length
- + off += ffio_read_varlen(pb); // length
- + avio_r8(pb); // '5'
- + avio_r8(pb); //codec_id
- + avio_rl16(pb); //codec_subid
- + acodec->channels = avio_rl16(pb); // channels
- + acodec->sample_rate = avio_rl32(pb); // sample_rate
- + avio_seek(pb, 10, SEEK_CUR); // data_1
- + q = avio_r8(pb);
- + avio_seek(pb, q, SEEK_CUR); // data_2
- + avio_r8(pb); // zeropad
- +
- + if(avio_tell(pb) < off) {
- + int num_data;
- + int xd_size = 0;
- + int data_len[256];
- + uint8_t * p;
- + int offset = 1;
- + //ff_get_v(pb); // val_13
- + ffio_read_varlen(pb); // val_13
- + avio_r8(pb); // '19'
- + //ff_get_v(pb); // len_3
- + ffio_read_varlen(pb); // len_3
- + num_data = avio_r8(pb);
- + for(j=0;j<num_data;j++) {
- + //data_len[j] = ff_get_v(pb);
- + data_len[j] = ffio_read_varlen(pb);
- + xd_size += data_len[j];
- + }
- +
- + acodec->extradata_size = 64 + xd_size + xd_size / 255;
- + acodec->extradata = (uint8_t*)av_mallocz(acodec->extradata_size);
- +
- + p = acodec->extradata;
- + p[0] = 2;
- +
- + for(j=0;j<num_data-1;j++)
- + offset += av_xiphlacing(&p[offset], data_len[j]);
- +
- + for(j=0;j<num_data;j++) {
- + avio_read(pb, &p[offset], data_len[j]);
- + offset += data_len[j];
- + }
- +
- + acodec->extradata_size = offset;
- + }
- + }
- +
- + av_free(pb);
- +}
- +
- +static void track_index(VIV_DemuxContext *viv, AVFormatContext *s, uint8_t *buf, int size)
- +{
- + int i;
- + int64_t off;
- + int poff;
- + int maxnp=0;
- + AVIOContext *pb=0;
- +
- + pb = avio_alloc_context(buf, size, 0, NULL, NULL, NULL, NULL);
- + //ff_get_v(pb); // track_index_len
- + ffio_read_varlen(pb); // track_index_len
- + avio_r8(pb); // 'c'
- + //viv->n_sb_blocks = ff_get_v(pb);
- + viv->n_sb_blocks = ffio_read_varlen(pb);
- + viv->sb_blocks = av_mallocz(sizeof(VIV_SB_block) * viv->n_sb_blocks);
- + if(!viv->sb_blocks) {
- + viv->n_sb_blocks = 0;
- + av_free(pb);
- + return;
- + }
- +
- + off = 0;
- + poff = 0;
- +
- + for(i=0;i<viv->n_sb_blocks;i++) {
- + viv->sb_blocks[i].byte_offset = off;
- + viv->sb_blocks[i].packet_offset = poff;
- +
- + //viv->sb_blocks[i].size = ff_get_v(pb);
- + //viv->sb_blocks[i].n_packets = ff_get_v(pb);
- + viv->sb_blocks[i].size = ffio_read_varlen(pb);
- + viv->sb_blocks[i].n_packets = ffio_read_varlen(pb);
- +
- + off += viv->sb_blocks[i].size;
- + poff += viv->sb_blocks[i].n_packets;
- +
- +
- + if(maxnp < viv->sb_blocks[i].n_packets)
- + maxnp = viv->sb_blocks[i].n_packets;
- + }
- +
- + viv->sb_entries = av_mallocz(maxnp * sizeof(VIV_SB_entry));
- + av_free(pb);
- +}
- +
- +static void load_sb_block(AVFormatContext *s, VIV_DemuxContext *viv, int expected_size)
- +{
- + uint32_t size=0;
- + int i;
- + AVIOContext *pb = 0;
- + if(viv->sb_pb) {
- + av_free(viv->sb_pb);
- + viv->sb_pb = NULL;
- + }
- +
- + if(viv->sb_buf)
- + av_free(viv->sb_buf);
- +
- + viv->sb_buf = read_sb_block(s->pb, &size, &viv->sb_key, expected_size);
- + if(!viv->sb_buf) {
- + return;
- + }
- +
- + pb = avio_alloc_context(viv->sb_buf, size, 0, NULL, NULL, NULL, NULL);
- + viv->sb_pb = pb;
- +
- + avio_r8(pb); // 'S'
- + avio_r8(pb); // 'B'
- + //ff_get_v(pb); // size
- + ffio_read_varlen(pb); // size
- + avio_r8(pb); // junk
- + //ff_get_v(pb); // first packet
- + ffio_read_varlen(pb); // first packet
- +
- + viv->n_sb_entries = viv->sb_blocks[viv->current_sb].n_packets;
- +
- + for(i=0;i<viv->n_sb_entries;i++) {
- + //viv->sb_entries[i].size = ff_get_v(pb);
- + viv->sb_entries[i].size = ffio_read_varlen(pb);
- + viv->sb_entries[i].flag = avio_r8(pb);
- + }
- +
- + //ff_get_v(pb); // 0
- + ffio_read_varlen(pb); // 0
- + avio_r8(pb); // 0
- +
- + viv->current_sb_entry = 0;
- +}
- +
- +static int viv_read_header(AVFormatContext *s)
- +{
- + VIV_DemuxContext *viv = s->priv_data;
- + AVIOContext *pb = s->pb;
- + int64_t header_end;
- + int num_tracks;
- + uint32_t key, k2;
- + uint32_t v;
- + uint8_t keybuffer[187];
- + uint32_t b22_size = 0;
- + uint32_t b22_key = 0;
- + uint8_t *buf = 0;
- +
- + // string "vividas03"
- + avio_seek(pb, 9, SEEK_CUR);
- +
- + header_end = avio_tell(pb);
- +
- + // v: header size
- + //header_end += ff_get_v(pb);
- + header_end += ffio_read_varlen(pb);
- +
- + // u8: n tracks
- + num_tracks = avio_r8(pb);
- +
- + if(num_tracks != 1) {
- + av_log(s, AV_LOG_ERROR, "number of tracks %d is not 1\n", num_tracks);
- + return AVERROR(EINVAL);
- + }
- +
- + v = avio_r8(pb);
- + avio_seek(pb, v, SEEK_CUR);
- +
- + avio_read(pb, keybuffer, 187);
- + key = decode_key(keybuffer);
- + viv->sb_key = key;
- +
- + avio_rl32(pb); // track_header_len
- +
- + for(;;) {
- + int64_t here = avio_tell(pb);
- + int block_len, block_type;
- +
- + if(here >= header_end)
- + break;
- +
- + //block_len = ff_get_v(pb);
- + block_len = ffio_read_varlen(pb);
- + block_type = avio_r8(pb);
- +
- + if(block_type == 22) {
- + avio_read(pb, keybuffer, 187);
- + b22_key = decode_key(keybuffer);
- + b22_size = avio_rl32(pb);
- + }
- +
- + avio_seek(pb, here + block_len, SEEK_SET);
- + }
- +
- + if(b22_size) {
- + k2 = b22_key;
- + buf = read_vblock(pb, &v, b22_key, &k2, 0);
- + if(!buf)
- + return AVERROR(EIO);
- +
- + av_free(buf);
- + }
- +
- + k2 = key;
- + buf = read_vblock(pb, &v, key, &k2, 0);
- + if(!buf)
- + return AVERROR(EIO);
- + track_header(viv, s, buf, v);
- + av_free(buf);
- +
- + buf = read_vblock(pb, &v, key, &k2, v);
- + if(!buf)
- + return AVERROR(EIO);
- + track_index(viv, s, buf, v);
- + av_free(buf);
- +
- + viv->sb_offset = avio_tell(pb);
- + if(viv->n_sb_blocks > 0) {
- + viv->current_sb = 0;
- + load_sb_block(s, viv, viv->sb_blocks[0].size);
- + } else {
- + viv->current_sb = -1;
- + }
- +
- + return 0;
- +}
- +
- +static int viv_read_packet(AVFormatContext *s,
- + AVPacket *pkt)
- +{
- + VIV_DemuxContext *viv = s->priv_data;
- + AVIOContext *pb;
- + int64_t off;
- +
- + if(viv->current_audio_subpacket < viv->n_audio_subpackets) {
- + // audio packets
- + AVStream *astream;
- + int size = viv->audio_subpackets[viv->current_audio_subpacket+1].start - viv->audio_subpackets[viv->current_audio_subpacket].start;
- + pb = viv->sb_pb;
- + av_get_packet(pb, pkt, size);
- + pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
- +
- + pkt->stream_index = 1;
- + astream = s->streams[pkt->stream_index];
- +
- + pkt->pts = viv->audio_sample * (long long)astream->time_base.den / (long long)astream->time_base.num / (long long)astream->codec->sample_rate;
- + viv->audio_sample += viv->audio_subpackets[viv->current_audio_subpacket].pcm_bytes / 2 / astream->codec->channels;
- + pkt->flags |= AV_PKT_FLAG_KEY;
- + viv->current_audio_subpacket++;
- + return 0;
- + }
- +
- + if(viv->current_sb_entry >= viv->n_sb_entries) {
- + if(viv->current_sb+1 >= viv->n_sb_blocks)
- + return AVERROR(EIO);
- + viv->current_sb++;
- +
- + load_sb_block(s, viv, 0);
- + viv->current_sb_entry = 0;
- + }
- +
- + pb = viv->sb_pb;
- + off = avio_tell(pb);
- + off += viv->sb_entries[viv->current_sb_entry].size;
- +
- + if(viv->sb_entries[viv->current_sb_entry].flag == 0) {
- + // A/V packet
- + int i;
- + //int v_size = ff_get_v(pb);
- + int v_size = ffio_read_varlen(pb);
- + ///*int a_size = */ff_get_v(pb);
- + /*int a_size = */ffio_read_varlen(pb);
- + av_get_packet(pb, pkt, v_size);
- + pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
- +
- + pkt->pts = viv->sb_blocks[viv->current_sb].packet_offset + viv->current_sb_entry;
- + pkt->flags |= (pkt->data[0]&0x80)?0:AV_PKT_FLAG_KEY;
- + pkt->stream_index = 0;
- +
- + for(i=0;i<MAX_AUDIO_SUBPACKETS-1;i++) {
- + int start, pcm_bytes;
- + //start = ff_get_v(pb);
- + //pcm_bytes = ff_get_v(pb);
- + start = ffio_read_varlen(pb);
- + pcm_bytes = ffio_read_varlen(pb);
- +
- + if(i > 0 && start == 0)
- + break;
- +
- + viv->n_audio_subpackets = i+1;
- + viv->audio_subpackets[i].start = start;
- + viv->audio_subpackets[i].pcm_bytes = pcm_bytes;
- + }
- + viv->audio_subpackets[viv->n_audio_subpackets].start = (int)(off - avio_tell(pb));
- + viv->current_audio_subpacket = 0;
- + //viv->n_audio_subpackets = 0;
- + //avio_seek(pb, off, SEEK_SET);
- +
- + } else {
- + // V packet
- + //int v_size = ff_get_v(pb);
- + int v_size = ffio_read_varlen(pb);
- + av_get_packet(pb, pkt, v_size);
- + pkt->pos += viv->sb_offset + viv->sb_blocks[viv->current_sb].byte_offset;
- + pkt->pts = viv->sb_blocks[viv->current_sb].packet_offset + viv->current_sb_entry;
- + pkt->flags |= (pkt->data[0]&0x80)?0:AV_PKT_FLAG_KEY;
- + pkt->stream_index = 0;
- + }
- +
- + viv->current_sb_entry++;
- +
- +// avio_seek(pb, off, SEEK_SET);
- +
- + return 0;
- +}
- +
- +static int viv_read_close(AVFormatContext *s)
- +{
- + VIV_DemuxContext *viv = s->priv_data;
- + if(viv->sb_pb)
- + av_free(viv->sb_pb);
- +
- + if(viv->sb_buf)
- + av_free(viv->sb_buf);
- +
- + if(viv->sb_blocks)
- + av_free(viv->sb_blocks);
- +
- + if(viv->sb_entries)
- + av_free(viv->sb_entries);
- +
- + return 0;
- +}
- +
- +static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
- +{
- + VIV_DemuxContext *viv = s->priv_data;
- + int frame = 0;
- + int i;
- +
- + if(stream_index == 0)
- + frame = (int)timestamp;
- + else
- + 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;
- +
- + for(i=0;i<viv->n_sb_blocks;i++) {
- + if(frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) {
- + // flush audio packet queue
- + viv->current_audio_subpacket = 0;
- + viv->n_audio_subpackets = 0;
- + viv->current_sb = i;
- + // seek to ith sb block
- + avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET);
- + // load the block
- + load_sb_block(s, viv, 0);
- + // most problematic part: guess audio offset
- + 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;
- + // hand-tuned 1.3s a/v offset
- + viv->audio_sample += 1300 * s->streams[1]->codec->sample_rate / 1000;
- + viv->current_sb_entry = 0;
- + return 1;
- + }
- + }
- + return 0;
- +}
- +
- +AVInputFormat ff_vividas_demuxer = {
- + .name = "vividas",
- + .long_name = NULL_IF_CONFIG_SMALL("Vividas VIV format"),
- + .priv_data_size = sizeof(VIV_DemuxContext),
- + .read_probe = viv_probe,
- + .read_header = viv_read_header,
- + .read_packet = viv_read_packet,
- + .read_close = viv_read_close,
- + .read_seek = viv_read_seek
- +};
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement