static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt)
{
- int size, ret;
+ int ret;
+ buffer_size_t size;
const uint8_t *data;
uint32_t flags;
int64_t val;
return 0;
}
-int ff_decode_bsfs_init(AVCodecContext *avctx)
+static int decode_bsfs_init(AVCodecContext *avctx)
{
AVCodecInternal *avci = avctx->internal;
int ret;
AVCodecInternal *avci = avctx->internal;
DecodeSimpleContext *ds = &avci->ds;
AVPacket *pkt = ds->in_pkt;
- // copy to ensure we do not change pkt
int got_frame, actual_got_frame;
int ret;
got_frame = 0;
} else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
uint8_t *side;
- int side_size;
+ buffer_size_t side_size;
uint32_t discard_padding = 0;
uint8_t skip_reason = 0;
uint8_t discard_reason = 0;
int *got_sub_ptr,
AVPacket *avpkt)
{
- int i, ret = 0;
+ int ret = 0;
if (!avpkt->data && avpkt->size) {
av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
if (ret < 0)
return ret;
- if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE)
- sub->pts = av_rescale_q(avpkt->pts,
- avctx->pkt_timebase, AV_TIME_BASE_Q);
- ret = avctx->codec->decode(avctx, sub, got_sub_ptr, pkt);
- av_assert1((ret >= 0) >= !!*got_sub_ptr &&
- !!*got_sub_ptr >= !!sub->num_rects);
+ if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE)
+ sub->pts = av_rescale_q(avpkt->pts,
+ avctx->pkt_timebase, AV_TIME_BASE_Q);
+ ret = avctx->codec->decode(avctx, sub, got_sub_ptr, pkt);
+ av_assert1((ret >= 0) >= !!*got_sub_ptr &&
+ !!*got_sub_ptr >= !!sub->num_rects);
#if FF_API_ASS_TIMING
- if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS
- && *got_sub_ptr && sub->num_rects) {
- const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase
- : avctx->time_base;
- int err = convert_sub_to_old_ass_form(sub, avpkt, tb);
- if (err < 0)
- ret = err;
- }
+ if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS
+ && *got_sub_ptr && sub->num_rects) {
+ const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase
+ : avctx->time_base;
+ int err = convert_sub_to_old_ass_form(sub, avpkt, tb);
+ if (err < 0)
+ ret = err;
+ }
#endif
- if (sub->num_rects && !sub->end_display_time && avpkt->duration &&
- avctx->pkt_timebase.num) {
- AVRational ms = { 1, 1000 };
- sub->end_display_time = av_rescale_q(avpkt->duration,
- avctx->pkt_timebase, ms);
- }
+ if (sub->num_rects && !sub->end_display_time && avpkt->duration &&
+ avctx->pkt_timebase.num) {
+ AVRational ms = { 1, 1000 };
+ sub->end_display_time = av_rescale_q(avpkt->duration,
+ avctx->pkt_timebase, ms);
+ }
- if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)
- sub->format = 0;
- else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
- sub->format = 1;
-
- for (i = 0; i < sub->num_rects; i++) {
- if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_IGNORE &&
- sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid UTF-8 in decoded subtitles text; "
- "maybe missing -sub_charenc option\n");
- avsubtitle_free(sub);
- ret = AVERROR_INVALIDDATA;
- break;
- }
+ if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)
+ sub->format = 0;
+ else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
+ sub->format = 1;
+
+ for (unsigned i = 0; i < sub->num_rects; i++) {
+ if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_IGNORE &&
+ sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid UTF-8 in decoded subtitles text; "
+ "maybe missing -sub_charenc option\n");
+ avsubtitle_free(sub);
+ ret = AVERROR_INVALIDDATA;
+ break;
}
+ }
if (*got_sub_ptr)
avctx->frame_number++;
static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame)
{
- int size;
+ buffer_size_t size;
const uint8_t *side_metadata;
AVDictionary **frame_md = &frame->metadata;
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
{
AVPacket *pkt = avctx->internal->last_pkt_props;
- int i;
static const struct {
enum AVPacketSideDataType packet;
enum AVFrameSideDataType frame;
av_fifo_generic_read(avctx->internal->pkt_props,
pkt, sizeof(*pkt), NULL);
- if (pkt) {
- frame->pts = pkt->pts;
+ frame->pts = pkt->pts;
#if FF_API_PKT_PTS
FF_DISABLE_DEPRECATION_WARNINGS
- frame->pkt_pts = pkt->pts;
+ frame->pkt_pts = pkt->pts;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
- frame->pkt_pos = pkt->pos;
- frame->pkt_duration = pkt->duration;
- frame->pkt_size = pkt->size;
-
- for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) {
- int size;
- uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size);
- if (packet_sd) {
- AVFrameSideData *frame_sd = av_frame_new_side_data(frame,
- sd[i].frame,
- size);
- if (!frame_sd)
- return AVERROR(ENOMEM);
-
- memcpy(frame_sd->data, packet_sd, size);
- }
+ frame->pkt_pos = pkt->pos;
+ frame->pkt_duration = pkt->duration;
+ frame->pkt_size = pkt->size;
+
+ for (int i = 0; i < FF_ARRAY_ELEMS(sd); i++) {
+ buffer_size_t size;
+ uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size);
+ if (packet_sd) {
+ AVFrameSideData *frame_sd = av_frame_new_side_data(frame,
+ sd[i].frame,
+ size);
+ if (!frame_sd)
+ return AVERROR(ENOMEM);
+
+ memcpy(frame_sd->data, packet_sd, size);
}
- add_metadata_from_side_data(pkt, frame);
+ }
+ add_metadata_from_side_data(pkt, frame);
- if (pkt->flags & AV_PKT_FLAG_DISCARD) {
- frame->flags |= AV_FRAME_FLAG_DISCARD;
- } else {
- frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD);
- }
+ if (pkt->flags & AV_PKT_FLAG_DISCARD) {
+ frame->flags |= AV_FRAME_FLAG_DISCARD;
+ } else {
+ frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD);
}
frame->reordered_opaque = avctx->reordered_opaque;
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return ret;
}
+
+int ff_decode_preinit(AVCodecContext *avctx)
+{
+ int ret = 0;
+
+ /* if the decoder init function was already called previously,
+ * free the already allocated subtitle_header before overwriting it */
+ av_freep(&avctx->subtitle_header);
+
+#if FF_API_THREAD_SAFE_CALLBACKS
+FF_DISABLE_DEPRECATION_WARNINGS
+ if ((avctx->thread_type & FF_THREAD_FRAME) &&
+ avctx->get_buffer2 != avcodec_default_get_buffer2 &&
+ !avctx->thread_safe_callbacks) {
+ av_log(avctx, AV_LOG_WARNING, "Requested frame threading with a "
+ "custom get_buffer2() implementation which is not marked as "
+ "thread safe. This is not supported anymore, make your "
+ "callback thread-safe.\n");
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && avctx->channels == 0 &&
+ !(avctx->codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)) {
+ av_log(avctx, AV_LOG_ERROR, "Decoder requires channel count but channels not set\n");
+ return AVERROR(EINVAL);
+ }
+ if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) {
+ av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
+ avctx->codec->max_lowres);
+ avctx->lowres = avctx->codec->max_lowres;
+ }
+ if (avctx->sub_charenc) {
+ if (avctx->codec_type != AVMEDIA_TYPE_SUBTITLE) {
+ av_log(avctx, AV_LOG_ERROR, "Character encoding is only "
+ "supported with subtitles codecs\n");
+ return AVERROR(EINVAL);
+ } else if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) {
+ av_log(avctx, AV_LOG_WARNING, "Codec '%s' is bitmap-based, "
+ "subtitles character encoding will be ignored\n",
+ avctx->codec_descriptor->name);
+ avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_DO_NOTHING;
+ } else {
+ /* input character encoding is set for a text based subtitle
+ * codec at this point */
+ if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_AUTOMATIC)
+ avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_PRE_DECODER;
+
+ if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_PRE_DECODER) {
+#if CONFIG_ICONV
+ iconv_t cd = iconv_open("UTF-8", avctx->sub_charenc);
+ if (cd == (iconv_t)-1) {
+ ret = AVERROR(errno);
+ av_log(avctx, AV_LOG_ERROR, "Unable to open iconv context "
+ "with input character encoding \"%s\"\n", avctx->sub_charenc);
+ return ret;
+ }
+ iconv_close(cd);
+#else
+ av_log(avctx, AV_LOG_ERROR, "Character encoding subtitles "
+ "conversion needs a libavcodec built with iconv support "
+ "for this codec\n");
+ return AVERROR(ENOSYS);
+#endif
+ }
+ }
+ }
+
+ avctx->pts_correction_num_faulty_pts =
+ avctx->pts_correction_num_faulty_dts = 0;
+ avctx->pts_correction_last_pts =
+ avctx->pts_correction_last_dts = INT64_MIN;
+
+ if ( !CONFIG_GRAY && avctx->flags & AV_CODEC_FLAG_GRAY
+ && avctx->codec_descriptor->type == AVMEDIA_TYPE_VIDEO)
+ av_log(avctx, AV_LOG_WARNING,
+ "gray decoding requested but not enabled at configuration time\n");
+ if (avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS) {
+ avctx->export_side_data |= AV_CODEC_EXPORT_DATA_MVS;
+ }
+
+ ret = decode_bsfs_init(avctx);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int ff_copy_palette(void *dst, const AVPacket *src, void *logctx)
+{
+ buffer_size_t size;
+ const void *pal = av_packet_get_side_data(src, AV_PKT_DATA_PALETTE, &size);
+
+ if (pal && size == AVPALETTE_SIZE) {
+ memcpy(dst, pal, AVPALETTE_SIZE);
+ return 1;
+ } else if (pal) {
+ av_log(logctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
+ }
+ return 0;
+}