History

lavc/qsvenc: fill the padding area

qsvenc makes a copy when the input in system memory is not padded as the SDK requires, however the padding area is not filled with right data

Haihao Xiang committed 4 years ago

Commit e253bc41 parent 3bd0bf71 file · +67 −2Browse files

Unified · Split

libavcodec/qsvenc.c+67−2
@@ -1514,6 +1514,64 @@ static int get_free_frame(QSVEncContext *q, QSVFrame **f) · 1513 unmodified lines
1514 return 0;1514 return 0;
1515}1515}
1516 1516
1517static int qsvenc_fill_padding_area(AVFrame *frame, int new_w, int new_h)
1518{
1519 const AVPixFmtDescriptor *desc;
1520 int max_step[4], filled[4] = { 0 };
1521
1522 desc = av_pix_fmt_desc_get(frame->format);
1523 av_assert0(desc);
1524 av_image_fill_max_pixsteps(max_step, NULL, desc);
1525
1526 for (int i = 0; i < desc->nb_components; i++) {
1527 const AVComponentDescriptor *comp = &desc->comp[i];
1528 int sheight, dheight, plane = comp->plane;
1529 ptrdiff_t swidth = av_image_get_linesize(frame->format,
1530 frame->width,
1531 plane);
1532 ptrdiff_t dwidth = av_image_get_linesize(frame->format,
1533 new_w,
1534 plane);
1535
1536 if (swidth < 0 || dwidth < 0) {
1537 av_log(NULL, AV_LOG_ERROR, "av_image_get_linesize failed\n");
1538 return AVERROR(EINVAL);
1539 }
1540
1541 if (filled[plane])
1542 continue;
1543
1544 sheight = frame->height;
1545 dheight = new_h;
1546
1547 if (plane) {
1548 sheight = AV_CEIL_RSHIFT(frame->height, desc->log2_chroma_h);
1549 dheight = AV_CEIL_RSHIFT(new_h, desc->log2_chroma_h);
1550 }
1551
1552 // Fill right padding
1553 if (new_w > frame->width) {
1554 for (int j = 0; j < sheight; j++) {
1555 void *line_ptr = frame->data[plane] + j * frame->linesize[plane] + swidth;
1556
1557 av_memcpy_backptr(line_ptr,
1558 max_step[plane],
1559 new_w - frame->width);
1560 }
1561 }
1562
1563 // Fill bottom padding
1564 for (int j = sheight; j < dheight; j++)
1565 memcpy(frame->data[plane] + j * frame->linesize[plane],
1566 frame->data[plane] + (sheight - 1) * frame->linesize[plane],
1567 dwidth);
1568
1569 filled[plane] = 1;
1570 }
1571
1572 return 0;
1573}
1574
1517static int submit_frame(QSVEncContext *q, const AVFrame *frame,1575static int submit_frame(QSVEncContext *q, const AVFrame *frame,
1518 QSVFrame **new_frame)1576 QSVFrame **new_frame)
1519{1577{
@@ -1543,8 +1601,9 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, · 23 unmodified lines
1543 /* and to make allocation continious for data[0]/data[1] */1601 /* and to make allocation continious for data[0]/data[1] */
1544 if ((frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) ||1602 if ((frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) ||
1545 (frame->data[1] - frame->data[0] != frame->linesize[0] * FFALIGN(qf->frame->height, q->height_align))) {1603 (frame->data[1] - frame->data[0] != frame->linesize[0] * FFALIGN(qf->frame->height, q->height_align))) {
1546 qf->frame->height = FFALIGN(frame->height, q->height_align);1604 int tmp_w, tmp_h;
1547 qf->frame->width = FFALIGN(frame->width, q->width_align);1605 qf->frame->height = tmp_h = FFALIGN(frame->height, q->height_align);
1606 qf->frame->width = tmp_w = FFALIGN(frame->width, q->width_align);
1548 1607
1549 qf->frame->format = frame->format;1608 qf->frame->format = frame->format;
1550 1609
@@ -1562,6 +1621,12 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, · 11 unmodified lines
1562 av_frame_unref(qf->frame);1621 av_frame_unref(qf->frame);
1563 return ret;1622 return ret;
1564 }1623 }
1624
1625 ret = qsvenc_fill_padding_area(qf->frame, tmp_w, tmp_h);
1626 if (ret < 0) {
1627 av_frame_unref(qf->frame);
1628 return ret;
1629 }
1565 } else {1630 } else {
1566 av_frame_unref(qf->frame);1631 av_frame_unref(qf->frame);
1567 ret = av_frame_ref(qf->frame, frame);1632 ret = av_frame_ref(qf->frame, frame);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t