| 2130 | } |
| 2131 | |
| 2132 | static int set_roi_encode_ctrl(AVCodecContext *avctx, const AVFrame *frame, |
| 2133 | mfxEncodeCtrl *enc_ctrl) |
| 2134 | { |
| 2135 | AVFrameSideData *sd = NULL; |
| 2136 | int mb_size; |
| 2137 | |
| 2138 | if (avctx->codec_id == AV_CODEC_ID_H264) |
| 2139 | mb_size = 16; |
| 2140 | else if (avctx->codec_id == AV_CODEC_ID_H265) |
| 2141 | mb_size = 32; |
| 2142 | else |
| 2143 | return 0; |
| 2144 | |
| 2145 | if (frame) |
| 2146 | sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST); |
| 2147 | |
| 2148 | if (sd) { |
| 2149 | mfxExtEncoderROI *enc_roi = NULL; |
| 2150 | AVRegionOfInterest *roi; |
| 2151 | uint32_t roi_size; |
| 2152 | int nb_roi, i; |
| 2153 | |
| 2154 | roi = (AVRegionOfInterest *)sd->data; |
| 2155 | roi_size = roi->self_size; |
| 2156 | if (!roi_size || sd->size % roi_size) { |
| 2157 | av_log(avctx, AV_LOG_ERROR, "Invalid ROI Data.\n"); |
| 2158 | return AVERROR(EINVAL); |
| 2159 | } |
| 2160 | nb_roi = sd->size / roi_size; |
| 2161 | if (nb_roi > QSV_MAX_ROI_NUM) { |
| 2162 | av_log(avctx, AV_LOG_WARNING, "More ROIs set than " |
| 2163 | "supported by driver (%d > %d).\n", |
| 2164 | nb_roi, QSV_MAX_ROI_NUM); |
| 2165 | nb_roi = QSV_MAX_ROI_NUM; |
| 2166 | } |
| 2167 | |
| 2168 | enc_roi = av_mallocz(sizeof(*enc_roi)); |
| 2169 | if (!enc_roi) |
| 2170 | return AVERROR(ENOMEM); |
| 2171 | enc_roi->Header.BufferId = MFX_EXTBUFF_ENCODER_ROI; |
| 2172 | enc_roi->Header.BufferSz = sizeof(*enc_roi); |
| 2173 | enc_roi->NumROI = nb_roi; |
| 2174 | enc_roi->ROIMode = MFX_ROI_MODE_QP_DELTA; |
| 2175 | for (i = 0; i < nb_roi; i++) { |
| 2176 | roi = (AVRegionOfInterest *)(sd->data + roi_size * i); |
| 2177 | enc_roi->ROI[i].Top = FFALIGN(roi->top, mb_size); |
| 2178 | enc_roi->ROI[i].Bottom = FFALIGN(roi->bottom, mb_size); |
| 2179 | enc_roi->ROI[i].Left = FFALIGN(roi->left, mb_size); |
| 2180 | enc_roi->ROI[i].Right = FFALIGN(roi->right, mb_size); |
| 2181 | enc_roi->ROI[i].DeltaQP = |
| 2182 | roi->qoffset.num * 51 / roi->qoffset.den; |
| 2183 | av_log(avctx, AV_LOG_DEBUG, "ROI: (%d,%d)-(%d,%d) -> %+d.\n", |
| 2184 | roi->top, roi->left, roi->bottom, roi->right, |
| 2185 | enc_roi->ROI[i].DeltaQP); |
| 2186 | } |
| 2187 | enc_ctrl->ExtParam[enc_ctrl->NumExtParam] = (mfxExtBuffer *)enc_roi; |
| 2188 | enc_ctrl->NumExtParam++; |
| 2189 | } |
no test coverage detected