const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format);
int i;
- if (pic->data[0]) {
- av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n");
+ if (pic->data[0] || pic->data[1] || pic->data[2] || pic->data[3]) {
+ av_log(s, AV_LOG_ERROR, "pic->data[*]!=NULL in avcodec_default_get_buffer\n");
return -1;
}
return ff_init_buffer_info(avctx, frame);
}
+static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame)
+{
+ if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+ int i;
+ int num_planes = av_pix_fmt_count_planes(frame->format);
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+ int flags = desc ? desc->flags : 0;
+ if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL))
+ num_planes = 2;
+ for (i = 0; i < num_planes; i++) {
+ av_assert0(frame->data[i]);
+ }
+ // For now do not enforce anything for palette of pseudopal formats
+ if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PSEUDOPAL))
+ num_planes = 2;
+ // For formats without data like hwaccel allow unused pointers to be non-NULL.
+ for (i = num_planes; num_planes > 0 && i < FF_ARRAY_ELEMS(frame->data); i++) {
+ if (frame->data[i])
+ av_log(avctx, AV_LOG_ERROR, "Buffer returned by get_buffer2() did not zero unused plane pointers\n");
+ frame->data[i] = NULL;
+ }
+ }
+}
+
static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
{
const AVHWAccel *hwaccel = avctx->hwaccel;
frame->height = FFMAX(avctx->height, AV_CEIL_RSHIFT(avctx->coded_height, avctx->lowres));
override_dimensions = 0;
}
+
+ if (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3]) {
+ av_log(avctx, AV_LOG_ERROR, "pic->data[*]!=NULL in get_buffer_internal\n");
+ return AVERROR(EINVAL);
+ }
}
ret = ff_decode_frame_props(avctx, frame);
if (ret < 0)
avctx->sw_pix_fmt = avctx->pix_fmt;
ret = avctx->get_buffer2(avctx, frame, flags);
+ if (ret >= 0)
+ validate_avframe_allocation(avctx, frame);
end:
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions) {
return 1;
}
+#if FF_API_ASS_TIMING
static void insert_ts(AVBPrint *buf, int ts)
{
if (ts == -1) {
av_bprint_finalize(&buf, NULL);
return 0;
}
+#endif
int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
int *got_sub_ptr,
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)
ret = convert_sub_to_old_ass_form(sub, avpkt, avctx->time_base);
+#endif
if (sub->num_rects && !sub->end_display_time && avpkt->duration &&
avctx->pkt_timebase.num) {
return props;
}
+
+#ifdef TEST
+int main(void){
+ avcodec_register_all();
+ AVCodec *codec = NULL;
+ int ret = 0;
+
+ while (codec = av_codec_next(codec)) {
+ if (av_codec_is_encoder(codec)) {
+ if (codec->type == AVMEDIA_TYPE_AUDIO) {
+ if (!codec->sample_fmts) {
+ av_log(NULL, AV_LOG_FATAL, "Encoder %s is missing the sample_fmts field\n", codec->name);
+ ret = 1;
+ }
+ }
+ }
+ }
+ return ret;
+}
+#endif /* TEST */