Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * 3GPP TS 26.245 Timed Text decoder
3
 * Copyright (c) 2012  Philip Langdale 
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
};