FFmpeg
srtdec.c
Go to the documentation of this file.
1 /*
2  * SubRip subtitle decoder
3  * Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.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 "libavutil/avstring.h"
23 #include "libavutil/common.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/parseutils.h"
26 #include "avcodec.h"
27 #include "ass.h"
28 #include "htmlsubtitles.h"
29 
30 static int srt_to_ass(AVCodecContext *avctx, AVBPrint *dst,
31  const char *in, int x1, int y1, int x2, int y2)
32 {
33  if (x1 >= 0 && y1 >= 0) {
34  /* XXX: here we rescale coordinate assuming they are in DVD resolution
35  * (720x480) since we don't have anything better */
36 
37  if (x2 >= 0 && y2 >= 0 && (x2 != x1 || y2 != y1) && x2 >= x1 && y2 >= y1) {
38  /* text rectangle defined, write the text at the center of the rectangle */
39  const int cx = x1 + (x2 - x1)/2;
40  const int cy = y1 + (y2 - y1)/2;
41  const int scaled_x = cx * (int64_t)ASS_DEFAULT_PLAYRESX / 720;
42  const int scaled_y = cy * (int64_t)ASS_DEFAULT_PLAYRESY / 480;
43  av_bprintf(dst, "{\\an5}{\\pos(%d,%d)}", scaled_x, scaled_y);
44  } else {
45  /* only the top left corner, assume the text starts in that corner */
46  const int scaled_x = x1 * (int64_t)ASS_DEFAULT_PLAYRESX / 720;
47  const int scaled_y = y1 * (int64_t)ASS_DEFAULT_PLAYRESY / 480;
48  av_bprintf(dst, "{\\an1}{\\pos(%d,%d)}", scaled_x, scaled_y);
49  }
50  }
51 
52  return ff_htmlmarkup_to_ass(avctx, dst, in);
53 }
54 
55 static int srt_decode_frame(AVCodecContext *avctx,
56  void *data, int *got_sub_ptr, AVPacket *avpkt)
57 {
58  AVSubtitle *sub = data;
59  AVBPrint buffer;
60  int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
61  int size, ret;
64 
65  if (p && size == 16) {
66  x1 = AV_RL32(p );
67  y1 = AV_RL32(p + 4);
68  x2 = AV_RL32(p + 8);
69  y2 = AV_RL32(p + 12);
70  }
71 
72  if (avpkt->size <= 0)
73  return avpkt->size;
74 
76 
77  ret = srt_to_ass(avctx, &buffer, avpkt->data, x1, y1, x2, y2);
78  if (ret >= 0)
79  ret = ff_ass_add_rect(sub, buffer.str, s->readorder++, 0, NULL, NULL);
81  if (ret < 0)
82  return ret;
83 
84  *got_sub_ptr = sub->num_rects > 0;
85  return avpkt->size;
86 }
87 
88 #if CONFIG_SRT_DECODER
89 /* deprecated decoder */
91  .name = "srt",
92  .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
93  .type = AVMEDIA_TYPE_SUBTITLE,
94  .id = AV_CODEC_ID_SUBRIP,
96  .decode = srt_decode_frame,
97  .flush = ff_ass_decoder_flush,
98  .priv_data_size = sizeof(FFASSDecoderContext),
99 };
100 #endif
101 
102 #if CONFIG_SUBRIP_DECODER
104  .name = "subrip",
105  .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
106  .type = AVMEDIA_TYPE_SUBTITLE,
107  .id = AV_CODEC_ID_SUBRIP,
109  .decode = srt_decode_frame,
110  .flush = ff_ass_decoder_flush,
111  .priv_data_size = sizeof(FFASSDecoderContext),
112 };
113 #endif
AVSubtitle
Definition: avcodec.h:2694
AVCodec
AVCodec.
Definition: codec.h:190
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
ff_ass_subtitle_header_default
int ff_ass_subtitle_header_default(AVCodecContext *avctx)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS with default style.
Definition: ass.c:97
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
htmlsubtitles.h
AVSubtitle::num_rects
unsigned num_rects
Definition: avcodec.h:2698
ff_ass_add_rect
int ff_ass_add_rect(AVSubtitle *sub, const char *dialog, int readorder, int layer, const char *style, const char *speaker)
Add an ASS dialog to a subtitle.
Definition: ass.c:118
AVPacket::data
uint8_t * data
Definition: packet.h:355
data
const char data[16]
Definition: mxf.c:91
ass.h
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
srt_to_ass
static int srt_to_ass(AVCodecContext *avctx, AVBPrint *dst, const char *in, int x1, int y1, int x2, int y2)
Definition: srtdec.c:30
av_packet_get_side_data
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, int *size)
Get side information from packet.
Definition: avpacket.c:353
NULL
#define NULL
Definition: coverity.c:32
parseutils.h
ASS_DEFAULT_PLAYRESY
#define ASS_DEFAULT_PLAYRESY
Definition: ass.h:29
AV_PKT_DATA_SUBTITLE_POSITION
@ AV_PKT_DATA_SUBTITLE_POSITION
Subtitle event position.
Definition: packet.h:183
AVPacket::size
int size
Definition: packet.h:356
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:188
size
int size
Definition: twinvq_data.h:11134
ASS_DEFAULT_PLAYRESX
#define ASS_DEFAULT_PLAYRESX
Definition: ass.h:28
ff_subrip_decoder
AVCodec ff_subrip_decoder
ff_ass_decoder_flush
void ff_ass_decoder_flush(AVCodecContext *avctx)
Helper to flush a text subtitles decoder making use of the FFASSDecoderContext.
Definition: ass.c:141
in
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Definition: audio_convert.c:326
AV_CODEC_ID_SUBRIP
@ AV_CODEC_ID_SUBRIP
Definition: codec_id.h:526
common.h
ff_htmlmarkup_to_ass
int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in)
Definition: htmlsubtitles.c:129
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:197
avcodec.h
ret
ret
Definition: filter_design.txt:187
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:88
srt_decode_frame
static int srt_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt)
Definition: srtdec.c:55
AVCodecContext
main external API structure.
Definition: avcodec.h:526
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:553
AVPacket
This structure stores compressed data.
Definition: packet.h:332
FFASSDecoderContext
Definition: ass.h:46
avstring.h
ff_srt_decoder
AVCodec ff_srt_decoder