FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavcodec
movtextenc.c
Go to the documentation of this file.
1
/*
2
* 3GPP TS 26.245 Timed Text encoder
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 <stdarg.h>
23
#include "
avcodec.h
"
24
#include "
libavutil/avassert.h
"
25
#include "
libavutil/avstring.h
"
26
#include "
libavutil/intreadwrite.h
"
27
#include "
ass_split.h
"
28
#include "
ass.h
"
29
30
typedef
struct
{
31
ASSSplitContext
*
ass_ctx
;
32
char
buffer
[2048];
33
char
*
ptr
;
34
char
*
end
;
35
}
MovTextContext
;
36
37
38
static
av_cold
int
mov_text_encode_init
(
AVCodecContext
*avctx)
39
{
40
/*
41
* For now, we'll use a fixed default style. When we add styling
42
* support, this will be generated from the ASS style.
43
*/
44
static
uint8_t
text_sample_entry[] = {
45
0x00, 0x00, 0x00, 0x00,
// uint32_t displayFlags
46
0x01,
// int8_t horizontal-justification
47
0xFF,
// int8_t vertical-justification
48
0x00, 0x00, 0x00, 0x00,
// uint8_t background-color-rgba[4]
49
// BoxRecord {
50
0x00, 0x00,
// int16_t top
51
0x00, 0x00,
// int16_t left
52
0x00, 0x00,
// int16_t bottom
53
0x00, 0x00,
// int16_t right
54
// };
55
// StyleRecord {
56
0x00, 0x00,
// uint16_t startChar
57
0x00, 0x00,
// uint16_t endChar
58
0x00, 0x01,
// uint16_t font-ID
59
0x00,
// uint8_t face-style-flags
60
0x12,
// uint8_t font-size
61
0xFF, 0xFF, 0xFF, 0xFF,
// uint8_t text-color-rgba[4]
62
// };
63
// FontTableBox {
64
0x00, 0x00, 0x00, 0x12,
// uint32_t size
65
'f'
,
't'
,
'a'
,
'b'
,
// uint8_t name[4]
66
0x00, 0x01,
// uint16_t entry-count
67
// FontRecord {
68
0x00, 0x01,
// uint16_t font-ID
69
0x05,
// uint8_t font-name-length
70
'S'
,
'e'
,
'r'
,
'i'
,
'f'
,
// uint8_t font[font-name-length]
71
// };
72
// };
73
};
74
75
MovTextContext
*
s
= avctx->
priv_data
;
76
77
avctx->
extradata_size
=
sizeof
text_sample_entry;
78
avctx->
extradata
=
av_mallocz
(avctx->
extradata_size
);
79
if
(!avctx->
extradata
)
80
return
AVERROR
(ENOMEM);
81
82
memcpy(avctx->
extradata
, text_sample_entry, avctx->
extradata_size
);
83
84
s->
ass_ctx
=
ff_ass_split
(avctx->
subtitle_header
);
85
return
s->
ass_ctx
? 0 :
AVERROR_INVALIDDATA
;
86
}
87
88
static
void
mov_text_text_cb
(
void
*priv,
const
char
*text,
int
len
)
89
{
90
MovTextContext
*
s
= priv;
91
av_assert0
(s->
end
>= s->
ptr
);
92
av_strlcpy
(s->
ptr
, text,
FFMIN
(s->
end
- s->
ptr
, len + 1));
93
s->
ptr
+=
FFMIN
(s->
end
- s->
ptr
, len);
94
}
95
96
static
void
mov_text_new_line_cb
(
void
*priv,
int
forced)
97
{
98
MovTextContext
*
s
= priv;
99
av_assert0
(s->
end
>= s->
ptr
);
100
av_strlcpy
(s->
ptr
,
"\n"
,
FFMIN
(s->
end
- s->
ptr
, 2));
101
if
(s->
end
> s->
ptr
)
102
s->
ptr
++;
103
}
104
105
static
const
ASSCodesCallbacks
mov_text_callbacks
= {
106
.
text
=
mov_text_text_cb
,
107
.new_line =
mov_text_new_line_cb
,
108
};
109
110
static
int
mov_text_encode_frame
(
AVCodecContext
*avctx,
unsigned
char
*
buf
,
111
int
bufsize,
const
AVSubtitle
*sub)
112
{
113
MovTextContext
*
s
= avctx->
priv_data
;
114
ASSDialog
*dialog;
115
int
i,
len
, num;
116
117
s->
ptr
= s->
buffer
;
118
s->
end
= s->
ptr
+
sizeof
(s->
buffer
);
119
120
for
(i = 0; i < sub->
num_rects
; i++) {
121
122
if
(sub->
rects
[i]->
type
!=
SUBTITLE_ASS
) {
123
av_log
(avctx,
AV_LOG_ERROR
,
"Only SUBTITLE_ASS type supported.\n"
);
124
return
AVERROR
(ENOSYS);
125
}
126
127
dialog =
ff_ass_split_dialog
(s->
ass_ctx
, sub->
rects
[i]->
ass
, 0, &num);
128
for
(; dialog && num--; dialog++) {
129
ff_ass_split_override_codes
(&mov_text_callbacks, s, dialog->
text
);
130
}
131
}
132
133
if
(s->
ptr
== s->
buffer
)
134
return
0;
135
136
AV_WB16
(buf, strlen(s->
buffer
));
137
buf += 2;
138
139
len =
av_strlcpy
(buf, s->
buffer
, bufsize - 2);
140
141
if
(len > bufsize-3) {
142
av_log
(avctx,
AV_LOG_ERROR
,
"Buffer too small for ASS event.\n"
);
143
return
AVERROR
(EINVAL);
144
}
145
146
return
len + 2;
147
}
148
149
static
int
mov_text_encode_close
(
AVCodecContext
*avctx)
150
{
151
MovTextContext
*
s
= avctx->
priv_data
;
152
ff_ass_split_free
(s->
ass_ctx
);
153
return
0;
154
}
155
156
AVCodec
ff_movtext_encoder
= {
157
.
name
=
"mov_text"
,
158
.long_name =
NULL_IF_CONFIG_SMALL
(
"3GPP Timed Text subtitle"
),
159
.type =
AVMEDIA_TYPE_SUBTITLE
,
160
.id =
AV_CODEC_ID_MOV_TEXT
,
161
.priv_data_size =
sizeof
(
MovTextContext
),
162
.
init
=
mov_text_encode_init
,
163
.encode_sub =
mov_text_encode_frame
,
164
.
close
=
mov_text_encode_close
,
165
};
Generated on Sun Mar 23 2014 23:49:59 for FFmpeg by
1.8.2