mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-26 19:01:44 +02:00
avcodec/codec_internal: Add FFCodec.decode_sub
This increases type-safety by avoiding conversions from/through void*. It also avoids the boilerplate "AVSubtitle *sub = data;" line for subtitle decoders. Its only downside is that it increases sizeof(FFCodec), yet this can be more than offset lateron. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
1c3c29d07d
commit
fb59a42ef9
@ -40,11 +40,9 @@ static av_cold int ass_decode_init(AVCodecContext *avctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr,
|
static int ass_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
AVSubtitle *sub = data;
|
|
||||||
|
|
||||||
if (avpkt->size <= 0)
|
if (avpkt->size <= 0)
|
||||||
return avpkt->size;
|
return avpkt->size;
|
||||||
|
|
||||||
@ -70,7 +68,7 @@ const FFCodec ff_ssa_decoder = {
|
|||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_ASS,
|
.p.id = AV_CODEC_ID_ASS,
|
||||||
.init = ass_decode_init,
|
.init = ass_decode_init,
|
||||||
.decode = ass_decode_frame,
|
.decode_sub = ass_decode_frame,
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -82,7 +80,7 @@ const FFCodec ff_ass_decoder = {
|
|||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_ASS,
|
.p.id = AV_CODEC_ID_ASS,
|
||||||
.init = ass_decode_init,
|
.init = ass_decode_init,
|
||||||
.decode = ass_decode_frame,
|
.decode_sub = ass_decode_frame,
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -838,10 +838,10 @@ static int process_cc608(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt)
|
static int decode(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
|
int *got_sub, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
CCaptionSubContext *ctx = avctx->priv_data;
|
CCaptionSubContext *ctx = avctx->priv_data;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
int64_t in_time = sub->pts;
|
int64_t in_time = sub->pts;
|
||||||
int64_t start_time;
|
int64_t start_time;
|
||||||
int64_t end_time;
|
int64_t end_time;
|
||||||
@ -955,6 +955,6 @@ const FFCodec ff_ccaption_decoder = {
|
|||||||
.init = init_decoder,
|
.init = init_decoder,
|
||||||
.close = close_decoder,
|
.close = close_decoder,
|
||||||
.flush = flush_decoder,
|
.flush = flush_decoder,
|
||||||
.decode = decode,
|
.decode_sub = decode,
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
};
|
};
|
||||||
|
@ -148,19 +148,24 @@ typedef struct FFCodec {
|
|||||||
int (*encode2)(struct AVCodecContext *avctx, struct AVPacket *avpkt,
|
int (*encode2)(struct AVCodecContext *avctx, struct AVPacket *avpkt,
|
||||||
const struct AVFrame *frame, int *got_packet_ptr);
|
const struct AVFrame *frame, int *got_packet_ptr);
|
||||||
/**
|
/**
|
||||||
* Decode picture or subtitle data.
|
* Decode picture data.
|
||||||
*
|
*
|
||||||
* @param avctx codec context
|
* @param avctx codec context
|
||||||
* @param outdata codec type dependent output struct
|
* @param outdata codec type dependent output struct
|
||||||
* @param[out] got_frame_ptr decoder sets to 0 or 1 to indicate that a
|
* @param[out] got_frame_ptr decoder sets to 0 or 1 to indicate that a
|
||||||
* non-empty frame or subtitle was returned in
|
* non-empty frame was returned in outdata.
|
||||||
* outdata.
|
|
||||||
* @param[in] avpkt AVPacket containing the data to be decoded
|
* @param[in] avpkt AVPacket containing the data to be decoded
|
||||||
* @return amount of bytes read from the packet on success, negative error
|
* @return amount of bytes read from the packet on success, negative error
|
||||||
* code on failure
|
* code on failure
|
||||||
*/
|
*/
|
||||||
int (*decode)(struct AVCodecContext *avctx, void *outdata,
|
int (*decode)(struct AVCodecContext *avctx, void *outdata,
|
||||||
int *got_frame_ptr, struct AVPacket *avpkt);
|
int *got_frame_ptr, struct AVPacket *avpkt);
|
||||||
|
/**
|
||||||
|
* Decode subtitle data. Same as decode except that it uses
|
||||||
|
* a struct AVSubtitle structure for output.
|
||||||
|
*/
|
||||||
|
int (*decode_sub)(struct AVCodecContext *avctx, struct AVSubtitle *sub,
|
||||||
|
int *got_frame_ptr, struct AVPacket *avpkt);
|
||||||
int (*close)(struct AVCodecContext *);
|
int (*close)(struct AVCodecContext *);
|
||||||
/**
|
/**
|
||||||
* Encode API with decoupled frame/packet dataflow. This function is called
|
* Encode API with decoupled frame/packet dataflow. This function is called
|
||||||
|
@ -862,7 +862,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
|
|||||||
if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE)
|
if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE)
|
||||||
sub->pts = av_rescale_q(avpkt->pts,
|
sub->pts = av_rescale_q(avpkt->pts,
|
||||||
avctx->pkt_timebase, AV_TIME_BASE_Q);
|
avctx->pkt_timebase, AV_TIME_BASE_Q);
|
||||||
ret = ffcodec(avctx->codec)->decode(avctx, sub, got_sub_ptr, pkt);
|
ret = ffcodec(avctx->codec)->decode_sub(avctx, sub, got_sub_ptr, pkt);
|
||||||
if (pkt == avci->buffer_pkt) // did we recode?
|
if (pkt == avci->buffer_pkt) // did we recode?
|
||||||
av_packet_unref(avci->buffer_pkt);
|
av_packet_unref(avci->buffer_pkt);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -1607,14 +1607,12 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dvbsub_decode(AVCodecContext *avctx,
|
static int dvbsub_decode(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
void *data, int *got_sub_ptr,
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
AVPacket *avpkt)
|
|
||||||
{
|
{
|
||||||
const uint8_t *buf = avpkt->data;
|
const uint8_t *buf = avpkt->data;
|
||||||
int buf_size = avpkt->size;
|
int buf_size = avpkt->size;
|
||||||
DVBSubContext *ctx = avctx->priv_data;
|
DVBSubContext *ctx = avctx->priv_data;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
const uint8_t *p, *p_end;
|
const uint8_t *p, *p_end;
|
||||||
int segment_type;
|
int segment_type;
|
||||||
int page_id;
|
int page_id;
|
||||||
@ -1748,7 +1746,7 @@ const FFCodec ff_dvbsub_decoder = {
|
|||||||
.priv_data_size = sizeof(DVBSubContext),
|
.priv_data_size = sizeof(DVBSubContext),
|
||||||
.init = dvbsub_init_decoder,
|
.init = dvbsub_init_decoder,
|
||||||
.close = dvbsub_close_decoder,
|
.close = dvbsub_close_decoder,
|
||||||
.decode = dvbsub_decode,
|
.decode_sub = dvbsub_decode,
|
||||||
.p.priv_class = &dvbsubdec_class,
|
.p.priv_class = &dvbsubdec_class,
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
};
|
};
|
||||||
|
@ -548,14 +548,12 @@ static int append_to_cached_buf(AVCodecContext *avctx,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dvdsub_decode(AVCodecContext *avctx,
|
static int dvdsub_decode(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
void *data, int *data_size,
|
int *data_size, AVPacket *avpkt)
|
||||||
AVPacket *avpkt)
|
|
||||||
{
|
{
|
||||||
DVDSubContext *ctx = avctx->priv_data;
|
DVDSubContext *ctx = avctx->priv_data;
|
||||||
const uint8_t *buf = avpkt->data;
|
const uint8_t *buf = avpkt->data;
|
||||||
int buf_size = avpkt->size;
|
int buf_size = avpkt->size;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
int appended = 0;
|
int appended = 0;
|
||||||
int is_menu;
|
int is_menu;
|
||||||
|
|
||||||
@ -762,7 +760,7 @@ const FFCodec ff_dvdsub_decoder = {
|
|||||||
.p.id = AV_CODEC_ID_DVD_SUBTITLE,
|
.p.id = AV_CODEC_ID_DVD_SUBTITLE,
|
||||||
.priv_data_size = sizeof(DVDSubContext),
|
.priv_data_size = sizeof(DVDSubContext),
|
||||||
.init = dvdsub_init,
|
.init = dvdsub_init,
|
||||||
.decode = dvdsub_decode,
|
.decode_sub = dvdsub_decode,
|
||||||
.flush = dvdsub_flush,
|
.flush = dvdsub_flush,
|
||||||
.p.priv_class = &dvdsub_class,
|
.p.priv_class = &dvdsub_class,
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
|
@ -162,11 +162,10 @@ static void jacosub_to_ass(AVCodecContext *avctx, AVBPrint *dst, const char *src
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jacosub_decode_frame(AVCodecContext *avctx,
|
static int jacosub_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
void *data, int *got_sub_ptr, AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
const char *ptr = avpkt->data;
|
const char *ptr = avpkt->data;
|
||||||
FFASSDecoderContext *s = avctx->priv_data;
|
FFASSDecoderContext *s = avctx->priv_data;
|
||||||
|
|
||||||
@ -200,7 +199,7 @@ const FFCodec ff_jacosub_decoder = {
|
|||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_JACOSUB,
|
.p.id = AV_CODEC_ID_JACOSUB,
|
||||||
.init = ff_ass_subtitle_header_default,
|
.init = ff_ass_subtitle_header_default,
|
||||||
.decode = jacosub_decode_frame,
|
.decode_sub = jacosub_decode_frame,
|
||||||
.flush = ff_ass_decoder_flush,
|
.flush = ff_ass_decoder_flush,
|
||||||
.priv_data_size = sizeof(FFASSDecoderContext),
|
.priv_data_size = sizeof(FFASSDecoderContext),
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
|
@ -283,10 +283,10 @@ next_region:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int libaribb24_decode(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *pkt)
|
static int libaribb24_decode(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
|
int *got_sub_ptr, AVPacket *pkt)
|
||||||
{
|
{
|
||||||
Libaribb24Context *b24 = avctx->priv_data;
|
Libaribb24Context *b24 = avctx->priv_data;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
size_t parsed_data_size = 0;
|
size_t parsed_data_size = 0;
|
||||||
size_t decoded_subtitle_size = 0;
|
size_t decoded_subtitle_size = 0;
|
||||||
const unsigned char *parsed_data = NULL;
|
const unsigned char *parsed_data = NULL;
|
||||||
@ -391,6 +391,6 @@ const FFCodec ff_libaribb24_decoder = {
|
|||||||
.priv_data_size = sizeof(Libaribb24Context),
|
.priv_data_size = sizeof(Libaribb24Context),
|
||||||
.init = libaribb24_init,
|
.init = libaribb24_init,
|
||||||
.close = libaribb24_close,
|
.close = libaribb24_close,
|
||||||
.decode = libaribb24_decode,
|
.decode_sub = libaribb24_decode,
|
||||||
.flush = libaribb24_flush,
|
.flush = libaribb24_flush,
|
||||||
};
|
};
|
||||||
|
@ -637,10 +637,10 @@ static int slice_to_vbi_lines(TeletextContext *ctx, uint8_t* buf, int size)
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int teletext_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *pkt)
|
static int teletext_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
|
int *got_sub_ptr, AVPacket *pkt)
|
||||||
{
|
{
|
||||||
TeletextContext *ctx = avctx->priv_data;
|
TeletextContext *ctx = avctx->priv_data;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!ctx->vbi) {
|
if (!ctx->vbi) {
|
||||||
@ -822,6 +822,6 @@ const FFCodec ff_libzvbi_teletext_decoder = {
|
|||||||
.priv_data_size = sizeof(TeletextContext),
|
.priv_data_size = sizeof(TeletextContext),
|
||||||
.init = teletext_init_decoder,
|
.init = teletext_init_decoder,
|
||||||
.close = teletext_close_decoder,
|
.close = teletext_close_decoder,
|
||||||
.decode = teletext_decode_frame,
|
.decode_sub = teletext_decode_frame,
|
||||||
.flush = teletext_flush,
|
.flush = teletext_flush,
|
||||||
};
|
};
|
||||||
|
@ -274,10 +274,9 @@ static void microdvd_close_no_persistent_tags(AVBPrint *new_line,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int microdvd_decode_frame(AVCodecContext *avctx,
|
static int microdvd_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
void *data, int *got_sub_ptr, AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
AVSubtitle *sub = data;
|
|
||||||
AVBPrint new_line;
|
AVBPrint new_line;
|
||||||
char *line = avpkt->data;
|
char *line = avpkt->data;
|
||||||
char *end = avpkt->data + avpkt->size;
|
char *end = avpkt->data + avpkt->size;
|
||||||
@ -375,7 +374,7 @@ const FFCodec ff_microdvd_decoder = {
|
|||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_MICRODVD,
|
.p.id = AV_CODEC_ID_MICRODVD,
|
||||||
.init = microdvd_init,
|
.init = microdvd_init,
|
||||||
.decode = microdvd_decode_frame,
|
.decode_sub = microdvd_decode_frame,
|
||||||
.flush = ff_ass_decoder_flush,
|
.flush = ff_ass_decoder_flush,
|
||||||
.priv_data_size = sizeof(FFASSDecoderContext),
|
.priv_data_size = sizeof(FFASSDecoderContext),
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
|
@ -472,10 +472,9 @@ static int mov_text_init(AVCodecContext *avctx) {
|
|||||||
return ff_ass_subtitle_header_default(avctx);
|
return ff_ass_subtitle_header_default(avctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mov_text_decode_frame(AVCodecContext *avctx,
|
static int mov_text_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
void *data, int *got_sub_ptr, AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
AVSubtitle *sub = data;
|
|
||||||
MovTextContext *m = avctx->priv_data;
|
MovTextContext *m = avctx->priv_data;
|
||||||
int ret;
|
int ret;
|
||||||
AVBPrint buf;
|
AVBPrint buf;
|
||||||
@ -600,7 +599,7 @@ const FFCodec ff_movtext_decoder = {
|
|||||||
.priv_data_size = sizeof(MovTextContext),
|
.priv_data_size = sizeof(MovTextContext),
|
||||||
.p.priv_class = &mov_text_decoder_class,
|
.p.priv_class = &mov_text_decoder_class,
|
||||||
.init = mov_text_init,
|
.init = mov_text_init,
|
||||||
.decode = mov_text_decode_frame,
|
.decode_sub = mov_text_decode_frame,
|
||||||
.close = mov_text_decode_close,
|
.close = mov_text_decode_close,
|
||||||
.flush = mov_text_flush,
|
.flush = mov_text_flush,
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
|
@ -63,12 +63,11 @@ static int mpl2_event_to_ass(AVBPrint *buf, const char *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpl2_decode_frame(AVCodecContext *avctx, void *data,
|
static int mpl2_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
int *got_sub_ptr, AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
AVBPrint buf;
|
AVBPrint buf;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
const char *ptr = avpkt->data;
|
const char *ptr = avpkt->data;
|
||||||
FFASSDecoderContext *s = avctx->priv_data;
|
FFASSDecoderContext *s = avctx->priv_data;
|
||||||
|
|
||||||
@ -87,7 +86,7 @@ const FFCodec ff_mpl2_decoder = {
|
|||||||
.p.long_name = NULL_IF_CONFIG_SMALL("MPL2 subtitle"),
|
.p.long_name = NULL_IF_CONFIG_SMALL("MPL2 subtitle"),
|
||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_MPL2,
|
.p.id = AV_CODEC_ID_MPL2,
|
||||||
.decode = mpl2_decode_frame,
|
.decode_sub = mpl2_decode_frame,
|
||||||
.init = ff_ass_subtitle_header_default,
|
.init = ff_ass_subtitle_header_default,
|
||||||
.flush = ff_ass_decoder_flush,
|
.flush = ff_ass_decoder_flush,
|
||||||
.priv_data_size = sizeof(FFASSDecoderContext),
|
.priv_data_size = sizeof(FFASSDecoderContext),
|
||||||
|
@ -494,10 +494,9 @@ static int parse_presentation_segment(AVCodecContext *avctx,
|
|||||||
* @param buf pointer to the packet to process
|
* @param buf pointer to the packet to process
|
||||||
* @param buf_size size of packet to process
|
* @param buf_size size of packet to process
|
||||||
*/
|
*/
|
||||||
static int display_end_segment(AVCodecContext *avctx, void *data,
|
static int display_end_segment(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
const uint8_t *buf, int buf_size)
|
const uint8_t *buf, int buf_size)
|
||||||
{
|
{
|
||||||
AVSubtitle *sub = data;
|
|
||||||
PGSSubContext *ctx = avctx->priv_data;
|
PGSSubContext *ctx = avctx->priv_data;
|
||||||
int64_t pts;
|
int64_t pts;
|
||||||
PGSSubPalette *palette;
|
PGSSubPalette *palette;
|
||||||
@ -590,8 +589,8 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode(AVCodecContext *avctx, void *data, int *got_sub_ptr,
|
static int decode(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
const uint8_t *buf = avpkt->data;
|
const uint8_t *buf = avpkt->data;
|
||||||
int buf_size = avpkt->size;
|
int buf_size = avpkt->size;
|
||||||
@ -639,7 +638,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub_ptr,
|
|||||||
ret = parse_object_segment(avctx, buf, segment_length);
|
ret = parse_object_segment(avctx, buf, segment_length);
|
||||||
break;
|
break;
|
||||||
case PRESENTATION_SEGMENT:
|
case PRESENTATION_SEGMENT:
|
||||||
ret = parse_presentation_segment(avctx, buf, segment_length, ((AVSubtitle*)(data))->pts);
|
ret = parse_presentation_segment(avctx, buf, segment_length, sub->pts);
|
||||||
break;
|
break;
|
||||||
case WINDOW_SEGMENT:
|
case WINDOW_SEGMENT:
|
||||||
/*
|
/*
|
||||||
@ -657,7 +656,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub_ptr,
|
|||||||
ret = AVERROR_INVALIDDATA;
|
ret = AVERROR_INVALIDDATA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = display_end_segment(avctx, data, buf, segment_length);
|
ret = display_end_segment(avctx, sub, buf, segment_length);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
*got_sub_ptr = ret;
|
*got_sub_ptr = ret;
|
||||||
break;
|
break;
|
||||||
@ -699,7 +698,7 @@ const FFCodec ff_pgssub_decoder = {
|
|||||||
.priv_data_size = sizeof(PGSSubContext),
|
.priv_data_size = sizeof(PGSSubContext),
|
||||||
.init = init_decoder,
|
.init = init_decoder,
|
||||||
.close = close_decoder,
|
.close = close_decoder,
|
||||||
.decode = decode,
|
.decode_sub = decode,
|
||||||
.p.priv_class = &pgsdec_class,
|
.p.priv_class = &pgsdec_class,
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
};
|
};
|
||||||
|
@ -56,11 +56,10 @@ static int rt_event_to_ass(AVBPrint *buf, const char *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int realtext_decode_frame(AVCodecContext *avctx,
|
static int realtext_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
void *data, int *got_sub_ptr, AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
const char *ptr = avpkt->data;
|
const char *ptr = avpkt->data;
|
||||||
FFASSDecoderContext *s = avctx->priv_data;
|
FFASSDecoderContext *s = avctx->priv_data;
|
||||||
AVBPrint buf;
|
AVBPrint buf;
|
||||||
@ -80,7 +79,7 @@ const FFCodec ff_realtext_decoder = {
|
|||||||
.p.long_name = NULL_IF_CONFIG_SMALL("RealText subtitle"),
|
.p.long_name = NULL_IF_CONFIG_SMALL("RealText subtitle"),
|
||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_REALTEXT,
|
.p.id = AV_CODEC_ID_REALTEXT,
|
||||||
.decode = realtext_decode_frame,
|
.decode_sub = realtext_decode_frame,
|
||||||
.init = ff_ass_subtitle_header_default,
|
.init = ff_ass_subtitle_header_default,
|
||||||
.flush = ff_ass_decoder_flush,
|
.flush = ff_ass_decoder_flush,
|
||||||
.priv_data_size = sizeof(FFASSDecoderContext),
|
.priv_data_size = sizeof(FFASSDecoderContext),
|
||||||
|
@ -132,10 +132,9 @@ end:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sami_decode_frame(AVCodecContext *avctx,
|
static int sami_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
void *data, int *got_sub_ptr, AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
AVSubtitle *sub = data;
|
|
||||||
const char *ptr = avpkt->data;
|
const char *ptr = avpkt->data;
|
||||||
SAMIContext *sami = avctx->priv_data;
|
SAMIContext *sami = avctx->priv_data;
|
||||||
|
|
||||||
@ -189,7 +188,7 @@ const FFCodec ff_sami_decoder = {
|
|||||||
.priv_data_size = sizeof(SAMIContext),
|
.priv_data_size = sizeof(SAMIContext),
|
||||||
.init = sami_init,
|
.init = sami_init,
|
||||||
.close = sami_close,
|
.close = sami_close,
|
||||||
.decode = sami_decode_frame,
|
.decode_sub = sami_decode_frame,
|
||||||
.flush = sami_flush,
|
.flush = sami_flush,
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
};
|
};
|
||||||
|
@ -55,10 +55,9 @@ static int srt_to_ass(AVCodecContext *avctx, AVBPrint *dst,
|
|||||||
return ff_htmlmarkup_to_ass(avctx, dst, in);
|
return ff_htmlmarkup_to_ass(avctx, dst, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int srt_decode_frame(AVCodecContext *avctx,
|
static int srt_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
void *data, int *got_sub_ptr, AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
AVSubtitle *sub = data;
|
|
||||||
AVBPrint buffer;
|
AVBPrint buffer;
|
||||||
int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
|
int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
|
||||||
int ret;
|
int ret;
|
||||||
@ -97,7 +96,7 @@ const FFCodec ff_srt_decoder = {
|
|||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_SUBRIP,
|
.p.id = AV_CODEC_ID_SUBRIP,
|
||||||
.init = ff_ass_subtitle_header_default,
|
.init = ff_ass_subtitle_header_default,
|
||||||
.decode = srt_decode_frame,
|
.decode_sub = srt_decode_frame,
|
||||||
.flush = ff_ass_decoder_flush,
|
.flush = ff_ass_decoder_flush,
|
||||||
.priv_data_size = sizeof(FFASSDecoderContext),
|
.priv_data_size = sizeof(FFASSDecoderContext),
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
@ -111,7 +110,7 @@ const FFCodec ff_subrip_decoder = {
|
|||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_SUBRIP,
|
.p.id = AV_CODEC_ID_SUBRIP,
|
||||||
.init = ff_ass_subtitle_header_default,
|
.init = ff_ass_subtitle_header_default,
|
||||||
.decode = srt_decode_frame,
|
.decode_sub = srt_decode_frame,
|
||||||
.flush = ff_ass_decoder_flush,
|
.flush = ff_ass_decoder_flush,
|
||||||
.priv_data_size = sizeof(FFASSDecoderContext),
|
.priv_data_size = sizeof(FFASSDecoderContext),
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
|
@ -47,11 +47,10 @@ static int subviewer_event_to_ass(AVBPrint *buf, const char *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int subviewer_decode_frame(AVCodecContext *avctx,
|
static int subviewer_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
void *data, int *got_sub_ptr, AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
const char *ptr = avpkt->data;
|
const char *ptr = avpkt->data;
|
||||||
FFASSDecoderContext *s = avctx->priv_data;
|
FFASSDecoderContext *s = avctx->priv_data;
|
||||||
AVBPrint buf;
|
AVBPrint buf;
|
||||||
@ -71,7 +70,7 @@ const FFCodec ff_subviewer_decoder = {
|
|||||||
.p.long_name = NULL_IF_CONFIG_SMALL("SubViewer subtitle"),
|
.p.long_name = NULL_IF_CONFIG_SMALL("SubViewer subtitle"),
|
||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_SUBVIEWER,
|
.p.id = AV_CODEC_ID_SUBVIEWER,
|
||||||
.decode = subviewer_decode_frame,
|
.decode_sub = subviewer_decode_frame,
|
||||||
.init = ff_ass_subtitle_header_default,
|
.init = ff_ass_subtitle_header_default,
|
||||||
.flush = ff_ass_decoder_flush,
|
.flush = ff_ass_decoder_flush,
|
||||||
.priv_data_size = sizeof(FFASSDecoderContext),
|
.priv_data_size = sizeof(FFASSDecoderContext),
|
||||||
|
@ -135,12 +135,13 @@ int main(void){
|
|||||||
codec->capabilities & AV_CODEC_CAP_ENCODER_FLUSH)
|
codec->capabilities & AV_CODEC_CAP_ENCODER_FLUSH)
|
||||||
ERR("Frame-threaded encoder %s claims to support flushing\n");
|
ERR("Frame-threaded encoder %s claims to support flushing\n");
|
||||||
} else {
|
} else {
|
||||||
if (codec->type == AVMEDIA_TYPE_SUBTITLE && !codec2->decode)
|
if (codec->type == AVMEDIA_TYPE_SUBTITLE && !codec2->decode_sub)
|
||||||
ERR("Subtitle decoder %s does not implement decode callback\n");
|
ERR("Subtitle decoder %s does not implement decode_sub callback\n");
|
||||||
if (codec->type == AVMEDIA_TYPE_SUBTITLE && codec2->bsfs)
|
if (codec->type == AVMEDIA_TYPE_SUBTITLE && codec2->bsfs)
|
||||||
ERR("Automatic bitstream filtering unsupported for subtitles; "
|
ERR("Automatic bitstream filtering unsupported for subtitles; "
|
||||||
"yet decoder %s has it set\n");
|
"yet decoder %s has it set\n");
|
||||||
if (!!codec2->decode + !!codec2->receive_frame != 1)
|
if ((codec->type != AVMEDIA_TYPE_SUBTITLE) !=
|
||||||
|
(!!codec2->decode + !!codec2->receive_frame))
|
||||||
ERR("Decoder %s does not implement exactly one decode API.\n");
|
ERR("Decoder %s does not implement exactly one decode API.\n");
|
||||||
if (codec->capabilities & (AV_CODEC_CAP_SMALL_LAST_FRAME |
|
if (codec->capabilities & (AV_CODEC_CAP_SMALL_LAST_FRAME |
|
||||||
AV_CODEC_CAP_VARIABLE_FRAME_SIZE |
|
AV_CODEC_CAP_VARIABLE_FRAME_SIZE |
|
||||||
|
@ -45,12 +45,11 @@ static const AVOption options[] = {
|
|||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int text_decode_frame(AVCodecContext *avctx, void *data,
|
static int text_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
int *got_sub_ptr, AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
AVBPrint buf;
|
AVBPrint buf;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
const char *ptr = avpkt->data;
|
const char *ptr = avpkt->data;
|
||||||
TextContext *text = avctx->priv_data;
|
TextContext *text = avctx->priv_data;
|
||||||
|
|
||||||
@ -87,7 +86,7 @@ const FFCodec ff_text_decoder = {
|
|||||||
.priv_data_size = sizeof(TextContext),
|
.priv_data_size = sizeof(TextContext),
|
||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_TEXT,
|
.p.id = AV_CODEC_ID_TEXT,
|
||||||
.decode = text_decode_frame,
|
.decode_sub = text_decode_frame,
|
||||||
.init = ff_ass_subtitle_header_default,
|
.init = ff_ass_subtitle_header_default,
|
||||||
.p.priv_class = &textsub_decoder_class,
|
.p.priv_class = &textsub_decoder_class,
|
||||||
.flush = text_flush,
|
.flush = text_flush,
|
||||||
@ -111,7 +110,7 @@ const FFCodec ff_vplayer_decoder = {
|
|||||||
.priv_data_size = sizeof(TextContext),
|
.priv_data_size = sizeof(TextContext),
|
||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_VPLAYER,
|
.p.id = AV_CODEC_ID_VPLAYER,
|
||||||
.decode = text_decode_frame,
|
.decode_sub = text_decode_frame,
|
||||||
.init = linebreak_init,
|
.init = linebreak_init,
|
||||||
.p.priv_class = &textsub_decoder_class,
|
.p.priv_class = &textsub_decoder_class,
|
||||||
.flush = text_flush,
|
.flush = text_flush,
|
||||||
@ -126,7 +125,7 @@ const FFCodec ff_stl_decoder = {
|
|||||||
.priv_data_size = sizeof(TextContext),
|
.priv_data_size = sizeof(TextContext),
|
||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_STL,
|
.p.id = AV_CODEC_ID_STL,
|
||||||
.decode = text_decode_frame,
|
.decode_sub = text_decode_frame,
|
||||||
.init = linebreak_init,
|
.init = linebreak_init,
|
||||||
.p.priv_class = &textsub_decoder_class,
|
.p.priv_class = &textsub_decoder_class,
|
||||||
.flush = text_flush,
|
.flush = text_flush,
|
||||||
@ -141,7 +140,7 @@ const FFCodec ff_pjs_decoder = {
|
|||||||
.priv_data_size = sizeof(TextContext),
|
.priv_data_size = sizeof(TextContext),
|
||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_PJS,
|
.p.id = AV_CODEC_ID_PJS,
|
||||||
.decode = text_decode_frame,
|
.decode_sub = text_decode_frame,
|
||||||
.init = linebreak_init,
|
.init = linebreak_init,
|
||||||
.p.priv_class = &textsub_decoder_class,
|
.p.priv_class = &textsub_decoder_class,
|
||||||
.flush = text_flush,
|
.flush = text_flush,
|
||||||
@ -156,7 +155,7 @@ const FFCodec ff_subviewer1_decoder = {
|
|||||||
.priv_data_size = sizeof(TextContext),
|
.priv_data_size = sizeof(TextContext),
|
||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_SUBVIEWER1,
|
.p.id = AV_CODEC_ID_SUBVIEWER1,
|
||||||
.decode = text_decode_frame,
|
.decode_sub = text_decode_frame,
|
||||||
.init = linebreak_init,
|
.init = linebreak_init,
|
||||||
.p.priv_class = &textsub_decoder_class,
|
.p.priv_class = &textsub_decoder_class,
|
||||||
.flush = text_flush,
|
.flush = text_flush,
|
||||||
|
@ -80,7 +80,7 @@ int av_codec_is_encoder(const AVCodec *avcodec)
|
|||||||
int av_codec_is_decoder(const AVCodec *avcodec)
|
int av_codec_is_decoder(const AVCodec *avcodec)
|
||||||
{
|
{
|
||||||
const FFCodec *const codec = ffcodec(avcodec);
|
const FFCodec *const codec = ffcodec(avcodec);
|
||||||
return codec && (codec->decode || codec->receive_frame);
|
return codec && (codec->decode || codec->decode_sub || codec->receive_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ff_set_dimensions(AVCodecContext *s, int width, int height)
|
int ff_set_dimensions(AVCodecContext *s, int width, int height)
|
||||||
|
@ -80,11 +80,10 @@ static int webvtt_event_to_ass(AVBPrint *buf, const char *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int webvtt_decode_frame(AVCodecContext *avctx,
|
static int webvtt_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
void *data, int *got_sub_ptr, AVPacket *avpkt)
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
const char *ptr = avpkt->data;
|
const char *ptr = avpkt->data;
|
||||||
FFASSDecoderContext *s = avctx->priv_data;
|
FFASSDecoderContext *s = avctx->priv_data;
|
||||||
AVBPrint buf;
|
AVBPrint buf;
|
||||||
@ -104,7 +103,7 @@ const FFCodec ff_webvtt_decoder = {
|
|||||||
.p.long_name = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
|
.p.long_name = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
|
||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_WEBVTT,
|
.p.id = AV_CODEC_ID_WEBVTT,
|
||||||
.decode = webvtt_decode_frame,
|
.decode_sub = webvtt_decode_frame,
|
||||||
.init = ff_ass_subtitle_header_default,
|
.init = ff_ass_subtitle_header_default,
|
||||||
.flush = ff_ass_decoder_flush,
|
.flush = ff_ass_decoder_flush,
|
||||||
.priv_data_size = sizeof(FFASSDecoderContext),
|
.priv_data_size = sizeof(FFASSDecoderContext),
|
||||||
|
@ -47,11 +47,11 @@ static int64_t parse_timecode(const uint8_t *buf, int64_t packet_time) {
|
|||||||
return ms - packet_time;
|
return ms - packet_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr,
|
static int decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
|
||||||
AVPacket *avpkt) {
|
int *got_sub_ptr, AVPacket *avpkt)
|
||||||
|
{
|
||||||
const uint8_t *buf = avpkt->data;
|
const uint8_t *buf = avpkt->data;
|
||||||
int buf_size = avpkt->size;
|
int buf_size = avpkt->size;
|
||||||
AVSubtitle *sub = data;
|
|
||||||
AVSubtitleRect *rect;
|
AVSubtitleRect *rect;
|
||||||
const uint8_t *buf_end = buf + buf_size;
|
const uint8_t *buf_end = buf + buf_size;
|
||||||
uint8_t *bitmap;
|
uint8_t *bitmap;
|
||||||
@ -160,6 +160,6 @@ const FFCodec ff_xsub_decoder = {
|
|||||||
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
.p.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
.p.id = AV_CODEC_ID_XSUB,
|
.p.id = AV_CODEC_ID_XSUB,
|
||||||
.init = decode_init,
|
.init = decode_init,
|
||||||
.decode = decode_frame,
|
.decode_sub = decode_frame,
|
||||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user