LCOV - code coverage report
Current view: top level - libavcodec - assenc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 18 34 52.9 %
Date: 2017-12-11 04:34:20 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SSA/ASS encoder
       3             :  * Copyright (c) 2010  Aurelien Jacobs <aurel@gnuage.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 <string.h>
      23             : 
      24             : #include "avcodec.h"
      25             : #include "ass.h"
      26             : #include "libavutil/avstring.h"
      27             : #include "libavutil/internal.h"
      28             : #include "libavutil/mem.h"
      29             : 
      30             : typedef struct {
      31             :     int id; ///< current event id, ReadOrder field
      32             : } ASSEncodeContext;
      33             : 
      34          25 : static av_cold int ass_encode_init(AVCodecContext *avctx)
      35             : {
      36          25 :     avctx->extradata = av_malloc(avctx->subtitle_header_size + 1);
      37          25 :     if (!avctx->extradata)
      38           0 :         return AVERROR(ENOMEM);
      39          25 :     memcpy(avctx->extradata, avctx->subtitle_header, avctx->subtitle_header_size);
      40          25 :     avctx->extradata_size = avctx->subtitle_header_size;
      41          25 :     avctx->extradata[avctx->extradata_size] = 0;
      42          25 :     return 0;
      43             : }
      44             : 
      45         472 : static int ass_encode_frame(AVCodecContext *avctx,
      46             :                             unsigned char *buf, int bufsize,
      47             :                             const AVSubtitle *sub)
      48             : {
      49         472 :     ASSEncodeContext *s = avctx->priv_data;
      50         472 :     int i, len, total_len = 0;
      51             : 
      52        1888 :     for (i=0; i<sub->num_rects; i++) {
      53             :         char ass_line[2048];
      54         472 :         const char *ass = sub->rects[i]->ass;
      55             :         long int layer;
      56             :         char *p;
      57             : 
      58         472 :         if (sub->rects[i]->type != SUBTITLE_ASS) {
      59           0 :             av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
      60           0 :             return -1;
      61             :         }
      62             : 
      63             : #if FF_API_ASS_TIMING
      64         472 :         if (!strncmp(ass, "Dialogue: ", 10)) {
      65           0 :             if (i > 0) {
      66           0 :                 av_log(avctx, AV_LOG_ERROR, "ASS encoder supports only one "
      67             :                        "ASS rectangle field.\n");
      68           0 :                 return AVERROR_INVALIDDATA;
      69             :             }
      70             : 
      71           0 :             ass += 10; // skip "Dialogue: "
      72             :             /* parse Layer field. If it's a Marked field, the content
      73             :              * will be "Marked=N" instead of the layer num, so we will
      74             :              * have layer=0, which is fine. */
      75           0 :             layer = strtol(ass, &p, 10);
      76             : 
      77             : #define SKIP_ENTRY(ptr) do {        \
      78             :     char *sep = strchr(ptr, ',');   \
      79             :     if (sep)                        \
      80             :         ptr = sep + 1;              \
      81             : } while (0)
      82             : 
      83           0 :             SKIP_ENTRY(p); // skip layer or marked
      84           0 :             SKIP_ENTRY(p); // skip start timestamp
      85           0 :             SKIP_ENTRY(p); // skip end timestamp
      86           0 :             snprintf(ass_line, sizeof(ass_line), "%d,%ld,%s", ++s->id, layer, p);
      87           0 :             ass_line[strcspn(ass_line, "\r\n")] = 0;
      88           0 :             ass = ass_line;
      89             :         }
      90             : #endif
      91             : 
      92         472 :         len = av_strlcpy(buf+total_len, ass, bufsize-total_len);
      93             : 
      94         472 :         if (len > bufsize-total_len-1) {
      95           0 :             av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
      96           0 :             return -1;
      97             :         }
      98             : 
      99         472 :         total_len += len;
     100             :     }
     101             : 
     102         472 :     return total_len;
     103             : }
     104             : 
     105             : #if CONFIG_SSA_ENCODER
     106             : AVCodec ff_ssa_encoder = {
     107             :     .name         = "ssa",
     108             :     .long_name    = NULL_IF_CONFIG_SMALL("ASS (Advanced SubStation Alpha) subtitle"),
     109             :     .type         = AVMEDIA_TYPE_SUBTITLE,
     110             :     .id           = AV_CODEC_ID_ASS,
     111             :     .init         = ass_encode_init,
     112             :     .encode_sub   = ass_encode_frame,
     113             :     .priv_data_size = sizeof(ASSEncodeContext),
     114             : };
     115             : #endif
     116             : 
     117             : #if CONFIG_ASS_ENCODER
     118             : AVCodec ff_ass_encoder = {
     119             :     .name         = "ass",
     120             :     .long_name    = NULL_IF_CONFIG_SMALL("ASS (Advanced SubStation Alpha) subtitle"),
     121             :     .type         = AVMEDIA_TYPE_SUBTITLE,
     122             :     .id           = AV_CODEC_ID_ASS,
     123             :     .init         = ass_encode_init,
     124             :     .encode_sub   = ass_encode_frame,
     125             :     .priv_data_size = sizeof(ASSEncodeContext),
     126             : };
     127             : #endif

Generated by: LCOV version 1.13