Subversion Repositories Kolibri OS

Rev

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.  * Raw subtitles decoder
  24.  */
  25.  
  26. #include "avcodec.h"
  27. #include "ass.h"
  28. #include "libavutil/bprint.h"
  29. #include "libavutil/opt.h"
  30.  
  31. typedef struct {
  32.     AVClass *class;
  33.     const char *linebreaks;
  34.     int keep_ass_markup;
  35. } TextContext;
  36.  
  37. #define OFFSET(x) offsetof(TextContext, x)
  38. #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
  39. static const AVOption options[] = {
  40.     { "keep_ass_markup", "Set if ASS tags must be escaped", OFFSET(keep_ass_markup), AV_OPT_TYPE_INT,    {.i64=0}, 0, 1, .flags=SD },
  41.     { NULL }
  42. };
  43.  
  44. static int text_decode_frame(AVCodecContext *avctx, void *data,
  45.                              int *got_sub_ptr, AVPacket *avpkt)
  46. {
  47.     int ret = 0;
  48.     AVBPrint buf;
  49.     AVSubtitle *sub = data;
  50.     const char *ptr = avpkt->data;
  51.     const TextContext *text = avctx->priv_data;
  52.     const int ts_start     = av_rescale_q(avpkt->pts,      avctx->time_base, (AVRational){1,100});
  53.     const int ts_duration  = avpkt->duration != -1 ?
  54.                              av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1;
  55.  
  56.     av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
  57.     if (ptr && avpkt->size > 0 && *ptr) {
  58.         ff_ass_bprint_text_event(&buf, ptr, avpkt->size, text->linebreaks, text->keep_ass_markup);
  59.         ret = ff_ass_add_rect_bprint(sub, &buf, ts_start, ts_duration);
  60.     }
  61.     av_bprint_finalize(&buf, NULL);
  62.     if (ret < 0)
  63.         return ret;
  64.     *got_sub_ptr = sub->num_rects > 0;
  65.     return avpkt->size;
  66. }
  67.  
  68. #define DECLARE_CLASS(decname) static const AVClass decname ## _decoder_class = {   \
  69.     .class_name = #decname " decoder",      \
  70.     .item_name  = av_default_item_name,     \
  71.     .option     = decname ## _options,      \
  72.     .version    = LIBAVUTIL_VERSION_INT,    \
  73. }
  74.  
  75. #if CONFIG_TEXT_DECODER
  76. #define text_options options
  77. DECLARE_CLASS(text);
  78.  
  79. AVCodec ff_text_decoder = {
  80.     .name           = "text",
  81.     .long_name      = NULL_IF_CONFIG_SMALL("Raw text subtitle"),
  82.     .priv_data_size = sizeof(TextContext),
  83.     .type           = AVMEDIA_TYPE_SUBTITLE,
  84.     .id             = AV_CODEC_ID_TEXT,
  85.     .decode         = text_decode_frame,
  86.     .init           = ff_ass_subtitle_header_default,
  87.     .priv_class     = &text_decoder_class,
  88. };
  89. #endif
  90.  
  91. #if CONFIG_VPLAYER_DECODER || CONFIG_PJS_DECODER || CONFIG_SUBVIEWER1_DECODER || CONFIG_STL_DECODER
  92.  
  93. static int linebreak_init(AVCodecContext *avctx)
  94. {
  95.     TextContext *text = avctx->priv_data;
  96.     text->linebreaks = "|";
  97.     return ff_ass_subtitle_header_default(avctx);
  98. }
  99.  
  100. #if CONFIG_VPLAYER_DECODER
  101. #define vplayer_options options
  102. DECLARE_CLASS(vplayer);
  103.  
  104. AVCodec ff_vplayer_decoder = {
  105.     .name           = "vplayer",
  106.     .long_name      = NULL_IF_CONFIG_SMALL("VPlayer subtitle"),
  107.     .priv_data_size = sizeof(TextContext),
  108.     .type           = AVMEDIA_TYPE_SUBTITLE,
  109.     .id             = AV_CODEC_ID_VPLAYER,
  110.     .decode         = text_decode_frame,
  111.     .init           = linebreak_init,
  112.     .priv_class     = &vplayer_decoder_class,
  113. };
  114. #endif
  115.  
  116. #if CONFIG_STL_DECODER
  117. #define stl_options options
  118. DECLARE_CLASS(stl);
  119.  
  120. AVCodec ff_stl_decoder = {
  121.     .name           = "stl",
  122.     .long_name      = NULL_IF_CONFIG_SMALL("Spruce subtitle format"),
  123.     .priv_data_size = sizeof(TextContext),
  124.     .type           = AVMEDIA_TYPE_SUBTITLE,
  125.     .id             = AV_CODEC_ID_STL,
  126.     .decode         = text_decode_frame,
  127.     .init           = linebreak_init,
  128.     .priv_class     = &stl_decoder_class,
  129. };
  130. #endif
  131.  
  132. #if CONFIG_PJS_DECODER
  133. #define pjs_options options
  134. DECLARE_CLASS(pjs);
  135.  
  136. AVCodec ff_pjs_decoder = {
  137.     .name           = "pjs",
  138.     .long_name      = NULL_IF_CONFIG_SMALL("PJS subtitle"),
  139.     .priv_data_size = sizeof(TextContext),
  140.     .type           = AVMEDIA_TYPE_SUBTITLE,
  141.     .id             = AV_CODEC_ID_PJS,
  142.     .decode         = text_decode_frame,
  143.     .init           = linebreak_init,
  144.     .priv_class     = &pjs_decoder_class,
  145. };
  146. #endif
  147.  
  148. #if CONFIG_SUBVIEWER1_DECODER
  149. #define subviewer1_options options
  150. DECLARE_CLASS(subviewer1);
  151.  
  152. AVCodec ff_subviewer1_decoder = {
  153.     .name           = "subviewer1",
  154.     .long_name      = NULL_IF_CONFIG_SMALL("SubViewer1 subtitle"),
  155.     .priv_data_size = sizeof(TextContext),
  156.     .type           = AVMEDIA_TYPE_SUBTITLE,
  157.     .id             = AV_CODEC_ID_SUBVIEWER1,
  158.     .decode         = text_decode_frame,
  159.     .init           = linebreak_init,
  160.     .priv_class     = &subviewer1_decoder_class,
  161. };
  162. #endif
  163.  
  164. #endif /* text subtitles with '|' line break */
  165.