summaryrefslogtreecommitdiff
path: root/toxav/toxmedia.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/toxmedia.c')
-rw-r--r--toxav/toxmedia.c473
1 files changed, 24 insertions, 449 deletions
diff --git a/toxav/toxmedia.c b/toxav/toxmedia.c
index aff3cf8c..359832d3 100644
--- a/toxav/toxmedia.c
+++ b/toxav/toxmedia.c
@@ -34,45 +34,13 @@
34#include <libswscale/swscale.h> 34#include <libswscale/swscale.h>
35#include <libavdevice/avdevice.h> 35#include <libavdevice/avdevice.h>
36#include <libavutil/opt.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> 37#include <opus/opus.h>
38#include <assert.h>
43 39
44#include "toxmsi.h" 40#include "toxmsi.h"
45#include "toxrtp.h" 41#include "toxrtp.h"
46#include "toxmedia.h" 42#include "toxmedia.h"
47 43
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 { 44struct jitter_buffer {
77 RTPMessage **queue; 45 RTPMessage **queue;
78 uint16_t capacity; 46 uint16_t capacity;
@@ -85,6 +53,7 @@ struct jitter_buffer {
85 uint8_t id_set; 53 uint8_t id_set;
86}; 54};
87 55
56
88struct jitter_buffer *create_queue(int capacity) 57struct jitter_buffer *create_queue(int capacity)
89{ 58{
90 struct jitter_buffer *q; 59 struct jitter_buffer *q;
@@ -240,10 +209,23 @@ int queue(struct jitter_buffer *q, RTPMessage *pk)
240 209
241int init_receive_audio(codec_state *cs) 210int init_receive_audio(codec_state *cs)
242{ 211{
243 int err = OPUS_OK; 212 int rc;
244 cs->audio_decoder = opus_decoder_create(48000, 1, &err); 213 cs->audio_decoder = opus_decoder_create(48000, 1, &rc );
245 opus_decoder_init(cs->audio_decoder, 48000, 1); 214
246 printf("init audio decoder successful\n"); 215 if ( rc != OPUS_OK ){
216 printf("Error while starting audio decoder!\n");
217 return 0;
218 }
219
220 rc = opus_decoder_init(cs->audio_decoder, 48000, 1);
221
222 if ( rc != OPUS_OK ){
223 printf("Error while starting audio decoder!\n");
224 return 0;
225 }
226
227
228 printf("Init audio decoder successful\n");
247 return 1; 229 return 1;
248} 230}
249 231
@@ -252,23 +234,23 @@ int init_receive_video(codec_state *cs)
252 cs->video_decoder = avcodec_find_decoder(VIDEO_CODEC); 234 cs->video_decoder = avcodec_find_decoder(VIDEO_CODEC);
253 235
254 if (!cs->video_decoder) { 236 if (!cs->video_decoder) {
255 printf("init video_decoder failed\n"); 237 printf("Init video_decoder failed\n");
256 return 0; 238 return 0;
257 } 239 }
258 240
259 cs->video_decoder_ctx = avcodec_alloc_context3(cs->video_decoder); 241 cs->video_decoder_ctx = avcodec_alloc_context3(cs->video_decoder);
260 242
261 if (!cs->video_decoder_ctx) { 243 if (!cs->video_decoder_ctx) {
262 printf("init video_decoder_ctx failed\n"); 244 printf("Init video_decoder_ctx failed\n");
263 return 0; 245 return 0;
264 } 246 }
265 247
266 if (avcodec_open2(cs->video_decoder_ctx, cs->video_decoder, NULL) < 0) { 248 if (avcodec_open2(cs->video_decoder_ctx, cs->video_decoder, NULL) < 0) {
267 printf("opening video decoder failed\n"); 249 printf("Opening video decoder failed\n");
268 return 0; 250 return 0;
269 } 251 }
270 252
271 printf("init video decoder successful\n"); 253 printf("Init video decoder successful\n");
272 return 1; 254 return 1;
273} 255}
274 256
@@ -356,32 +338,6 @@ int init_send_audio(codec_state *cs)
356{ 338{
357 cs->support_send_audio = 0; 339 cs->support_send_audio = 0;
358 340
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; 341 int err = OPUS_OK;
386 cs->audio_bitrate = AUDIO_BITRATE; 342 cs->audio_bitrate = AUDIO_BITRATE;
387 cs->audio_encoder = opus_encoder_create(AUDIO_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, &err); 343 cs->audio_encoder = opus_encoder_create(AUDIO_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, &err);
@@ -435,385 +391,4 @@ int init_decoder(codec_state *cs)
435 cs->receive_video = 1; 391 cs->receive_video = 1;
436 392
437 return 1; 393 return 1;
438} 394} \ No newline at end of file
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}