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
libavformat
srtenc.c
Go to the documentation of this file.
1
/*
2
* SubRip subtitle muxer
3
* Copyright (c) 2012 Nicolas George <nicolas.george@normalesup.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 "
avformat.h
"
23
#include "
internal.h
"
24
#include "
libavutil/log.h
"
25
#include "
libavutil/intreadwrite.h
"
26
27
/* TODO: add options for:
28
- character encoding;
29
- LF / CRLF;
30
- byte order mark.
31
*/
32
33
typedef
struct
SRTContext
{
34
unsigned
index
;
35
}
SRTContext
;
36
37
static
int
srt_write_header
(
AVFormatContext
*avf)
38
{
39
SRTContext
*srt = avf->
priv_data
;
40
41
if
(avf->
nb_streams
!= 1 ||
42
avf->
streams
[0]->
codec
->
codec_type
!=
AVMEDIA_TYPE_SUBTITLE
) {
43
av_log
(avf,
AV_LOG_ERROR
,
44
"SRT supports only a single subtitles stream.\n"
);
45
return
AVERROR
(EINVAL);
46
}
47
if
(avf->
streams
[0]->
codec
->
codec_id
!=
AV_CODEC_ID_TEXT
&&
48
avf->
streams
[0]->
codec
->
codec_id
!=
AV_CODEC_ID_SUBRIP
) {
49
av_log
(avf,
AV_LOG_ERROR
,
50
"Unsupported subtitles codec: %s\n"
,
51
avcodec_get_name
(avf->
streams
[0]->
codec
->
codec_id
));
52
return
AVERROR
(EINVAL);
53
}
54
avpriv_set_pts_info
(avf->
streams
[0], 64, 1, 1000);
55
srt->
index
= 1;
56
return
0;
57
}
58
59
static
int
srt_write_packet
(
AVFormatContext
*avf,
AVPacket
*
pkt
)
60
{
61
SRTContext
*srt = avf->
priv_data
;
62
63
// TODO: reindent
64
int64_t
s
= pkt->
pts
, e, d = pkt->
duration
;
65
int
size
, x1 = -1, y1 = -1, x2 = -1, y2 = -1;
66
const
uint8_t
*p;
67
68
p =
av_packet_get_side_data
(pkt,
AV_PKT_DATA_SUBTITLE_POSITION
, &size);
69
if
(p && size == 16) {
70
x1 =
AV_RL32
(p );
71
y1 =
AV_RL32
(p + 4);
72
x2 =
AV_RL32
(p + 8);
73
y2 =
AV_RL32
(p + 12);
74
}
75
76
if
(d <= 0)
77
/* For backward compatibility, fallback to convergence_duration. */
78
d = pkt->
convergence_duration
;
79
if
(s ==
AV_NOPTS_VALUE
|| d < 0) {
80
av_log
(avf,
AV_LOG_WARNING
,
81
"Insufficient timestamps in event number %d.\n"
, srt->
index
);
82
return
0;
83
}
84
e = s + d;
85
avio_printf
(avf->
pb
,
"%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d"
,
86
srt->
index
,
87
(
int
)(s / 3600000), (
int
)(s / 60000) % 60,
88
(
int
)(s / 1000) % 60, (
int
)(s % 1000),
89
(
int
)(e / 3600000), (
int
)(e / 60000) % 60,
90
(
int
)(e / 1000) % 60, (
int
)(e % 1000));
91
if
(p)
92
avio_printf
(avf->
pb
,
" X1:%03d X2:%03d Y1:%03d Y2:%03d"
,
93
x1, x2, y1, y2);
94
avio_printf
(avf->
pb
,
"\n"
);
95
96
avio_write
(avf->
pb
, pkt->
data
, pkt->
size
);
97
avio_write
(avf->
pb
,
"\n\n"
, 2);
98
srt->
index
++;
99
return
0;
100
}
101
102
AVOutputFormat
ff_srt_muxer
= {
103
.
name
=
"srt"
,
104
.long_name =
NULL_IF_CONFIG_SMALL
(
"SubRip subtitle"
),
105
.mime_type =
"application/x-subrip"
,
106
.extensions =
"srt"
,
107
.priv_data_size =
sizeof
(
SRTContext
),
108
.
write_header
=
srt_write_header
,
109
.
write_packet
=
srt_write_packet
,
110
.
flags
=
AVFMT_VARIABLE_FPS
|
AVFMT_TS_NONSTRICT
,
111
.subtitle_codec =
AV_CODEC_ID_SUBRIP
,
112
};
Generated on Fri Dec 5 2014 04:42:02 for FFmpeg by
1.8.2