libavcodec/assdec.c
Go to the documentation of this file.
1 /*
2  * SSA/ASS 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 <string.h>
23 
24 #include "avcodec.h"
25 #include "ass.h"
26 #include "ass_split.h"
27 #include "libavutil/internal.h"
28 #include "libavutil/mem.h"
29 
31 {
32  avctx->subtitle_header = av_malloc(avctx->extradata_size + 1);
33  if (!avctx->subtitle_header)
34  return AVERROR(ENOMEM);
35  memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size);
36  avctx->subtitle_header[avctx->extradata_size] = 0;
37  avctx->subtitle_header_size = avctx->extradata_size;
38  avctx->priv_data = ff_ass_split(avctx->extradata);
39  if(!avctx->priv_data)
40  return -1;
41  return 0;
42 }
43 
44 static int ass_decode_close(AVCodecContext *avctx)
45 {
47  avctx->priv_data = NULL;
48  return 0;
49 }
50 
51 #if CONFIG_SSA_DECODER
52 static int ssa_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr,
53  AVPacket *avpkt)
54 {
55  const char *ptr = avpkt->data;
56  int len, size = avpkt->size;
57 
58  while (size > 0) {
59  int duration;
60  ASSDialog *dialog = ff_ass_split_dialog(avctx->priv_data, ptr, 0, NULL);
61  if (!dialog)
62  return AVERROR_INVALIDDATA;
63  duration = dialog->end - dialog->start;
64  len = ff_ass_add_rect(data, ptr, 0, duration, 1);
65  if (len < 0)
66  return len;
67  ptr += len;
68  size -= len;
69  }
70 
71  *got_sub_ptr = avpkt->size > 0;
72  return avpkt->size;
73 }
74 
75 AVCodec ff_ssa_decoder = {
76  .name = "ssa",
77  .long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"),
78  .type = AVMEDIA_TYPE_SUBTITLE,
79  .id = AV_CODEC_ID_SSA,
80  .init = ass_decode_init,
81  .decode = ssa_decode_frame,
82  .close = ass_decode_close,
83 };
84 #endif
85 
86 #if CONFIG_ASS_DECODER
87 static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr,
88  AVPacket *avpkt)
89 {
90  int ret;
91  AVSubtitle *sub = data;
92  const char *ptr = avpkt->data;
93  static const AVRational ass_tb = {1, 100};
94  const int ts_start = av_rescale_q(avpkt->pts, avctx->time_base, ass_tb);
95  const int ts_duration = av_rescale_q(avpkt->duration, avctx->time_base, ass_tb);
96 
97  if (avpkt->size <= 0)
98  return avpkt->size;
99 
100  ret = ff_ass_add_rect(sub, ptr, ts_start, ts_duration, 2);
101  if (ret < 0) {
102  if (ret == AVERROR_INVALIDDATA)
103  av_log(avctx, AV_LOG_ERROR, "Invalid ASS packet\n");
104  return ret;
105  }
106 
107  *got_sub_ptr = avpkt->size > 0;
108  return avpkt->size;
109 }
110 
111 AVCodec ff_ass_decoder = {
112  .name = "ass",
113  .long_name = NULL_IF_CONFIG_SMALL("ASS (Advanced SubStation Alpha) subtitle"),
114  .type = AVMEDIA_TYPE_SUBTITLE,
115  .id = AV_CODEC_ID_ASS,
116  .init = ass_decode_init,
117  .decode = ass_decode_frame,
118  .close = ass_decode_close,
119 };
120 #endif
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
fields extracted from the [Events] section
Definition: ass_split.h:56
memory handling functions
ASSSplitContext * ff_ass_split(const char *buf)
Split a full ASS file or a ASS header from a string buffer and store the split structure in a newly a...
Definition: ass_split.c:303
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
static av_cold int ass_decode_init(AVCodecContext *avctx)
#define av_cold
Definition: attributes.h:78
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
uint8_t * data
static int64_t duration
Definition: ffplay.c:294
int duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
ASSDialog * ff_ass_split_dialog(ASSSplitContext *ctx, const char *buf, int cache, int *number)
Split one or several ASS "Dialogue" lines from a string buffer and store them in a already initialize...
Definition: ass_split.c:338
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 NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
int end
end time of the dialog in centiseconds
Definition: ass_split.h:59
external API header
int size
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
common internal API header
ret
Definition: avfilter.c:821
NULL
Definition: eval.c:55
main external API structure.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
int start
start time of the dialog in centiseconds
Definition: ass_split.h:58
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
static int ass_decode_close(AVCodecContext *avctx)
ASS as defined in Matroska.
int len
void ff_ass_split_free(ASSSplitContext *ctx)
Free all the memory allocated for an ASSSplitContext.
Definition: ass_split.c:357
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
uint8_t * subtitle_header
Header containing style information for text subtitles.