summaryrefslogtreecommitdiff
path: root/toxav
diff options
context:
space:
mode:
authorEniz Vukovic <eniz_vukovic@hotmail.com>2015-10-23 22:52:32 +0200
committerEniz Vukovic <eniz_vukovic@hotmail.com>2015-10-23 22:53:56 +0200
commit90b1ca872731d7911d6318c3a6e05133ea6071b8 (patch)
treefab45a53e0054a83f9bf9f7bd273ec63e82dd05f /toxav
parentb5809f073241c778a97665b2924b85890e52ea1e (diff)
Fix setting resolution for vpx v1.4 (or newer i suppose)
Diffstat (limited to 'toxav')
-rw-r--r--toxav/toxav.c2
-rw-r--r--toxav/video.c142
-rw-r--r--toxav/video.h2
3 files changed, 85 insertions, 61 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 7585206c..a9e8b6f1 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -752,7 +752,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
752 goto END; 752 goto END;
753 } 753 }
754 754
755 if (vc_reconfigure_encoder(call->video.second->encoder, call->video_bit_rate * 1000, width, height) != 0) { 755 if (vc_reconfigure_encoder(call->video.second, call->video_bit_rate * 1000, width, height) != 0) {
756 pthread_mutex_unlock(call->mutex_video); 756 pthread_mutex_unlock(call->mutex_video);
757 rc = TOXAV_ERR_SEND_FRAME_INVALID; 757 rc = TOXAV_ERR_SEND_FRAME_INVALID;
758 goto END; 758 goto END;
diff --git a/toxav/video.c b/toxav/video.c
index 919e3c81..acc1852b 100644
--- a/toxav/video.c
+++ b/toxav/video.c
@@ -36,9 +36,6 @@
36#define MAX_DECODE_TIME_US 0 /* Good quality encode. */ 36#define MAX_DECODE_TIME_US 0 /* Good quality encode. */
37#define VIDEO_DECODE_BUFFER_SIZE 20 37#define VIDEO_DECODE_BUFFER_SIZE 20
38 38
39
40bool create_video_encoder (vpx_codec_ctx_t *dest, int32_t bit_rate);
41
42VCSession *vc_new(ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data) 39VCSession *vc_new(ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data)
43{ 40{
44 VCSession *vc = calloc(sizeof(VCSession), 1); 41 VCSession *vc = calloc(sizeof(VCSession), 1);
@@ -64,9 +61,41 @@ VCSession *vc_new(ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_c
64 goto BASE_CLEANUP; 61 goto BASE_CLEANUP;
65 } 62 }
66 63
67 if (!create_video_encoder(vc->encoder, 500000)) { 64 /* Set encoder to some initial values
68 vpx_codec_destroy(vc->decoder); 65 */
69 goto BASE_CLEANUP; 66 vpx_codec_enc_cfg_t cfg;
67 rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
68
69 if (rc != VPX_CODEC_OK) {
70 LOGGER_ERROR("Failed to get config: %s", vpx_codec_err_to_string(rc));
71 goto BASE_CLEANUP_1;
72 }
73
74 cfg.rc_target_bitrate = 500000;
75 cfg.g_w = 800;
76 cfg.g_h = 600;
77 cfg.g_pass = VPX_RC_ONE_PASS;
78 /* FIXME If we set error resilience the app will crash due to bug in vp8.
79 Perhaps vp9 has solved it?*/
80// cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS;
81 cfg.g_lag_in_frames = 0;
82 cfg.kf_min_dist = 0;
83 cfg.kf_max_dist = 48;
84 cfg.kf_mode = VPX_KF_AUTO;
85
86 rc = vpx_codec_enc_init(vc->encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
87
88 if (rc != VPX_CODEC_OK) {
89 LOGGER_ERROR("Failed to initialize encoder: %s", vpx_codec_err_to_string(rc));
90 goto BASE_CLEANUP_1;
91 }
92
93 rc = vpx_codec_control(vc->encoder, VP8E_SET_CPUUSED, 8);
94
95 if (rc != VPX_CODEC_OK) {
96 LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
97 vpx_codec_destroy(vc->encoder);
98 goto BASE_CLEANUP_1;
70 } 99 }
71 100
72 vc->linfts = current_time_monotonic(); 101 vc->linfts = current_time_monotonic();
@@ -78,6 +107,8 @@ VCSession *vc_new(ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_c
78 107
79 return vc; 108 return vc;
80 109
110BASE_CLEANUP_1:
111 vpx_codec_destroy(vc->decoder);
81BASE_CLEANUP: 112BASE_CLEANUP:
82 pthread_mutex_destroy(vc->queue_mutex); 113 pthread_mutex_destroy(vc->queue_mutex);
83 rb_kill(vc->vbuf_raw); 114 rb_kill(vc->vbuf_raw);
@@ -176,68 +207,61 @@ int vc_queue_message(void *vcp, struct RTPMessage *msg)
176 207
177 return 0; 208 return 0;
178} 209}
179int vc_reconfigure_encoder(vpx_codec_ctx_t *vccdc, uint32_t bit_rate, uint16_t width, uint16_t height) 210int vc_reconfigure_encoder(VCSession* vc, uint32_t bit_rate, uint16_t width, uint16_t height)
180{ 211{
181 if (!vccdc) 212 if (!vc)
182 return -1; 213 return -1;
183 214
184 vpx_codec_enc_cfg_t cfg = *vccdc->config.enc; 215 vpx_codec_enc_cfg_t cfg = *vc->encoder->config.enc;
185 216 int rc;
217
186 if (cfg.rc_target_bitrate == bit_rate && cfg.g_w == width && cfg.g_h == height) 218 if (cfg.rc_target_bitrate == bit_rate && cfg.g_w == width && cfg.g_h == height)
187 return 0; /* Nothing changed */ 219 return 0; /* Nothing changed */
188 220
189 cfg.rc_target_bitrate = bit_rate; 221 if (cfg.g_w == width && cfg.g_h == height)
190 cfg.g_w = width; 222 {
191 cfg.g_h = height; 223 /* Only bit rate changed */
192 224 cfg.rc_target_bitrate = bit_rate;
193 int rc = vpx_codec_enc_config_set(vccdc, &cfg); 225
194 226 rc = vpx_codec_enc_config_set(vc->encoder, &cfg);
195 if (rc != VPX_CODEC_OK) { 227
196 LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc)); 228 if (rc != VPX_CODEC_OK) {
197 return -1; 229 LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
198 } 230 return -1;
199 231 }
200 return 0;
201}
202
203
204bool create_video_encoder (vpx_codec_ctx_t *dest, int32_t bit_rate)
205{
206 assert(dest);
207
208 vpx_codec_enc_cfg_t cfg;
209 int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
210
211 if (rc != VPX_CODEC_OK) {
212 LOGGER_ERROR("Failed to get config: %s", vpx_codec_err_to_string(rc));
213 return false;
214 }
215
216 cfg.rc_target_bitrate = bit_rate;
217 cfg.g_w = 800;
218 cfg.g_h = 600;
219 cfg.g_pass = VPX_RC_ONE_PASS;
220 /* FIXME If we set error resilience the app will crash due to bug in vp8.
221 Perhaps vp9 has solved it?*/
222// cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS;
223 cfg.g_lag_in_frames = 0;
224 cfg.kf_min_dist = 0;
225 cfg.kf_max_dist = 48;
226 cfg.kf_mode = VPX_KF_AUTO;
227
228 rc = vpx_codec_enc_init(dest, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
229
230 if (rc != VPX_CODEC_OK) {
231 LOGGER_ERROR("Failed to initialize encoder: %s", vpx_codec_err_to_string(rc));
232 return false;
233 } 232 }
233 else
234 {
235 /* Resolution is changed, must reinitialize encoder since libvpx v1.4 doesn't support
236 * reconfiguring encoder to use resolutions greater than initially set.
237 */
238
239 LOGGER_DEBUG("Have to reinitialize vpx encoder on session %p", vc);
240
241 cfg.rc_target_bitrate = bit_rate;
242 cfg.g_w = width;
243 cfg.g_h = height;
244
245 vpx_codec_ctx_t new_c;
246
247 rc = vpx_codec_enc_init(&new_c, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
248
249 if (rc != VPX_CODEC_OK) {
250 LOGGER_ERROR("Failed to initialize encoder: %s", vpx_codec_err_to_string(rc));
251 return -1;
252 }
234 253
235 rc = vpx_codec_control(dest, VP8E_SET_CPUUSED, 8); 254 rc = vpx_codec_control(&new_c, VP8E_SET_CPUUSED, 8);
236 255
237 if (rc != VPX_CODEC_OK) { 256 if (rc != VPX_CODEC_OK) {
238 LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc)); 257 LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
239 vpx_codec_destroy(dest); 258 vpx_codec_destroy(&new_c);
259 return -1;
260 }
261
262 vpx_codec_destroy(vc->encoder);
263 memcpy(vc->encoder, &new_c, sizeof(new_c));
240 } 264 }
241 265
242 return true; 266 return 0;
243} 267}
diff --git a/toxav/video.h b/toxav/video.h
index 1ad1f6f5..51f34318 100644
--- a/toxav/video.h
+++ b/toxav/video.h
@@ -62,6 +62,6 @@ VCSession *vc_new(ToxAV* av, uint32_t friend_number, toxav_video_receive_frame_c
62void vc_kill(VCSession *vc); 62void vc_kill(VCSession *vc);
63void vc_iterate(VCSession *vc); 63void vc_iterate(VCSession *vc);
64int vc_queue_message(void *vcp, struct RTPMessage *msg); 64int vc_queue_message(void *vcp, struct RTPMessage *msg);
65int vc_reconfigure_encoder(vpx_codec_ctx_t *vccdc, uint32_t bit_rate, uint16_t width, uint16_t height); 65int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uint16_t height);
66 66
67#endif /* VIDEO_H */ 67#endif /* VIDEO_H */