summaryrefslogtreecommitdiffstats
path: root/media/ffvpx/libavcodec/decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/ffvpx/libavcodec/decode.c')
-rw-r--r--media/ffvpx/libavcodec/decode.c518
1 files changed, 149 insertions, 369 deletions
diff --git a/media/ffvpx/libavcodec/decode.c b/media/ffvpx/libavcodec/decode.c
index 421a8f1a3..fb1824be1 100644
--- a/media/ffvpx/libavcodec/decode.c
+++ b/media/ffvpx/libavcodec/decode.c
@@ -40,7 +40,6 @@
#include "avcodec.h"
#include "bytestream.h"
#include "decode.h"
-#include "hwaccel.h"
#include "internal.h"
#include "thread.h"
@@ -130,7 +129,7 @@ static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt)
if (pkt) {
ret = av_packet_copy_props(avci->last_pkt_props, pkt);
if (!ret)
- avci->last_pkt_props->size = pkt->size; // HACK: Needed for ff_decode_frame_props().
+ avci->last_pkt_props->size = pkt->size; // HACK: Needed for ff_init_buffer_info().
}
return ret;
}
@@ -370,7 +369,8 @@ static int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame)
DecodeSimpleContext *ds = &avci->ds;
AVPacket *pkt = ds->in_pkt;
// copy to ensure we do not change pkt
- int got_frame, actual_got_frame;
+ AVPacket tmp;
+ int got_frame, actual_got_frame, did_split;
int ret;
if (!pkt->data && !avci->draining) {
@@ -390,12 +390,31 @@ static int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame)
avctx->active_thread_type & FF_THREAD_FRAME))
return AVERROR_EOF;
+ tmp = *pkt;
+#if FF_API_MERGE_SD
+FF_DISABLE_DEPRECATION_WARNINGS
+ did_split = avci->compat_decode_partial_size ?
+ ff_packet_split_and_drop_side_data(&tmp) :
+ av_packet_split_side_data(&tmp);
+
+ if (did_split) {
+ ret = extract_packet_props(avctx->internal, &tmp);
+ if (ret < 0)
+ return ret;
+
+ ret = apply_param_change(avctx, &tmp);
+ if (ret < 0)
+ return ret;
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
got_frame = 0;
if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) {
- ret = ff_thread_decode_frame(avctx, frame, &got_frame, pkt);
+ ret = ff_thread_decode_frame(avctx, frame, &got_frame, &tmp);
} else {
- ret = avctx->codec->decode(avctx, frame, &got_frame, pkt);
+ ret = avctx->codec->decode(avctx, frame, &got_frame, &tmp);
if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS))
frame->pkt_dts = pkt->dts;
@@ -525,6 +544,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
}
}
+#if FF_API_MERGE_SD
+ if (did_split) {
+ av_packet_free_side_data(&tmp);
+ if(ret == tmp.size)
+ ret = pkt->size;
+ }
+#endif
if (avctx->codec->type == AVMEDIA_TYPE_AUDIO &&
!avci->showed_multi_packet_warning &&
@@ -614,28 +640,6 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
if (ret == AVERROR_EOF)
avci->draining_done = 1;
- if (!ret) {
- /* the only case where decode data is not set should be decoders
- * that do not call ff_get_buffer() */
- av_assert0((frame->private_ref && frame->private_ref->size == sizeof(FrameDecodeData)) ||
- !(avctx->codec->capabilities & AV_CODEC_CAP_DR1));
-
- if (frame->private_ref) {
- FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data;
-
- if (fdd->post_process) {
- ret = fdd->post_process(avctx, frame);
- if (ret < 0) {
- av_frame_unref(frame);
- return ret;
- }
- }
- }
- }
-
- /* free the per-frame decode data */
- av_buffer_unref(&frame->private_ref);
-
return ret;
}
@@ -1000,6 +1004,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
AVPacket *avpkt)
{
int i, ret = 0;
+ AVCodecInternal *avci = avctx->internal;
if (!avpkt->data && avpkt->size) {
av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
@@ -1016,9 +1021,29 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
get_subtitle_defaults(sub);
if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) {
- AVPacket pkt_recoded = *avpkt;
+ AVPacket pkt_recoded;
+ AVPacket tmp = *avpkt;
+#if FF_API_MERGE_SD
+FF_DISABLE_DEPRECATION_WARNINGS
+ int did_split = avci->compat_decode_partial_size ?
+ ff_packet_split_and_drop_side_data(&tmp) :
+ av_packet_split_side_data(&tmp);
+ //apply_param_change(avctx, &tmp);
+
+ if (did_split) {
+ /* FFMIN() prevents overflow in case the packet wasn't allocated with
+ * proper padding.
+ * If the side data is smaller than the buffer padding size, the
+ * remaining bytes should have already been filled with zeros by the
+ * original packet allocation anyway. */
+ memset(tmp.data + tmp.size, 0,
+ FFMIN(avpkt->size - tmp.size, AV_INPUT_BUFFER_PADDING_SIZE));
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
- ret = recode_subtitle(avctx, &pkt_recoded, avpkt);
+ pkt_recoded = tmp;
+ ret = recode_subtitle(avctx, &pkt_recoded, &tmp);
if (ret < 0) {
*got_sub_ptr = 0;
} else {
@@ -1057,8 +1082,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *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)) {
+ if (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");
@@ -1068,7 +1092,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
}
}
- if (avpkt->data != pkt_recoded.data) { // did we recode?
+ if (tmp.data != pkt_recoded.data) { // did we recode?
/* prevent from destroying side data from original packet */
pkt_recoded.side_data = NULL;
pkt_recoded.side_data_elems = 0;
@@ -1077,6 +1101,14 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
}
}
+#if FF_API_MERGE_SD
+ if (did_split) {
+ av_packet_free_side_data(&tmp);
+ if(ret == tmp.size)
+ ret = avpkt->size;
+ }
+#endif
+
if (*got_sub_ptr)
avctx->frame_number++;
}
@@ -1084,238 +1116,84 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
return ret;
}
-enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *avctx,
- const enum AVPixelFormat *fmt)
+static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt)
{
- const AVPixFmtDescriptor *desc;
- const AVCodecHWConfig *config;
- int i, n;
-
- // If a device was supplied when the codec was opened, assume that the
- // user wants to use it.
- if (avctx->hw_device_ctx && avctx->codec->hw_configs) {
- AVHWDeviceContext *device_ctx =
- (AVHWDeviceContext*)avctx->hw_device_ctx->data;
- for (i = 0;; i++) {
- config = &avctx->codec->hw_configs[i]->public;
- if (!config)
- break;
- if (!(config->methods &
- AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
- continue;
- if (device_ctx->type != config->device_type)
- continue;
- for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) {
- if (config->pix_fmt == fmt[n])
- return fmt[n];
- }
- }
- }
- // No device or other setup, so we have to choose from things which
- // don't any other external information.
-
- // If the last element of the list is a software format, choose it
- // (this should be best software format if any exist).
- for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++);
- desc = av_pix_fmt_desc_get(fmt[n - 1]);
- if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
- return fmt[n - 1];
-
- // Finally, traverse the list in order and choose the first entry
- // with no external dependencies (if there is no hardware configuration
- // information available then this just picks the first entry).
- for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) {
- for (i = 0;; i++) {
- config = avcodec_get_hw_config(avctx->codec, i);
- if (!config)
- break;
- if (config->pix_fmt == fmt[n])
- break;
- }
- if (!config) {
- // No specific config available, so the decoder must be able
- // to handle this format without any additional setup.
- return fmt[n];
- }
- if (config->methods & AV_CODEC_HW_CONFIG_METHOD_INTERNAL) {
- // Usable with only internal setup.
- return fmt[n];
- }
- }
-
- // Nothing is usable, give up.
- return AV_PIX_FMT_NONE;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+ return desc->flags & AV_PIX_FMT_FLAG_HWACCEL;
}
-int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
- enum AVHWDeviceType dev_type)
+enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt)
{
- AVHWDeviceContext *device_ctx;
- AVHWFramesContext *frames_ctx;
- int ret;
-
- if (!avctx->hwaccel)
- return AVERROR(ENOSYS);
-
- if (avctx->hw_frames_ctx)
- return 0;
- if (!avctx->hw_device_ctx) {
- av_log(avctx, AV_LOG_ERROR, "A hardware frames or device context is "
- "required for hardware accelerated decoding.\n");
- return AVERROR(EINVAL);
- }
-
- device_ctx = (AVHWDeviceContext *)avctx->hw_device_ctx->data;
- if (device_ctx->type != dev_type) {
- av_log(avctx, AV_LOG_ERROR, "Device type %s expected for hardware "
- "decoding, but got %s.\n", av_hwdevice_get_type_name(dev_type),
- av_hwdevice_get_type_name(device_ctx->type));
- return AVERROR(EINVAL);
- }
-
- ret = avcodec_get_hw_frames_parameters(avctx,
- avctx->hw_device_ctx,
- avctx->hwaccel->pix_fmt,
- &avctx->hw_frames_ctx);
- if (ret < 0)
- return ret;
-
- frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
-
-
- if (frames_ctx->initial_pool_size) {
- // We guarantee 4 base work surfaces. The function above guarantees 1
- // (the absolute minimum), so add the missing count.
- frames_ctx->initial_pool_size += 3;
- }
+ while (*fmt != AV_PIX_FMT_NONE && is_hwaccel_pix_fmt(*fmt))
+ ++fmt;
+ return fmt[0];
+}
- ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
- if (ret < 0) {
- av_buffer_unref(&avctx->hw_frames_ctx);
- return ret;
- }
+static AVHWAccel *find_hwaccel(enum AVCodecID codec_id,
+ enum AVPixelFormat pix_fmt)
+{
+ AVHWAccel *hwaccel = NULL;
- return 0;
+ while ((hwaccel = av_hwaccel_next(hwaccel)))
+ if (hwaccel->id == codec_id
+ && hwaccel->pix_fmt == pix_fmt)
+ return hwaccel;
+ return NULL;
}
-int avcodec_get_hw_frames_parameters(AVCodecContext *avctx,
- AVBufferRef *device_ref,
- enum AVPixelFormat hw_pix_fmt,
- AVBufferRef **out_frames_ref)
+static int setup_hwaccel(AVCodecContext *avctx,
+ const enum AVPixelFormat fmt,
+ const char *name)
{
- AVBufferRef *frames_ref = NULL;
- const AVCodecHWConfigInternal *hw_config;
- const AVHWAccel *hwa;
- int i, ret;
+ AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt);
+ int ret = 0;
- for (i = 0;; i++) {
- hw_config = avctx->codec->hw_configs[i];
- if (!hw_config)
- return AVERROR(ENOENT);
- if (hw_config->public.pix_fmt == hw_pix_fmt)
- break;
- }
-
- hwa = hw_config->hwaccel;
- if (!hwa || !hwa->frame_params)
+ if (!hwa) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Could not find an AVHWAccel for the pixel format: %s",
+ name);
return AVERROR(ENOENT);
-
- frames_ref = av_hwframe_ctx_alloc(device_ref);
- if (!frames_ref)
- return AVERROR(ENOMEM);
-
- ret = hwa->frame_params(avctx, frames_ref);
- if (ret >= 0) {
- AVHWFramesContext *frames_ctx = (AVHWFramesContext*)frames_ref->data;
-
- if (frames_ctx->initial_pool_size) {
- // If the user has requested that extra output surfaces be
- // available then add them here.
- if (avctx->extra_hw_frames > 0)
- frames_ctx->initial_pool_size += avctx->extra_hw_frames;
-
- // If frame threading is enabled then an extra surface per thread
- // is also required.
- if (avctx->active_thread_type & FF_THREAD_FRAME)
- frames_ctx->initial_pool_size += avctx->thread_count;
- }
-
- *out_frames_ref = frames_ref;
- } else {
- av_buffer_unref(&frames_ref);
}
- return ret;
-}
-
-static int hwaccel_init(AVCodecContext *avctx,
- const AVCodecHWConfigInternal *hw_config)
-{
- const AVHWAccel *hwaccel;
- int err;
- hwaccel = hw_config->hwaccel;
- if (hwaccel->capabilities & AV_HWACCEL_CODEC_CAP_EXPERIMENTAL &&
+ if (hwa->capabilities & AV_HWACCEL_CODEC_CAP_EXPERIMENTAL &&
avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
av_log(avctx, AV_LOG_WARNING, "Ignoring experimental hwaccel: %s\n",
- hwaccel->name);
+ hwa->name);
return AVERROR_PATCHWELCOME;
}
- if (hwaccel->priv_data_size) {
- avctx->internal->hwaccel_priv_data =
- av_mallocz(hwaccel->priv_data_size);
+ if (hwa->priv_data_size) {
+ avctx->internal->hwaccel_priv_data = av_mallocz(hwa->priv_data_size);
if (!avctx->internal->hwaccel_priv_data)
return AVERROR(ENOMEM);
}
- avctx->hwaccel = hwaccel;
- if (hwaccel->init) {
- err = hwaccel->init(avctx);
- if (err < 0) {
- av_log(avctx, AV_LOG_ERROR, "Failed setup for format %s: "
- "hwaccel initialisation returned error.\n",
- av_get_pix_fmt_name(hw_config->public.pix_fmt));
+ avctx->hwaccel = hwa;
+ if (hwa->init) {
+ ret = hwa->init(avctx);
+ if (ret < 0) {
av_freep(&avctx->internal->hwaccel_priv_data);
avctx->hwaccel = NULL;
- return err;
+ return ret;
}
}
return 0;
}
-static void hwaccel_uninit(AVCodecContext *avctx)
-{
- if (avctx->hwaccel && avctx->hwaccel->uninit)
- avctx->hwaccel->uninit(avctx);
-
- av_freep(&avctx->internal->hwaccel_priv_data);
-
- avctx->hwaccel = NULL;
-
- av_buffer_unref(&avctx->hw_frames_ctx);
-}
-
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
{
const AVPixFmtDescriptor *desc;
enum AVPixelFormat *choices;
- enum AVPixelFormat ret, user_choice;
- const AVCodecHWConfigInternal *hw_config;
- const AVCodecHWConfig *config;
- int i, n, err;
-
- // Find end of list.
- for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++);
- // Must contain at least one entry.
+ enum AVPixelFormat ret;
+ unsigned n = 0;
+
+ while (fmt[n] != AV_PIX_FMT_NONE)
+ ++n;
+
av_assert0(n >= 1);
- // If a software format is available, it must be the last entry.
- desc = av_pix_fmt_desc_get(fmt[n - 1]);
- if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
- // No software format is available.
- } else {
- avctx->sw_pix_fmt = fmt[n - 1];
- }
+ avctx->sw_pix_fmt = fmt[n - 1];
+ av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt));
choices = av_malloc_array(n + 1, sizeof(*choices));
if (!choices)
@@ -1324,108 +1202,48 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
memcpy(choices, fmt, (n + 1) * sizeof(*choices));
for (;;) {
- // Remove the previous hwaccel, if there was one.
- hwaccel_uninit(avctx);
+ if (avctx->hwaccel && avctx->hwaccel->uninit)
+ avctx->hwaccel->uninit(avctx);
+ av_freep(&avctx->internal->hwaccel_priv_data);
+ avctx->hwaccel = NULL;
- user_choice = avctx->get_format(avctx, choices);
- if (user_choice == AV_PIX_FMT_NONE) {
- // Explicitly chose nothing, give up.
- ret = AV_PIX_FMT_NONE;
- break;
- }
+ av_buffer_unref(&avctx->hw_frames_ctx);
+
+ ret = avctx->get_format(avctx, choices);
- desc = av_pix_fmt_desc_get(user_choice);
+ desc = av_pix_fmt_desc_get(ret);
if (!desc) {
- av_log(avctx, AV_LOG_ERROR, "Invalid format returned by "
- "get_format() callback.\n");
ret = AV_PIX_FMT_NONE;
break;
}
- av_log(avctx, AV_LOG_DEBUG, "Format %s chosen by get_format().\n",
- desc->name);
- for (i = 0; i < n; i++) {
- if (choices[i] == user_choice)
- break;
- }
- if (i == n) {
- av_log(avctx, AV_LOG_ERROR, "Invalid return from get_format(): "
- "%s not in possible list.\n", desc->name);
+ if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
break;
- }
+#if FF_API_CAP_VDPAU
+ if (avctx->codec->capabilities&AV_CODEC_CAP_HWACCEL_VDPAU)
+ break;
+#endif
- if (avctx->codec->hw_configs) {
- for (i = 0;; i++) {
- hw_config = avctx->codec->hw_configs[i];
- if (!hw_config)
- break;
- if (hw_config->public.pix_fmt == user_choice)
- break;
+ if (avctx->hw_frames_ctx) {
+ AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
+ if (hw_frames_ctx->format != ret) {
+ av_log(avctx, AV_LOG_ERROR, "Format returned from get_buffer() "
+ "does not match the format of provided AVHWFramesContext\n");
+ ret = AV_PIX_FMT_NONE;
+ break;
}
- } else {
- hw_config = NULL;
}
- if (!hw_config) {
- // No config available, so no extra setup required.
- ret = user_choice;
+ if (!setup_hwaccel(avctx, ret, desc->name))
break;
- }
- config = &hw_config->public;
-
- if (config->methods &
- AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX &&
- avctx->hw_frames_ctx) {
- const AVHWFramesContext *frames_ctx =
- (AVHWFramesContext*)avctx->hw_frames_ctx->data;
- if (frames_ctx->format != user_choice) {
- av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: "
- "does not match the format of the provided frames "
- "context.\n", desc->name);
- goto try_again;
- }
- } else if (config->methods &
- AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
- avctx->hw_device_ctx) {
- const AVHWDeviceContext *device_ctx =
- (AVHWDeviceContext*)avctx->hw_device_ctx->data;
- if (device_ctx->type != config->device_type) {
- av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: "
- "does not match the type of the provided device "
- "context.\n", desc->name);
- goto try_again;
- }
- } else if (config->methods &
- AV_CODEC_HW_CONFIG_METHOD_INTERNAL) {
- // Internal-only setup, no additional configuration.
- } else if (config->methods &
- AV_CODEC_HW_CONFIG_METHOD_AD_HOC) {
- // Some ad-hoc configuration we can't see and can't check.
- } else {
- av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: "
- "missing configuration.\n", desc->name);
- goto try_again;
- }
- if (hw_config->hwaccel) {
- av_log(avctx, AV_LOG_DEBUG, "Format %s requires hwaccel "
- "initialisation.\n", desc->name);
- err = hwaccel_init(avctx, hw_config);
- if (err < 0)
- goto try_again;
- }
- ret = user_choice;
- break;
- try_again:
- av_log(avctx, AV_LOG_DEBUG, "Format %s not usable, retrying "
- "get_format() without it.\n", desc->name);
- for (i = 0; i < n; i++) {
- if (choices[i] == user_choice)
- break;
- }
- for (; i + 1 < n; i++)
- choices[i] = choices[i + 1];
- --n;
+ /* Remove failed hwaccel from choices */
+ for (n = 0; choices[n] != ret; n++)
+ av_assert0(choices[n] != AV_PIX_FMT_NONE);
+
+ do
+ choices[n] = choices[n + 1];
+ while (choices[n++] != AV_PIX_FMT_NONE);
}
av_freep(&choices);
@@ -1614,7 +1432,7 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
pic->linesize[i] = 0;
}
if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
- ((desc->flags & FF_PSEUDOPAL) && pic->data[1]))
+ desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
avpriv_set_systematic_pal2((uint32_t *)pic->data[1], pic->format);
if (s->debug & FF_DEBUG_BUFFERS)
@@ -1662,7 +1480,7 @@ static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame)
return av_packet_unpack_dictionary(side_metadata, size, frame_md);
}
-int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
+int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame)
{
const AVPacket *pkt = avctx->internal->last_pkt_props;
int i;
@@ -1770,6 +1588,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
return 0;
}
+int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
+{
+ return ff_init_buffer_info(avctx, frame);
+}
+
static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame)
{
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -1779,11 +1602,12 @@ static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame)
int flags = desc ? desc->flags : 0;
if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL))
num_planes = 2;
- if ((flags & FF_PSEUDOPAL) && frame->data[1])
- 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])
@@ -1793,43 +1617,6 @@ static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame)
}
}
-static void decode_data_free(void *opaque, uint8_t *data)
-{
- FrameDecodeData *fdd = (FrameDecodeData*)data;
-
- if (fdd->post_process_opaque_free)
- fdd->post_process_opaque_free(fdd->post_process_opaque);
-
- if (fdd->hwaccel_priv_free)
- fdd->hwaccel_priv_free(fdd->hwaccel_priv);
-
- av_freep(&fdd);
-}
-
-int ff_attach_decode_data(AVFrame *frame)
-{
- AVBufferRef *fdd_buf;
- FrameDecodeData *fdd;
-
- av_assert1(!frame->private_ref);
- av_buffer_unref(&frame->private_ref);
-
- fdd = av_mallocz(sizeof(*fdd));
- if (!fdd)
- return AVERROR(ENOMEM);
-
- fdd_buf = av_buffer_create((uint8_t*)fdd, sizeof(*fdd), decode_data_free,
- NULL, AV_BUFFER_FLAG_READONLY);
- if (!fdd_buf) {
- av_freep(&fdd);
- return AVERROR(ENOMEM);
- }
-
- frame->private_ref = fdd_buf;
-
- return 0;
-}
-
static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
{
const AVHWAccel *hwaccel = avctx->hwaccel;
@@ -1866,14 +1653,8 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
avctx->sw_pix_fmt = avctx->pix_fmt;
ret = avctx->get_buffer2(avctx, frame, flags);
- if (ret < 0)
- goto end;
-
- validate_avframe_allocation(avctx, frame);
-
- ret = ff_attach_decode_data(frame);
- if (ret < 0)
- goto end;
+ if (ret >= 0)
+ validate_avframe_allocation(avctx, frame);
end:
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions &&
@@ -1882,9 +1663,6 @@ end:
frame->height = avctx->height;
}
- if (ret < 0)
- av_frame_unref(frame);
-
return ret;
}
@@ -1911,6 +1689,8 @@ static int reget_buffer_internal(AVCodecContext *avctx, AVFrame *frame)
av_frame_unref(frame);
}
+ ff_init_buffer_info(avctx, frame);
+
if (!frame->data[0])
return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF);