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
15141514 return 0;
15151515 }
15161516
1517+static 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+
15171575 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
15181576 QSVFrame **new_frame)
15191577 {
@@ -1543,8 +1601,9 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, · 23 unmodified lines
15431601 /* and to make allocation continious for data[0]/data[1] */
15441602 if ((frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) ||
15451603 (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);
1547− qf->frame->width = FFALIGN(frame->width, q->width_align);
1604+ int tmp_w, tmp_h;
1605+ qf->frame->height = tmp_h = FFALIGN(frame->height, q->height_align);
1606+ qf->frame->width = tmp_w = FFALIGN(frame->width, q->width_align);
15481607
15491608 qf->frame->format = frame->format;
15501609
@@ -1562,6 +1621,12 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, · 11 unmodified lines
15621621 av_frame_unref(qf->frame);
15631622 return ret;
15641623 }
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+ }
15651630 } else {
15661631 av_frame_unref(qf->frame);
15671632 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