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
lrcenc.c
Go to the documentation of this file.
1
/*
2
* LRC lyrics file format decoder
3
* Copyright (c) 2014 StarBrilliant <m13253@hotmail.com>
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 <inttypes.h>
23
#include <stdint.h>
24
#include <string.h>
25
26
#include "
avformat.h
"
27
#include "
internal.h
"
28
#include "
lrc.h
"
29
#include "
metadata.h
"
30
#include "
subtitles.h
"
31
#include "
version.h
"
32
#include "
libavutil/bprint.h
"
33
#include "
libavutil/dict.h
"
34
#include "
libavutil/log.h
"
35
#include "
libavutil/macros.h
"
36
37
static
int
lrc_write_header
(
AVFormatContext
*
s
)
38
{
39
const
AVDictionaryEntry
*metadata_item;
40
41
if
(s->
nb_streams
!= 1 ||
42
s->
streams
[0]->
codec
->
codec_type
!=
AVMEDIA_TYPE_SUBTITLE
) {
43
av_log
(s,
AV_LOG_ERROR
,
44
"LRC supports only a single subtitle stream.\n"
);
45
return
AVERROR
(EINVAL);
46
}
47
if
(s->
streams
[0]->
codec
->
codec_id
!=
AV_CODEC_ID_SUBRIP
&&
48
s->
streams
[0]->
codec
->
codec_id
!=
AV_CODEC_ID_TEXT
) {
49
av_log
(s,
AV_LOG_ERROR
,
"Unsupported subtitle codec: %s\n"
,
50
avcodec_get_name
(s->
streams
[0]->
codec
->
codec_id
));
51
return
AVERROR
(EINVAL);
52
}
53
avpriv_set_pts_info
(s->
streams
[0], 64, 1, 100);
54
55
ff_metadata_conv_ctx
(s,
ff_lrc_metadata_conv
,
NULL
);
56
if
(!(s->
flags
&
AVFMT_FLAG_BITEXACT
)) {
// avoid breaking regression tests
57
/* LRC provides a metadata slot for specifying encoder version
58
* in addition to encoder name. We will store LIBAVFORMAT_VERSION
59
* to it.
60
*/
61
av_dict_set
(&s->
metadata
,
"ve"
,
AV_STRINGIFY
(
LIBAVFORMAT_VERSION
), 0);
62
}
else
{
63
av_dict_set
(&s->
metadata
,
"ve"
,
NULL
, 0);
64
}
65
for
(metadata_item =
NULL
;
66
(metadata_item =
av_dict_get
(s->
metadata
,
""
, metadata_item,
67
AV_DICT_IGNORE_SUFFIX
));) {
68
char
*delim;
69
if
(!metadata_item->
value
[0]) {
70
continue
;
71
}
72
while
((delim = strchr(metadata_item->
value
,
'\n'
))) {
73
*delim =
' '
;
74
}
75
while
((delim = strchr(metadata_item->
value
,
'\r'
))) {
76
*delim =
' '
;
77
}
78
avio_printf
(s->
pb
,
"[%s:%s]\n"
,
79
metadata_item->
key
, metadata_item->
value
);
80
}
81
avio_printf
(s->
pb
,
"\n"
);
82
return
0;
83
}
84
85
static
int
lrc_write_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
86
{
87
if
(pkt->
pts
!=
AV_NOPTS_VALUE
) {
88
char
*
data
=
av_malloc
(pkt->
size
+ 1);
89
char
*
line
;
90
char
*delim;
91
92
if
(!data) {
93
return
AVERROR
(ENOMEM);
94
}
95
memcpy(data, pkt->
data
, pkt->
size
);
96
data[pkt->
size
] =
'\0'
;
97
98
for
(delim = data + pkt->
size
- 1;
99
delim >= data && (delim[0] ==
'\n'
|| delim[0] ==
'\r'
); delim--) {
100
delim[0] =
'\0'
;
// Strip last empty lines
101
}
102
line =
data
;
103
while
(line[0] ==
'\n'
|| line[0] ==
'\r'
) {
104
line++;
// Skip first empty lines
105
}
106
107
while
(line) {
108
delim = strchr(line,
'\n'
);
109
if
(delim) {
110
if
(delim > line && delim[-1] ==
'\r'
) {
111
delim[-1] =
'\0'
;
112
}
113
delim[0] =
'\0'
;
114
delim++;
115
}
116
if
(line[0] ==
'['
) {
117
av_log
(s,
AV_LOG_WARNING
,
118
"Subtitle starts with '[', may cause problems with LRC format.\n"
);
119
}
120
121
if
(pkt->
pts
>= 0) {
122
avio_printf
(s->
pb
,
"[%02"
PRId64
":%02"
PRId64
".%02"
PRId64
"]"
,
123
(pkt->
pts
/ 6000),
124
((pkt->
pts
/ 100) % 60),
125
(pkt->
pts
% 100));
126
}
else
{
127
/* Offset feature of LRC can easily make pts negative,
128
* we just output it directly and let the player drop it. */
129
avio_printf
(s->
pb
,
"[-%02"
PRId64
":%02"
PRId64
".%02"
PRId64
"]"
,
130
(-pkt->
pts
) / 6000,
131
((-pkt->
pts
) / 100) % 60,
132
(-pkt->
pts
) % 100);
133
}
134
avio_printf
(s->
pb
,
"%s\n"
, line);
135
line = delim;
136
}
137
av_free
(data);
138
}
139
return
0;
140
}
141
142
AVOutputFormat
ff_lrc_muxer
= {
143
.
name
=
"lrc"
,
144
.long_name =
NULL_IF_CONFIG_SMALL
(
"LRC lyrics"
),
145
.extensions =
"lrc"
,
146
.priv_data_size = 0,
147
.write_header =
lrc_write_header
,
148
.write_packet =
lrc_write_packet
,
149
.flags =
AVFMT_VARIABLE_FPS
|
AVFMT_GLOBALHEADER
|
150
AVFMT_TS_NEGATIVE
|
AVFMT_TS_NONSTRICT
,
151
.subtitle_codec =
AV_CODEC_ID_SUBRIP
152
};
Generated on Sun Mar 8 2015 02:35:10 for FFmpeg by
1.8.2