movtextdec.c
Go to the documentation of this file.
1 /*
2  * 3GPP TS 26.245 Timed Text decoder
3  * Copyright (c) 2012 Philip Langdale <philipl@overt.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 "avcodec.h"
23 #include "ass.h"
24 #include "libavutil/avstring.h"
25 #include "libavutil/common.h"
26 #include "libavutil/bprint.h"
27 #include "libavutil/intreadwrite.h"
28 
29 static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end)
30 {
31  while (text < text_end) {
32  switch (*text) {
33  case '\r':
34  break;
35  case '\n':
36  av_bprintf(buf, "\\N");
37  break;
38  default:
39  av_bprint_chars(buf, *text, 1);
40  break;
41  }
42  text++;
43  }
44 
45  av_bprintf(buf, "\r\n");
46  return 0;
47 }
48 
49 static int mov_text_init(AVCodecContext *avctx) {
50  /*
51  * TODO: Handle the default text style.
52  * NB: Most players ignore styles completely, with the result that
53  * it's very common to find files where the default style is broken
54  * and respecting it results in a worse experience than ignoring it.
55  */
56  return ff_ass_subtitle_header_default(avctx);
57 }
58 
60  void *data, int *got_sub_ptr, AVPacket *avpkt)
61 {
62  AVSubtitle *sub = data;
63  int ts_start, ts_end;
64  AVBPrint buf;
65  const char *ptr = avpkt->data;
66  const char *end;
67 
68  if (!ptr || avpkt->size < 2)
69  return AVERROR_INVALIDDATA;
70 
71  /*
72  * A packet of size two with value zero is an empty subtitle
73  * used to mark the end of the previous non-empty subtitle.
74  * We can just drop them here as we have duration information
75  * already. If the value is non-zero, then it's technically a
76  * bad packet.
77  */
78  if (avpkt->size == 2)
79  return AV_RB16(ptr) == 0 ? 0 : AVERROR_INVALIDDATA;
80 
81  /*
82  * The first two bytes of the packet are the length of the text string
83  * In complex cases, there are style descriptors appended to the string
84  * so we can't just assume the packet size is the string size.
85  */
86  end = ptr + FFMIN(2 + AV_RB16(ptr), avpkt->size);
87  ptr += 2;
88 
89  ts_start = av_rescale_q(avpkt->pts,
90  avctx->time_base,
91  (AVRational){1,100});
92  ts_end = av_rescale_q(avpkt->pts + avpkt->duration,
93  avctx->time_base,
94  (AVRational){1,100});
95 
96  // Note that the spec recommends lines be no longer than 2048 characters.
98  text_to_ass(&buf, ptr, end);
99 
100  if (!av_bprint_is_complete(&buf))
101  return AVERROR(ENOMEM);
102 
103  ff_ass_add_rect(sub, buf.str, ts_start, ts_end-ts_start, 0);
104  *got_sub_ptr = sub->num_rects > 0;
105  av_bprint_finalize(&buf, NULL);
106  return avpkt->size;
107 }
108 
110  .name = "mov_text",
111  .long_name = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
112  .type = AVMEDIA_TYPE_SUBTITLE,
113  .id = AV_CODEC_ID_MOV_TEXT,
114  .init = mov_text_init,
115  .decode = mov_text_decode_frame,
116 };
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:93
text(-8, 1,'a)')
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:193
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
end end
int ff_ass_subtitle_header_default(AVCodecContext *avctx)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS with default style.
Definition: ass.c:54
static int mov_text_init(AVCodecContext *avctx)
Definition: movtextdec.c:49
uint8_t * data
int duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:130
#define AV_BPRINT_SIZE_UNLIMITED
Convenience macros for special values for av_bprint_init() size_max parameter.
Definition: bprint.h:89
#define AV_RB16
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Init a print buffer.
Definition: bprint.c:68
Spectrum Plot time data
static int av_bprint_is_complete(AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:166
const char * name
Name of the codec implementation.
external API header
int ff_ass_add_rect(AVSubtitle *sub, const char *dialog, int ts_start, int duration, int raw)
Add an ASS dialog line to an AVSubtitle as a new AVSubtitleRect.
Definition: ass.c:80
Buffer to print data progressively.
Definition: bprint.h:75
#define FFMIN(a, b)
Definition: common.h:58
NULL
Definition: eval.c:55
main external API structure.
static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end)
Definition: movtextdec.c:29
void * buf
Definition: avisynth_c.h:594
rational number numerator/denominator
Definition: rational.h:43
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
common internal and external API header
AVCodec ff_movtext_decoder
Definition: movtextdec.c:109
static int mov_text_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt)
Definition: movtextdec.c:59
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:116