1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2012 Clément Bœsch
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#ifndef AVFORMAT_SUBTITLES_H
22cabdff1aSopenharmony_ci#define AVFORMAT_SUBTITLES_H
23cabdff1aSopenharmony_ci
24cabdff1aSopenharmony_ci#include <stdint.h>
25cabdff1aSopenharmony_ci#include <stddef.h>
26cabdff1aSopenharmony_ci#include "avformat.h"
27cabdff1aSopenharmony_ci#include "libavutil/bprint.h"
28cabdff1aSopenharmony_ci#include "avio_internal.h"
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_cienum sub_sort {
31cabdff1aSopenharmony_ci    SUB_SORT_TS_POS = 0,    ///< sort by timestamps, then position
32cabdff1aSopenharmony_ci    SUB_SORT_POS_TS,        ///< sort by position, then timestamps
33cabdff1aSopenharmony_ci};
34cabdff1aSopenharmony_ci
35cabdff1aSopenharmony_cienum ff_utf_type {
36cabdff1aSopenharmony_ci    FF_UTF_8,       // or other 8 bit encodings
37cabdff1aSopenharmony_ci    FF_UTF16LE,
38cabdff1aSopenharmony_ci    FF_UTF16BE,
39cabdff1aSopenharmony_ci};
40cabdff1aSopenharmony_ci
41cabdff1aSopenharmony_citypedef struct {
42cabdff1aSopenharmony_ci    int type;
43cabdff1aSopenharmony_ci    AVIOContext *pb;
44cabdff1aSopenharmony_ci    unsigned char buf[8];
45cabdff1aSopenharmony_ci    int buf_pos, buf_len;
46cabdff1aSopenharmony_ci    FFIOContext buf_pb;
47cabdff1aSopenharmony_ci} FFTextReader;
48cabdff1aSopenharmony_ci
49cabdff1aSopenharmony_ci/**
50cabdff1aSopenharmony_ci * Initialize the FFTextReader from the given AVIOContext. This function will
51cabdff1aSopenharmony_ci * read some bytes from pb, and test for UTF-8 or UTF-16 BOMs. Further accesses
52cabdff1aSopenharmony_ci * to FFTextReader will read more data from pb.
53cabdff1aSopenharmony_ci * If s is not NULL, the user will be warned if a UTF-16 conversion takes place.
54cabdff1aSopenharmony_ci *
55cabdff1aSopenharmony_ci * The purpose of FFTextReader is to transparently convert read data to UTF-8
56cabdff1aSopenharmony_ci * if the stream had a UTF-16 BOM.
57cabdff1aSopenharmony_ci *
58cabdff1aSopenharmony_ci * @param s Pointer to provide av_log context
59cabdff1aSopenharmony_ci * @param r object which will be initialized
60cabdff1aSopenharmony_ci * @param pb stream to read from (referenced as long as FFTextReader is in use)
61cabdff1aSopenharmony_ci */
62cabdff1aSopenharmony_civoid ff_text_init_avio(void *s, FFTextReader *r, AVIOContext *pb);
63cabdff1aSopenharmony_ci
64cabdff1aSopenharmony_ci/**
65cabdff1aSopenharmony_ci * Similar to ff_text_init_avio(), but sets it up to read from a bounded buffer.
66cabdff1aSopenharmony_ci *
67cabdff1aSopenharmony_ci * @param r object which will be initialized
68cabdff1aSopenharmony_ci * @param buf buffer to read from (referenced as long as FFTextReader is in use)
69cabdff1aSopenharmony_ci * @param size size of buf
70cabdff1aSopenharmony_ci */
71cabdff1aSopenharmony_civoid ff_text_init_buf(FFTextReader *r, void *buf, size_t size);
72cabdff1aSopenharmony_ci
73cabdff1aSopenharmony_ci/**
74cabdff1aSopenharmony_ci * Return the byte position of the next byte returned by ff_text_r8(). For
75cabdff1aSopenharmony_ci * UTF-16 source streams, this will return the original position, but it will
76cabdff1aSopenharmony_ci * be incorrect if a codepoint was only partially read with ff_text_r8().
77cabdff1aSopenharmony_ci */
78cabdff1aSopenharmony_ciint64_t ff_text_pos(FFTextReader *r);
79cabdff1aSopenharmony_ci
80cabdff1aSopenharmony_ci/**
81cabdff1aSopenharmony_ci * Return the next byte. The return value is always 0 - 255. Returns 0 on EOF.
82cabdff1aSopenharmony_ci * If the source stream is UTF-16, this reads from the stream converted to
83cabdff1aSopenharmony_ci * UTF-8. On invalid UTF-16, 0 is returned.
84cabdff1aSopenharmony_ci */
85cabdff1aSopenharmony_ciint ff_text_r8(FFTextReader *r);
86cabdff1aSopenharmony_ci
87cabdff1aSopenharmony_ci/**
88cabdff1aSopenharmony_ci * Return non-zero if EOF was reached.
89cabdff1aSopenharmony_ci */
90cabdff1aSopenharmony_ciint ff_text_eof(FFTextReader *r);
91cabdff1aSopenharmony_ci
92cabdff1aSopenharmony_ci/**
93cabdff1aSopenharmony_ci * Like ff_text_r8(), but don't remove the byte from the buffer.
94cabdff1aSopenharmony_ci */
95cabdff1aSopenharmony_ciint ff_text_peek_r8(FFTextReader *r);
96cabdff1aSopenharmony_ci
97cabdff1aSopenharmony_ci/**
98cabdff1aSopenharmony_ci * Read the given number of bytes (in UTF-8). On error or EOF, \0 bytes are
99cabdff1aSopenharmony_ci * written.
100cabdff1aSopenharmony_ci */
101cabdff1aSopenharmony_civoid ff_text_read(FFTextReader *r, char *buf, size_t size);
102cabdff1aSopenharmony_ci
103cabdff1aSopenharmony_citypedef struct {
104cabdff1aSopenharmony_ci    AVPacket **subs;         ///< array of subtitles packets
105cabdff1aSopenharmony_ci    int nb_subs;            ///< number of subtitles packets
106cabdff1aSopenharmony_ci    int allocated_size;     ///< allocated size for subs
107cabdff1aSopenharmony_ci    int current_sub_idx;    ///< current position for the read packet callback
108cabdff1aSopenharmony_ci    enum sub_sort sort;     ///< sort method to use when finalizing subtitles
109cabdff1aSopenharmony_ci    int keep_duplicates;    ///< set to 1 to keep duplicated subtitle events
110cabdff1aSopenharmony_ci} FFDemuxSubtitlesQueue;
111cabdff1aSopenharmony_ci
112cabdff1aSopenharmony_ci/**
113cabdff1aSopenharmony_ci * Insert a new subtitle event.
114cabdff1aSopenharmony_ci *
115cabdff1aSopenharmony_ci * @param event the subtitle line, may not be zero terminated
116cabdff1aSopenharmony_ci * @param len   the length of the event (in strlen() sense, so without '\0')
117cabdff1aSopenharmony_ci * @param merge set to 1 if the current event should be concatenated with the
118cabdff1aSopenharmony_ci *              previous one instead of adding a new entry, 0 otherwise
119cabdff1aSopenharmony_ci */
120cabdff1aSopenharmony_ciAVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q,
121cabdff1aSopenharmony_ci                                    const uint8_t *event, size_t len, int merge);
122cabdff1aSopenharmony_ci
123cabdff1aSopenharmony_ci/**
124cabdff1aSopenharmony_ci * Set missing durations, sort subtitles by PTS (and then byte position), and
125cabdff1aSopenharmony_ci * drop duplicated events.
126cabdff1aSopenharmony_ci */
127cabdff1aSopenharmony_civoid ff_subtitles_queue_finalize(void *log_ctx, FFDemuxSubtitlesQueue *q);
128cabdff1aSopenharmony_ci
129cabdff1aSopenharmony_ci/**
130cabdff1aSopenharmony_ci * Generic read_packet() callback for subtitles demuxers using this queue
131cabdff1aSopenharmony_ci * system.
132cabdff1aSopenharmony_ci */
133cabdff1aSopenharmony_ciint ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt);
134cabdff1aSopenharmony_ci
135cabdff1aSopenharmony_ci/**
136cabdff1aSopenharmony_ci * Update current_sub_idx to emulate a seek. Except the first parameter, it
137cabdff1aSopenharmony_ci * matches AVInputFormat->read_seek2 prototypes.
138cabdff1aSopenharmony_ci */
139cabdff1aSopenharmony_ciint ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int stream_index,
140cabdff1aSopenharmony_ci                            int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
141cabdff1aSopenharmony_ci
142cabdff1aSopenharmony_ci/**
143cabdff1aSopenharmony_ci * Remove and destroy all the subtitles packets.
144cabdff1aSopenharmony_ci */
145cabdff1aSopenharmony_civoid ff_subtitles_queue_clean(FFDemuxSubtitlesQueue *q);
146cabdff1aSopenharmony_ci
147cabdff1aSopenharmony_ciint ff_subtitles_read_packet(AVFormatContext *s, AVPacket *pkt);
148cabdff1aSopenharmony_ci
149cabdff1aSopenharmony_ciint ff_subtitles_read_seek(AVFormatContext *s, int stream_index,
150cabdff1aSopenharmony_ci                           int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
151cabdff1aSopenharmony_ci
152cabdff1aSopenharmony_ciint ff_subtitles_read_close(AVFormatContext *s);
153cabdff1aSopenharmony_ci
154cabdff1aSopenharmony_ci/**
155cabdff1aSopenharmony_ci * SMIL helper to load next chunk ("<...>" or untagged content) in buf.
156cabdff1aSopenharmony_ci *
157cabdff1aSopenharmony_ci * @param c cached character, to avoid a backward seek
158cabdff1aSopenharmony_ci */
159cabdff1aSopenharmony_ciint ff_smil_extract_next_text_chunk(FFTextReader *tr, AVBPrint *buf, char *c);
160cabdff1aSopenharmony_ci
161cabdff1aSopenharmony_ci/**
162cabdff1aSopenharmony_ci * SMIL helper to point on the value of an attribute in the given tag.
163cabdff1aSopenharmony_ci *
164cabdff1aSopenharmony_ci * @param s    SMIL tag ("<...>")
165cabdff1aSopenharmony_ci * @param attr the attribute to look for
166cabdff1aSopenharmony_ci */
167cabdff1aSopenharmony_ciconst char *ff_smil_get_attr_ptr(const char *s, const char *attr);
168cabdff1aSopenharmony_ci
169cabdff1aSopenharmony_ci/**
170cabdff1aSopenharmony_ci * @brief Same as ff_subtitles_read_text_chunk(), but read from an AVIOContext.
171cabdff1aSopenharmony_ci */
172cabdff1aSopenharmony_civoid ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf);
173cabdff1aSopenharmony_ci
174cabdff1aSopenharmony_ci/**
175cabdff1aSopenharmony_ci * @brief Read a subtitles chunk from FFTextReader.
176cabdff1aSopenharmony_ci *
177cabdff1aSopenharmony_ci * A chunk is defined by a multiline "event", ending with a second line break.
178cabdff1aSopenharmony_ci * The trailing line breaks are trimmed. CRLF are supported.
179cabdff1aSopenharmony_ci * Example: "foo\r\nbar\r\n\r\nnext" will print "foo\r\nbar" into buf, and pb
180cabdff1aSopenharmony_ci * will focus on the 'n' of the "next" string.
181cabdff1aSopenharmony_ci *
182cabdff1aSopenharmony_ci * @param tr  I/O context
183cabdff1aSopenharmony_ci * @param buf an initialized buf where the chunk is written
184cabdff1aSopenharmony_ci *
185cabdff1aSopenharmony_ci * @note buf is cleared before writing into it.
186cabdff1aSopenharmony_ci */
187cabdff1aSopenharmony_civoid ff_subtitles_read_text_chunk(FFTextReader *tr, AVBPrint *buf);
188cabdff1aSopenharmony_ci
189cabdff1aSopenharmony_ci/**
190cabdff1aSopenharmony_ci * Get the number of characters to increment to jump to the next line, or to
191cabdff1aSopenharmony_ci * the end of the string.
192cabdff1aSopenharmony_ci * The function handles the following line breaks schemes:
193cabdff1aSopenharmony_ci * LF, CRLF (MS), or standalone CR (old MacOS).
194cabdff1aSopenharmony_ci */
195cabdff1aSopenharmony_cistatic av_always_inline int ff_subtitles_next_line(const char *ptr)
196cabdff1aSopenharmony_ci{
197cabdff1aSopenharmony_ci    int n = strcspn(ptr, "\r\n");
198cabdff1aSopenharmony_ci    ptr += n;
199cabdff1aSopenharmony_ci    while (*ptr == '\r') {
200cabdff1aSopenharmony_ci        ptr++;
201cabdff1aSopenharmony_ci        n++;
202cabdff1aSopenharmony_ci    }
203cabdff1aSopenharmony_ci    if (*ptr == '\n')
204cabdff1aSopenharmony_ci        n++;
205cabdff1aSopenharmony_ci    return n;
206cabdff1aSopenharmony_ci}
207cabdff1aSopenharmony_ci
208cabdff1aSopenharmony_ci/**
209cabdff1aSopenharmony_ci * Read a line of text. Discards line ending characters.
210cabdff1aSopenharmony_ci * The function handles the following line breaks schemes:
211cabdff1aSopenharmony_ci * LF, CRLF (MS), or standalone CR (old MacOS).
212cabdff1aSopenharmony_ci *
213cabdff1aSopenharmony_ci * Returns the number of bytes written to buf. Always writes a terminating 0,
214cabdff1aSopenharmony_ci * similar as with snprintf.
215cabdff1aSopenharmony_ci *
216cabdff1aSopenharmony_ci * @note returns a negative error code if a \0 byte is found
217cabdff1aSopenharmony_ci */
218cabdff1aSopenharmony_ciptrdiff_t ff_subtitles_read_line(FFTextReader *tr, char *buf, size_t size);
219cabdff1aSopenharmony_ci
220cabdff1aSopenharmony_ci#endif /* AVFORMAT_SUBTITLES_H */
221