Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * 3GPP TS 26.245 Timed Text decoder
  3.  * Copyright (c) 2012  Philip Langdale <philipl@overt.org>
  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. #include "avcodec.h"
  23. #include "ass.h"
  24. #include "libavutil/avstring.h"
  25. #include "libavutil/common.h"
  26. #include "libavutil/bprint.h"
  27. #include "libavutil/intreadwrite.h"
  28.  
  29. static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end)
  30. {
  31.     while (text < text_end) {
  32.         switch (*text) {
  33.         case '\r':
  34.             break;
  35.         case '\n':
  36.             av_bprintf(buf, "\\N");
  37.             break;
  38.         default:
  39.             av_bprint_chars(buf, *text, 1);
  40.             break;
  41.         }
  42.         text++;
  43.     }
  44.  
  45.     av_bprintf(buf, "\r\n");
  46.     return 0;
  47. }
  48.  
  49. static int mov_text_init(AVCodecContext *avctx) {
  50.     /*
  51.      * TODO: Handle the default text style.
  52.      * NB: Most players ignore styles completely, with the result that
  53.      * it's very common to find files where the default style is broken
  54.      * and respecting it results in a worse experience than ignoring it.
  55.      */
  56.     return ff_ass_subtitle_header_default(avctx);
  57. }
  58.  
  59. static int mov_text_decode_frame(AVCodecContext *avctx,
  60.                             void *data, int *got_sub_ptr, AVPacket *avpkt)
  61. {
  62.     AVSubtitle *sub = data;
  63.     int ts_start, ts_end;
  64.     AVBPrint buf;
  65.     const char *ptr = avpkt->data;
  66.     const char *end;
  67.  
  68.     if (!ptr || avpkt->size < 2)
  69.         return AVERROR_INVALIDDATA;
  70.  
  71.     /*
  72.      * A packet of size two with value zero is an empty subtitle
  73.      * used to mark the end of the previous non-empty subtitle.
  74.      * We can just drop them here as we have duration information
  75.      * already. If the value is non-zero, then it's technically a
  76.      * bad packet.
  77.      */
  78.     if (avpkt->size == 2)
  79.         return AV_RB16(ptr) == 0 ? 0 : AVERROR_INVALIDDATA;
  80.  
  81.     /*
  82.      * The first two bytes of the packet are the length of the text string
  83.      * In complex cases, there are style descriptors appended to the string
  84.      * so we can't just assume the packet size is the string size.
  85.      */
  86.     end = ptr + FFMIN(2 + AV_RB16(ptr), avpkt->size);
  87.     ptr += 2;
  88.  
  89.     ts_start = av_rescale_q(avpkt->pts,
  90.                             avctx->time_base,
  91.                             (AVRational){1,100});
  92.     ts_end   = av_rescale_q(avpkt->pts + avpkt->duration,
  93.                             avctx->time_base,
  94.                             (AVRational){1,100});
  95.  
  96.     // Note that the spec recommends lines be no longer than 2048 characters.
  97.     av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
  98.     text_to_ass(&buf, ptr, end);
  99.  
  100.     if (!av_bprint_is_complete(&buf))
  101.         return AVERROR(ENOMEM);
  102.  
  103.     ff_ass_add_rect(sub, buf.str, ts_start, ts_end-ts_start, 0);
  104.     *got_sub_ptr = sub->num_rects > 0;
  105.     av_bprint_finalize(&buf, NULL);
  106.     return avpkt->size;
  107. }
  108.  
  109. AVCodec ff_movtext_decoder = {
  110.     .name         = "mov_text",
  111.     .long_name    = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
  112.     .type         = AVMEDIA_TYPE_SUBTITLE,
  113.     .id           = AV_CODEC_ID_MOV_TEXT,
  114.     .init         = mov_text_init,
  115.     .decode       = mov_text_decode_frame,
  116. };
  117.