Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Silicon Graphics Movie demuxer
  3.  * Copyright (c) 2012 Peter Ross
  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.  * Silicon Graphics Movie demuxer
  25.  */
  26.  
  27. #include "libavutil/channel_layout.h"
  28. #include "libavutil/eval.h"
  29. #include "libavutil/intreadwrite.h"
  30. #include "libavutil/rational.h"
  31.  
  32. #include "avformat.h"
  33. #include "internal.h"
  34.  
  35. typedef struct MvContext {
  36.     int nb_video_tracks;
  37.     int nb_audio_tracks;
  38.  
  39.     int eof_count;        ///< number of streams that have finished
  40.     int stream_index;     ///< current stream index
  41.     int frame[2];         ///< frame nb for current stream
  42.  
  43.     int acompression;     ///< compression level for audio stream
  44.     int aformat;          ///< audio format
  45. } MvContext;
  46.  
  47. #define AUDIO_FORMAT_SIGNED 401
  48.  
  49. static int mv_probe(AVProbeData *p)
  50. {
  51.     if (AV_RB32(p->buf) == MKBETAG('M', 'O', 'V', 'I') &&
  52.         AV_RB16(p->buf + 4) < 3)
  53.         return AVPROBE_SCORE_MAX;
  54.     return 0;
  55. }
  56.  
  57. static char *var_read_string(AVIOContext *pb, int size)
  58. {
  59.     int n;
  60.     char *str;
  61.  
  62.     if (size < 0 || size == INT_MAX)
  63.         return NULL;
  64.  
  65.     str = av_malloc(size + 1);
  66.     if (!str)
  67.         return NULL;
  68.     n = avio_get_str(pb, size, str, size + 1);
  69.     if (n < size)
  70.         avio_skip(pb, size - n);
  71.     return str;
  72. }
  73.  
  74. static int var_read_int(AVIOContext *pb, int size)
  75. {
  76.     int v;
  77.     char *s = var_read_string(pb, size);
  78.     if (!s)
  79.         return 0;
  80.     v = strtol(s, NULL, 10);
  81.     av_free(s);
  82.     return v;
  83. }
  84.  
  85. static AVRational var_read_float(AVIOContext *pb, int size)
  86. {
  87.     AVRational v;
  88.     char *s = var_read_string(pb, size);
  89.     if (!s)
  90.         return (AVRational) { 0, 0 };
  91.     v = av_d2q(av_strtod(s, NULL), INT_MAX);
  92.     av_free(s);
  93.     return v;
  94. }
  95.  
  96. static void var_read_metadata(AVFormatContext *avctx, const char *tag, int size)
  97. {
  98.     char *value = var_read_string(avctx->pb, size);
  99.     if (value)
  100.         av_dict_set(&avctx->metadata, tag, value, AV_DICT_DONT_STRDUP_VAL);
  101. }
  102.  
  103. static int set_channels(AVFormatContext *avctx, AVStream *st, int channels)
  104. {
  105.     if (channels <= 0) {
  106.         av_log(avctx, AV_LOG_ERROR, "Channel count %d invalid.\n", channels);
  107.         return AVERROR_INVALIDDATA;
  108.     }
  109.     st->codec->channels       = channels;
  110.     st->codec->channel_layout = (st->codec->channels == 1) ? AV_CH_LAYOUT_MONO
  111.                                                            : AV_CH_LAYOUT_STEREO;
  112.     return 0;
  113. }
  114.  
  115. /**
  116.  * Parse global variable
  117.  * @return < 0 if unknown
  118.  */
  119. static int parse_global_var(AVFormatContext *avctx, AVStream *st,
  120.                             const char *name, int size)
  121. {
  122.     MvContext *mv = avctx->priv_data;
  123.     AVIOContext *pb = avctx->pb;
  124.     if (!strcmp(name, "__NUM_I_TRACKS")) {
  125.         mv->nb_video_tracks = var_read_int(pb, size);
  126.     } else if (!strcmp(name, "__NUM_A_TRACKS")) {
  127.         mv->nb_audio_tracks = var_read_int(pb, size);
  128.     } else if (!strcmp(name, "COMMENT") || !strcmp(name, "TITLE")) {
  129.         var_read_metadata(avctx, name, size);
  130.     } else if (!strcmp(name, "LOOP_MODE") || !strcmp(name, "NUM_LOOPS") ||
  131.                !strcmp(name, "OPTIMIZED")) {
  132.         avio_skip(pb, size); // ignore
  133.     } else
  134.         return AVERROR_INVALIDDATA;
  135.  
  136.     return 0;
  137. }
  138.  
  139. /**
  140.  * Parse audio variable
  141.  * @return < 0 if unknown
  142.  */
  143. static int parse_audio_var(AVFormatContext *avctx, AVStream *st,
  144.                            const char *name, int size)
  145. {
  146.     MvContext *mv = avctx->priv_data;
  147.     AVIOContext *pb = avctx->pb;
  148.     if (!strcmp(name, "__DIR_COUNT")) {
  149.         st->nb_frames = var_read_int(pb, size);
  150.     } else if (!strcmp(name, "AUDIO_FORMAT")) {
  151.         mv->aformat = var_read_int(pb, size);
  152.     } else if (!strcmp(name, "COMPRESSION")) {
  153.         mv->acompression = var_read_int(pb, size);
  154.     } else if (!strcmp(name, "DEFAULT_VOL")) {
  155.         var_read_metadata(avctx, name, size);
  156.     } else if (!strcmp(name, "NUM_CHANNELS")) {
  157.         return set_channels(avctx, st, var_read_int(pb, size));
  158.     } else if (!strcmp(name, "SAMPLE_RATE")) {
  159.         st->codec->sample_rate = var_read_int(pb, size);
  160.         avpriv_set_pts_info(st, 33, 1, st->codec->sample_rate);
  161.     } else if (!strcmp(name, "SAMPLE_WIDTH")) {
  162.         st->codec->bits_per_coded_sample = var_read_int(pb, size) * 8;
  163.     } else
  164.         return AVERROR_INVALIDDATA;
  165.  
  166.     return 0;
  167. }
  168.  
  169. /**
  170.  * Parse video variable
  171.  * @return < 0 if unknown
  172.  */
  173. static int parse_video_var(AVFormatContext *avctx, AVStream *st,
  174.                            const char *name, int size)
  175. {
  176.     AVIOContext *pb = avctx->pb;
  177.     if (!strcmp(name, "__DIR_COUNT")) {
  178.         st->nb_frames = st->duration = var_read_int(pb, size);
  179.     } else if (!strcmp(name, "COMPRESSION")) {
  180.         char *str = var_read_string(pb, size);
  181.         if (!str)
  182.             return AVERROR_INVALIDDATA;
  183.         if (!strcmp(str, "1")) {
  184.             st->codec->codec_id = AV_CODEC_ID_MVC1;
  185.         } else if (!strcmp(str, "2")) {
  186.             st->codec->pix_fmt  = AV_PIX_FMT_ABGR;
  187.             st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
  188.         } else if (!strcmp(str, "3")) {
  189.             st->codec->codec_id = AV_CODEC_ID_SGIRLE;
  190.         } else if (!strcmp(str, "10")) {
  191.             st->codec->codec_id = AV_CODEC_ID_MJPEG;
  192.         } else if (!strcmp(str, "MVC2")) {
  193.             st->codec->codec_id = AV_CODEC_ID_MVC2;
  194.         } else {
  195.             avpriv_request_sample(avctx, "Video compression %s", str);
  196.         }
  197.         av_free(str);
  198.     } else if (!strcmp(name, "FPS")) {
  199.         AVRational fps = var_read_float(pb, size);
  200.         avpriv_set_pts_info(st, 64, fps.den, fps.num);
  201.         st->avg_frame_rate = fps;
  202.     } else if (!strcmp(name, "HEIGHT")) {
  203.         st->codec->height = var_read_int(pb, size);
  204.     } else if (!strcmp(name, "PIXEL_ASPECT")) {
  205.         st->sample_aspect_ratio = var_read_float(pb, size);
  206.         av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
  207.                   st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
  208.                   INT_MAX);
  209.     } else if (!strcmp(name, "WIDTH")) {
  210.         st->codec->width = var_read_int(pb, size);
  211.     } else if (!strcmp(name, "ORIENTATION")) {
  212.         if (var_read_int(pb, size) == 1101) {
  213.             st->codec->extradata      = av_strdup("BottomUp");
  214.             st->codec->extradata_size = 9;
  215.         }
  216.     } else if (!strcmp(name, "Q_SPATIAL") || !strcmp(name, "Q_TEMPORAL")) {
  217.         var_read_metadata(avctx, name, size);
  218.     } else if (!strcmp(name, "INTERLACING") || !strcmp(name, "PACKING")) {
  219.         avio_skip(pb, size); // ignore
  220.     } else
  221.         return AVERROR_INVALIDDATA;
  222.  
  223.     return 0;
  224. }
  225.  
  226. static int read_table(AVFormatContext *avctx, AVStream *st,
  227.                        int (*parse)(AVFormatContext *avctx, AVStream *st,
  228.                                     const char *name, int size))
  229. {
  230.     int count, i;
  231.     AVIOContext *pb = avctx->pb;
  232.     avio_skip(pb, 4);
  233.     count = avio_rb32(pb);
  234.     avio_skip(pb, 4);
  235.     for (i = 0; i < count; i++) {
  236.         char name[17];
  237.         int size;
  238.         avio_read(pb, name, 16);
  239.         name[sizeof(name) - 1] = 0;
  240.         size = avio_rb32(pb);
  241.         if (size < 0) {
  242.             av_log(avctx, AV_LOG_ERROR, "entry size %d is invalid\n", size);
  243.             return AVERROR_INVALIDDATA;
  244.         }
  245.         if (parse(avctx, st, name, size) < 0) {
  246.             avpriv_request_sample(avctx, "Variable %s", name);
  247.             avio_skip(pb, size);
  248.         }
  249.     }
  250.     return 0;
  251. }
  252.  
  253. static void read_index(AVIOContext *pb, AVStream *st)
  254. {
  255.     uint64_t timestamp = 0;
  256.     int i;
  257.     for (i = 0; i < st->nb_frames; i++) {
  258.         uint32_t pos  = avio_rb32(pb);
  259.         uint32_t size = avio_rb32(pb);
  260.         avio_skip(pb, 8);
  261.         av_add_index_entry(st, pos, timestamp, size, 0, AVINDEX_KEYFRAME);
  262.         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
  263.             timestamp += size / (st->codec->channels * 2);
  264.         } else {
  265.             timestamp++;
  266.         }
  267.     }
  268. }
  269.  
  270. static int mv_read_header(AVFormatContext *avctx)
  271. {
  272.     MvContext *mv = avctx->priv_data;
  273.     AVIOContext *pb = avctx->pb;
  274.     AVStream *ast = NULL, *vst = NULL; //initialization to suppress warning
  275.     int version, i;
  276.     int ret;
  277.  
  278.     avio_skip(pb, 4);
  279.  
  280.     version = avio_rb16(pb);
  281.     if (version == 2) {
  282.         uint64_t timestamp;
  283.         int v;
  284.         avio_skip(pb, 22);
  285.  
  286.         /* allocate audio track first to prevent unnecessary seeking
  287.          * (audio packet always precede video packet for a given frame) */
  288.         ast = avformat_new_stream(avctx, NULL);
  289.         if (!ast)
  290.             return AVERROR(ENOMEM);
  291.  
  292.         vst = avformat_new_stream(avctx, NULL);
  293.         if (!vst)
  294.             return AVERROR(ENOMEM);
  295.         avpriv_set_pts_info(vst, 64, 1, 15);
  296.         vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  297.         vst->avg_frame_rate    = av_inv_q(vst->time_base);
  298.         vst->nb_frames         = avio_rb32(pb);
  299.         v = avio_rb32(pb);
  300.         switch (v) {
  301.         case 1:
  302.             vst->codec->codec_id = AV_CODEC_ID_MVC1;
  303.             break;
  304.         case 2:
  305.             vst->codec->pix_fmt  = AV_PIX_FMT_ARGB;
  306.             vst->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
  307.             break;
  308.         default:
  309.             avpriv_request_sample(avctx, "Video compression %i", v);
  310.             break;
  311.         }
  312.         vst->codec->codec_tag = 0;
  313.         vst->codec->width     = avio_rb32(pb);
  314.         vst->codec->height    = avio_rb32(pb);
  315.         avio_skip(pb, 12);
  316.  
  317.         ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
  318.         ast->nb_frames          = vst->nb_frames;
  319.         ast->codec->sample_rate = avio_rb32(pb);
  320.         avpriv_set_pts_info(ast, 33, 1, ast->codec->sample_rate);
  321.         if (set_channels(avctx, ast, avio_rb32(pb)) < 0)
  322.             return AVERROR_INVALIDDATA;
  323.  
  324.         v = avio_rb32(pb);
  325.         if (v == AUDIO_FORMAT_SIGNED) {
  326.             ast->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
  327.         } else {
  328.             avpriv_request_sample(avctx, "Audio compression (format %i)", v);
  329.         }
  330.  
  331.         avio_skip(pb, 12);
  332.         var_read_metadata(avctx, "title", 0x80);
  333.         var_read_metadata(avctx, "comment", 0x100);
  334.         avio_skip(pb, 0x80);
  335.  
  336.         timestamp = 0;
  337.         for (i = 0; i < vst->nb_frames; i++) {
  338.             uint32_t pos   = avio_rb32(pb);
  339.             uint32_t asize = avio_rb32(pb);
  340.             uint32_t vsize = avio_rb32(pb);
  341.             avio_skip(pb, 8);
  342.             av_add_index_entry(ast, pos, timestamp, asize, 0, AVINDEX_KEYFRAME);
  343.             av_add_index_entry(vst, pos + asize, i, vsize, 0, AVINDEX_KEYFRAME);
  344.             timestamp += asize / (ast->codec->channels * 2);
  345.         }
  346.     } else if (!version && avio_rb16(pb) == 3) {
  347.         avio_skip(pb, 4);
  348.  
  349.         if ((ret = read_table(avctx, NULL, parse_global_var)) < 0)
  350.             return ret;
  351.  
  352.         if (mv->nb_audio_tracks > 1) {
  353.             avpriv_request_sample(avctx, "Multiple audio streams support");
  354.             return AVERROR_PATCHWELCOME;
  355.         } else if (mv->nb_audio_tracks) {
  356.             ast = avformat_new_stream(avctx, NULL);
  357.             if (!ast)
  358.                 return AVERROR(ENOMEM);
  359.             ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
  360.             if ((read_table(avctx, ast, parse_audio_var)) < 0)
  361.                 return ret;
  362.             if (mv->acompression == 100 &&
  363.                 mv->aformat == AUDIO_FORMAT_SIGNED &&
  364.                 ast->codec->bits_per_coded_sample == 16) {
  365.                 ast->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
  366.             } else {
  367.                 avpriv_request_sample(avctx,
  368.                                       "Audio compression %i (format %i, sr %i)",
  369.                                       mv->acompression, mv->aformat,
  370.                                       ast->codec->bits_per_coded_sample);
  371.                 ast->codec->codec_id = AV_CODEC_ID_NONE;
  372.             }
  373.             if (ast->codec->channels <= 0) {
  374.                 av_log(avctx, AV_LOG_ERROR, "No valid channel count found.\n");
  375.                 return AVERROR_INVALIDDATA;
  376.             }
  377.         }
  378.  
  379.         if (mv->nb_video_tracks > 1) {
  380.             avpriv_request_sample(avctx, "Multiple video streams support");
  381.             return AVERROR_PATCHWELCOME;
  382.         } else if (mv->nb_video_tracks) {
  383.             vst = avformat_new_stream(avctx, NULL);
  384.             if (!vst)
  385.                 return AVERROR(ENOMEM);
  386.             vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  387.             if ((ret = read_table(avctx, vst, parse_video_var))<0)
  388.                 return ret;
  389.         }
  390.  
  391.         if (mv->nb_audio_tracks)
  392.             read_index(pb, ast);
  393.  
  394.         if (mv->nb_video_tracks)
  395.             read_index(pb, vst);
  396.     } else {
  397.         avpriv_request_sample(avctx, "Version %i", version);
  398.         return AVERROR_PATCHWELCOME;
  399.     }
  400.  
  401.     return 0;
  402. }
  403.  
  404. static int mv_read_packet(AVFormatContext *avctx, AVPacket *pkt)
  405. {
  406.     MvContext *mv = avctx->priv_data;
  407.     AVIOContext *pb = avctx->pb;
  408.     AVStream *st = avctx->streams[mv->stream_index];
  409.     const AVIndexEntry *index;
  410.     int frame = mv->frame[mv->stream_index];
  411.     int64_t ret;
  412.     uint64_t pos;
  413.  
  414.     if (frame < st->nb_index_entries) {
  415.         index = &st->index_entries[frame];
  416.         pos   = avio_tell(pb);
  417.         if (index->pos > pos)
  418.             avio_skip(pb, index->pos - pos);
  419.         else if (index->pos < pos) {
  420.             if (!pb->seekable)
  421.                 return AVERROR(EIO);
  422.             ret = avio_seek(pb, index->pos, SEEK_SET);
  423.             if (ret < 0)
  424.                 return ret;
  425.         }
  426.         ret = av_get_packet(pb, pkt, index->size);
  427.         if (ret < 0)
  428.             return ret;
  429.  
  430.         pkt->stream_index = mv->stream_index;
  431.         pkt->pts          = index->timestamp;
  432.         pkt->flags       |= AV_PKT_FLAG_KEY;
  433.  
  434.         mv->frame[mv->stream_index]++;
  435.         mv->eof_count = 0;
  436.     } else {
  437.         mv->eof_count++;
  438.         if (mv->eof_count >= avctx->nb_streams)
  439.             return AVERROR_EOF;
  440.  
  441.         // avoid returning 0 without a packet
  442.         return AVERROR(EAGAIN);
  443.     }
  444.  
  445.     mv->stream_index++;
  446.     if (mv->stream_index >= avctx->nb_streams)
  447.         mv->stream_index = 0;
  448.  
  449.     return 0;
  450. }
  451.  
  452. static int mv_read_seek(AVFormatContext *avctx, int stream_index,
  453.                         int64_t timestamp, int flags)
  454. {
  455.     MvContext *mv = avctx->priv_data;
  456.     AVStream *st = avctx->streams[stream_index];
  457.     int frame, i;
  458.  
  459.     if ((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE))
  460.         return AVERROR(ENOSYS);
  461.  
  462.     if (!avctx->pb->seekable)
  463.         return AVERROR(EIO);
  464.  
  465.     frame = av_index_search_timestamp(st, timestamp, flags);
  466.     if (frame < 0)
  467.         return AVERROR_INVALIDDATA;
  468.  
  469.     for (i = 0; i < avctx->nb_streams; i++)
  470.         mv->frame[i] = frame;
  471.     return 0;
  472. }
  473.  
  474. AVInputFormat ff_mv_demuxer = {
  475.     .name           = "mv",
  476.     .long_name      = NULL_IF_CONFIG_SMALL("Silicon Graphics Movie"),
  477.     .priv_data_size = sizeof(MvContext),
  478.     .read_probe     = mv_probe,
  479.     .read_header    = mv_read_header,
  480.     .read_packet    = mv_read_packet,
  481.     .read_seek      = mv_read_seek,
  482. };
  483.