#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
+#include "libavutil/mem_internal.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "internal.h"
+#include "qp_table.h"
#include "avfilter.h"
#define MAX_LEVEL 8 /* quality levels */
int outbuf_size;
uint8_t *outbuf;
AVCodecContext *avctx_enc[BLOCK*BLOCK];
+ AVPacket *pkt;
AVFrame *frame;
AVFrame *frame_dec;
- uint8_t *non_b_qp_table;
- int non_b_qp_alloc_size;
+ int8_t *non_b_qp_table;
+ int non_b_qp_stride;
int use_bframe_qp;
} USPPContext;
const int y1c = y1 >> p->vsub;
const int BLOCKc = BLOCK >> p->hsub;
int offset;
- AVPacket pkt = {0};
+ AVPacket *pkt = p->pkt;
int got_pkt_ptr;
- av_init_packet(&pkt);
- pkt.data = p->outbuf;
- pkt.size = p->outbuf_size;
+ av_packet_unref(pkt);
+ pkt->data = p->outbuf;
+ pkt->size = p->outbuf_size;
p->frame->data[0] = p->src[0] + x1 + y1 * p->frame->linesize[0];
p->frame->data[1] = p->src[1] + x1c + y1c * p->frame->linesize[1];
p->frame->data[2] = p->src[2] + x1c + y1c * p->frame->linesize[2];
p->frame->format = p->avctx_enc[i]->pix_fmt;
- ret = avcodec_encode_video2(p->avctx_enc[i], &pkt, p->frame, &got_pkt_ptr);
+ ret = avcodec_encode_video2(p->avctx_enc[i], pkt, p->frame, &got_pkt_ptr);
if (ret < 0) {
av_log(p->avctx_enc[i], AV_LOG_ERROR, "Encoding failed\n");
continue;
}
+ av_packet_unref(pkt);
p->frame_dec = p->avctx_enc[i]->coded_frame;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
int i;
- AVCodec *enc = avcodec_find_encoder(AV_CODEC_ID_SNOW);
+ const AVCodec *enc = avcodec_find_encoder(AV_CODEC_ID_SNOW);
if (!enc) {
av_log(ctx, AV_LOG_ERROR, "SNOW encoder not found.\n");
return AVERROR(EINVAL);
uspp->outbuf_size = (width + BLOCK) * (height + BLOCK) * 10;
if (!(uspp->frame = av_frame_alloc()))
return AVERROR(ENOMEM);
+ if (!(uspp->pkt = av_packet_alloc()))
+ return AVERROR(ENOMEM);
if (!(uspp->outbuf = av_malloc(uspp->outbuf_size)))
return AVERROR(ENOMEM);
AVFrame *out = in;
int qp_stride = 0;
- uint8_t *qp_table = NULL;
+ int8_t *qp_table = NULL;
+ int ret = 0;
/* if we are not in a constant user quantizer mode and we don't want to use
* the quantizers from the B-frames (B-frames often have a higher QP), we
* need to save the qp table from the last non B-frame; this is what the
* following code block does */
- if (!uspp->qp) {
- qp_table = av_frame_get_qp_table(in, &qp_stride, &uspp->qscale_type);
-
- if (qp_table && !uspp->use_bframe_qp && in->pict_type != AV_PICTURE_TYPE_B) {
- int w, h;
-
- /* if the qp stride is not set, it means the QP are only defined on
- * a line basis */
- if (!qp_stride) {
- w = AV_CEIL_RSHIFT(inlink->w, 4);
- h = 1;
- } else {
- w = qp_stride;
- h = AV_CEIL_RSHIFT(inlink->h, 4);
- }
-
- if (w * h > uspp->non_b_qp_alloc_size) {
- int ret = av_reallocp_array(&uspp->non_b_qp_table, w, h);
- if (ret < 0) {
- uspp->non_b_qp_alloc_size = 0;
- return ret;
- }
- uspp->non_b_qp_alloc_size = w * h;
- }
+ if (!uspp->qp && (uspp->use_bframe_qp || in->pict_type != AV_PICTURE_TYPE_B)) {
+ ret = ff_qp_table_extract(in, &qp_table, &qp_stride, NULL, &uspp->qscale_type);
+ if (ret < 0) {
+ av_frame_free(&in);
+ return ret;
+ }
- av_assert0(w * h <= uspp->non_b_qp_alloc_size);
- memcpy(uspp->non_b_qp_table, qp_table, w * h);
+ if (!uspp->use_bframe_qp && in->pict_type != AV_PICTURE_TYPE_B) {
+ av_freep(&uspp->non_b_qp_table);
+ uspp->non_b_qp_table = qp_table;
+ uspp->non_b_qp_stride = qp_stride;
}
}
if (uspp->log2_count && !ctx->is_disabled) {
- if (!uspp->use_bframe_qp && uspp->non_b_qp_table)
+ if (!uspp->use_bframe_qp && uspp->non_b_qp_table) {
qp_table = uspp->non_b_qp_table;
+ qp_stride = uspp->non_b_qp_stride;
+ }
if (qp_table || uspp->qp) {
out = ff_get_video_buffer(outlink, aligned_w, aligned_h);
if (!out) {
av_frame_free(&in);
+ if (qp_table != uspp->non_b_qp_table)
+ av_free(qp_table);
return AVERROR(ENOMEM);
}
av_frame_copy_props(out, in);
inlink->w, inlink->h);
av_frame_free(&in);
}
- return ff_filter_frame(outlink, out);
+ ret = ff_filter_frame(outlink, out);
+ if (qp_table != uspp->non_b_qp_table)
+ av_freep(&qp_table);
+ return ret;
}
static av_cold void uninit(AVFilterContext *ctx)
av_freep(&uspp->non_b_qp_table);
av_freep(&uspp->outbuf);
+ av_packet_free(&uspp->pkt);
av_frame_free(&uspp->frame);
}
{ NULL }
};
-AVFilter ff_vf_uspp = {
+const AVFilter ff_vf_uspp = {
.name = "uspp",
.description = NULL_IF_CONFIG_SMALL("Apply Ultra Simple / Slow Post-processing filter."),
.priv_size = sizeof(USPPContext),