Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Vivo stream demuxer
  3.  * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
  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.  * @brief Vivo stream demuxer
  25.  * @author Daniel Verkamp <daniel at drv.nu>
  26.  * @sa http://wiki.multimedia.cx/index.php?title=Vivo
  27.  */
  28.  
  29. #include "libavutil/parseutils.h"
  30. #include "avformat.h"
  31. #include "internal.h"
  32.  
  33. typedef struct VivoContext {
  34.     int version;
  35.  
  36.     int type;
  37.     int sequence;
  38.     int length;
  39.  
  40.     uint8_t  text[1024 + 1];
  41. } VivoContext;
  42.  
  43. static int vivo_probe(AVProbeData *p)
  44. {
  45.     const unsigned char *buf = p->buf;
  46.     unsigned c, length = 0;
  47.  
  48.     // stream must start with packet of type 0 and sequence number 0
  49.     if (*buf++ != 0)
  50.         return 0;
  51.  
  52.     // read at most 2 bytes of coded length
  53.     c = *buf++;
  54.     length = c & 0x7F;
  55.     if (c & 0x80) {
  56.         c = *buf++;
  57.         length = (length << 7) | (c & 0x7F);
  58.     }
  59.     if (c & 0x80 || length > 1024 || length < 21)
  60.         return 0;
  61.  
  62.     if (memcmp(buf, "\r\nVersion:Vivo/", 15))
  63.         return 0;
  64.     buf += 15;
  65.  
  66.     if (*buf < '0' && *buf > '2')
  67.         return 0;
  68.  
  69.     return AVPROBE_SCORE_MAX;
  70. }
  71.  
  72. static int vivo_get_packet_header(AVFormatContext *s)
  73. {
  74.     VivoContext *vivo = s->priv_data;
  75.     AVIOContext *pb = s->pb;
  76.     unsigned c, get_length = 0;
  77.  
  78.     if (url_feof(pb))
  79.         return AVERROR_EOF;
  80.  
  81.     c = avio_r8(pb);
  82.     if (c == 0x82) {
  83.         get_length = 1;
  84.         c = avio_r8(pb);
  85.     }
  86.  
  87.     vivo->type     = c >> 4;
  88.     vivo->sequence = c & 0xF;
  89.  
  90.     switch (vivo->type) {
  91.     case 0:   get_length =   1; break;
  92.     case 1: vivo->length = 128; break;
  93.     case 2:   get_length =   1; break;
  94.     case 3: vivo->length =  40; break;
  95.     case 4: vivo->length =  24; break;
  96.     default:
  97.         av_log(s, AV_LOG_ERROR, "unknown packet type %d\n", vivo->type);
  98.         return AVERROR_INVALIDDATA;
  99.     }
  100.  
  101.     if (get_length) {
  102.         c = avio_r8(pb);
  103.         vivo->length = c & 0x7F;
  104.         if (c & 0x80) {
  105.             c = avio_r8(pb);
  106.             vivo->length = (vivo->length << 7) | (c & 0x7F);
  107.  
  108.             if (c & 0x80) {
  109.                 av_log(s, AV_LOG_ERROR, "coded length is more than two bytes\n");
  110.                 return AVERROR_INVALIDDATA;
  111.             }
  112.         }
  113.     }
  114.  
  115.     return 0;
  116. }
  117.  
  118. static int vivo_read_header(AVFormatContext *s)
  119. {
  120.     VivoContext *vivo = s->priv_data;
  121.     AVRational fps = { 1, 25};
  122.     AVStream *ast, *vst;
  123.     unsigned char *line, *line_end, *key, *value;
  124.     long value_int;
  125.     int ret, value_used;
  126.     int64_t duration = 0;
  127.     char *end_value;
  128.  
  129.     vst = avformat_new_stream(s, NULL);
  130.     ast = avformat_new_stream(s, NULL);
  131.     if (!ast || !vst)
  132.         return AVERROR(ENOMEM);
  133.  
  134.     ast->codec->sample_rate = 8000;
  135.  
  136.     while (1) {
  137.         if ((ret = vivo_get_packet_header(s)) < 0)
  138.             return ret;
  139.  
  140.         // done reading all text header packets?
  141.         if (vivo->sequence || vivo->type)
  142.             break;
  143.  
  144.         if (vivo->length <= 1024) {
  145.             avio_read(s->pb, vivo->text, vivo->length);
  146.             vivo->text[vivo->length] = 0;
  147.         } else {
  148.             av_log(s, AV_LOG_WARNING, "too big header, skipping\n");
  149.             avio_skip(s->pb, vivo->length);
  150.             continue;
  151.         }
  152.  
  153.         line = vivo->text;
  154.         while (*line) {
  155.             line_end = strstr(line, "\r\n");
  156.             if (!line_end)
  157.                 break;
  158.  
  159.             *line_end = 0;
  160.             key = line;
  161.             line = line_end + 2; // skip \r\n
  162.  
  163.             if (line_end == key) // skip blank lines
  164.                 continue;
  165.  
  166.             value = strchr(key, ':');
  167.             if (!value) {
  168.                 av_log(s, AV_LOG_WARNING, "missing colon in key:value pair '%s'\n",
  169.                        value);
  170.                 continue;
  171.             }
  172.  
  173.             *value++ = 0;
  174.  
  175.             av_log(s, AV_LOG_DEBUG, "header: '%s' = '%s'\n", key, value);
  176.  
  177.             value_int = strtol(value, &end_value, 10);
  178.             value_used = 0;
  179.             if (*end_value == 0) { // valid integer
  180.                 av_log(s, AV_LOG_DEBUG, "got a valid integer (%ld)\n", value_int);
  181.                 value_used = 1;
  182.                 if (!strcmp(key, "Duration")) {
  183.                     duration = value_int;
  184.                 } else if (!strcmp(key, "Width")) {
  185.                     vst->codec->width = value_int;
  186.                 } else if (!strcmp(key, "Height")) {
  187.                     vst->codec->height = value_int;
  188.                 } else if (!strcmp(key, "TimeUnitNumerator")) {
  189.                     fps.num = value_int / 1000;
  190.                 } else if (!strcmp(key, "TimeUnitDenominator")) {
  191.                     fps.den = value_int;
  192.                 } else if (!strcmp(key, "SamplingFrequency")) {
  193.                     ast->codec->sample_rate = value_int;
  194.                 } else if (!strcmp(key, "NominalBitrate")) {
  195.                 } else if (!strcmp(key, "Length")) {
  196.                     // size of file
  197.                 } else {
  198.                     value_used = 0;
  199.                 }
  200.             }
  201.  
  202.             if (!strcmp(key, "Version")) {
  203.                 if (sscanf(value, "Vivo/%d.", &vivo->version) != 1)
  204.                     return AVERROR_INVALIDDATA;
  205.                 value_used = 1;
  206.             } else if (!strcmp(key, "FPS")) {
  207.                 AVRational tmp;
  208.  
  209.                 value_used = 1;
  210.                 if (!av_parse_ratio(&tmp, value, 10000, AV_LOG_WARNING, s))
  211.                     fps = av_inv_q(tmp);
  212.             }
  213.  
  214.             if (!value_used)
  215.                 av_dict_set(&s->metadata, key, value, 0);
  216.         }
  217.     }
  218.  
  219.     avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
  220.     avpriv_set_pts_info(vst, 64, fps.num, fps.den);
  221.     if (duration)
  222.         s->duration = av_rescale(duration, 1000, 1);
  223.  
  224.     vst->start_time        = 0;
  225.     vst->codec->codec_tag  = 0;
  226.     vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  227.  
  228.     if (vivo->version == 1) {
  229.         vst->codec->codec_id = AV_CODEC_ID_H263;
  230.         ast->codec->codec_id = AV_CODEC_ID_G723_1;
  231.         ast->codec->bits_per_coded_sample = 8;
  232.         ast->codec->block_align = 24;
  233.         ast->codec->bit_rate = 6400;
  234.     }
  235.  
  236.     ast->start_time        = 0;
  237.     ast->codec->codec_tag  = 0;
  238.     ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
  239.     ast->codec->channels = 1;
  240.  
  241.     return 0;
  242. }
  243.  
  244. static int vivo_read_packet(AVFormatContext *s, AVPacket *pkt)
  245. {
  246.     VivoContext *vivo = s->priv_data;
  247.     AVIOContext *pb = s->pb;
  248.     unsigned old_sequence = vivo->sequence, old_type = vivo->type;
  249.     int stream_index, ret = 0;
  250.  
  251. restart:
  252.  
  253.     if (url_feof(pb))
  254.         return AVERROR_EOF;
  255.  
  256.     switch (vivo->type) {
  257.     case 0:
  258.         avio_skip(pb, vivo->length);
  259.         if ((ret = vivo_get_packet_header(s)) < 0)
  260.             return ret;
  261.         goto restart;
  262.     case 1:
  263.     case 2: // video
  264.         stream_index = 0;
  265.         break;
  266.     case 3:
  267.     case 4: // audio
  268.         stream_index = 1;
  269.         break;
  270.     default:
  271.         av_log(s, AV_LOG_ERROR, "unknown packet type %d\n", vivo->type);
  272.         return AVERROR_INVALIDDATA;
  273.     }
  274.  
  275.     if ((ret = av_get_packet(pb, pkt, vivo->length)) < 0)
  276.         goto fail;
  277.  
  278.     // get next packet header
  279.     if ((ret = vivo_get_packet_header(s)) < 0)
  280.         goto fail;
  281.  
  282.     while (vivo->sequence == old_sequence &&
  283.            (((vivo->type - 1) >> 1) == ((old_type - 1) >> 1))) {
  284.         if (url_feof(pb)) {
  285.             ret = AVERROR_EOF;
  286.             break;
  287.         }
  288.  
  289.         if ((ret = av_append_packet(pb, pkt, vivo->length)) < 0)
  290.             break;
  291.  
  292.         // get next packet header
  293.         if ((ret = vivo_get_packet_header(s)) < 0)
  294.             break;
  295.     }
  296.  
  297.     pkt->stream_index = stream_index;
  298.  
  299. fail:
  300.     if (ret < 0)
  301.         av_free_packet(pkt);
  302.     return ret;
  303. }
  304.  
  305. AVInputFormat ff_vivo_demuxer = {
  306.     .name           = "vivo",
  307.     .long_name      = NULL_IF_CONFIG_SMALL("Vivo"),
  308.     .priv_data_size = sizeof(VivoContext),
  309.     .read_probe     = vivo_probe,
  310.     .read_header    = vivo_read_header,
  311.     .read_packet    = vivo_read_packet,
  312.     .extensions     = "viv",
  313. };
  314.