@@ -677,13 +677,52 @@ static inline void copy_data(AVFrame *pic, const struct encoder_frame *frame,
677677 }
678678}
679679
680+ static void roi_cb (void * param , struct obs_encoder_roi * roi )
681+ {
682+ struct darray * da = param ;
683+ darray_push_back (sizeof (struct obs_encoder_roi ), da , roi );
684+ }
685+
686+ static void add_roi (struct vaapi_encoder * enc , AVFrame * frame )
687+ {
688+ DARRAY (struct obs_encoder_roi ) rois ;
689+ da_init (rois );
690+ obs_encoder_enum_roi (enc -> encoder , roi_cb , & rois );
691+
692+ AVRegionOfInterest * roi ;
693+ AVBufferRef * roi_ref = av_buffer_alloc (sizeof (* roi ) * rois .num );
694+ if (!roi_ref )
695+ goto out ;
696+
697+ roi = (AVRegionOfInterest * )roi_ref -> data ;
698+ for (size_t i = 0 ; i < rois .num ; ++ i ) {
699+ roi [i ] = (AVRegionOfInterest ){
700+ .self_size = sizeof (* roi ),
701+ .top = rois .array [i ].top ,
702+ .bottom = rois .array [i ].bottom ,
703+ .left = rois .array [i ].left ,
704+ .right = rois .array [i ].right ,
705+ .qoffset = av_d2q (-1.0 * rois .array [i ].priority , 1000 ),
706+ };
707+ }
708+ if (!av_frame_new_side_data_from_buf (
709+ frame , AV_FRAME_DATA_REGIONS_OF_INTEREST , roi_ref ))
710+ av_buffer_unref (& roi_ref );
711+
712+ out :
713+ da_free (rois );
714+ }
715+
680716static bool vaapi_encode_internal (struct vaapi_encoder * enc , AVFrame * frame ,
681717 struct encoder_packet * packet ,
682718 bool * received_packet )
683719{
684720 int got_packet ;
685721 int ret ;
686722
723+ if (obs_encoder_has_roi (enc -> encoder ))
724+ add_roi (enc , frame );
725+
687726 ret = avcodec_send_frame (enc -> context , frame );
688727 if (ret == 0 || ret == AVERROR (EAGAIN ))
689728 ret = avcodec_receive_packet (enc -> context , enc -> packet );
@@ -1300,7 +1339,7 @@ struct obs_encoder_info h264_vaapi_encoder_info = {
13001339 .get_extra_data = vaapi_extra_data ,
13011340 .get_sei_data = vaapi_sei_data ,
13021341 .get_video_info = vaapi_video_info ,
1303- .caps = OBS_ENCODER_CAP_INTERNAL ,
1342+ .caps = OBS_ENCODER_CAP_INTERNAL | OBS_ENCODER_CAP_ROI ,
13041343};
13051344
13061345struct obs_encoder_info h264_vaapi_encoder_tex_info = {
@@ -1316,7 +1355,7 @@ struct obs_encoder_info h264_vaapi_encoder_tex_info = {
13161355 .get_extra_data = vaapi_extra_data ,
13171356 .get_sei_data = vaapi_sei_data ,
13181357 .get_video_info = vaapi_video_info ,
1319- .caps = OBS_ENCODER_CAP_PASS_TEXTURE ,
1358+ .caps = OBS_ENCODER_CAP_PASS_TEXTURE | OBS_ENCODER_CAP_ROI ,
13201359};
13211360
13221361struct obs_encoder_info av1_vaapi_encoder_info = {
@@ -1332,7 +1371,7 @@ struct obs_encoder_info av1_vaapi_encoder_info = {
13321371 .get_extra_data = vaapi_extra_data ,
13331372 .get_sei_data = vaapi_sei_data ,
13341373 .get_video_info = vaapi_video_info ,
1335- .caps = OBS_ENCODER_CAP_INTERNAL ,
1374+ .caps = OBS_ENCODER_CAP_INTERNAL | OBS_ENCODER_CAP_ROI ,
13361375};
13371376
13381377struct obs_encoder_info av1_vaapi_encoder_tex_info = {
@@ -1348,7 +1387,7 @@ struct obs_encoder_info av1_vaapi_encoder_tex_info = {
13481387 .get_extra_data = vaapi_extra_data ,
13491388 .get_sei_data = vaapi_sei_data ,
13501389 .get_video_info = vaapi_video_info ,
1351- .caps = OBS_ENCODER_CAP_PASS_TEXTURE ,
1390+ .caps = OBS_ENCODER_CAP_PASS_TEXTURE | OBS_ENCODER_CAP_ROI ,
13521391};
13531392
13541393#ifdef ENABLE_HEVC
@@ -1365,7 +1404,7 @@ struct obs_encoder_info hevc_vaapi_encoder_info = {
13651404 .get_extra_data = vaapi_extra_data ,
13661405 .get_sei_data = vaapi_sei_data ,
13671406 .get_video_info = vaapi_video_info ,
1368- .caps = OBS_ENCODER_CAP_INTERNAL ,
1407+ .caps = OBS_ENCODER_CAP_INTERNAL | OBS_ENCODER_CAP_ROI ,
13691408};
13701409
13711410struct obs_encoder_info hevc_vaapi_encoder_tex_info = {
@@ -1381,6 +1420,6 @@ struct obs_encoder_info hevc_vaapi_encoder_tex_info = {
13811420 .get_extra_data = vaapi_extra_data ,
13821421 .get_sei_data = vaapi_sei_data ,
13831422 .get_video_info = vaapi_video_info ,
1384- .caps = OBS_ENCODER_CAP_PASS_TEXTURE ,
1423+ .caps = OBS_ENCODER_CAP_PASS_TEXTURE | OBS_ENCODER_CAP_ROI ,
13851424};
13861425#endif
0 commit comments