Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Tiertex Limited SEQ File Demuxer
  3.  * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. /**
  23.  * @file
  24.  * Tiertex Limited SEQ file demuxer
  25.  */
  26.  
  27. #include "libavutil/channel_layout.h"
  28. #include "avformat.h"
  29. #include "internal.h"
  30.  
  31. #define SEQ_FRAME_SIZE         6144
  32. #define SEQ_FRAME_W            256
  33. #define SEQ_FRAME_H            128
  34. #define SEQ_NUM_FRAME_BUFFERS  30
  35. #define SEQ_AUDIO_BUFFER_SIZE  882
  36. #define SEQ_SAMPLE_RATE        22050
  37. #define SEQ_FRAME_RATE         25
  38.  
  39.  
  40. typedef struct TiertexSeqFrameBuffer {
  41.     int fill_size;
  42.     int data_size;
  43.     unsigned char *data;
  44. } TiertexSeqFrameBuffer;
  45.  
  46. typedef struct SeqDemuxContext {
  47.     int audio_stream_index;
  48.     int video_stream_index;
  49.     int current_frame_pts;
  50.     int current_frame_offs;
  51.     TiertexSeqFrameBuffer frame_buffers[SEQ_NUM_FRAME_BUFFERS];
  52.     int frame_buffers_count;
  53.     unsigned int current_audio_data_size;
  54.     unsigned int current_audio_data_offs;
  55.     unsigned int current_pal_data_size;
  56.     unsigned int current_pal_data_offs;
  57.     unsigned int current_video_data_size;
  58.     unsigned char *current_video_data_ptr;
  59.     int audio_buffer_full;
  60. } SeqDemuxContext;
  61.  
  62.  
  63. static int seq_probe(AVProbeData *p)
  64. {
  65.     int i;
  66.  
  67.     if (p->buf_size < 258)
  68.         return 0;
  69.  
  70.     /* there's no real header in a .seq file, the only thing they have in common */
  71.     /* is the first 256 bytes of the file which are always filled with 0 */
  72.     for (i = 0; i < 256; i++)
  73.         if (p->buf[i])
  74.             return 0;
  75.  
  76.     if(p->buf[256]==0 && p->buf[257]==0)
  77.         return 0;
  78.  
  79.     /* only one fourth of the score since the previous check is too naive */
  80.     return AVPROBE_SCORE_MAX / 4;
  81. }
  82.  
  83. static int seq_init_frame_buffers(SeqDemuxContext *seq, AVIOContext *pb)
  84. {
  85.     int i, sz;
  86.     TiertexSeqFrameBuffer *seq_buffer;
  87.  
  88.     avio_seek(pb, 256, SEEK_SET);
  89.  
  90.     for (i = 0; i < SEQ_NUM_FRAME_BUFFERS; i++) {
  91.         sz = avio_rl16(pb);
  92.         if (sz == 0)
  93.             break;
  94.         else {
  95.             seq_buffer = &seq->frame_buffers[i];
  96.             seq_buffer->fill_size = 0;
  97.             seq_buffer->data_size = sz;
  98.             seq_buffer->data = av_malloc(sz);
  99.             if (!seq_buffer->data)
  100.                 return AVERROR(ENOMEM);
  101.         }
  102.     }
  103.     seq->frame_buffers_count = i;
  104.     return 0;
  105. }
  106.  
  107. static int seq_fill_buffer(SeqDemuxContext *seq, AVIOContext *pb, int buffer_num, unsigned int data_offs, int data_size)
  108. {
  109.     TiertexSeqFrameBuffer *seq_buffer;
  110.  
  111.     if (buffer_num >= SEQ_NUM_FRAME_BUFFERS)
  112.         return AVERROR_INVALIDDATA;
  113.  
  114.     seq_buffer = &seq->frame_buffers[buffer_num];
  115.     if (seq_buffer->fill_size + data_size > seq_buffer->data_size || data_size <= 0)
  116.         return AVERROR_INVALIDDATA;
  117.  
  118.     avio_seek(pb, seq->current_frame_offs + data_offs, SEEK_SET);
  119.     if (avio_read(pb, seq_buffer->data + seq_buffer->fill_size, data_size) != data_size)
  120.         return AVERROR(EIO);
  121.  
  122.     seq_buffer->fill_size += data_size;
  123.     return 0;
  124. }
  125.  
  126. static int seq_parse_frame_data(SeqDemuxContext *seq, AVIOContext *pb)
  127. {
  128.     unsigned int offset_table[4], buffer_num[4];
  129.     TiertexSeqFrameBuffer *seq_buffer;
  130.     int i, e, err;
  131.  
  132.     seq->current_frame_offs += SEQ_FRAME_SIZE;
  133.     avio_seek(pb, seq->current_frame_offs, SEEK_SET);
  134.  
  135.     /* sound data */
  136.     seq->current_audio_data_offs = avio_rl16(pb);
  137.     if (seq->current_audio_data_offs) {
  138.         seq->current_audio_data_size = SEQ_AUDIO_BUFFER_SIZE * 2;
  139.     } else {
  140.         seq->current_audio_data_size = 0;
  141.     }
  142.  
  143.     /* palette data */
  144.     seq->current_pal_data_offs = avio_rl16(pb);
  145.     if (seq->current_pal_data_offs) {
  146.         seq->current_pal_data_size = 768;
  147.     } else {
  148.         seq->current_pal_data_size = 0;
  149.     }
  150.  
  151.     /* video data */
  152.     for (i = 0; i < 4; i++)
  153.         buffer_num[i] = avio_r8(pb);
  154.  
  155.     for (i = 0; i < 4; i++)
  156.         offset_table[i] = avio_rl16(pb);
  157.  
  158.     for (i = 0; i < 3; i++) {
  159.         if (offset_table[i]) {
  160.             for (e = i + 1; e < 3 && offset_table[e] == 0; e++);
  161.             err = seq_fill_buffer(seq, pb, buffer_num[1 + i],
  162.               offset_table[i],
  163.               offset_table[e] - offset_table[i]);
  164.             if (err)
  165.                 return err;
  166.         }
  167.     }
  168.  
  169.     if (buffer_num[0] != 255) {
  170.         if (buffer_num[0] >= SEQ_NUM_FRAME_BUFFERS)
  171.             return AVERROR_INVALIDDATA;
  172.  
  173.         seq_buffer = &seq->frame_buffers[buffer_num[0]];
  174.         seq->current_video_data_size = seq_buffer->fill_size;
  175.         seq->current_video_data_ptr  = seq_buffer->data;
  176.         seq_buffer->fill_size = 0;
  177.     } else {
  178.         seq->current_video_data_size = 0;
  179.         seq->current_video_data_ptr  = 0;
  180.     }
  181.  
  182.     return 0;
  183. }
  184.  
  185. static int seq_read_header(AVFormatContext *s)
  186. {
  187.     int i, rc;
  188.     SeqDemuxContext *seq = s->priv_data;
  189.     AVIOContext *pb = s->pb;
  190.     AVStream *st;
  191.  
  192.     /* init internal buffers */
  193.     rc = seq_init_frame_buffers(seq, pb);
  194.     if (rc)
  195.         return rc;
  196.  
  197.     seq->current_frame_offs = 0;
  198.  
  199.     /* preload (no audio data, just buffer operations related data) */
  200.     for (i = 1; i <= 100; i++) {
  201.         rc = seq_parse_frame_data(seq, pb);
  202.         if (rc)
  203.             return rc;
  204.     }
  205.  
  206.     seq->current_frame_pts = 0;
  207.  
  208.     seq->audio_buffer_full = 0;
  209.  
  210.     /* initialize the video decoder stream */
  211.     st = avformat_new_stream(s, NULL);
  212.     if (!st)
  213.         return AVERROR(ENOMEM);
  214.  
  215.     avpriv_set_pts_info(st, 32, 1, SEQ_FRAME_RATE);
  216.     seq->video_stream_index = st->index;
  217.     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  218.     st->codec->codec_id = AV_CODEC_ID_TIERTEXSEQVIDEO;
  219.     st->codec->codec_tag = 0;  /* no fourcc */
  220.     st->codec->width = SEQ_FRAME_W;
  221.     st->codec->height = SEQ_FRAME_H;
  222.  
  223.     /* initialize the audio decoder stream */
  224.     st = avformat_new_stream(s, NULL);
  225.     if (!st)
  226.         return AVERROR(ENOMEM);
  227.  
  228.     st->start_time = 0;
  229.     avpriv_set_pts_info(st, 32, 1, SEQ_SAMPLE_RATE);
  230.     seq->audio_stream_index = st->index;
  231.     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
  232.     st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
  233.     st->codec->codec_tag = 0;  /* no tag */
  234.     st->codec->channels = 1;
  235.     st->codec->channel_layout = AV_CH_LAYOUT_MONO;
  236.     st->codec->sample_rate = SEQ_SAMPLE_RATE;
  237.     st->codec->bits_per_coded_sample = 16;
  238.     st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels;
  239.     st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample / 8;
  240.  
  241.     return 0;
  242. }
  243.  
  244. static int seq_read_packet(AVFormatContext *s, AVPacket *pkt)
  245. {
  246.     int rc;
  247.     SeqDemuxContext *seq = s->priv_data;
  248.     AVIOContext *pb = s->pb;
  249.  
  250.     if (!seq->audio_buffer_full) {
  251.         rc = seq_parse_frame_data(seq, pb);
  252.         if (rc)
  253.             return rc;
  254.  
  255.         /* video packet */
  256.         if (seq->current_pal_data_size + seq->current_video_data_size != 0) {
  257.             if (av_new_packet(pkt, 1 + seq->current_pal_data_size + seq->current_video_data_size))
  258.                 return AVERROR(ENOMEM);
  259.  
  260.             pkt->data[0] = 0;
  261.             if (seq->current_pal_data_size) {
  262.                 pkt->data[0] |= 1;
  263.                 avio_seek(pb, seq->current_frame_offs + seq->current_pal_data_offs, SEEK_SET);
  264.                 if (avio_read(pb, &pkt->data[1], seq->current_pal_data_size) != seq->current_pal_data_size)
  265.                     return AVERROR(EIO);
  266.             }
  267.             if (seq->current_video_data_size) {
  268.                 pkt->data[0] |= 2;
  269.                 memcpy(&pkt->data[1 + seq->current_pal_data_size],
  270.                   seq->current_video_data_ptr,
  271.                   seq->current_video_data_size);
  272.             }
  273.             pkt->stream_index = seq->video_stream_index;
  274.             pkt->pts = seq->current_frame_pts;
  275.  
  276.             /* sound buffer will be processed on next read_packet() call */
  277.             seq->audio_buffer_full = 1;
  278.             return 0;
  279.        }
  280.     }
  281.  
  282.     /* audio packet */
  283.     if (seq->current_audio_data_offs == 0) /* end of data reached */
  284.         return AVERROR(EIO);
  285.  
  286.     avio_seek(pb, seq->current_frame_offs + seq->current_audio_data_offs, SEEK_SET);
  287.     rc = av_get_packet(pb, pkt, seq->current_audio_data_size);
  288.     if (rc < 0)
  289.         return rc;
  290.  
  291.     pkt->stream_index = seq->audio_stream_index;
  292.     seq->current_frame_pts++;
  293.  
  294.     seq->audio_buffer_full = 0;
  295.     return 0;
  296. }
  297.  
  298. static int seq_read_close(AVFormatContext *s)
  299. {
  300.     int i;
  301.     SeqDemuxContext *seq = s->priv_data;
  302.  
  303.     for (i = 0; i < SEQ_NUM_FRAME_BUFFERS; i++)
  304.         av_free(seq->frame_buffers[i].data);
  305.  
  306.     return 0;
  307. }
  308.  
  309. AVInputFormat ff_tiertexseq_demuxer = {
  310.     .name           = "tiertexseq",
  311.     .long_name      = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ"),
  312.     .priv_data_size = sizeof(SeqDemuxContext),
  313.     .read_probe     = seq_probe,
  314.     .read_header    = seq_read_header,
  315.     .read_packet    = seq_read_packet,
  316.     .read_close     = seq_read_close,
  317. };
  318.