|
38 | 38 |
|
39 | 39 | static const char *TAG = "VENC_EL"; |
40 | 40 |
|
| 41 | +/** |
| 42 | + * @brief Video encoder extra setting mask |
| 43 | + */ |
| 44 | +typedef enum { |
| 45 | + VENC_EXTRA_SET_MASK_NONE = 0, |
| 46 | + VENC_EXTRA_SET_MASK_BITRATE = (1 << 0), |
| 47 | + VENC_EXTRA_SET_MASK_QP = (1 << 1), |
| 48 | + VENC_EXTRA_SET_MASK_GOP = (1 << 2), |
| 49 | + VENC_EXTRA_SET_MASK_ALL = (0xFF), |
| 50 | +} venc_extra_set_mask_t; |
| 51 | + |
| 52 | +/** |
| 53 | + * @brief Video encoder extra setting |
| 54 | + */ |
| 55 | +typedef struct { |
| 56 | + uint32_t bitrate; |
| 57 | + uint32_t min_qp; |
| 58 | + uint32_t max_qp; |
| 59 | + uint32_t gop; |
| 60 | + venc_extra_set_mask_t mask; |
| 61 | +} venc_extra_set_t; |
| 62 | + |
41 | 63 | /** |
42 | 64 | * @brief Video encoder definition |
43 | 65 | */ |
44 | 66 | typedef struct { |
45 | 67 | esp_gmf_video_element_t parent; /*!< Video element parent */ |
46 | 68 | esp_video_codec_type_t dst_codec; /*!< Video encoder destination codec */ |
47 | 69 | bool venc_bypass; /*!< Whether video encoder is bypassed or not */ |
48 | | - uint32_t bitrate; /*!< Output bitrate setting */ |
49 | 70 | uint32_t codec_cc; /*!< FourCC used to find encoder if set */ |
50 | 71 | esp_video_enc_handle_t enc_handle; /*!< Video encoder handle */ |
| 72 | + venc_extra_set_t extra_set; /*!< Video encoder extra setting */ |
51 | 73 | } venc_t; |
52 | 74 |
|
53 | 75 | static int venc_get_input_codecs(venc_t *venc, uint32_t dst_codec, const uint32_t **codecs, uint8_t *num) |
@@ -106,11 +128,24 @@ static int venc_get_frame_size(venc_t *venc, int *in_frame_size, int *out_frame_ |
106 | 128 | return ESP_GMF_ERR_OK; |
107 | 129 | } |
108 | 130 |
|
109 | | -static void venc_el_apply_settings(venc_t *venc) |
| 131 | +static esp_gmf_err_t venc_el_apply_settings(venc_t *venc, venc_extra_set_mask_t mask) |
110 | 132 | { |
111 | | - if (venc->bitrate) { |
112 | | - esp_video_enc_set_bitrate(venc->enc_handle, venc->bitrate); |
| 133 | + venc_extra_set_t *extra_set = &venc->extra_set; |
| 134 | + if (venc->enc_handle == NULL || |
| 135 | + extra_set->mask == VENC_EXTRA_SET_MASK_NONE) { |
| 136 | + return ESP_GMF_ERR_OK; |
| 137 | + } |
| 138 | + esp_vc_err_t ret = ESP_VC_ERR_OK; |
| 139 | + if (extra_set->mask & (mask & VENC_EXTRA_SET_MASK_BITRATE)) { |
| 140 | + ret |= esp_video_enc_set_bitrate(venc->enc_handle, extra_set->bitrate); |
| 141 | + } |
| 142 | + if (extra_set->mask & (mask & VENC_EXTRA_SET_MASK_QP)) { |
| 143 | + ret |= esp_video_enc_set_qp(venc->enc_handle, extra_set->min_qp, extra_set->max_qp); |
113 | 144 | } |
| 145 | + if (extra_set->mask & (mask & VENC_EXTRA_SET_MASK_GOP)) { |
| 146 | + ret |= esp_video_enc_set_gop(venc->enc_handle, extra_set->gop); |
| 147 | + } |
| 148 | + return ret == ESP_VC_ERR_OK ? ESP_GMF_ERR_OK : ESP_GMF_ERR_NOT_SUPPORT; |
114 | 149 | } |
115 | 150 |
|
116 | 151 | static esp_gmf_job_err_t venc_el_open(esp_gmf_video_element_handle_t self, void *para) |
@@ -143,7 +178,7 @@ static esp_gmf_job_err_t venc_el_open(esp_gmf_video_element_handle_t self, void |
143 | 178 | venc_get_frame_size(venc, &in_frame_size, &out_frame_size); |
144 | 179 | ESP_GMF_ELEMENT_GET(venc)->in_attr.data_size = in_frame_size; |
145 | 180 | ESP_GMF_ELEMENT_GET(venc)->out_attr.data_size = out_frame_size; |
146 | | - venc_el_apply_settings(venc); |
| 181 | + venc_el_apply_settings(venc, VENC_EXTRA_SET_MASK_ALL); |
147 | 182 | } |
148 | 183 | // Report info to next element |
149 | 184 | esp_gmf_info_video_t out_info = venc->parent.src_info; |
@@ -276,12 +311,9 @@ static esp_gmf_err_t set_bitrate(esp_gmf_element_handle_t handle, esp_gmf_args_d |
276 | 311 | ESP_GMF_NULL_CHECK(TAG, arg_desc, return ESP_GMF_ERR_INVALID_ARG); |
277 | 312 | venc_t *venc = (venc_t *)handle; |
278 | 313 | int offset = 0; |
279 | | - COPY_ARG(&venc->bitrate, buf, offset, sizeof(uint32_t), buf_len) |
280 | | - // TODO allow set bitrate before running? |
281 | | - if (venc->enc_handle) { |
282 | | - return esp_video_enc_set_bitrate(venc->enc_handle, venc->bitrate); |
283 | | - } |
284 | | - return ESP_GMF_ERR_OK; |
| 314 | + COPY_ARG(&venc->extra_set.bitrate, buf, offset, sizeof(uint32_t), buf_len); |
| 315 | + venc->extra_set.mask |= VENC_EXTRA_SET_MASK_BITRATE; |
| 316 | + return venc_el_apply_settings(venc, VENC_EXTRA_SET_MASK_BITRATE); |
285 | 317 | } |
286 | 318 |
|
287 | 319 | static esp_gmf_err_t get_in_formats(esp_gmf_element_handle_t handle, esp_gmf_args_desc_t *arg_desc, |
@@ -440,11 +472,28 @@ esp_gmf_err_t esp_gmf_video_enc_set_bitrate(esp_gmf_element_handle_t self, uint3 |
440 | 472 | { |
441 | 473 | ESP_GMF_NULL_CHECK(TAG, self, return ESP_GMF_ERR_INVALID_ARG); |
442 | 474 | venc_t *venc = (venc_t *)self; |
443 | | - venc->bitrate = bitrate; |
444 | | - // TODO allow set bitrate before running? |
445 | | - if (venc->enc_handle) { |
446 | | - return esp_video_enc_set_bitrate(venc->enc_handle, bitrate); |
447 | | - } |
| 475 | + venc->extra_set.bitrate = bitrate; |
| 476 | + venc->extra_set.mask |= VENC_EXTRA_SET_MASK_BITRATE; |
| 477 | + return venc_el_apply_settings(venc, VENC_EXTRA_SET_MASK_BITRATE); |
| 478 | +} |
| 479 | + |
| 480 | +esp_gmf_err_t esp_gmf_video_enc_set_gop(esp_gmf_element_handle_t self, uint32_t gop) |
| 481 | +{ |
| 482 | + ESP_GMF_NULL_CHECK(TAG, self, return ESP_GMF_ERR_INVALID_ARG); |
| 483 | + venc_t *venc = (venc_t *)self; |
| 484 | + venc->extra_set.gop = gop; |
| 485 | + venc->extra_set.mask |= VENC_EXTRA_SET_MASK_GOP; |
| 486 | + return venc_el_apply_settings(venc, VENC_EXTRA_SET_MASK_GOP); |
| 487 | +} |
| 488 | + |
| 489 | +esp_gmf_err_t esp_gmf_video_enc_set_qp(esp_gmf_element_handle_t self, uint32_t min_qp, uint32_t max_qp) |
| 490 | +{ |
| 491 | + ESP_GMF_NULL_CHECK(TAG, self, return ESP_GMF_ERR_INVALID_ARG); |
| 492 | + venc_t *venc = (venc_t *)self; |
| 493 | + venc->extra_set.min_qp = min_qp; |
| 494 | + venc->extra_set.max_qp = max_qp; |
| 495 | + venc->extra_set.mask |= VENC_EXTRA_SET_MASK_QP; |
| 496 | + venc_el_apply_settings(venc, VENC_EXTRA_SET_MASK_QP); |
448 | 497 | return ESP_GMF_ERR_OK; |
449 | 498 | } |
450 | 499 |
|
|
0 commit comments