diff --git a/doc/APIchanges b/doc/APIchanges index 121fbee9ce..f6ad2169a2 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2017-10-21 API changes, most recent first: +2018-04-03 - xxxxxxx - lavu 56.13.100 - pixdesc.h + Deprecate AV_PIX_FMT_FLAG_PSEUDOPAL and make allocating a pseudo palette + optional for API users (see AV_PIX_FMT_FLAG_PSEUDOPAL doxygen for details). + 2018-04-01 - xxxxxxx - lavc 58.17.100 - avcodec.h Add av_packet_make_refcounted(). diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 2582649fd3..82dfe4f58a 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -3118,7 +3118,9 @@ static void ffprobe_show_pixel_formats(WriterContext *w) PRINT_PIX_FMT_FLAG(HWACCEL, "hwaccel"); PRINT_PIX_FMT_FLAG(PLANAR, "planar"); PRINT_PIX_FMT_FLAG(RGB, "rgb"); +#if FF_API_PSEUDOPAL PRINT_PIX_FMT_FLAG(PSEUDOPAL, "pseudopal"); +#endif PRINT_PIX_FMT_FLAG(ALPHA, "alpha"); writer_print_section_footer(w); } diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 40c8a8855c..d883a5f9fc 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1614,7 +1614,7 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) pic->linesize[i] = 0; } if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) + ((desc->flags & FF_PSEUDOPAL) && pic->data[1])) avpriv_set_systematic_pal2((uint32_t *)pic->data[1], pic->format); if (s->debug & FF_DEBUG_BUFFERS) @@ -1782,9 +1782,6 @@ static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame) 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]) diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index b4a183c5b7..7658a51685 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -950,7 +950,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + desc->flags & FF_PSEUDOPAL) { dst[1] = p->data[1]; src[1] = f->last_picture.f->data[1]; } diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index 1893b26444..53f5b76e93 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -92,12 +92,14 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) return AVERROR(EINVAL); } - if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL)) { + if (desc->flags & (AV_PIX_FMT_FLAG_PAL | FF_PSEUDOPAL)) { context->palette = av_buffer_alloc(AVPALETTE_SIZE); if (!context->palette) return AVERROR(ENOMEM); +#if FF_API_PSEUDOPAL if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) avpriv_set_systematic_pal2((uint32_t*)context->palette->data, avctx->pix_fmt); +#endif else { memset(context->palette->data, 0, AVPALETTE_SIZE); if (avctx->bits_per_coded_sample == 1) @@ -423,7 +425,7 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, } if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->frame_size) || - (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) { + (desc->flags & FF_PSEUDOPAL)) { frame->buf[1] = av_buffer_ref(context->palette); if (!frame->buf[1]) { av_buffer_unref(&frame->buf[0]); diff --git a/libavcodec/smvjpegdec.c b/libavcodec/smvjpegdec.c index 0b05d19f7b..7ea82ebfee 100644 --- a/libavcodec/smvjpegdec.c +++ b/libavcodec/smvjpegdec.c @@ -71,7 +71,7 @@ static inline void smv_img_pnt(uint8_t *dst_data[4], uint8_t *src_data[4], src_linesizes[i], h, nlines); } if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) + desc->flags & FF_PSEUDOPAL) dst_data[1] = src_data[1]; } diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c index 17e26c764a..db8c7a6226 100644 --- a/libavfilter/drawutils.c +++ b/libavfilter/drawutils.c @@ -184,7 +184,7 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) if (!desc || !desc->name) return AVERROR(EINVAL); - if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL | AV_PIX_FMT_FLAG_ALPHA)) + if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL | AV_PIX_FMT_FLAG_ALPHA)) return AVERROR(ENOSYS); if (format == AV_PIX_FMT_P010LE || format == AV_PIX_FMT_P010BE || format == AV_PIX_FMT_P016LE || format == AV_PIX_FMT_P016BE) return AVERROR(ENOSYS); diff --git a/libavfilter/framepool.c b/libavfilter/framepool.c index da2ac5cf69..3b178cebb8 100644 --- a/libavfilter/framepool.c +++ b/libavfilter/framepool.c @@ -103,7 +103,7 @@ FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size), } if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + desc->flags & FF_PSEUDOPAL) { pool->pools[1] = av_buffer_pool_init(AVPALETTE_SIZE, alloc); if (!pool->pools[1]) goto fail; @@ -227,7 +227,7 @@ AVFrame *ff_frame_pool_get(FFFramePool *pool) } if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + desc->flags & FF_PSEUDOPAL) { enum AVPixelFormat format = pool->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : pool->format; diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index 0fdc4949e3..84be4c7d0d 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -288,7 +288,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) frame->data[0] += s->y * frame->linesize[0]; frame->data[0] += s->x * s->max_step[0]; - if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) { + if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & FF_PSEUDOPAL)) { for (i = 1; i < 3; i ++) { if (frame->data[i]) { frame->data[i] += (s->y >> s->vsub) * frame->linesize[i]; diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c index d6423acb91..2d0749e20b 100644 --- a/libavfilter/vf_pixdesctest.c +++ b/libavfilter/vf_pixdesctest.c @@ -81,7 +81,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) /* copy palette */ if (priv->pix_desc->flags & AV_PIX_FMT_FLAG_PAL || - priv->pix_desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) + ((priv->pix_desc->flags & FF_PSEUDOPAL) && out->data[1] && in->data[1])) memcpy(out->data[1], in->data[1], AVPALETTE_SIZE); for (c = 0; c < priv->pix_desc->nb_components; c++) { diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 9f45032e85..f741419e7e 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -261,11 +261,10 @@ static int config_props(AVFilterLink *outlink) /* TODO: make algorithm configurable */ - scale->input_is_pal = desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL; + scale->input_is_pal = desc->flags & AV_PIX_FMT_FLAG_PAL; if (outfmt == AV_PIX_FMT_PAL8) outfmt = AV_PIX_FMT_BGR8; scale->output_is_pal = av_pix_fmt_desc_get(outfmt)->flags & AV_PIX_FMT_FLAG_PAL || - av_pix_fmt_desc_get(outfmt)->flags & AV_PIX_FMT_FLAG_PSEUDOPAL; + av_pix_fmt_desc_get(outfmt)->flags & FF_PSEUDOPAL; if (scale->sws) sws_freeContext(scale->sws); diff --git a/libavfilter/vf_shuffleplanes.c b/libavfilter/vf_shuffleplanes.c index 4bc7b79f87..32d2d585f3 100644 --- a/libavfilter/vf_shuffleplanes.c +++ b/libavfilter/vf_shuffleplanes.c @@ -69,7 +69,7 @@ static av_cold int shuffleplanes_config_input(AVFilterLink *inlink) } if ((desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) && + desc->flags & FF_PSEUDOPAL) && (i == 1) != (s->map[i] == 1)) { av_log(ctx, AV_LOG_ERROR, "Cannot map between a palette plane and a data plane.\n"); diff --git a/libavutil/frame.c b/libavutil/frame.c index ea13cd3ed6..00215ac29a 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -247,7 +247,7 @@ static int get_video_buffer(AVFrame *frame, int align) frame->data[i] = frame->buf[i]->data; } - if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & FF_PSEUDOPAL) { av_buffer_unref(&frame->buf[1]); frame->buf[1] = av_buffer_alloc(AVPALETTE_SIZE); if (!frame->buf[1]) @@ -848,7 +848,7 @@ static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame, int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0; int shift_y = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; - if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL) && i == 1) { + if (desc->flags & (AV_PIX_FMT_FLAG_PAL | FF_PSEUDOPAL) && i == 1) { offsets[i] = 0; break; } diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index 5af4fc20a0..4938a7ef67 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -125,7 +125,7 @@ int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int hei size[0] = linesizes[0] * height; if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + desc->flags & FF_PSEUDOPAL) { data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */ return size[0] + 256 * 4; } @@ -216,7 +216,7 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4], av_free(buf); return ret; } - if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + if (desc->flags & AV_PIX_FMT_FLAG_PAL || (desc->flags & FF_PSEUDOPAL && pointers[1])) { avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt); if (align < 4) { av_log(NULL, AV_LOG_ERROR, "Formats with a palette require a minimum alignment of 4\n"); @@ -225,7 +225,7 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4], } if ((desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) && + desc->flags & FF_PSEUDOPAL) && pointers[1] && pointers[1] - pointers[0] > linesizes[0] * h) { /* zero-initialize the padding before the palette */ memset(pointers[0] + linesizes[0] * h, 0, @@ -354,12 +354,13 @@ static void image_copy(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], return; if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + desc->flags & FF_PSEUDOPAL) { copy_plane(dst_data[0], dst_linesizes[0], src_data[0], src_linesizes[0], width, height); /* copy the palette */ - memcpy(dst_data[1], src_data[1], 4*256); + if ((desc->flags & AV_PIX_FMT_FLAG_PAL) || (dst_data[1] && src_data[1])) + memcpy(dst_data[1], src_data[1], 4*256); } else { int i, planes_nb = 0; @@ -442,7 +443,7 @@ int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, return ret; // do not include palette for these pseudo-paletted formats - if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) + if (desc->flags & FF_PSEUDOPAL) return FFALIGN(width, align) * height; return av_image_fill_arrays(data, linesize, NULL, pix_fmt, diff --git a/libavutil/internal.h b/libavutil/internal.h index c77dfa7d3c..06bd561e82 100644 --- a/libavutil/internal.h +++ b/libavutil/internal.h @@ -360,4 +360,13 @@ void ff_check_pixfmt_descriptors(void); */ int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp); +// Helper macro for AV_PIX_FMT_FLAG_PSEUDOPAL deprecation. Code inside FFmpeg +// should always use FF_PSEUDOPAL. Once the public API flag gets removed, all +// code using it is dead code. +#if FF_API_PSEUDOPAL +#define FF_PSEUDOPAL AV_PIX_FMT_FLAG_PSEUDOPAL +#else +#define FF_PSEUDOPAL 0 +#endif + #endif /* AVUTIL_INTERNAL_H */ diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index e77d5f44b9..8ed52751c1 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -257,7 +257,7 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { .comp = { { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ }, - .flags = AV_PIX_FMT_FLAG_PSEUDOPAL, + .flags = FF_PSEUDOPAL, .alias = "gray8,y8", }, [AV_PIX_FMT_MONOWHITE] = { @@ -362,7 +362,7 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { { 0, 1, 0, 3, 3, 0, 2, 1 }, /* G */ { 0, 1, 0, 6, 2, 0, 1, 1 }, /* B */ }, - .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, }, [AV_PIX_FMT_BGR4] = { .name = "bgr4", @@ -386,7 +386,7 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { { 0, 1, 0, 1, 2, 0, 1, 1 }, /* G */ { 0, 1, 0, 3, 1, 0, 0, 1 }, /* B */ }, - .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, }, [AV_PIX_FMT_RGB8] = { .name = "rgb8", @@ -398,7 +398,7 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { { 0, 1, 0, 3, 3, 0, 2, 1 }, /* G */ { 0, 1, 0, 0, 3, 0, 2, 1 }, /* B */ }, - .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, }, [AV_PIX_FMT_RGB4] = { .name = "rgb4", @@ -422,7 +422,7 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { { 0, 1, 0, 1, 2, 0, 1, 1 }, /* G */ { 0, 1, 0, 0, 1, 0, 0, 1 }, /* B */ }, - .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, }, [AV_PIX_FMT_NV12] = { .name = "nv12", diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h index ea046033a3..1ab372782a 100644 --- a/libavutil/pixdesc.h +++ b/libavutil/pixdesc.h @@ -154,6 +154,14 @@ typedef struct AVPixFmtDescriptor { * in some cases be simpler. Or the data can be interpreted purely based on * the pixel format without using the palette. * An example of a pseudo-paletted format is AV_PIX_FMT_GRAY8 + * + * @deprecated This flag is deprecated, and will be removed. When it is removed, + * the extra palette allocation in AVFrame.data[1] is removed as well. Only + * actual paletted formats (as indicated by AV_PIX_FMT_FLAG_PAL) will have a + * palette. Starting with FFmpeg versions which have this flag deprecated, the + * extra "pseudo" palette is already ignored, and API users are not required to + * allocate a palette for AV_PIX_FMT_FLAG_PSEUDOPAL formats (it was required + * before the deprecation, though). */ #define AV_PIX_FMT_FLAG_PSEUDOPAL (1 << 6) diff --git a/libavutil/version.h b/libavutil/version.h index d3dd2df544..d81d51011b 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 56 -#define LIBAVUTIL_VERSION_MINOR 12 +#define LIBAVUTIL_VERSION_MINOR 13 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ @@ -126,6 +126,9 @@ #ifndef FF_API_FRAME_GET_SET #define FF_API_FRAME_GET_SET (LIBAVUTIL_VERSION_MAJOR < 57) #endif +#ifndef FF_API_PSEUDOPAL +#define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) +#endif /** diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index c9120d8f5f..1703856ab2 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -806,9 +806,17 @@ static av_always_inline int isPlanarRGB(enum AVPixelFormat pix_fmt) static av_always_inline int usePal(enum AVPixelFormat pix_fmt) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - av_assert0(desc); - return (desc->flags & AV_PIX_FMT_FLAG_PAL) || (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL); + switch (pix_fmt) { + case AV_PIX_FMT_PAL8: + case AV_PIX_FMT_BGR4_BYTE: + case AV_PIX_FMT_BGR8: + case AV_PIX_FMT_GRAY8: + case AV_PIX_FMT_RGB4_BYTE: + case AV_PIX_FMT_RGB8: + return 1; + default: + return 0; + } } extern const uint64_t ff_dither4[2];