FFmpeg
supenc.c
Go to the documentation of this file.
1 /*
2  * SUP muxer
3  * Copyright (c) 2014 Petri Hintukainen <phintuka@users.sourceforge.net>
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/intreadwrite.h"
26 
27 #define SUP_PGS_MAGIC 0x5047 /* "PG", big endian */
28 
30 {
31  const uint8_t *data = pkt->data;
32  size_t size = pkt->size;
33  uint32_t pts = 0, dts = 0;
34 
35  if (pkt->pts != AV_NOPTS_VALUE) {
36  pts = pkt->pts;
37  }
38  if (pkt->dts != AV_NOPTS_VALUE) {
39  dts = pkt->dts;
40  }
41 
42  /*
43  Split frame to segments.
44  mkvmerge stores multiple segments in one frame.
45  */
46  while (size > 2) {
47  size_t len = AV_RB16(data + 1) + 3;
48 
49  if (len > size) {
50  av_log(s, AV_LOG_ERROR, "Not enough data, skipping %"SIZE_SPECIFIER" bytes\n",
51  size);
52  return AVERROR_INVALIDDATA;
53  }
54 
55  /* header */
57  avio_wb32(s->pb, pts);
58  avio_wb32(s->pb, dts);
59 
60  avio_write(s->pb, data, len);
61 
62  data += len;
63  size -= len;
64  }
65 
66  if (size > 0) {
67  av_log(s, AV_LOG_ERROR, "Skipping %"SIZE_SPECIFIER" bytes after last segment in frame\n",
68  size);
69  return AVERROR_INVALIDDATA;
70  }
71 
72  return 0;
73 }
74 
76 {
77  avpriv_set_pts_info(s->streams[0], 32, 1, 90000);
78 
79  return 0;
80 }
81 
83  .p.name = "sup",
84  .p.long_name = NULL_IF_CONFIG_SMALL("raw HDMV Presentation Graphic Stream subtitles"),
85  .p.extensions = "sup",
86  .p.mime_type = "application/x-pgs",
87  .p.video_codec = AV_CODEC_ID_NONE,
88  .p.audio_codec = AV_CODEC_ID_NONE,
89  .p.subtitle_codec = AV_CODEC_ID_HDMV_PGS_SUBTITLE,
91  .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
92  .init = sup_init,
93  .write_packet = sup_write_packet,
94 };
AVOutputFormat::name
const char * name
Definition: avformat.h:510
AVFMT_VARIABLE_FPS
#define AVFMT_VARIABLE_FPS
Format allows variable fps.
Definition: avformat.h:482
AVPacket::data
uint8_t * data
Definition: packet.h:522
data
const char data[16]
Definition: mxf.c:148
AV_CODEC_ID_HDMV_PGS_SUBTITLE
@ AV_CODEC_ID_HDMV_PGS_SUBTITLE
Definition: codec_id.h:555
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:853
pts
static int64_t pts
Definition: transcode_aac.c:643
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
internal.h
ff_sup_muxer
const FFOutputFormat ff_sup_muxer
Definition: supenc.c:82
FFOutputFormat
Definition: mux.h:61
AVPacket::size
int size
Definition: packet.h:523
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:106
SUP_PGS_MAGIC
#define SUP_PGS_MAGIC
Definition: supenc.c:27
size
int size
Definition: twinvq_data.h:10344
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:521
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:200
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:364
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:515
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
len
int len
Definition: vorbis_enc_data.h:426
AVFMT_TS_NONSTRICT
#define AVFMT_TS_NONSTRICT
Format does not require strictly increasing timestamps, but they must still be monotonic.
Definition: avformat.h:491
avformat.h
SIZE_SPECIFIER
#define SIZE_SPECIFIER
Definition: internal.h:141
sup_init
static av_cold int sup_init(AVFormatContext *s)
Definition: supenc.c:75
sup_write_packet
static int sup_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: supenc.c:29
AVPacket
This structure stores compressed data.
Definition: packet.h:499
avio_wb16
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:442
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
mux.h