Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2017/01/27 21:58:11... | ... |
@@ -435,6 +435,7 @@ OBJS-$(CONFIG_SAP_DEMUXER) += sapdec.o |
435 | 435 |
OBJS-$(CONFIG_SAP_MUXER) += sapenc.o |
436 | 436 |
OBJS-$(CONFIG_SBG_DEMUXER) += sbgdec.o |
437 | 437 |
OBJS-$(CONFIG_SCC_DEMUXER) += sccdec.o subtitles.o |
438 |
+OBJS-$(CONFIG_SCC_MUXER) += sccenc.o subtitles.o |
|
438 | 439 |
OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o |
439 | 440 |
OBJS-$(CONFIG_SDR2_DEMUXER) += sdr2.o |
440 | 441 |
OBJS-$(CONFIG_SDS_DEMUXER) += sdsdec.o |
... | ... |
@@ -273,7 +273,7 @@ void av_register_all(void) |
273 | 273 |
REGISTER_DEMUXER (SAMI, sami); |
274 | 274 |
REGISTER_MUXDEMUX(SAP, sap); |
275 | 275 |
REGISTER_DEMUXER (SBG, sbg); |
276 |
- REGISTER_DEMUXER (SCC, scc); |
|
276 |
+ REGISTER_MUXDEMUX(SCC, scc); |
|
277 | 277 |
REGISTER_DEMUXER (SDP, sdp); |
278 | 278 |
REGISTER_DEMUXER (SDR2, sdr2); |
279 | 279 |
REGISTER_DEMUXER (SDS, sds); |
280 | 280 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,123 @@ |
0 |
+/* |
|
1 |
+ * SCC muxer |
|
2 |
+ * Copyright (c) 2017 Paul B Mahol |
|
3 |
+ * |
|
4 |
+ * This file is part of FFmpeg. |
|
5 |
+ * |
|
6 |
+ * FFmpeg is free software; you can redistribute it and/or |
|
7 |
+ * modify it under the terms of the GNU Lesser General Public |
|
8 |
+ * License as published by the Free Software Foundation; either |
|
9 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
10 |
+ * |
|
11 |
+ * FFmpeg is distributed in the hope that it will be useful, |
|
12 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
+ * Lesser General Public License for more details. |
|
15 |
+ * |
|
16 |
+ * You should have received a copy of the GNU Lesser General Public |
|
17 |
+ * License along with FFmpeg; if not, write to the Free Software |
|
18 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
19 |
+ */ |
|
20 |
+ |
|
21 |
+#include "avformat.h" |
|
22 |
+#include "internal.h" |
|
23 |
+#include "libavutil/log.h" |
|
24 |
+#include "libavutil/intreadwrite.h" |
|
25 |
+ |
|
26 |
+typedef struct SCCContext { |
|
27 |
+ int prev_h, prev_m, prev_s, prev_f; |
|
28 |
+ int inside; |
|
29 |
+ int n; |
|
30 |
+} SCCContext; |
|
31 |
+ |
|
32 |
+static int scc_write_header(AVFormatContext *avf) |
|
33 |
+{ |
|
34 |
+ SCCContext *scc = avf->priv_data; |
|
35 |
+ |
|
36 |
+ if (avf->nb_streams != 1 || |
|
37 |
+ avf->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) { |
|
38 |
+ av_log(avf, AV_LOG_ERROR, |
|
39 |
+ "SCC supports only a single subtitles stream.\n"); |
|
40 |
+ return AVERROR(EINVAL); |
|
41 |
+ } |
|
42 |
+ if (avf->streams[0]->codecpar->codec_id != AV_CODEC_ID_EIA_608) { |
|
43 |
+ av_log(avf, AV_LOG_ERROR, |
|
44 |
+ "Unsupported subtitles codec: %s\n", |
|
45 |
+ avcodec_get_name(avf->streams[0]->codecpar->codec_id)); |
|
46 |
+ return AVERROR(EINVAL); |
|
47 |
+ } |
|
48 |
+ avpriv_set_pts_info(avf->streams[0], 64, 1, 1000); |
|
49 |
+ avio_printf(avf->pb, "Scenarist_SCC V1.0\n"); |
|
50 |
+ |
|
51 |
+ scc->prev_h = scc->prev_m = scc->prev_s = scc->prev_f = -1; |
|
52 |
+ scc->inside = 0; |
|
53 |
+ |
|
54 |
+ return 0; |
|
55 |
+} |
|
56 |
+ |
|
57 |
+static int scc_write_packet(AVFormatContext *avf, AVPacket *pkt) |
|
58 |
+{ |
|
59 |
+ SCCContext *scc = avf->priv_data; |
|
60 |
+ int64_t pts = pkt->pts; |
|
61 |
+ int i, h, m, s, f; |
|
62 |
+ |
|
63 |
+ if (pts == AV_NOPTS_VALUE) { |
|
64 |
+ av_log(avf, AV_LOG_WARNING, |
|
65 |
+ "Insufficient timestamps.\n"); |
|
66 |
+ return 0; |
|
67 |
+ } |
|
68 |
+ |
|
69 |
+ h = (int)(pts / (3600000)); |
|
70 |
+ m = (int)(pts / (60000)) % 60; |
|
71 |
+ s = (int)(pts / 1000) % 60; |
|
72 |
+ f = (int)(pts % 1000) / 33; |
|
73 |
+ |
|
74 |
+ for (i = 0; i < pkt->size; i+=3) { |
|
75 |
+ if (pkt->data[i] == 0xfc && ((pkt->data[i + 1] != 0x80 || pkt->data[i + 2] != 0x80))) |
|
76 |
+ break; |
|
77 |
+ } |
|
78 |
+ if (i >= pkt->size) |
|
79 |
+ return 0; |
|
80 |
+ |
|
81 |
+ if (!scc->inside && (scc->prev_h != h || scc->prev_m != m || scc->prev_s != s || scc->prev_f != f)) { |
|
82 |
+ avio_printf(avf->pb, "\n%02d:%02d:%02d:%02d\t", h, m, s, f); |
|
83 |
+ scc->inside = 1; |
|
84 |
+ } |
|
85 |
+ for (i = 0; i < pkt->size; i+=3) { |
|
86 |
+ if (i + 3 > pkt->size) |
|
87 |
+ break; |
|
88 |
+ |
|
89 |
+ if (pkt->data[i] != 0xfc || (pkt->data[i + 1] == 0x80 && pkt->data[i + 2] == 0x80)) |
|
90 |
+ continue; |
|
91 |
+ if (!scc->inside) { |
|
92 |
+ avio_printf(avf->pb, "\n%02d:%02d:%02d:%02d\t", h, m, s, f); |
|
93 |
+ scc->inside = 1; |
|
94 |
+ } |
|
95 |
+ if (scc->n > 0) |
|
96 |
+ avio_printf(avf->pb, " "); |
|
97 |
+ avio_printf(avf->pb, "%02x%02x", pkt->data[i + 1], pkt->data[i + 2]); |
|
98 |
+ scc->n++; |
|
99 |
+ } |
|
100 |
+ if (scc->inside && (scc->prev_h != h || scc->prev_m != m || scc->prev_s != s || scc->prev_f != f)) { |
|
101 |
+ avio_printf(avf->pb, "\n"); |
|
102 |
+ scc->n = 0; |
|
103 |
+ scc->inside = 0; |
|
104 |
+ } |
|
105 |
+ |
|
106 |
+ scc->prev_h = h; |
|
107 |
+ scc->prev_m = m; |
|
108 |
+ scc->prev_s = s; |
|
109 |
+ scc->prev_f = f; |
|
110 |
+ return 0; |
|
111 |
+} |
|
112 |
+ |
|
113 |
+AVOutputFormat ff_scc_muxer = { |
|
114 |
+ .name = "scc", |
|
115 |
+ .long_name = NULL_IF_CONFIG_SMALL("Scenarist Closed Captions"), |
|
116 |
+ .extensions = "scc", |
|
117 |
+ .priv_data_size = sizeof(SCCContext), |
|
118 |
+ .write_header = scc_write_header, |
|
119 |
+ .write_packet = scc_write_packet, |
|
120 |
+ .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT, |
|
121 |
+ .subtitle_codec = AV_CODEC_ID_EIA_608, |
|
122 |
+}; |
... | ... |
@@ -32,7 +32,7 @@ |
32 | 32 |
// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) |
33 | 33 |
// Also please add any ticket numbers that you believe might be affected here |
34 | 34 |
#define LIBAVFORMAT_VERSION_MAJOR 57 |
35 |
-#define LIBAVFORMAT_VERSION_MINOR 65 |
|
35 |
+#define LIBAVFORMAT_VERSION_MINOR 66 |
|
36 | 36 |
#define LIBAVFORMAT_VERSION_MICRO 100 |
37 | 37 |
|
38 | 38 |
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |