Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright (c) 2012 Clément Bœsch
  3.  *
  4.  * This file is part of FFmpeg.
  5.  *
  6.  * FFmpeg is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * FFmpeg is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with FFmpeg; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  */
  20.  
  21. /**
  22.  * @file
  23.  * MPL2 subtitles decoder
  24.  *
  25.  * @see http://web.archive.org/web/20090328040233/http://napisy.ussbrowarek.org/mpl2-eng.html
  26.  */
  27.  
  28. #include "avcodec.h"
  29. #include "ass.h"
  30. #include "libavutil/bprint.h"
  31.  
  32. static int mpl2_event_to_ass(AVBPrint *buf, const char *p)
  33. {
  34.     if (*p == ' ')
  35.         p++;
  36.  
  37.     while (*p) {
  38.         int got_style = 0;
  39.  
  40.         while (*p && strchr("/\\_", *p)) {
  41.             if      (*p == '/')  av_bprintf(buf, "{\\i1}");
  42.             else if (*p == '\\') av_bprintf(buf, "{\\b1}");
  43.             else if (*p == '_')  av_bprintf(buf, "{\\u1}");
  44.             got_style = 1;
  45.             p++;
  46.         }
  47.  
  48.         while (*p && *p != '|') {
  49.             if (*p != '\r' && *p != '\n')
  50.                 av_bprint_chars(buf, *p, 1);
  51.             p++;
  52.         }
  53.  
  54.         if (*p == '|') {
  55.             if (got_style)
  56.                 av_bprintf(buf, "{\\r}");
  57.             av_bprintf(buf, "\\N");
  58.             p++;
  59.         }
  60.     }
  61.  
  62.     av_bprintf(buf, "\r\n");
  63.     return 0;
  64. }
  65.  
  66. static int mpl2_decode_frame(AVCodecContext *avctx, void *data,
  67.                              int *got_sub_ptr, AVPacket *avpkt)
  68. {
  69.     AVBPrint buf;
  70.     AVSubtitle *sub = data;
  71.     const char *ptr = avpkt->data;
  72.     const int ts_start     = av_rescale_q(avpkt->pts,      avctx->time_base, (AVRational){1,100});
  73.     const int ts_duration  = avpkt->duration != -1 ?
  74.                              av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1;
  75.  
  76.     av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
  77.     if (ptr && avpkt->size > 0 && *ptr && !mpl2_event_to_ass(&buf, ptr)) {
  78.         if (!av_bprint_is_complete(&buf)) {
  79.             av_bprint_finalize(&buf, NULL);
  80.             return AVERROR(ENOMEM);
  81.         }
  82.         ff_ass_add_rect(sub, buf.str, ts_start, ts_duration, 0);
  83.     }
  84.     *got_sub_ptr = sub->num_rects > 0;
  85.     av_bprint_finalize(&buf, NULL);
  86.     return avpkt->size;
  87. }
  88.  
  89. AVCodec ff_mpl2_decoder = {
  90.     .name           = "mpl2",
  91.     .long_name      = NULL_IF_CONFIG_SMALL("MPL2 subtitle"),
  92.     .type           = AVMEDIA_TYPE_SUBTITLE,
  93.     .id             = AV_CODEC_ID_MPL2,
  94.     .decode         = mpl2_decode_frame,
  95.     .init           = ff_ass_subtitle_header_default,
  96. };
  97.