Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -44,6 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | typedef struct USPPContext { |
| 45 | 45 | const AVClass *av_class; |
| 46 | 46 | int log2_count; |
| 47 | + int count; | |
| 47 | 48 | int hsub, vsub; |
| 48 | 49 | int qp; |
| 49 | 50 | char *codec_name; |
| @@ -55,12 +56,13 @@ typedef struct USPPContext { · 5 unmodified lines | ||
| 55 | 56 | uint8_t *outbuf; |
| 56 | 57 | AVCodecContext *avctx_enc[BLOCK*BLOCK]; |
| 57 | 58 | AVCodecContext *avctx_dec[BLOCK*BLOCK]; |
| 58 | − AVPacket *pkt; | |
| 59 | − AVFrame *frame; | |
| 60 | − AVFrame *frame_dec; | |
| 59 | + AVPacket *pkt [BLOCK*BLOCK]; | |
| 60 | + AVFrame *frame [BLOCK*BLOCK]; | |
| 61 | + AVFrame *frame_dec [BLOCK*BLOCK]; | |
| 61 | 62 | int8_t *non_b_qp_table; |
| 62 | 63 | int non_b_qp_stride; |
| 63 | 64 | int use_bframe_qp; |
| 65 | + int quality; | |
| 64 | 66 | } USPPContext; |
| 65 | 67 | |
| 66 | 68 | #define OFFSET(x) offsetof(USPPContext, x) |
| @@ -188,13 +190,87 @@ static void store_slice_c(uint8_t *dst, const uint16_t *src, · 121 unmodified lines | ||
| 188 | 190 | } |
| 189 | 191 | } |
| 190 | 192 | |
| 191 | −static void filter(USPPContext *p, uint8_t *dst[3], uint8_t *src[3], | |
| 193 | +static int filter_1phase(AVFilterContext *ctx, void *arg, int i, int nb_jobs) | |
| 194 | +{ | |
| 195 | + USPPContext *p = ctx->priv; | |
| 196 | + int ret, x, y; | |
| 197 | + int width = ctx->inputs[0]->w; | |
| 198 | + int height = ctx->inputs[0]->h; | |
| 199 | + | |
| 200 | + const int x1 = offset[i+nb_jobs-1][0]; | |
| 201 | + const int y1 = offset[i+nb_jobs-1][1]; | |
| 202 | + const int x1c = x1 >> p->hsub; | |
| 203 | + const int y1c = y1 >> p->vsub; | |
| 204 | + const int BLOCKc = BLOCK >> p->hsub; | |
| 205 | + int offset; | |
| 206 | + AVPacket *pkt = p->pkt[i]; | |
| 207 | + | |
| 208 | + av_packet_unref(pkt); | |
| 209 | + pkt->data = p->outbuf; | |
| 210 | + pkt->size = p->outbuf_size; | |
| 211 | + | |
| 212 | + p->frame[i]->linesize[0] = p->temp_stride[0]; | |
| 213 | + p->frame[i]->linesize[1] = p->temp_stride[1]; | |
| 214 | + p->frame[i]->linesize[2] = p->temp_stride[2]; | |
| 215 | + p->frame[i]->height = height + BLOCK; | |
| 216 | + p->frame[i]->width = width + BLOCK; | |
| 217 | + p->frame[i]->data[0] = p->src[0] + x1 + y1 * p->frame[i]->linesize[0]; | |
| 218 | + p->frame[i]->data[1] = p->src[1] + x1c + y1c * p->frame[i]->linesize[1]; | |
| 219 | + p->frame[i]->data[2] = p->src[2] + x1c + y1c * p->frame[i]->linesize[2]; | |
| 220 | + p->frame[i]->format = p->avctx_enc[i]->pix_fmt; | |
| 221 | + p->frame[i]->quality = p->quality; | |
| 222 | + | |
| 223 | + ret = avcodec_send_frame(p->avctx_enc[i], p->frame[i]); | |
| 224 | + if (ret < 0) { | |
| 225 | + av_log(p->avctx_enc[i], AV_LOG_ERROR, "Error sending a frame for encoding\n"); | |
| 226 | + return ret; | |
| 227 | + } | |
| 228 | + ret = avcodec_receive_packet(p->avctx_enc[i], pkt); | |
| 229 | + if (ret < 0) { | |
| 230 | + av_log(p->avctx_enc[i], AV_LOG_ERROR, "Error receiving a packet from encoding\n"); | |
| 231 | + return ret; | |
| 232 | + } | |
| 233 | + | |
| 234 | + ret = avcodec_send_packet(p->avctx_dec[i], pkt); | |
| 235 | + av_packet_unref(pkt); | |
| 236 | + if (ret < 0) { | |
| 237 | + av_log(p->avctx_dec[i], AV_LOG_ERROR, "Error sending a packet for decoding\n"); | |
| 238 | + return ret; | |
| 239 | + } | |
| 240 | + ret = avcodec_receive_frame(p->avctx_dec[i], p->frame_dec[i]); | |
| 241 | + if (ret < 0) { | |
| 242 | + av_log(p->avctx_dec[i], AV_LOG_ERROR, "Error receiving a frame from decoding\n"); | |
| 243 | + return ret; | |
| 244 | + } | |
| 245 | + | |
| 246 | + offset = (BLOCK-x1) + (BLOCK-y1) * p->frame_dec[i]->linesize[0]; | |
| 247 | + | |
| 248 | + for (y = 0; y < height; y++) | |
| 249 | + for (x = 0; x < width; x++) | |
| 250 | + p->temp[0][x + y * p->temp_stride[0]] += p->frame_dec[i]->data[0][x + y * p->frame_dec[i]->linesize[0] + offset]; | |
| 251 | + | |
| 252 | + | |
| 253 | + if (!p->frame_dec[i]->data[2] || !p->temp[2]) | |
| 254 | + return 0; | |
| 255 | + | |
| 256 | + offset = (BLOCKc-x1c) + (BLOCKc-y1c) * p->frame_dec[i]->linesize[1]; | |
| 257 | + | |
| 258 | + for (y = 0; y < AV_CEIL_RSHIFT(height, p->vsub); y++) { | |
| 259 | + for (x = 0; x < AV_CEIL_RSHIFT(width, p->hsub); x++) { | |
| 260 | + p->temp[1][x + y * p->temp_stride[1]] += p->frame_dec[i]->data[1][x + y * p->frame_dec[i]->linesize[1] + offset]; | |
| 261 | + p->temp[2][x + y * p->temp_stride[2]] += p->frame_dec[i]->data[2][x + y * p->frame_dec[i]->linesize[2] + offset]; | |
| 262 | + } | |
| 263 | + } | |
| 264 | + | |
| 265 | + return 0; | |
| 266 | +} | |
| 267 | + | |
| 268 | +static void filter(AVFilterContext *ctx, uint8_t *dst[3], uint8_t *src[3], | |
| 192 | 269 | int dst_stride[3], int src_stride[3], int width, |
| 193 | 270 | int height, uint8_t *qp_store, int qp_stride) |
| 194 | 271 | { |
| 272 | + USPPContext *p = ctx->priv; | |
| 195 | 273 | int x, y, i, j; |
| 196 | − const int count = 1<<p->log2_count; | |
| 197 | − int ret; | |
| 198 | 274 | |
| 199 | 275 | for (i = 0; i < 3; i++) { |
| 200 | 276 | int is_chroma = !!i; |
| @@ -219,12 +295,11 @@ static void filter(USPPContext *p, uint8_t *dst[3], uint8_t *src[3], · 18 unmodified lines | ||
| 219 | 295 | memcpy(p->src[i] + (h+block +y) * stride, p->src[i] + (h-y+block-1) * stride, stride); |
| 220 | 296 | } |
| 221 | 297 | |
| 222 | − p->frame->linesize[i] = stride; | |
| 223 | 298 | memset(p->temp[i], 0, (h + 2 * block) * stride * sizeof(int16_t)); |
| 224 | 299 | } |
| 225 | 300 | |
| 226 | 301 | if (p->qp) |
| 227 | − p->frame->quality = p->qp * FF_QP2LAMBDA; | |
| 302 | + p->quality = p->qp * FF_QP2LAMBDA; | |
| 228 | 303 | else { |
| 229 | 304 | int qpsum=0; |
| 230 | 305 | int qpcount = (height>>4) * (height>>4); |
| @@ -233,71 +308,11 @@ static void filter(USPPContext *p, uint8_t *dst[3], uint8_t *src[3], · 2 unmodified lines | ||
| 233 | 308 | for (x = 0; x < (width>>4); x++) |
| 234 | 309 | qpsum += qp_store[x + y * qp_stride]; |
| 235 | 310 | } |
| 236 | − p->frame->quality = ff_norm_qscale((qpsum + qpcount/2) / qpcount, p->qscale_type) * FF_QP2LAMBDA; | |
| 311 | + p->quality = ff_norm_qscale((qpsum + qpcount/2) / qpcount, p->qscale_type) * FF_QP2LAMBDA; | |
| 237 | 312 | } |
| 238 | 313 | // init per MB qscale stuff FIXME |
| 239 | − p->frame->height = height + BLOCK; | |
| 240 | − p->frame->width = width + BLOCK; | |
| 241 | − | |
| 242 | − for (i = 0; i < count; i++) { | |
| 243 | − const int x1 = offset[i+count-1][0]; | |
| 244 | − const int y1 = offset[i+count-1][1]; | |
| 245 | − const int x1c = x1 >> p->hsub; | |
| 246 | − const int y1c = y1 >> p->vsub; | |
| 247 | − const int BLOCKc = BLOCK >> p->hsub; | |
| 248 | − int offset; | |
| 249 | − AVPacket *pkt = p->pkt; | |
| 250 | − | |
| 251 | − av_packet_unref(pkt); | |
| 252 | − pkt->data = p->outbuf; | |
| 253 | − pkt->size = p->outbuf_size; | |
| 254 | − | |
| 255 | − p->frame->data[0] = p->src[0] + x1 + y1 * p->frame->linesize[0]; | |
| 256 | − p->frame->data[1] = p->src[1] + x1c + y1c * p->frame->linesize[1]; | |
| 257 | − p->frame->data[2] = p->src[2] + x1c + y1c * p->frame->linesize[2]; | |
| 258 | − p->frame->format = p->avctx_enc[i]->pix_fmt; | |
| 259 | − | |
| 260 | − ret = avcodec_send_frame(p->avctx_enc[i], p->frame); | |
| 261 | − if (ret < 0) { | |
| 262 | − av_log(p->avctx_enc[i], AV_LOG_ERROR, "Error sending a frame for encoding\n"); | |
| 263 | − continue; | |
| 264 | − } | |
| 265 | − ret = avcodec_receive_packet(p->avctx_enc[i], pkt); | |
| 266 | − if (ret < 0) { | |
| 267 | − av_log(p->avctx_enc[i], AV_LOG_ERROR, "Error receiving a packet from encoding\n"); | |
| 268 | − continue; | |
| 269 | − } | |
| 270 | − | |
| 271 | − ret = avcodec_send_packet(p->avctx_dec[i], pkt); | |
| 272 | − av_packet_unref(pkt); | |
| 273 | − if (ret < 0) { | |
| 274 | − av_log(p->avctx_dec[i], AV_LOG_ERROR, "Error sending a packet for decoding\n"); | |
| 275 | − continue; | |
| 276 | − } | |
| 277 | − ret = avcodec_receive_frame(p->avctx_dec[i], p->frame_dec); | |
| 278 | − if (ret < 0) { | |
| 279 | − av_log(p->avctx_dec[i], AV_LOG_ERROR, "Error receiving a frame from decoding\n"); | |
| 280 | − continue; | |
| 281 | − } | |
| 282 | − | |
| 283 | − offset = (BLOCK-x1) + (BLOCK-y1) * p->frame_dec->linesize[0]; | |
| 284 | − | |
| 285 | − for (y = 0; y < height; y++) | |
| 286 | − for (x = 0; x < width; x++) | |
| 287 | − p->temp[0][x + y * p->temp_stride[0]] += p->frame_dec->data[0][x + y * p->frame_dec->linesize[0] + offset]; | |
| 288 | − | |
| 289 | − if (!src[2] || !dst[2]) | |
| 290 | − continue; | |
| 291 | − | |
| 292 | − offset = (BLOCKc-x1c) + (BLOCKc-y1c) * p->frame_dec->linesize[1]; | |
| 293 | 314 | |
| 294 | − for (y = 0; y < AV_CEIL_RSHIFT(height, p->vsub); y++) { | |
| 295 | − for (x = 0; x < AV_CEIL_RSHIFT(width, p->hsub); x++) { | |
| 296 | − p->temp[1][x + y * p->temp_stride[1]] += p->frame_dec->data[1][x + y * p->frame_dec->linesize[1] + offset]; | |
| 297 | − p->temp[2][x + y * p->temp_stride[2]] += p->frame_dec->data[2][x + y * p->frame_dec->linesize[2] + offset]; | |
| 298 | − } | |
| 299 | − } | |
| 300 | − } | |
| 315 | + ff_filter_execute(ctx, filter_1phase, NULL, NULL, p->count); | |
| 301 | 316 | |
| 302 | 317 | for (j = 0; j < 3; j++) { |
| 303 | 318 | int is_chroma = !!j; |
| @@ -342,6 +357,7 @@ static int config_input(AVFilterLink *inlink) · 38 unmodified lines | ||
| 342 | 357 | |
| 343 | 358 | uspp->hsub = desc->log2_chroma_w; |
| 344 | 359 | uspp->vsub = desc->log2_chroma_h; |
| 360 | + uspp->count = 1<<uspp->log2_count; | |
| 345 | 361 | |
| 346 | 362 | for (i = 0; i < 3; i++) { |
| 347 | 363 | int is_chroma = !!i; |
| @@ -360,7 +376,7 @@ static int config_input(AVFilterLink *inlink) · 12 unmodified lines | ||
| 360 | 376 | return AVERROR(ENOMEM); |
| 361 | 377 | } |
| 362 | 378 | |
| 363 | − for (i = 0; i < (1<<uspp->log2_count); i++) { | |
| 379 | + for (i = 0; i < uspp->count; i++) { | |
| 364 | 380 | AVCodecContext *avctx_enc, *avctx_dec; |
| 365 | 381 | AVDictionary *opts = NULL; |
| 366 | 382 | int ret; |
| @@ -383,6 +399,8 @@ static int config_input(AVFilterLink *inlink) · 16 unmodified lines | ||
| 383 | 399 | avctx_enc->flags = AV_CODEC_FLAG_QSCALE | AV_CODEC_FLAG_LOW_DELAY; |
| 384 | 400 | avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; |
| 385 | 401 | avctx_enc->global_quality = 123; |
| 402 | + avctx_dec->thread_count = | |
| 403 | + avctx_enc->thread_count = 1; // We do threading in the filter with muiltiple codecs | |
| 386 | 404 | ret = avcodec_open2(avctx_enc, enc, &opts); |
| 387 | 405 | av_dict_free(&opts); |
| 388 | 406 | if (ret < 0) |
| @@ -394,15 +412,15 @@ static int config_input(AVFilterLink *inlink) · 5 unmodified lines | ||
| 394 | 412 | if (ret < 0) |
| 395 | 413 | return ret; |
| 396 | 414 | |
| 415 | + if (!(uspp->frame[i] = av_frame_alloc())) | |
| 416 | + return AVERROR(ENOMEM); | |
| 417 | + if (!(uspp->frame_dec[i] = av_frame_alloc())) | |
| 418 | + return AVERROR(ENOMEM); | |
| 419 | + if (!(uspp->pkt[i] = av_packet_alloc())) | |
| 420 | + return AVERROR(ENOMEM); | |
| 397 | 421 | } |
| 398 | 422 | |
| 399 | 423 | uspp->outbuf_size = (width + BLOCK) * (height + BLOCK) * 10; |
| 400 | − if (!(uspp->frame = av_frame_alloc())) | |
| 401 | − return AVERROR(ENOMEM); | |
| 402 | − if (!(uspp->frame_dec = av_frame_alloc())) | |
| 403 | − return AVERROR(ENOMEM); | |
| 404 | − if (!(uspp->pkt = av_packet_alloc())) | |
| 405 | − return AVERROR(ENOMEM); | |
| 406 | 424 | if (!(uspp->outbuf = av_malloc(uspp->outbuf_size))) |
| 407 | 425 | return AVERROR(ENOMEM); |
| 408 | 426 | |
| @@ -464,7 +482,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 55 unmodified lines | ||
| 464 | 482 | out->height = in->height; |
| 465 | 483 | } |
| 466 | 484 | |
| 467 | − filter(uspp, out->data, in->data, out->linesize, in->linesize, | |
| 485 | + filter(ctx, out->data, in->data, out->linesize, in->linesize, | |
| 468 | 486 | inlink->w, inlink->h, qp_table, qp_stride); |
| 469 | 487 | } |
| 470 | 488 | } |
| @@ -492,15 +510,16 @@ static av_cold void uninit(AVFilterContext *ctx) · 21 unmodified lines | ||
| 492 | 510 | av_freep(&uspp->src[i]); |
| 493 | 511 | } |
| 494 | 512 | |
| 495 | − for (i = 0; i < (1 << uspp->log2_count); i++) { | |
| 513 | + for (i = 0; i < uspp->count; i++) { | |
| 496 | 514 | avcodec_free_context(&uspp->avctx_enc[i]); |
| 497 | 515 | avcodec_free_context(&uspp->avctx_dec[i]); |
| 516 | + av_frame_free(&uspp->frame[i]); | |
| 517 | + av_frame_free(&uspp->frame_dec[i]); | |
| 518 | + av_packet_free(&uspp->pkt[i]); | |
| 498 | 519 | } |
| 499 | 520 | |
| 500 | 521 | av_freep(&uspp->non_b_qp_table); |
| 501 | 522 | av_freep(&uspp->outbuf); |
| 502 | − av_packet_free(&uspp->pkt); | |
| 503 | − av_frame_free(&uspp->frame); | |
| 504 | 523 | } |
| 505 | 524 | |
| 506 | 525 | static const AVFilterPad uspp_inputs[] = { |
| @@ -528,5 +547,5 @@ const AVFilter ff_vf_uspp = { · 21 unmodified lines | ||
| 528 | 547 | FILTER_OUTPUTS(uspp_outputs), |
| 529 | 548 | FILTER_PIXFMTS_ARRAY(pix_fmts), |
| 530 | 549 | .priv_class = &uspp_class, |
| 531 | − .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, | |
| 550 | + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, | |
| 532 | 551 | }; |