History

libavutil/hwcontext_qsv: Align width and heigh when download qsv frame

The width and height for qsv frame to download need to be aligned with 16. Add the alignment operation. Now the following command works: ffmpeg -hwaccel qsv -f rawvideo -s 1920x1080 -pix_fmt yuv420p -i \ input.yuv -vf "hwupload=extra_hw_frames=16,format=qsv,hwdownload, \ format=nv12" -f null -

Wenbin Chen committed 4 years ago

Commit 7e7b3a41 parent 7427b871 file · +42 −5Browse files

Unified · Split

libavutil/hwcontext_qsv.c+42−5
@@ -91,7 +91,8 @@ typedef struct QSVFramesContext { · 90 unmodified lines
91 91
92 mfxExtOpaqueSurfaceAlloc opaque_alloc;92 mfxExtOpaqueSurfaceAlloc opaque_alloc;
93 mfxExtBuffer *ext_buffers[1];93 mfxExtBuffer *ext_buffers[1];
94 AVFrame realigned_tmp_frame;94 AVFrame realigned_upload_frame;
95 AVFrame realigned_download_frame;
95} QSVFramesContext;96} QSVFramesContext;
96 97
97static const struct {98static const struct {
@@ -303,7 +304,8 @@ static void qsv_frames_uninit(AVHWFramesContext *ctx) · 205 unmodified lines
303 av_freep(&s->surface_ptrs);304 av_freep(&s->surface_ptrs);
304 av_freep(&s->surfaces_internal);305 av_freep(&s->surfaces_internal);
305 av_freep(&s->handle_pairs_internal);306 av_freep(&s->handle_pairs_internal);
306 av_frame_unref(&s->realigned_tmp_frame);307 av_frame_unref(&s->realigned_upload_frame);
308 av_frame_unref(&s->realigned_download_frame);
307 av_buffer_unref(&s->child_frames_ref);309 av_buffer_unref(&s->child_frames_ref);
308}310}
309 311
@@ -1058,21 +1060,46 @@ static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, · 748 unmodified lines
1058 mfxSyncPoint sync = NULL;1060 mfxSyncPoint sync = NULL;
1059 mfxStatus err;1061 mfxStatus err;
1060 int ret = 0;1062 int ret = 0;
1063 /* download to temp frame if the output is not padded as libmfx requires */
1064 AVFrame *tmp_frame = &s->realigned_download_frame;
1065 AVFrame *dst_frame;
1066 int realigned = 0;
1061 1067
1062 ret = qsv_internal_session_check_init(ctx, 0);1068 ret = qsv_internal_session_check_init(ctx, 0);
1063 if (ret < 0)1069 if (ret < 0)
1064 return ret;1070 return ret;
1065 1071
1072 /* According to MSDK spec for mfxframeinfo, "Width must be a multiple of 16.
1073 * Height must be a multiple of 16 for progressive frame sequence and a
1074 * multiple of 32 otherwise.", so allign all frames to 16 before downloading. */
1075 if (dst->height & 15 || dst->linesize[0] & 15) {
1076 realigned = 1;
1077 if (tmp_frame->format != dst->format ||
1078 tmp_frame->width != FFALIGN(dst->linesize[0], 16) ||
1079 tmp_frame->height != FFALIGN(dst->height, 16)) {
1080 av_frame_unref(tmp_frame);
1081
1082 tmp_frame->format = dst->format;
1083 tmp_frame->width = FFALIGN(dst->linesize[0], 16);
1084 tmp_frame->height = FFALIGN(dst->height, 16);
1085 ret = av_frame_get_buffer(tmp_frame, 0);
1086 if (ret < 0)
1087 return ret;
1088 }
1089 }
1090
1091 dst_frame = realigned ? tmp_frame : dst;
1092
1066 if (!s->session_download) {1093 if (!s->session_download) {
1067 if (s->child_frames_ref)1094 if (s->child_frames_ref)
1068 return qsv_transfer_data_child(ctx, dst, src);1095 return qsv_transfer_data_child(ctx, dst_frame, src);
1069 1096
1070 av_log(ctx, AV_LOG_ERROR, "Surface download not possible\n");1097 av_log(ctx, AV_LOG_ERROR, "Surface download not possible\n");
1071 return AVERROR(ENOSYS);1098 return AVERROR(ENOSYS);
1072 }1099 }
1073 1100
1074 out.Info = in->Info;1101 out.Info = in->Info;
1075 map_frame_to_surface(dst, &out);1102 map_frame_to_surface(dst_frame, &out);
1076 1103
1077 do {1104 do {
1078 err = MFXVideoVPP_RunFrameVPPAsync(s->session_download, in, &out, NULL, &sync);1105 err = MFXVideoVPP_RunFrameVPPAsync(s->session_download, in, &out, NULL, &sync);
@@ -1093,6 +1120,16 @@ static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, · 14 unmodified lines
1093 return AVERROR_UNKNOWN;1120 return AVERROR_UNKNOWN;
1094 }1121 }
1095 1122
1123 if (realigned) {
1124 tmp_frame->width = dst->width;
1125 tmp_frame->height = dst->height;
1126 ret = av_frame_copy(dst, tmp_frame);
1127 tmp_frame->width = FFALIGN(dst->linesize[0], 16);
1128 tmp_frame->height = FFALIGN(dst->height, 16);
1129 if (ret < 0)
1130 return ret;
1131 }
1132
1096 return 0;1133 return 0;
1097}1134}
1098 1135
@@ -1108,7 +1145,7 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, · 9 unmodified lines
1108 mfxStatus err;1145 mfxStatus err;
1109 int ret = 0;1146 int ret = 0;
1110 /* make a copy if the input is not padded as libmfx requires */1147 /* make a copy if the input is not padded as libmfx requires */
1111 AVFrame *tmp_frame = &s->realigned_tmp_frame;1148 AVFrame *tmp_frame = &s->realigned_upload_frame;
1112 const AVFrame *src_frame;1149 const AVFrame *src_frame;
1113 int realigned = 0;1150 int realigned = 0;
1114 1151

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