Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | in experimental jsmpeg SDL video driver use runtime linking of ffmpeg libs |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | 52df327807c7dc22ad0442f75f6c7ff7 |
User & Date: | chw 2019-02-13 18:27:25 |
Context
2019-02-13
| ||
18:33 | use internally built libwebsockets for Wayland and KMSDRM undroidwishes check-in: 22ec538f4d user: chw tags: trunk | |
18:27 | in experimental jsmpeg SDL video driver use runtime linking of ffmpeg libs check-in: 52df327807 user: chw tags: trunk | |
18:20 | don't let SDL catch SIGINT in undroidwish check-in: 6ac0d784b2 user: chw tags: trunk | |
Changes
Changes to jni/SDL2/configure.
21696 21697 21698 21699 21700 21701 21702 21703 21704 21705 21706 21707 21708 21709 |
if ac_fn_c_try_compile "$LINENO"; then : video_jsmpeg=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_jsmpeg" >&5 $as_echo "$video_jsmpeg" >&6; } if test x$video_jsmpeg = xyes; then |
> > > |
21696 21697 21698 21699 21700 21701 21702 21703 21704 21705 21706 21707 21708 21709 21710 21711 21712 |
if ac_fn_c_try_compile "$LINENO"; then : video_jsmpeg=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test x$have_loadso = xyes; then LAV_LIBS="" fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_jsmpeg" >&5 $as_echo "$video_jsmpeg" >&6; } if test x$video_jsmpeg = xyes; then |
Changes to jni/SDL2/configure.in.
2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 |
struct lws_context *lwc; struct lws_context_creation_info lwi; lwc = lws_create_context(&lwi); ],[ video_jsmpeg=yes ]) CFLAGS="$save_CFLAGS" fi fi AC_MSG_RESULT($video_jsmpeg) if test x$video_jsmpeg = xyes; then AC_DEFINE(SDL_VIDEO_DRIVER_JSMPEG, 1, [ ]) JSMPEG_SOURCES="$srcdir/src/video/jsmpeg/*.c" |
> > > |
2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 |
struct lws_context *lwc; struct lws_context_creation_info lwi; lwc = lws_create_context(&lwi); ],[ video_jsmpeg=yes ]) CFLAGS="$save_CFLAGS" if test x$have_loadso = xyes; then LAV_LIBS="" fi fi fi AC_MSG_RESULT($video_jsmpeg) if test x$video_jsmpeg = xyes; then AC_DEFINE(SDL_VIDEO_DRIVER_JSMPEG, 1, [ ]) JSMPEG_SOURCES="$srcdir/src/video/jsmpeg/*.c" |
Changes to jni/SDL2/src/video/jsmpeg/SDL_jsmpeg.c.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 ... 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 ... 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 ... 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 ... 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 ... 752 753 754 755 756 757 758 759 760 761 762 763 764 765 ... 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 |
#include <libavutil/avutil.h> #include <libavutil/imgutils.h> #include <libavcodec/avcodec.h> #include <libswscale/swscale.h> #include <libwebsockets.h> #include "SDL_jsmpeg_files.h" #if SDL_THREADS_DISABLED #undef USE_ENCODER_THREAD #else #define USE_ENCODER_THREAD ................................................................................ p[0] = v >> 24; p[1] = v >> 16; p[2] = v >> 8; p[3] = v; } /* .keyCode to scancode https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode */ static const SDL_Scancode scancode_table[] = { /* 0 */ SDL_SCANCODE_UNKNOWN, /* 1 */ SDL_SCANCODE_UNKNOWN, /* 2 */ SDL_SCANCODE_UNKNOWN, /* 3 */ SDL_SCANCODE_CANCEL, /* 4 */ SDL_SCANCODE_UNKNOWN, /* 5 */ SDL_SCANCODE_UNKNOWN, ................................................................................ } static void silentium(void *avcl, int level, const char *fmt, va_list vl) { /* No log messages from ffmpeg libs */ } /* JSMPEG driver bootstrap functions */ static int JSMPEG_Available(void) { av_log_set_callback(silentium); avcodec_register_all(); lws_set_log_level(0, NULL); return 1; } static void JSMPEG_DeleteDevice(SDL_VideoDevice *device) { SDL_free(device); // unload?? } static SDL_VideoDevice * JSMPEG_CreateDevice(int devindex) { SDL_VideoDevice *device; SDL_VideoData *data; ................................................................................ } return SDL_Unsupported(); } static Frame * JSMPEG_EncodeFrame(SDL_WindowData *data) { AVPacket packet; Frame *frame = NULL; unsigned char *p; int ok = 0; memset(&packet, 0, sizeof(packet)); av_init_packet(&packet); avcodec_encode_video2(data->context, &packet, data->frame, &ok); if (ok) { frame = (Frame *) SDL_malloc(sizeof(Frame) + LWS_PRE + 8 + packet.size); if (frame != NULL) { frame->ref_count = 1; frame->size = packet.size + 8; frame->type = LWS_WRITE_BINARY; frame->data = frame + 1; p = (unsigned char *) frame->data; p += LWS_PRE; puti32(p + 0, FRAME_TYPE_VIDEO); puti32(p + 4, frame->size); memcpy(p + 8, packet.data, packet.size); } } av_free_packet(&packet); return frame; } static void JSMPEG_TransmitFrame(Frame *frame, Client *client) { while (frame != NULL && client != NULL) { ................................................................................ /* Transmission */ JSMPEG_TransmitFrame(frame, client); #endif ticks = SDL_GetTicks(); /* About 15 frames per second */ if (ticks - data->ticks >= 62) { uint8_t *pixels[1]; int linesizes[1]; data->ticks = ticks; if (client == NULL) { /* No client connected, do nothing */ ................................................................................ { SDL_WindowData *data; const Uint32 surface_format = SDL_PIXELFORMAT_BGR888; int w, h, bpp, frame_size; Uint32 Rmask, Gmask, Bmask, Amask; const char *env; struct lws_context_creation_info info; /* Free the old framebuffer surface and related data */ data = (SDL_WindowData *) window->driverdata; JSMPEG_CleanupWindowData(data); /* Create a new one */ SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); ................................................................................ data->context = avcodec_alloc_context3(data->codec); if (data->context == NULL) { JSMPEG_CleanupWindowData(data); return -1; } data->context->dct_algo = FF_DCT_FASTINT; data->context->bit_rate = 10000 * w; data->context->bit_rate_tolerance = data->context->bit_rate << 2; data->context->width = w; data->context->height = h; data->context->time_base.num = 1; data->context->time_base.den = 30; data->context->gop_size = 30; data->context->max_b_frames = 0; data->context->pix_fmt = AV_PIX_FMT_YUV420P; avcodec_open2(data->context, data->codec, NULL); data->frame = av_frame_alloc(); if (data->frame == NULL) { JSMPEG_CleanupWindowData(data); return -1; } data->frame->format = AV_PIX_FMT_YUV420P; data->frame->width = w; data->frame->height = h; data->frame->pts = 0; frame_size = avpicture_get_size(AV_PIX_FMT_YUV420P, w, h); data->frame_buffer = SDL_calloc(1, frame_size); if (data->frame_buffer == NULL) { JSMPEG_CleanupWindowData(data); return -1; } avpicture_fill((AVPicture *) data->frame, (uint8_t *) data->frame_buffer, AV_PIX_FMT_YUV420P, w, h); data->sws = sws_getContext(w, h, AV_PIX_FMT_RGB32, w, h, AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, 0, 0, 0); if (data->sws == NULL) { JSMPEG_CleanupWindowData(data); return -1; } data->clients = NULL; memset(&info, 0, sizeof(struct lws_context_creation_info)); |
> > > > > | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | > > > > > > > > > > > > > | | < | | | | | | > > > > > | > | > | < > | > | > | > | > | > | > | | | | < > | < < |
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 ... 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 ... 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 ... 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 ... 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 ... 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 ... 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 |
#include <libavutil/avutil.h> #include <libavutil/imgutils.h> #include <libavcodec/avcodec.h> #include <libswscale/swscale.h> #include <libwebsockets.h> #if !defined(SDL_LOADSO_DUMMY) && !defined(SDL_LOADSO_DISABLED) #define USE_LOADSO 1 #include "SDL_loadso.h" #endif #include "SDL_jsmpeg_files.h" #if SDL_THREADS_DISABLED #undef USE_ENCODER_THREAD #else #define USE_ENCODER_THREAD ................................................................................ p[0] = v >> 24; p[1] = v >> 16; p[2] = v >> 8; p[3] = v; } /* * .keyCode to scancode * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode */ static const SDL_Scancode scancode_table[] = { /* 0 */ SDL_SCANCODE_UNKNOWN, /* 1 */ SDL_SCANCODE_UNKNOWN, /* 2 */ SDL_SCANCODE_UNKNOWN, /* 3 */ SDL_SCANCODE_CANCEL, /* 4 */ SDL_SCANCODE_UNKNOWN, /* 5 */ SDL_SCANCODE_UNKNOWN, ................................................................................ } static void silentium(void *avcl, int level, const char *fmt, va_list vl) { /* No log messages from ffmpeg libs */ } /* Runtime linking if supported */ #ifdef USE_LOADSO static void *libavutil = NULL; static void *libavcodec = NULL; static void *libswscale = NULL; #if defined(__WIN32__) #define LIB_AVUTIL_55 "avutil-55.dll" #define LIB_AVUTIL_56 "avutil-56.dll" #define LIB_AVCODEC_57 "avcodec-57.dll" #define LIB_AVCODEC_58 "avcodec-58.dll" #define LIB_SWSCALE_4 "swscale-4.dll" #define LIB_SWSCALE_5 "swscale-5.dll" #elif defined(__MACOSX__) #error fix library names for MACOSX #else #define LIB_AVUTIL_55 "libavutil.so.55" #define LIB_AVUTIL_56 "libavutil.so.56" #define LIB_AVCODEC_57 "libavcodec.so.57" #define LIB_AVCODEC_58 "libavcodec.so.58" #define LIB_SWSCALE_4 "libswscale.so.4" #define LIB_SWSCALE_5 "libswscale.so.5" #endif static struct { /* avutil */ AVFrame *(*av_frame_alloc)(void); void (*av_free)(void *); enum AVPixelFormat (*av_get_pix_fmt)(const char *); void (*av_log_set_callback)(void (*)(void *, int, const char *, va_list)); int (*av_opt_set_image_size)(void *, const char *, int, int, int); int (*av_opt_set_int)(void *, const char *, int64_t, int); int (*av_opt_set_q)(void *, const char *, AVRational, int); int (*av_opt_set_pixel_fmt)(void *, const char *, enum AVPixelFormat, int); /* avcodec */ int (*av_image_fill_arrays)(uint8_t **, int *, uint8_t *, enum AVPixelFormat, int, int, int); AVPacket *(*av_packet_alloc)(void); void (*av_packet_free)(AVPacket **); AVCodecContext *(*avcodec_alloc_context3)(const AVCodec *codec); int (*avcodec_close)(AVCodecContext *); int (*avcodec_encode_video2)(AVCodecContext *, AVPacket *, const AVFrame *, int *); AVCodec *(*avcodec_find_encoder)(enum AVCodecID); int (*avcodec_open2)(AVCodecContext *, const AVCodec *, AVDictionary **); void (*avcodec_register_all)(void); int (*avpicture_get_size)(enum AVPixelFormat, int, int); /* swscale */ void (*sws_freeContext)(struct SwsContext *); struct SwsContext *(*sws_getContext)(int, int, enum AVPixelFormat, int, int, enum AVPixelFormat, int, SwsFilter *, SwsFilter *, const double *); int (*sws_scale)(struct SwsContext *, uint8_t **, int *, int, int, uint8_t **, int *); } syms; static int load_objects_and_syms() { if (libavutil != NULL && libavcodec != NULL && libswscale != NULL) { return 0; } libavutil = SDL_LoadObject(LIB_AVUTIL_55); if (libavutil == NULL) { libavutil = SDL_LoadObject(LIB_AVUTIL_56); } if (libavutil == NULL) { goto error; } libavcodec = SDL_LoadObject(LIB_AVCODEC_57); if (libavcodec == NULL) { libavcodec = SDL_LoadObject(LIB_AVCODEC_58); } if (libavcodec == NULL) { goto error; } libswscale = SDL_LoadObject(LIB_SWSCALE_4); if (libswscale == NULL) { libswscale = SDL_LoadObject(LIB_SWSCALE_5); } if (libswscale == NULL) { goto error; } #undef GET_SYM #define GET_SYM(x) \ if ((syms.x = SDL_LoadFunction(libavutil, #x)) == NULL) \ goto error; GET_SYM(av_frame_alloc); GET_SYM(av_free); GET_SYM(av_get_pix_fmt); GET_SYM(av_log_set_callback); GET_SYM(av_opt_set_image_size); GET_SYM(av_opt_set_int); GET_SYM(av_opt_set_q); GET_SYM(av_opt_set_pixel_fmt); #undef GET_SYM #define GET_SYM(x) \ if ((syms.x = SDL_LoadFunction(libavcodec, #x)) == NULL) \ goto error; GET_SYM(av_image_fill_arrays); GET_SYM(av_packet_alloc); GET_SYM(av_packet_free); GET_SYM(avcodec_alloc_context3); GET_SYM(avcodec_close); GET_SYM(avcodec_encode_video2); GET_SYM(avcodec_find_encoder); GET_SYM(avcodec_open2); GET_SYM(avcodec_register_all); GET_SYM(avpicture_get_size); #undef GET_SYM #define GET_SYM(x) \ if ((syms.x = SDL_LoadFunction(libswscale, #x)) == NULL) \ goto error; GET_SYM(sws_freeContext); GET_SYM(sws_getContext); GET_SYM(sws_scale); #undef GET_SYM return 0; error: if (libswscale != NULL) { SDL_UnloadObject(libswscale); libswscale = NULL; } if (libavcodec != NULL) { SDL_UnloadObject(libavcodec); libavcodec = NULL; } if (libavutil != NULL) { SDL_UnloadObject(libavutil); libavutil = NULL; } return -1; } /* avutil */ #define av_frame_alloc syms.av_frame_alloc #define av_free syms.av_free #define av_get_pix_fmt syms.av_get_pix_fmt #define av_log_set_callback syms.av_log_set_callback #define av_opt_set_image_size syms.av_opt_set_image_size #define av_opt_set_int syms.av_opt_set_int #define av_opt_set_q syms.av_opt_set_q #define av_opt_set_pixel_fmt syms.av_opt_set_pixel_fmt /* avcodec */ #define av_image_fill_arrays syms.av_image_fill_arrays #define av_packet_alloc syms.av_packet_alloc #define av_packet_free syms.av_packet_free #define avcodec_alloc_context3 syms.avcodec_alloc_context3 #define avcodec_close syms.avcodec_close #define avcodec_encode_video2 syms.avcodec_encode_video2 #define avcodec_find_encoder syms.avcodec_find_encoder #define avcodec_open2 syms.avcodec_open2 #define avcodec_register_all syms.avcodec_register_all #define avpicture_get_size syms.avpicture_get_size /* swscale */ #define sws_freeContext syms.sws_freeContext #define sws_getContext syms.sws_getContext #define sws_scale syms.sws_scale #endif /* JSMPEG driver bootstrap functions */ static int JSMPEG_Available(void) { lws_set_log_level(0, NULL); #ifdef USE_LOADSO if (load_objects_and_syms() < 0) { return 0; } #endif av_log_set_callback(silentium); avcodec_register_all(); return 1; } static void JSMPEG_DeleteDevice(SDL_VideoDevice *device) { SDL_free(device); #ifdef USE_LOADSO if (libswscale != NULL) { SDL_UnloadObject(libswscale); libswscale = NULL; } if (libavcodec != NULL) { SDL_UnloadObject(libavcodec); libavcodec = NULL; } if (libavutil != NULL) { SDL_UnloadObject(libavutil); libavutil = NULL; } #endif } static SDL_VideoDevice * JSMPEG_CreateDevice(int devindex) { SDL_VideoDevice *device; SDL_VideoData *data; ................................................................................ } return SDL_Unsupported(); } static Frame * JSMPEG_EncodeFrame(SDL_WindowData *data) { AVPacket *packet; Frame *frame = NULL; unsigned char *p; int ok = 0; packet = av_packet_alloc(); avcodec_encode_video2(data->context, packet, data->frame, &ok); if (ok) { frame = (Frame *) SDL_malloc(sizeof(Frame) + LWS_PRE + 8 + packet->size); if (frame != NULL) { frame->ref_count = 1; frame->size = packet->size + 8; frame->type = LWS_WRITE_BINARY; frame->data = frame + 1; p = (unsigned char *) frame->data; p += LWS_PRE; puti32(p + 0, FRAME_TYPE_VIDEO); puti32(p + 4, frame->size); memcpy(p + 8, packet->data, packet->size); } } av_packet_free(&packet); return frame; } static void JSMPEG_TransmitFrame(Frame *frame, Client *client) { while (frame != NULL && client != NULL) { ................................................................................ /* Transmission */ JSMPEG_TransmitFrame(frame, client); #endif ticks = SDL_GetTicks(); /* About 15 frames per second */ if (ticks - data->ticks >= 63) { uint8_t *pixels[1]; int linesizes[1]; data->ticks = ticks; if (client == NULL) { /* No client connected, do nothing */ ................................................................................ { SDL_WindowData *data; const Uint32 surface_format = SDL_PIXELFORMAT_BGR888; int w, h, bpp, frame_size; Uint32 Rmask, Gmask, Bmask, Amask; const char *env; struct lws_context_creation_info info; AVRational q; enum AVPixelFormat fmt_yuv, fmt_rgb; /* Free the old framebuffer surface and related data */ data = (SDL_WindowData *) window->driverdata; JSMPEG_CleanupWindowData(data); /* Create a new one */ SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); ................................................................................ data->context = avcodec_alloc_context3(data->codec); if (data->context == NULL) { JSMPEG_CleanupWindowData(data); return -1; } fmt_yuv = av_get_pix_fmt("yuv420p"); fmt_rgb = av_get_pix_fmt("rgb32"); /* dct_algo = FF_DCT_FASTINT */ av_opt_set_int(data->context, "dct", FF_DCT_FASTINT, 0); /* bit_rate = 10000 * w */ av_opt_set_int(data->context, "b", 10000 * w, 0); /* bit_rate_tolerance = (10000 * w) << 2 */ av_opt_set_int(data->context, "bt", (10000 * w) << 2, 0); /* width = w, height = h */ av_opt_set_image_size(data->context, "video_size", w, h, 0); /* time_base.num = 1, time_base.den = 30 */ q.num = 1; q.den = 30; av_opt_set_q(data->context, "time_base", q, 0); /* gop_size = 30 */ av_opt_set_int(data->context, "g", 30, 0); /* max_b_frames = 0 */ av_opt_set_int(data->context, "bf", 0, 0); /* pix_fmt = AV_PIX_FMT_YUV420P */ av_opt_set_pixel_fmt(data->context, "pixel_format", fmt_yuv, 0); avcodec_open2(data->context, data->codec, NULL); data->frame = av_frame_alloc(); if (data->frame == NULL) { JSMPEG_CleanupWindowData(data); return -1; } data->frame->format = fmt_yuv; data->frame->width = w; data->frame->height = h; data->frame->pts = 0; frame_size = avpicture_get_size(fmt_yuv, w, h); data->frame_buffer = SDL_malloc(frame_size); if (data->frame_buffer == NULL) { JSMPEG_CleanupWindowData(data); return -1; } av_image_fill_arrays(data->frame->data, data->frame->linesize, data->frame_buffer, fmt_yuv, w, h, 1); data->sws = sws_getContext(w, h, fmt_rgb, w, h, fmt_yuv, SWS_FAST_BILINEAR, NULL, NULL, NULL); if (data->sws == NULL) { JSMPEG_CleanupWindowData(data); return -1; } data->clients = NULL; memset(&info, 0, sizeof(struct lws_context_creation_info)); |