summaryrefslogtreecommitdiff
path: root/toxav/toxmedia.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/toxmedia.c')
-rw-r--r--toxav/toxmedia.c819
1 files changed, 819 insertions, 0 deletions
diff --git a/toxav/toxmedia.c b/toxav/toxmedia.c
new file mode 100644
index 00000000..aff3cf8c
--- /dev/null
+++ b/toxav/toxmedia.c
@@ -0,0 +1,819 @@
1/* AV_codec.c
2// *
3 * Audio and video codec intitialisation, encoding/decoding and playback
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24/*----------------------------------------------------------------------------------*/
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif /* HAVE_CONFIG_H */
29
30#include <stdio.h>
31#include <math.h>
32#include <libavcodec/avcodec.h>
33#include <libavformat/avformat.h>
34#include <libswscale/swscale.h>
35#include <libavdevice/avdevice.h>
36#include <libavutil/opt.h>
37#include <AL/al.h>
38#include <AL/alc.h>
39#include <SDL/SDL.h>
40#include <SDL/SDL_thread.h>
41#include <pthread.h>
42#include <opus/opus.h>
43
44#include "toxmsi.h"
45#include "toxrtp.h"
46#include "toxmedia.h"
47
48SDL_Surface *screen;
49
50int display_received_frame(codec_state *cs, AVFrame *r_video_frame)
51{
52 AVPicture pict;
53 SDL_LockYUVOverlay(cs->video_picture.bmp);
54
55 pict.data[0] = cs->video_picture.bmp->pixels[0];
56 pict.data[1] = cs->video_picture.bmp->pixels[2];
57 pict.data[2] = cs->video_picture.bmp->pixels[1];
58 pict.linesize[0] = cs->video_picture.bmp->pitches[0];
59 pict.linesize[1] = cs->video_picture.bmp->pitches[2];
60 pict.linesize[2] = cs->video_picture.bmp->pitches[1];
61
62 /* Convert the image into YUV format that SDL uses */
63 sws_scale(cs->sws_SDL_r_ctx, (uint8_t const * const *)r_video_frame->data, r_video_frame->linesize, 0,
64 cs->video_decoder_ctx->height, pict.data, pict.linesize );
65
66 SDL_UnlockYUVOverlay(cs->video_picture.bmp);
67 SDL_Rect rect;
68 rect.x = 0;
69 rect.y = 0;
70 rect.w = cs->video_decoder_ctx->width;
71 rect.h = cs->video_decoder_ctx->height;
72 SDL_DisplayYUVOverlay(cs->video_picture.bmp, &rect);
73 return 1;
74}
75
76struct jitter_buffer {
77 RTPMessage **queue;
78 uint16_t capacity;
79 uint16_t size;
80 uint16_t front;
81 uint16_t rear;
82 uint8_t queue_ready;
83 uint16_t current_id;
84 uint32_t current_ts;
85 uint8_t id_set;
86};
87
88struct jitter_buffer *create_queue(int capacity)
89{
90 struct jitter_buffer *q;
91 q = (struct jitter_buffer *)calloc(sizeof(struct jitter_buffer),1);
92 q->queue = (RTPMessage **)calloc((sizeof(RTPMessage) * capacity),1);
93 int i = 0;
94
95 for (i = 0; i < capacity; ++i) {
96 q->queue[i] = NULL;
97 }
98
99 q->size = 0;
100 q->capacity = capacity;
101 q->front = 0;
102 q->rear = -1;
103 q->queue_ready = 0;
104 q->current_id = 0;
105 q->current_ts = 0;
106 q->id_set = 0;
107 return q;
108}
109
110/* returns 1 if 'a' has a higher sequence number than 'b' */
111uint8_t sequence_number_older(uint16_t sn_a, uint16_t sn_b, uint32_t ts_a, uint32_t ts_b)
112{
113 /* should be stable enough */
114
115 /* TODO: There is already this kind of function in toxrtp.c.
116 * Maybe merge?
117 */
118 return (sn_a > sn_b || ts_a > ts_b);
119}
120
121/* success is 0 when there is nothing to dequeue, 1 when there's a good packet, 2 when there's a lost packet */
122RTPMessage *dequeue(struct jitter_buffer *q, int *success)
123{
124 if (q->size == 0 || q->queue_ready == 0) {
125 q->queue_ready = 0;
126 *success = 0;
127 return NULL;
128 }
129
130 int front = q->front;
131
132 if (q->id_set == 0) {
133 q->current_id = q->queue[front]->header->sequnum;
134 q->current_ts = q->queue[front]->header->timestamp;
135 q->id_set = 1;
136 } else {
137 int next_id = q->queue[front]->header->sequnum;
138 int next_ts = q->queue[front]->header->timestamp;
139
140 /* if this packet is indeed the expected packet */
141 if (next_id == (q->current_id + 1) % MAX_SEQU_NUM) {
142 q->current_id = next_id;
143 q->current_ts = next_ts;
144 } else {
145 if (sequence_number_older(next_id, q->current_id, next_ts, q->current_ts)) {
146 printf("nextid: %d current: %d\n", next_id, q->current_id);
147 q->current_id = (q->current_id + 1) % MAX_SEQU_NUM;
148 *success = 2; /* tell the decoder the packet is lost */
149 return NULL;
150 } else {
151 /* packet too old */
152 printf("packet too old\n");
153 *success = 0;
154 return NULL;
155 }
156 }
157 }
158
159 q->size--;
160 q->front++;
161
162 if (q->front == q->capacity)
163 q->front = 0;
164
165 *success = 1;
166 q->current_id = q->queue[front]->header->sequnum;
167 q->current_ts = q->queue[front]->header->timestamp;
168 return q->queue[front];
169}
170
171int empty_queue(struct jitter_buffer *q)
172{
173 while (q->size > 0) {
174 q->size--;
175 /* FIXME: */
176 /* rtp_free_msg(cs->_rtp_video, q->queue[q->front]); */
177 q->front++;
178
179 if (q->front == q->capacity)
180 q->front = 0;
181 }
182
183 q->id_set = 0;
184 q->queue_ready = 0;
185 return 0;
186}
187
188int queue(struct jitter_buffer *q, RTPMessage *pk)
189{
190 if (q->size == q->capacity) {
191 printf("buffer full, emptying buffer...\n");
192 empty_queue(q);
193 return 0;
194 }
195
196 if (q->size > 8)
197 q->queue_ready = 1;
198
199 ++q->size;
200 ++q->rear;
201
202 if (q->rear == q->capacity)
203 q->rear = 0;
204
205 q->queue[q->rear] = pk;
206
207 int a;
208 int b;
209 int j;
210 a = q->rear;
211
212 for (j = 0; j < q->size - 1; ++j) {
213 b = a - 1;
214
215 if (b < 0)
216 b += q->capacity;
217
218 if (sequence_number_older(q->queue[b]->header->sequnum, q->queue[a]->header->sequnum,
219 q->queue[b]->header->timestamp, q->queue[a]->header->timestamp)) {
220 RTPMessage *temp;
221 temp = q->queue[a];
222 q->queue[a] = q->queue[b];
223 q->queue[b] = temp;
224 printf("had to swap\n");
225 } else {
226 break;
227 }
228
229 a -= 1;
230
231 if (a < 0)
232 a += q->capacity;
233 }
234
235 if (pk)
236 return 1;
237
238 return 0;
239}
240
241int init_receive_audio(codec_state *cs)
242{
243 int err = OPUS_OK;
244 cs->audio_decoder = opus_decoder_create(48000, 1, &err);
245 opus_decoder_init(cs->audio_decoder, 48000, 1);
246 printf("init audio decoder successful\n");
247 return 1;
248}
249
250int init_receive_video(codec_state *cs)
251{
252 cs->video_decoder = avcodec_find_decoder(VIDEO_CODEC);
253
254 if (!cs->video_decoder) {
255 printf("init video_decoder failed\n");
256 return 0;
257 }
258
259 cs->video_decoder_ctx = avcodec_alloc_context3(cs->video_decoder);
260
261 if (!cs->video_decoder_ctx) {
262 printf("init video_decoder_ctx failed\n");
263 return 0;
264 }
265
266 if (avcodec_open2(cs->video_decoder_ctx, cs->video_decoder, NULL) < 0) {
267 printf("opening video decoder failed\n");
268 return 0;
269 }
270
271 printf("init video decoder successful\n");
272 return 1;
273}
274
275int init_send_video(codec_state *cs)
276{
277 cs->video_input_format = av_find_input_format(VIDEO_DRIVER);
278
279 if (avformat_open_input(&cs->video_format_ctx, DEFAULT_WEBCAM, cs->video_input_format, NULL) != 0) {
280 printf("opening video_input_format failed\n");
281 return 0;
282 }
283
284 avformat_find_stream_info(cs->video_format_ctx, NULL);
285 av_dump_format(cs->video_format_ctx, 0, DEFAULT_WEBCAM, 0);
286
287 int i;
288
289 for (i = 0; i < cs->video_format_ctx->nb_streams; ++i) {
290 if (cs->video_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
291 cs->video_stream = i;
292 break;
293 }
294 }
295
296 cs->webcam_decoder_ctx = cs->video_format_ctx->streams[cs->video_stream]->codec;
297 cs->webcam_decoder = avcodec_find_decoder(cs->webcam_decoder_ctx->codec_id);
298
299 if (cs->webcam_decoder == NULL) {
300 printf("Unsupported codec\n");
301 return 0;
302 }
303
304 if (cs->webcam_decoder_ctx == NULL) {
305 printf("init webcam_decoder_ctx failed\n");
306 return 0;
307 }
308
309 if (avcodec_open2(cs->webcam_decoder_ctx, cs->webcam_decoder, NULL) < 0) {
310 printf("opening webcam decoder failed\n");
311 return 0;
312 }
313
314 cs->video_encoder = avcodec_find_encoder(VIDEO_CODEC);
315
316 if (!cs->video_encoder) {
317 printf("init video_encoder failed\n");
318 return 0;
319 }
320
321 cs->video_encoder_ctx = avcodec_alloc_context3(cs->video_encoder);
322
323 if (!cs->video_encoder_ctx) {
324 printf("init video_encoder_ctx failed\n");
325 return 0;
326 }
327
328 cs->video_encoder_ctx->bit_rate = VIDEO_BITRATE;
329 cs->video_encoder_ctx->rc_min_rate = cs->video_encoder_ctx->rc_max_rate = cs->video_encoder_ctx->bit_rate;
330 av_opt_set_double(cs->video_encoder_ctx->priv_data, "max-intra-rate", 90, 0);
331 av_opt_set(cs->video_encoder_ctx->priv_data, "quality", "realtime", 0);
332
333 cs->video_encoder_ctx->thread_count = 4;
334 cs->video_encoder_ctx->rc_buffer_aggressivity = 0.95;
335 cs->video_encoder_ctx->rc_buffer_size = VIDEO_BITRATE * 6;
336 cs->video_encoder_ctx->profile = 3;
337 cs->video_encoder_ctx->qmax = 54;
338 cs->video_encoder_ctx->qmin = 4;
339 AVRational myrational = {1, 25};
340 cs->video_encoder_ctx->time_base = myrational;
341 cs->video_encoder_ctx->gop_size = 99999;
342 cs->video_encoder_ctx->pix_fmt = PIX_FMT_YUV420P;
343 cs->video_encoder_ctx->width = cs->webcam_decoder_ctx->width;
344 cs->video_encoder_ctx->height = cs->webcam_decoder_ctx->height;
345
346 if (avcodec_open2(cs->video_encoder_ctx, cs->video_encoder, NULL) < 0) {
347 printf("opening video encoder failed\n");
348 return 0;
349 }
350
351 printf("init video encoder successful\n");
352 return 1;
353}
354
355int init_send_audio(codec_state *cs)
356{
357 cs->support_send_audio = 0;
358
359 const ALchar *pDeviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
360 int i = 0;
361 const ALchar *device_names[20];
362
363 if (pDeviceList) {
364 printf("\nAvailable Capture Devices are:\n");
365
366 while (*pDeviceList) {
367 device_names[i] = pDeviceList;
368 printf("%d) %s\n", i, device_names[i]);
369 pDeviceList += strlen(pDeviceList) + 1;
370 ++i;
371 }
372 }
373
374 printf("enter capture device number: \n");
375 char dev[2];
376 fgets(dev, sizeof(dev), stdin);
377 cs->audio_capture_device = alcCaptureOpenDevice(device_names[dev[0] - 48], AUDIO_SAMPLE_RATE, AL_FORMAT_MONO16,
378 AUDIO_FRAME_SIZE * 4);
379
380 if (alcGetError(cs->audio_capture_device) != AL_NO_ERROR) {
381 printf("could not start capture device! %d\n", alcGetError(cs->audio_capture_device));
382 return 0;
383 }
384
385 int err = OPUS_OK;
386 cs->audio_bitrate = AUDIO_BITRATE;
387 cs->audio_encoder = opus_encoder_create(AUDIO_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, &err);
388 err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_BITRATE(cs->audio_bitrate));
389 err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_COMPLEXITY(10));
390 err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
391
392 opus_encoder_init(cs->audio_encoder, AUDIO_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP);
393
394 int nfo;
395 err = opus_encoder_ctl(cs->audio_encoder, OPUS_GET_LOOKAHEAD(&nfo));
396 /* printf("Encoder lookahead delay : %d\n", nfo); */
397 printf("init audio encoder successful\n");
398
399 return 1;
400}
401
402int init_encoder(codec_state *cs)
403{
404 avdevice_register_all();
405 avcodec_register_all();
406 avdevice_register_all();
407 av_register_all();
408
409 pthread_mutex_init(&cs->rtp_msg_mutex_lock, NULL);
410 pthread_mutex_init(&cs->avcodec_mutex_lock, NULL);
411
412 cs->support_send_video = init_send_video(cs);
413 cs->support_send_audio = init_send_audio(cs);
414
415 cs->send_audio = 1;
416 cs->send_video = 1;
417
418 return 1;
419}
420
421int init_decoder(codec_state *cs)
422{
423 avdevice_register_all();
424 avcodec_register_all();
425 avdevice_register_all();
426 av_register_all();
427
428 cs->receive_video = 0;
429 cs->receive_audio = 0;
430
431 cs->support_receive_video = init_receive_video(cs);
432 cs->support_receive_audio = init_receive_audio(cs);
433
434 cs->receive_audio = 1;
435 cs->receive_video = 1;
436
437 return 1;
438}
439
440int video_encoder_refresh(codec_state *cs, int bps)
441{
442 if (cs->video_encoder_ctx)
443 avcodec_close(cs->video_encoder_ctx);
444
445 cs->video_encoder = avcodec_find_encoder(VIDEO_CODEC);
446
447 if (!cs->video_encoder) {
448 printf("init video_encoder failed\n");
449 return -1;
450 }
451
452 cs->video_encoder_ctx = avcodec_alloc_context3(cs->video_encoder);
453
454 if (!cs->video_encoder_ctx) {
455 printf("init video_encoder_ctx failed\n");
456 return -1;
457 }
458
459 cs->video_encoder_ctx->bit_rate = bps;
460 cs->video_encoder_ctx->rc_min_rate = cs->video_encoder_ctx->rc_max_rate = cs->video_encoder_ctx->bit_rate;
461 av_opt_set_double(cs->video_encoder_ctx->priv_data, "max-intra-rate", 90, 0);
462 av_opt_set(cs->video_encoder_ctx->priv_data, "quality", "realtime", 0);
463
464 cs->video_encoder_ctx->thread_count = 4;
465 cs->video_encoder_ctx->rc_buffer_aggressivity = 0.95;
466 cs->video_encoder_ctx->rc_buffer_size = bps * 6;
467 cs->video_encoder_ctx->profile = 0;
468 cs->video_encoder_ctx->qmax = 54;
469 cs->video_encoder_ctx->qmin = 4;
470 AVRational myrational = {1, 25};
471 cs->video_encoder_ctx->time_base = myrational;
472 cs->video_encoder_ctx->gop_size = 99999;
473 cs->video_encoder_ctx->pix_fmt = PIX_FMT_YUV420P;
474 cs->video_encoder_ctx->width = cs->webcam_decoder_ctx->width;
475 cs->video_encoder_ctx->height = cs->webcam_decoder_ctx->height;
476
477 if (avcodec_open2(cs->video_encoder_ctx, cs->video_encoder, NULL) < 0) {
478 printf("opening video encoder failed\n");
479 return -1;
480 }
481 return 0;
482}
483
484void *encode_video_thread(void *arg)
485{
486 codec_state *cs = (codec_state *)arg;
487 AVPacket pkt1, *packet = &pkt1;
488 int p = 0;
489 int err;
490 int got_packet;
491 RTPMessage *s_video_msg;
492 int video_frame_finished;
493 AVFrame *s_video_frame;
494 AVFrame *webcam_frame;
495 s_video_frame = avcodec_alloc_frame();
496 webcam_frame = avcodec_alloc_frame();
497 AVPacket enc_video_packet;
498
499 uint8_t *buffer;
500 int numBytes;
501 /* Determine required buffer size and allocate buffer */
502 numBytes = avpicture_get_size(PIX_FMT_YUV420P, cs->webcam_decoder_ctx->width, cs->webcam_decoder_ctx->height);
503 buffer = (uint8_t *)av_calloc(numBytes * sizeof(uint8_t),1);
504 avpicture_fill((AVPicture *)s_video_frame, buffer, PIX_FMT_YUV420P, cs->webcam_decoder_ctx->width,
505 cs->webcam_decoder_ctx->height);
506 cs->sws_ctx = sws_getContext(cs->webcam_decoder_ctx->width, cs->webcam_decoder_ctx->height,
507 cs->webcam_decoder_ctx->pix_fmt, cs->webcam_decoder_ctx->width, cs->webcam_decoder_ctx->height, PIX_FMT_YUV420P,
508 SWS_BILINEAR, NULL, NULL, NULL);
509
510 while (!cs->quit && cs->send_video) {
511
512 if (av_read_frame(cs->video_format_ctx, packet) < 0) {
513 printf("error reading frame\n");
514
515 if (cs->video_format_ctx->pb->error != 0)
516 break;
517
518 continue;
519 }
520
521 if (packet->stream_index == cs->video_stream) {
522 if (avcodec_decode_video2(cs->webcam_decoder_ctx, webcam_frame, &video_frame_finished, packet) < 0) {
523 printf("couldn't decode\n");
524 continue;
525 }
526
527 av_free_packet(packet);
528 sws_scale(cs->sws_ctx, (uint8_t const * const *)webcam_frame->data, webcam_frame->linesize, 0,
529 cs->webcam_decoder_ctx->height, s_video_frame->data, s_video_frame->linesize);
530 /* create a new I-frame every 60 frames */
531 ++p;
532
533 if (p == 60) {
534
535 s_video_frame->pict_type = AV_PICTURE_TYPE_BI ;
536 } else if (p == 61) {
537 s_video_frame->pict_type = AV_PICTURE_TYPE_I ;
538 p = 0;
539 } else {
540 s_video_frame->pict_type = AV_PICTURE_TYPE_P ;
541 }
542
543 if (video_frame_finished) {
544 err = avcodec_encode_video2(cs->video_encoder_ctx, &enc_video_packet, s_video_frame, &got_packet);
545
546 if (err < 0) {
547 printf("could not encode video frame\n");
548 continue;
549 }
550
551 if (!got_packet) {
552 continue;
553 }
554
555 pthread_mutex_lock(&cs->rtp_msg_mutex_lock);
556
557 if (!enc_video_packet.data) fprintf(stderr, "video packet data is NULL\n");
558
559 if ( 0 > rtp_send_msg ( cs->_rtp_video, cs->_messenger, enc_video_packet.data, enc_video_packet.size) ) {
560 printf("invalid message\n");
561 }
562
563 pthread_mutex_unlock(&cs->rtp_msg_mutex_lock);
564 av_free_packet(&enc_video_packet);
565 }
566 } else {
567 av_free_packet(packet);
568 }
569 }
570
571 /* clean up codecs */
572 pthread_mutex_lock(&cs->avcodec_mutex_lock);
573 av_free(buffer);
574 av_free(webcam_frame);
575 av_free(s_video_frame);
576 sws_freeContext(cs->sws_ctx);
577 avcodec_close(cs->webcam_decoder_ctx);
578 avcodec_close(cs->video_encoder_ctx);
579 pthread_mutex_unlock(&cs->avcodec_mutex_lock);
580 pthread_exit ( NULL );
581}
582
583void *encode_audio_thread(void *arg)
584{
585 codec_state *cs = (codec_state *)arg;
586 RTPMessage *s_audio_msg;
587 unsigned char encoded_data[4096];
588 int encoded_size = 0;
589 int16_t frame[4096];
590 int frame_size = AUDIO_FRAME_SIZE;
591 ALint sample = 0;
592 alcCaptureStart(cs->audio_capture_device);
593
594 while (!cs->quit && cs->send_audio) {
595 alcGetIntegerv(cs->audio_capture_device, ALC_CAPTURE_SAMPLES, (ALCsizei)sizeof(ALint), &sample);
596
597 if (sample >= frame_size) {
598 alcCaptureSamples(cs->audio_capture_device, frame, frame_size);
599 encoded_size = opus_encode(cs->audio_encoder, frame, frame_size, encoded_data, 480);
600
601 if (encoded_size <= 0) {
602 printf("Could not encode audio packet\n");
603 } else {
604 pthread_mutex_lock(&cs->rtp_msg_mutex_lock);
605
606 rtp_send_msg ( cs->_rtp_audio, cs->_messenger, encoded_data, encoded_size );
607
608 pthread_mutex_unlock(&cs->rtp_msg_mutex_lock);
609
610 }
611 } else {
612 usleep(1000);
613 }
614 }
615
616 /* clean up codecs */
617 pthread_mutex_lock(&cs->avcodec_mutex_lock);
618 alcCaptureStop(cs->audio_capture_device);
619 alcCaptureCloseDevice(cs->audio_capture_device);
620
621 pthread_mutex_unlock(&cs->avcodec_mutex_lock);
622 pthread_exit ( NULL );
623}
624
625
626int video_decoder_refresh(codec_state *cs, int width, int height)
627{
628 printf("need to refresh\n");
629 screen = SDL_SetVideoMode(width, height, 0, 0);
630
631 if (cs->video_picture.bmp)
632 SDL_FreeYUVOverlay(cs->video_picture.bmp);
633
634 cs->video_picture.bmp = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, screen);
635 cs->sws_SDL_r_ctx = sws_getContext(width, height, cs->video_decoder_ctx->pix_fmt, width, height, PIX_FMT_YUV420P,
636 SWS_BILINEAR, NULL, NULL, NULL);
637 return 1;
638}
639
640void *decode_video_thread(void *arg)
641{
642 codec_state *cs = (codec_state *)arg;
643 cs->video_stream = 0;
644 RTPMessage *r_msg;
645 int dec_frame_finished;
646 AVFrame *r_video_frame;
647 r_video_frame = avcodec_alloc_frame();
648 AVPacket dec_video_packet;
649 av_new_packet (&dec_video_packet, 65536);
650 int width = 0;
651 int height = 0;
652
653 while (!cs->quit && cs->receive_video) {
654 r_msg = rtp_recv_msg ( cs->_rtp_video );
655
656 if (r_msg) {
657 memcpy(dec_video_packet.data, r_msg->data, r_msg->length);
658 dec_video_packet.size = r_msg->length;
659 avcodec_decode_video2(cs->video_decoder_ctx, r_video_frame, &dec_frame_finished, &dec_video_packet);
660
661 if (dec_frame_finished) {
662 if (cs->video_decoder_ctx->width != width || cs->video_decoder_ctx->height != height) {
663 width = cs->video_decoder_ctx->width;
664 height = cs->video_decoder_ctx->height;
665 printf("w: %d h%d \n", width, height);
666 video_decoder_refresh(cs, width, height);
667 }
668
669 display_received_frame(cs, r_video_frame);
670 } else {
671 /* TODO: request the sender to create a new i-frame immediatly */
672 printf("bad video packet\n");
673 }
674
675 rtp_free_msg(cs->_rtp_video, r_msg);
676 }
677
678 usleep(1000);
679 }
680
681 printf("vend\n");
682 /* clean up codecs */
683 pthread_mutex_lock(&cs->avcodec_mutex_lock);
684 av_free(r_video_frame);
685 avcodec_close(cs->video_decoder_ctx);
686 pthread_mutex_unlock(&cs->avcodec_mutex_lock);
687 pthread_exit ( NULL );
688}
689
690void *decode_audio_thread(void *arg)
691{
692 codec_state *cs = (codec_state *)arg;
693 RTPMessage *r_msg;
694
695 int frame_size = AUDIO_FRAME_SIZE;
696 int data_size;
697
698 ALCdevice *dev;
699 ALCcontext *ctx;
700 ALuint source, *buffers;
701 dev = alcOpenDevice(NULL);
702 ctx = alcCreateContext(dev, NULL);
703 alcMakeContextCurrent(ctx);
704 int openal_buffers = 5;
705
706 buffers = calloc(sizeof(ALuint) * openal_buffers,1);
707 alGenBuffers(openal_buffers, buffers);
708 alGenSources((ALuint)1, &source);
709 alSourcei(source, AL_LOOPING, AL_FALSE);
710
711 ALuint buffer;
712 ALint val;
713
714 ALenum error;
715 uint16_t zeros[frame_size];
716 int i;
717
718 for (i = 0; i < frame_size; i++) {
719 zeros[i] = 0;
720 }
721
722 for (i = 0; i < openal_buffers; ++i) {
723 alBufferData(buffers[i], AL_FORMAT_MONO16, zeros, frame_size, 48000);
724 }
725
726 alSourceQueueBuffers(source, openal_buffers, buffers);
727 alSourcePlay(source);
728
729 if (alGetError() != AL_NO_ERROR) {
730 fprintf(stderr, "Error starting audio\n");
731 cs->quit = 1;
732 }
733
734 struct jitter_buffer *j_buf = NULL;
735
736 j_buf = create_queue(20);
737
738 int success = 0;
739
740 int dec_frame_len;
741
742 opus_int16 PCM[frame_size];
743
744 while (!cs->quit && cs->receive_audio) {
745
746 r_msg = rtp_recv_msg ( cs->_rtp_audio );
747
748 if (r_msg) {
749 /* push the packet into the queue */
750 queue(j_buf, r_msg);
751 }
752
753 /* grab a packet from the queue */
754 success = 0;
755 alGetSourcei(source, AL_BUFFERS_PROCESSED, &val);
756
757 if (val > 0)
758 r_msg = dequeue(j_buf, &success);
759
760 if (success > 0) {
761 /* good packet */
762 if (success == 1) {
763 dec_frame_len = opus_decode(cs->audio_decoder, r_msg->data, r_msg->length, PCM, frame_size, 0);
764 rtp_free_msg(cs->_rtp_audio, r_msg);
765 }
766
767 /* lost packet */
768 if (success == 2) {
769 printf("lost packet\n");
770 dec_frame_len = opus_decode(cs->audio_decoder, NULL, 0, PCM, frame_size, 1);
771 }
772
773 if (dec_frame_len > 0) {
774 alGetSourcei(source, AL_BUFFERS_PROCESSED, &val);
775
776 if (val <= 0)
777 continue;
778
779 alSourceUnqueueBuffers(source, 1, &buffer);
780 data_size = av_samples_get_buffer_size(NULL, 1, dec_frame_len, AV_SAMPLE_FMT_S16, 1);
781 alBufferData(buffer, AL_FORMAT_MONO16, PCM, data_size, 48000);
782 int error = alGetError();
783
784 if (error != AL_NO_ERROR) {
785 fprintf(stderr, "Error setting buffer %d\n", error);
786 break;
787 }
788
789 alSourceQueueBuffers(source, 1, &buffer);
790
791 if (alGetError() != AL_NO_ERROR) {
792 fprintf(stderr, "error: could not buffer audio\n");
793 break;
794 }
795
796 alGetSourcei(source, AL_SOURCE_STATE, &val);
797
798 if (val != AL_PLAYING)
799 alSourcePlay(source);
800
801
802 }
803 }
804
805 usleep(1000);
806 }
807
808 /* clean up codecs */
809 pthread_mutex_lock(&cs->avcodec_mutex_lock);
810
811 /* clean up openal */
812 alDeleteSources(1, &source);
813 alDeleteBuffers(openal_buffers, buffers);
814 alcMakeContextCurrent(NULL);
815 alcDestroyContext(ctx);
816 alcCloseDevice(dev);
817 pthread_mutex_unlock(&cs->avcodec_mutex_lock);
818 pthread_exit ( NULL );
819}