FFmpeg
sccenc.c
Go to the documentation of this file.
1 /*
2  * SCC muxer
3  * Copyright (c) 2017 Paul B Mahol
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 "mux.h"
25 #include "libavutil/log.h"
26 #include "libavutil/intreadwrite.h"
27 
28 typedef struct SCCContext {
30  int inside;
31  int n;
32 } SCCContext;
33 
35 {
36  SCCContext *scc = avf->priv_data;
37 
38  avpriv_set_pts_info(avf->streams[0], 64, 1, 1000);
39  avio_printf(avf->pb, "Scenarist_SCC V1.0\n");
40 
41  scc->prev_h = scc->prev_m = scc->prev_s = scc->prev_f = -1;
42  scc->inside = 0;
43 
44  return 0;
45 }
46 
48 {
49  SCCContext *scc = avf->priv_data;
50  int64_t pts = pkt->pts;
51  int i, h, m, s, f;
52 
53  if (pts == AV_NOPTS_VALUE) {
55  "Insufficient timestamps.\n");
56  return 0;
57  }
58 
59  h = (int)(pts / (3600000));
60  m = (int)(pts / (60000)) % 60;
61  s = (int)(pts / 1000) % 60;
62  f = (int)(pts % 1000) / 33;
63 
64  for (i = 0; i < pkt->size - 2; i+=3) {
65  if (pkt->data[i] == 0xfc && ((pkt->data[i + 1] != 0x80 || pkt->data[i + 2] != 0x80)))
66  break;
67  }
68  if (i >= pkt->size - 2)
69  return 0;
70 
71  if (!scc->inside && (scc->prev_h != h || scc->prev_m != m || scc->prev_s != s || scc->prev_f != f)) {
72  avio_printf(avf->pb, "\n%02d:%02d:%02d:%02d\t", h, m, s, f);
73  scc->inside = 1;
74  }
75  for (i = 0; i < pkt->size; i+=3) {
76  if (i + 3 > pkt->size)
77  break;
78 
79  if (pkt->data[i] != 0xfc || (pkt->data[i + 1] == 0x80 && pkt->data[i + 2] == 0x80))
80  continue;
81  if (!scc->inside) {
82  avio_printf(avf->pb, "\n%02d:%02d:%02d:%02d\t", h, m, s, f);
83  scc->inside = 1;
84  }
85  if (scc->n > 0)
86  avio_w8(avf->pb, ' ');
87  avio_printf(avf->pb, "%02x%02x", pkt->data[i + 1], pkt->data[i + 2]);
88  scc->n++;
89  }
90  if (scc->inside && (scc->prev_h != h || scc->prev_m != m || scc->prev_s != s || scc->prev_f != f)) {
91  avio_w8(avf->pb, '\n');
92  scc->n = 0;
93  scc->inside = 0;
94  }
95 
96  scc->prev_h = h;
97  scc->prev_m = m;
98  scc->prev_s = s;
99  scc->prev_f = f;
100  return 0;
101 }
102 
104  .p.name = "scc",
105  .p.long_name = NULL_IF_CONFIG_SMALL("Scenarist Closed Captions"),
106  .p.extensions = "scc",
108  .p.video_codec = AV_CODEC_ID_NONE,
109  .p.audio_codec = AV_CODEC_ID_NONE,
110  .p.subtitle_codec = AV_CODEC_ID_EIA_608,
111  .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH |
113  .priv_data_size = sizeof(SCCContext),
116 };
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:566
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
AVOutputFormat::name
const char * name
Definition: avformat.h:510
scc_write_packet
static int scc_write_packet(AVFormatContext *avf, AVPacket *pkt)
Definition: sccenc.c:47
AVFMT_VARIABLE_FPS
#define AVFMT_VARIABLE_FPS
Format allows variable fps.
Definition: avformat.h:482
int64_t
long long int64_t
Definition: coverity.c:34
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1368
AVPacket::data
uint8_t * data
Definition: packet.h:539
SCCContext::prev_h
int prev_h
Definition: sccenc.c:29
FF_OFMT_FLAG_ONLY_DEFAULT_CODECS
#define FF_OFMT_FLAG_ONLY_DEFAULT_CODECS
If this flag is set, then the only permitted audio/video/subtitle codec ids are AVOutputFormat....
Definition: mux.h:59
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:867
pts
static int64_t pts
Definition: transcode_aac.c:644
SCCContext
Definition: sccdec.c:29
pkt
AVPacket * pkt
Definition: movenc.c:60
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
SCCContext::prev_m
int prev_m
Definition: sccenc.c:29
AVFormatContext
Format I/O context.
Definition: avformat.h:1300
internal.h
ff_scc_muxer
const FFOutputFormat ff_scc_muxer
Definition: sccenc.c:103
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1342
FFOutputFormat
Definition: mux.h:61
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:179
SCCContext::n
int n
Definition: sccenc.c:31
f
f
Definition: af_crystalizer.c:122
AVPacket::size
int size
Definition: packet.h:540
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
log.h
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:478
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:532
FF_OFMT_FLAG_MAX_ONE_OF_EACH
#define FF_OFMT_FLAG_MAX_ONE_OF_EACH
If this flag is set, it indicates that for each codec type whose corresponding default codec (i....
Definition: mux.h:50
write_packet
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:209
AVFMT_TS_NONSTRICT
#define AVFMT_TS_NONSTRICT
Format does not require strictly increasing timestamps, but they must still be monotonic.
Definition: avformat.h:491
SCCContext::prev_s
int prev_s
Definition: sccenc.c:29
avformat.h
avio_printf
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
scc_write_header
static int scc_write_header(AVFormatContext *avf)
Definition: sccenc.c:34
SCCContext::inside
int inside
Definition: sccenc.c:30
AVPacket
This structure stores compressed data.
Definition: packet.h:516
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2070
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:348
SCCContext::prev_f
int prev_f
Definition: sccenc.c:29
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1328
mux.h