26 #define SCREEN_ROWS 15 27 #define SCREEN_COLUMNS 32 29 #define SET_FLAG(var, val) ( (var) |= ( 1 << (val)) ) 30 #define UNSET_FLAG(var, val) ( (var) &= ~( 1 << (val)) ) 31 #define CHECK_FLAG(var, val) ( (var) & ( 1 << (val)) ) 254 int64_t buffer_time[2];
364 uint8_t cc_valid = (*cc_data_pair & 4) >>2;
365 uint8_t cc_type = *cc_data_pair & 3;
367 *hi = cc_data_pair[1];
373 if (cc_type==0 || cc_type==1) {
383 if ((cc_data_pair[0] == 0xFA || cc_data_pair[0] == 0xFC || cc_data_pair[0] == 0xFD)
384 && (cc_data_pair[1] & 0x7F) == 0 && (cc_data_pair[2] & 0x7F) == 0)
388 if (cc_type == 3 || cc_type == 2)
426 if (i > ctx->
cursor_row - keep_lines && i <= ctx->cursor_row)
431 for (i = 0; i < keep_lines && screen->
row_used; i++) {
432 const int i_row = ctx->
cursor_row - keep_lines + i + 1;
461 const char *charset = screen->
charsets[
i];
474 const char *font = screen->
fonts[
i];
475 const char *bg = screen->
bgs[
i];
477 const char *charset = screen->
charsets[
i];
478 const char *
override;
479 int x, y, seen_char = 0;
491 const char *e_tag =
"", *s_tag =
"", *c_tag =
"", *b_tag =
"";
496 if (prev_font != font[j]) {
505 e_tag =
"{\\u0}{\\i0}";
516 s_tag =
"{\\u1}{\\i1}";
520 if (prev_color != color[j]) {
523 c_tag =
"{\\c&HFFFFFF&}";
526 c_tag =
"{\\c&H00FF00&}";
529 c_tag =
"{\\c&HFF0000&}";
532 c_tag =
"{\\c&HFFFF00&}";
535 c_tag =
"{\\c&H0000FF&}";
538 c_tag =
"{\\c&H00FFFF&}";
541 c_tag =
"{\\c&HFF00FF&}";
545 if (prev_bg_color != bg[j]) {
548 b_tag =
"{\\3c&HFFFFFF&}";
551 b_tag =
"{\\3c&H00FF00&}";
554 b_tag =
"{\\3c&HFF0000&}";
557 b_tag =
"{\\3c&HFFFF00&}";
560 b_tag =
"{\\3c&H0000FF&}";
563 b_tag =
"{\\3c&H00FFFF&}";
566 b_tag =
"{\\3c&HFF00FF&}";
569 b_tag =
"{\\3c&H000000&}";
575 prev_color = color[j];
576 prev_bg_color = bg[j];
579 av_bprintf(&ctx->
buffer[bidx],
"%s%s%s%s%s", e_tag, s_tag, c_tag, b_tag,
override);
581 }
else if (row[j] ==
' ' && !seen_char) {
584 av_bprintf(&ctx->
buffer[bidx],
"%s%s%s%s%c", e_tag, s_tag, c_tag, b_tag, row[j]);
595 ctx->
buffer[bidx].len -= 2;
610 const int i = (lo & 0xf) >> 1;
632 static const int8_t row_map[] = {
633 11, -1, 1, 2, 3, 4, 12, 13, 14, 15, 5, 6, 7, 8, 9, 10
635 const int index = ( (hi<<1) & 0x0e) | ( (lo>>5) & 0x01 );
639 if (row_map[index] <= 0) {
652 for (i = 0; i < indent; i++) {
740 ff_dlog(ctx,
"(%c,%c)\n", hi, lo);
757 if ( (hi == 0x10 && (lo >= 0x40 && lo <= 0x5f)) ||
758 ( (hi >= 0x11 && hi <= 0x17) && (lo >= 0x40 && lo <= 0x7f) ) ) {
760 }
else if ( ( hi == 0x11 && lo >= 0x20 && lo <= 0x2f ) ||
761 ( hi == 0x17 && lo >= 0x2e && lo <= 0x2f) ) {
763 }
else if ((hi == 0x10 && lo >= 0x20 && lo <= 0x2f)) {
765 }
else if (hi == 0x14 || hi == 0x15 || hi == 0x1c) {
794 ff_dlog(ctx,
"carriage return\n");
815 ff_dlog(ctx,
"Unknown command 0x%hhx 0x%hhx\n", hi, lo);
818 }
else if (hi >= 0x11 && hi <= 0x13) {
821 }
else if (hi >= 0x20) {
825 }
else if (hi == 0x17 && lo >= 0x21 && lo <= 0x23) {
828 for (i = 0; i < lo - 0x20; i++) {
833 ff_dlog(ctx,
"Unknown command 0x%hhx 0x%hhx\n", hi, lo);
843 int64_t in_time = sub->
pts;
852 for (i = 0; i <
len; i += 3) {
878 ff_dlog(ctx,
"cdp writing data (%s)\n", ctx->
buffer[bidx].str);
925 #define OFFSET(x) offsetof(CCaptionSubContext, x) 926 #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM 928 {
"real_time",
"emit subtitle events as they are decoded for real-time display",
OFFSET(real_time),
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
SD },
929 {
"data_field",
"select data field",
OFFSET(data_field),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1,
SD,
"data_field" },
930 {
"auto",
"pick first one that appears", 0,
AV_OPT_TYPE_CONST, { .i64 =-1 }, 0, 0,
SD,
"data_field" },
953 .priv_class = &ccaption_dec_class,
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
ptrdiff_t const GLvoid * data
static void flush(AVCodecContext *avctx)
static void handle_pac(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo)
#define AV_LOG_WARNING
Something somehow does not look correct.
#define LIBAVUTIL_VERSION_INT
int ff_ass_subtitle_header(AVCodecContext *avctx, const char *font, int font_size, int color, int back_color, int bold, int italic, int underline, int border_style, int alignment)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS.
static av_cold int init(AVCodecContext *avctx)
uint8_t charsets[SCREEN_ROWS+1][SCREEN_COLUMNS+1]
const char * av_default_item_name(void *ptr)
Return the context name.
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.
static struct Screen * get_writing_screen(CCaptionSubContext *ctx)
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
#define CHECK_FLAG(var, val)
static int handle_eoc(CCaptionSubContext *ctx)
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
static int64_t start_time
#define ASS_DEFAULT_ALIGNMENT
static void write_char(CCaptionSubContext *ctx, struct Screen *screen, char ch)
#define AV_CODEC_FLAG2_RO_FLUSH_NOOP
Do not reset ASS ReadOrder field on flush (subtitles decoding)
static int handle_edm(CCaptionSubContext *ctx)
#define ASS_DEFAULT_PLAYRESY
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
#define ASS_DEFAULT_BACK_COLOR
#define ASS_DEFAULT_UNDERLINE
#define AV_BPRINT_SIZE_UNLIMITED
#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)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static const unsigned char bg_attribs[8]
const char * name
Name of the codec implementation.
AVCodec ff_ccaption_decoder
#define ASS_DEFAULT_FONT_SIZE
uint32_t end_display_time
int64_t pts
Same as packet pts, in AV_TIME_BASE.
#define SET_FLAG(var, val)
static av_cold int init_decoder(AVCodecContext *avctx)
static void update_time(CCaptionSubContext *ctx, int64_t pts)
uint8_t characters[SCREEN_ROWS+1][SCREEN_COLUMNS+1]
static int capture_screen(CCaptionSubContext *ctx)
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
static void handle_delete_end_of_row(CCaptionSubContext *ctx)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
uint8_t fonts[SCREEN_ROWS+1][SCREEN_COLUMNS+1]
Libavcodec external API header.
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
static const unsigned char pac2_attribs[32][3]
main external API structure.
static void flush_decoder(AVCodecContext *avctx)
Describe the class of an AVClass context structure.
Rational number (pair of numerator and denominator).
static const AVClass ccaption_dec_class
static const AVRational ms_tb
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
static void roll_up(CCaptionSubContext *ctx)
static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt)
static int validate_cc_data_pair(const uint8_t *cc_data_pair, uint8_t *hi)
This function after validating parity bit, also remove it from data pair.
#define ASS_DEFAULT_COLOR
static const char * charset_overrides[4][128]
static const AVOption options[]
#define UNSET_FLAG(var, val)
#define ASS_DEFAULT_ITALIC
static void handle_char(CCaptionSubContext *ctx, char hi, char lo)
static void handle_bgattr(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo)
static void handle_textattr(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo)
int flags2
AV_CODEC_FLAG2_*.
static const struct twinvq_data tab
uint8_t bgs[SCREEN_ROWS+1][SCREEN_COLUMNS+1]
static float sub(float src0, float src1)
static int process_cc608(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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.Frame references ownership and permissions
static av_cold int close_decoder(AVCodecContext *avctx)
#define ASS_DEFAULT_PLAYRESX
This structure stores compressed data.
mode
Use these values in ebur128_init (or'ed).
uint8_t colors[SCREEN_ROWS+1][SCREEN_COLUMNS+1]