Skip to content

Commit

Permalink
Added VideoMediaPort and VideoMediaPortCB
Browse files Browse the repository at this point in the history
  • Loading branch information
jim-page committed Jun 1, 2024
1 parent 53b2887 commit f67e0d5
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/build-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:
with:
branch: jse
- run: swig -version
- run: apt-get update
- run: apt-get install -y SDL2-devel ffmpeg-devel OpenH264 libyuv-devel libv4l2
# build x86_64 version, test, pack, package and native module
- run: npm i --ignore-scripts
# see https://github.com/bchr02/node-pre-gyp-github/pull/46
Expand Down Expand Up @@ -98,6 +100,7 @@ jobs:
registry-url: https://npm.pkg.github.com/
- run: apt-get update
- run: apt-get install -y libpcre2-dev autotools-dev autoconf libtool-bin g++ make bison uuid-dev
- run: apt-get install -y SDL2-devel ffmpeg-devel OpenH264 libyuv-devel libv4l2
- run: npm i -g node-gyp node-addon-api
- uses: mmomtchev/setup-swig@v3
with:
Expand Down
12 changes: 11 additions & 1 deletion binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@
"-lg7221codec",
"-lyuv",
"-lwebrtc",
"-lavdevice",
"-lavformat",
"-lavcodec",
"-lswscale",
"-lavutil",
"-lopenh264",
"-lSDL2",
],
'conditions': [
[ 'arch=="aarch64" or arch=="arm64"',
Expand Down Expand Up @@ -92,7 +99,10 @@
"-framework CoreMedia",
"-framework Metal",
"-framework MetalKit",
"-framework VideoToolbox"
"-framework VideoToolbox",
"-L/opt/homebrew/Cellar/ffmpeg/<!(ls -1 /opt/homebrew/Cellar/ffmpeg/)/lib",
"-L/opt/homebrew/Cellar/sdl2/<!(ls -1 /opt/homebrew/Cellar/sdl2/)/lib",
"-L/opt/homebrew/Cellar/openh264/<!(ls -1 /opt/homebrew/Cellar/openh264/)/lib"
]
}
]
Expand Down
13 changes: 11 additions & 2 deletions src/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,18 @@ else
CFLAGS="-fPIC"
LDFLAGS=""
fi
CONFIGUREFLAGS=""
if [ "$(uname)" == "Darwin" ] ; then
FFMPEGPATH="/opt/homebrew/Cellar/ffmpeg/$(ls -1 /opt/homebrew/Cellar/ffmpeg/)"
SDLPATH="/opt/homebrew/Cellar/sdl2/$(ls -1 /opt/homebrew/Cellar/sdl2/)"
OPENH264PATH="/opt/homebrew/Cellar/openh264/$(ls -1 /opt/homebrew/Cellar/openh264/)"
CFLAGS+=" -I$FFMPEGPATH/include -I$SDLPATH/include -I$OPENH264PATH/include"
# LDFLAGS+=" -L$FFMPEGPATH/lib -L$SDLPATH/lib -L$OPENH264PATH/lib"
# LDFLAGS+=" -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lpostproc -lswresample -lswscale"
fi
cp pjlib/include/pj/config_site_sample.h pjlib/include/pj/config_site.h
echo "#define PJMEDIA_HAS_VID_TOOLBOX_CODEC 1" >> pjlib/include/pj/config_site.h
./configure --prefix=$PREFIX CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h
./configure --prefix=$PREFIX CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" $CONFIGUREFLAGS
make -j 4
make install

Expand Down
32 changes: 30 additions & 2 deletions src/callback.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef __CALLBACK_HPP__
#define __CALLBACK_HPP__

#include "videomediaport.hpp"
#include "pjsua2.hpp"
using namespace pj;

Expand Down Expand Up @@ -167,6 +168,35 @@ class AudioMediaPortCB: public AudioMediaPort {
}
CB_IMPLTYPESPECRET(FrameRequested, MediaFrame)
CB_IMPLTYPESPEC(FrameReceived, MediaFrame)

// std::function<void(MediaFrame &)> onFrameReceivedCBFn;
// void setFrameReceivedCB(std::function<void(MediaFrame &)> fn) { onFrameReceivedArrayBufferCBFn = fn; } \
// virtual void onFrameReceived(MediaFrame &prm) {
// if (onFrameReceivedCBFn) {
// onFrameReceivedCBFn(prm);
// }
// }
};

class VideoMediaPortCB: public VideoMediaPort {
public:
void destroy() {
DESTRUCT(FrameRequested)
DESTRUCT(FrameReceived)
}
~VideoMediaPortCB() {
destroy();
}
CB_IMPLTYPESPECRET(FrameRequested, MediaFrame)
CB_IMPLTYPESPEC(FrameReceived, MediaFrame)

// std::function<void(MediaFrame &)> onFrameReceivedCBFn;
// void setFrameReceivedCB(std::function<void(MediaFrame &)> fn) { onFrameReceivedArrayBufferCBFn = fn; } \
// virtual void onFrameReceived(MediaFrame &prm) {
// if (onFrameReceivedCBFn) {
// onFrameReceivedCBFn(prm);
// }
// }
};

class AudioMediaPlayerCB: public AudioMediaPlayer {
Expand All @@ -193,6 +223,4 @@ class BuddyCB: public Buddy {
CB_IMPL(BuddyEvSubState) // OnBuddyEvSubStateParam
};



#endif
9 changes: 9 additions & 0 deletions src/callback.i
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ CB_IGNORE_PARENT(Buddy, BuddyEvSubState)
%include "../build/pjproject/pjsip-apps/src/swig/pjsua2.i"

%{
#include "videomediaport.hpp"
#include "callback.hpp"

#define ASYNC_CALLBACK_SUPPORT
Expand Down Expand Up @@ -351,6 +352,13 @@ CB_TYPEMAP_RET(MediaFrame, MediaFrame)
CB_MANAGE_INNER(AudioMediaPort, FrameRequested, MediaFrame, MediaFrame&, prm: MediaFrame)
CB_MANAGE_INNER(AudioMediaPort, FrameReceived, void, MediaFrame&, prm: MediaFrame)

// VideoMediaPortCB

// CB_TYPEMAP(MediaFrame)
// CB_TYPEMAP_RET(MediaFrame, MediaFrame)
CB_MANAGE_INNER(VideoMediaPort, FrameRequested, MediaFrame, MediaFrame&, prm: MediaFrame)
CB_MANAGE_INNER(VideoMediaPort, FrameReceived, void, MediaFrame&, prm: MediaFrame)

// AudioMediaPlayerCB

CB_TYPEMAP_VOID
Expand All @@ -364,5 +372,6 @@ CB_TYPEMAP(CB_PTYPE(BuddyEvSubState))
CB_MANAGE_VOID(Buddy, BuddyState)
CB_MANAGE(Buddy, BuddyEvSubState)

%include "videomediaport.hpp"
%include "callback.hpp"

136 changes: 136 additions & 0 deletions src/videomediaport.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#ifndef __VIDEOMEDIAPORT_HPP__
#define __VIDEOMEDIAPORT_HPP__

// missing VideoMediaPort implementation

#include <pjsua-lib/pjsua.h>
#include <pjsua2/types.hpp>
#include <pjsua2/media.hpp>

using namespace pj;
using namespace std;

#include <pjsua-lib/pjsua_internal.h>

#define THIS_FILE "videomediaport.hpp"


namespace pj
{
class VideoMediaPort: public VideoMedia {

public:

VideoMediaPort()
: pool(NULL)
{
pj_bzero(&port, sizeof(port));
}

virtual ~VideoMediaPort()
{
if (pool) {
PJSUA2_CATCH_IGNORE( unregisterMediaPort() );
pj_pool_release(pool);
pool = NULL;
}
}

static pj_status_t get_frame(pjmedia_port *port, pjmedia_frame *frame)
{
VideoMediaPort *mport = (VideoMediaPort *) port->port_data.pdata;
MediaFrame frame_;

frame_.size = frame->size;
mport->onFrameRequested(frame_);
frame->type = frame_.type;
frame->size = PJ_MIN(frame_.buf.size(), frame_.size);

#if ((defined(_MSVC_LANG) && _MSVC_LANG <= 199711L) || __cplusplus <= 199711L)
/* C++98 does not have Vector::data() */
if (frame->size > 0)
pj_memcpy(frame->buf, &frame_.buf[0], frame->size);
#else
/* Newer than C++98 */
pj_memcpy(frame->buf, frame_.buf.data(), frame->size);
#endif


return PJ_SUCCESS;
}

static pj_status_t put_frame(pjmedia_port *port, pjmedia_frame *frame)
{
VideoMediaPort *mport = (VideoMediaPort *) port->port_data.pdata;
MediaFrame frame_;

frame_.type = frame->type;
frame_.buf.assign((char *)frame->buf, ((char *)frame->buf) + frame->size);
frame_.size = frame->size;
mport->onFrameReceived(frame_);

return PJ_SUCCESS;
}

void createPort(const string &name, MediaFormatVideo &fmt)
PJSUA2_THROW(Error)
{
pj_str_t name_;
pjmedia_format fmt_;

if (pool) {
PJSUA2_RAISE_ERROR(PJ_EEXISTS);
}

pool = pjsua_pool_create( "vmport%p", 512, 512);
if (!pool) {
PJSUA2_RAISE_ERROR(PJ_ENOMEM);
}

/* Init port. */
pj_bzero(&port, sizeof(port));
pj_strdup2_with_null(pool, &name_, name.c_str());
fmt_ = fmt.toPj();
pjmedia_port_info_init2(&port.info, &name_,
PJMEDIA_SIG_CLASS_APP ('V', 'M', 'P'),
PJMEDIA_DIR_ENCODING_DECODING, &fmt_);

port.port_data.pdata = this;
port.put_frame = &put_frame;
port.get_frame = &get_frame;

registerMediaPort(&port, pool);
}

/*
* Callbacks
*/
/**
* This callback is called to request a frame from this port. On input,
* frame.size indicates the capacity of the frame buffer and frame.buf
* will initially be an empty vector. Application can then set the frame
* type and fill the vector.
*
* @param frame The frame.
*/
virtual void onFrameRequested(MediaFrame &frame)
{ PJ_UNUSED_ARG(frame); }

/**
* This callback is called when this port receives a frame. The frame
* content will be provided in frame.buf vector, and the frame size
* can be found in either frame.size or the vector's size (both
* have the same value).
*
* @param frame The frame.
*/
virtual void onFrameReceived(MediaFrame &frame)
{ PJ_UNUSED_ARG(frame); }

private:
pj_pool_t *pool;
pjmedia_port port;
};
}

#endif

0 comments on commit f67e0d5

Please sign in to comment.