Commit 7f9f64b6 authored by François Grisez's avatar François Grisez
Browse files

Adding MSMediaCodecH265Enc and MSMediaCodecH265Dec filters.

parent d7bfca22
......@@ -28,7 +28,7 @@ extern MSFilterDesc ms_h263_enc_desc;
extern MSFilterDesc ms_h263_dec_desc;
extern MSFilterDesc ms_h263_old_dec_desc;
extern MSFilterDesc ms_h264_dec_desc;
extern MSFilterDesc ms_mediacodec_h264_dec_desc;
extern MSFilterDesc ms_mediacodec_h265_dec_desc;
extern MSFilterDesc ms_mediacodec_h264_enc_desc;
extern MSFilterDesc ms_pix_conv_desc;
extern MSFilterDesc ms_size_conv_desc;
......@@ -86,7 +86,7 @@ MSFilterDesc * ms_voip_filter_descs[]={
&ms_h263_dec_desc,
&ms_h263_old_dec_desc,
&ms_h264_dec_desc,
&ms_mediacodec_h264_dec_desc,
&ms_mediacodec_h265_dec_desc,
&ms_mediacodec_h264_enc_desc,
&ms_pix_conv_desc,
&ms_size_conv_desc,
......
......@@ -164,7 +164,9 @@ typedef enum MSFilterId{
MS_G729_ENC_ID,
MS_WASAPI_READ_ID,
MS_WASAPI_WRITE_ID,
MS_AUDIO_FLOW_CONTROL_ID
MS_AUDIO_FLOW_CONTROL_ID,
MS_MEDIACODEC_H265_DEC_ID,
MS_MEDIACODEC_H265_ENC_ID,
} MSFilterId;
#endif
......@@ -384,6 +384,8 @@ if(ENABLE_VIDEO)
android/media-codec-encoder.cpp
android/media-codec-h264-decoder.cpp
android/media-codec-h264-encoder.cpp
android/media-codec-h265-decoder.cpp
android/media-codec-h265-encoder.cpp
)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a")
list(APPEND VOIP_SOURCE_FILES_ASM
......
......@@ -44,6 +44,7 @@ public:
MSVideoSize getVideoSize() const;
float getFps() const;
const MSFmtDescriptor *getOutFmt() const;
void addFmtp(const char *fmtp) {}
void enableAvpf(bool enable);
void enableFreezeOnError(bool enable);
......
/*
Mediastreamer2 media-codec-h265-decoder.cpp
Copyright (C) 2018 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "h265-nal-unpacker.h"
#include "media-codec-decoder.h"
namespace mediastreamer {
class MediaCodecH265DecoderFilterImpl: public MediaCodecDecoderFilterImpl {
public:
MediaCodecH265DecoderFilterImpl(MSFilter *f): MediaCodecDecoderFilterImpl(f, "video/hevc", new H265NalUnpacker()) {}
static void onFilterInit(MSFilter *f) {
f->data = new MediaCodecH265DecoderFilterImpl(f);
}
static void onFilterUninit(MSFilter *f) {
delete static_cast<MediaCodecH265DecoderFilterImpl *>(f->data);
}
static void onFilterPreProcess(MSFilter *f) {
static_cast<MediaCodecH265DecoderFilterImpl *>(f->data)->preprocess();
}
static void onFilterPostProcess(MSFilter *f) {
static_cast<MediaCodecH265DecoderFilterImpl *>(f->data)->postprocess();
}
static void onFilterProcces(MSFilter *f) {
static_cast<MediaCodecH265DecoderFilterImpl *>(f->data)->process();
}
static int onAddFmtpCall(MSFilter *f, void *arg) {
const char *fmtp = static_cast<const char *>(arg);
static_cast<MediaCodecH265DecoderFilterImpl *>(f->data)->addFmtp(fmtp);
return 0;
}
static int onResetFirstImageCall(MSFilter *f, void *arg) {
static_cast<MediaCodecH265DecoderFilterImpl *>(f->data)->resetFirstImage();
return 0;
}
static int onGetVideoSizeCall(MSFilter *f, void *arg) {
MSVideoSize *vsize = static_cast<MSVideoSize *>(arg);
*vsize = static_cast<MediaCodecH265DecoderFilterImpl *>(f->data)->getVideoSize();
return 0;
}
static int onGetFpsCall(MSFilter *f, void *arg) {
float *fps = static_cast<float *>(arg);
*fps = static_cast<MediaCodecH265DecoderFilterImpl *>(f->data)->getFps();
return 0;
}
static int onGetOutFmtCall(MSFilter *f, void *arg) {
MSPinFormat *pinFormat = static_cast<MSPinFormat *>(arg);
pinFormat->fmt = static_cast<MediaCodecH265DecoderFilterImpl *>(f->data)->getOutFmt();
return 0;
}
static int onEnableAvpfCall(MSFilter *f, void *arg) {
const bool_t *enable = static_cast<bool_t *>(arg);
static_cast<MediaCodecH265DecoderFilterImpl *>(f->data)->enableAvpf(enable);
return 0;
}
static int onEnableFreezeOnErrorCall(MSFilter *f, void *arg) {
const bool_t *enable = static_cast<bool_t *>(arg);
static_cast<MediaCodecH265DecoderFilterImpl *>(f->data)->enableFreezeOnError(enable);
return 0;
}
};
}
using namespace mediastreamer;
static MSFilterMethod mediacodec_h265_dec_methods[] = {
{ MS_FILTER_ADD_FMTP , MediaCodecH265DecoderFilterImpl::onAddFmtpCall },
{ MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION , MediaCodecH265DecoderFilterImpl::onResetFirstImageCall },
{ MS_FILTER_GET_VIDEO_SIZE , MediaCodecH265DecoderFilterImpl::onGetVideoSizeCall },
{ MS_FILTER_GET_FPS , MediaCodecH265DecoderFilterImpl::onGetFpsCall },
{ MS_FILTER_GET_OUTPUT_FMT , MediaCodecH265DecoderFilterImpl::onGetOutFmtCall },
{ MS_VIDEO_DECODER_ENABLE_AVPF , MediaCodecH265DecoderFilterImpl::onEnableAvpfCall },
{ MS_VIDEO_DECODER_FREEZE_ON_ERROR , MediaCodecH265DecoderFilterImpl::onEnableFreezeOnErrorCall },
{ 0 , nullptr }
};
extern "C" MSFilterDesc ms_mediacodec_h265_dec_desc = {
.id = MS_MEDIACODEC_H265_DEC_ID,
.name = "MSMediaCodecH265Dec",
.text = "A H265 decoder based on MediaCodec API.",
.category = MS_FILTER_DECODER,
.enc_fmt = "H265",
.ninputs = 1,
.noutputs = 1,
.init = MediaCodecH265DecoderFilterImpl::onFilterInit,
.preprocess = MediaCodecH265DecoderFilterImpl::onFilterPreProcess,
.process = MediaCodecH265DecoderFilterImpl::onFilterProcces,
.postprocess = MediaCodecH265DecoderFilterImpl::onFilterPostProcess,
.uninit = MediaCodecH265DecoderFilterImpl::onFilterUninit,
.methods = mediacodec_h265_dec_methods,
.flags = MS_FILTER_IS_PUMP
};
/*
Mediastreamer2 media-codec-h265-encoder.cpp
Copyright (C) 2018 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "h265-nal-packer.h"
#include "media-codec-encoder.h"
namespace mediastreamer {
class MediaCodecH265EncoderFilterImpl: public MediaCodecEncoderFilterImpl {
public:
MediaCodecH265EncoderFilterImpl(MSFilter *f): MediaCodecEncoderFilterImpl(f, "video/hevc", new H265NalPacker(f->factory)) {}
static void onFilterInit(MSFilter *f) {
f->data = new MediaCodecH265EncoderFilterImpl(f);
}
static void onFilterPreprocess(MSFilter *f) {
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->preprocess();
}
static void onFilterPostprocess(MSFilter *f) {
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->postprocess();
}
static void onFilterUninit(MSFilter *f) {
delete static_cast<MediaCodecH265EncoderFilterImpl *>(f->data);
}
static void onFilterProcess(MSFilter *f) {
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->process();
}
static int onGetBitrateCall(MSFilter *f, void *arg) {
int *bitrate = static_cast<int *>(arg);
*bitrate = static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->getBitrate();
return 0;
}
static int onSetConfigurationCall(MSFilter *f, void *arg) {
const MSVideoConfiguration *vconf = static_cast<MSVideoConfiguration *>(arg);
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->setVideoConfiguration(vconf);
return 0;
}
static int onSetBitrateCall(MSFilter *f, void *arg) {
int br = *static_cast<int *>(arg);
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->setBitrate(br);
return 0;
}
static int onSetFpsCall(MSFilter *f, void *arg) {
float fps = *static_cast<float *>(arg);
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->setFps(fps);
return 0;
}
static int onGetFpsCall(MSFilter *f, void *arg) {
float *fps = static_cast<float *>(arg);
*fps = static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->getFps();
return 0;
}
static int onGetVideoSizeCall(MSFilter *f, void *arg) {
MSVideoSize *vsize = static_cast<MSVideoSize *>(arg);
*vsize = static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->getVideoSize();
return 0;
}
static int onEnableAvpfCall(MSFilter *f, void *data) {
bool_t enable = *static_cast<bool_t *>(data);
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->enableAvpf(enable);
return 0;
}
static int onSetVideoSizeCall(MSFilter *f, void *arg) {
const MSVideoSize *vsize = static_cast<MSVideoSize *>(arg);
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->setVideoSize(*vsize);
return 0;
}
static int onNotifyPliCall(MSFilter *f, void *data) {
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->notifyPli();
return 0;
}
static int onNotifyFirCall(MSFilter *f, void *data) {
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->notifyFir();
return 0;
}
static int onGetVideoConfigurationsCall(MSFilter *f, void *data) {
const MSVideoConfiguration **vconfs = static_cast<const MSVideoConfiguration **>(data);
*vconfs = static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->getVideoConfiguratons();
return 0;
}
static int onSetVideoConfigurationsCall(MSFilter *f, void *data) {
const MSVideoConfiguration *vconfs = static_cast<const MSVideoConfiguration *>(data);
static_cast<MediaCodecH265EncoderFilterImpl *>(f->data)->setVideoConfigurations(vconfs);
return 0;
}
};
}
using namespace mediastreamer;
static MSFilterMethod mediacodec_h265_enc_methods[] = {
{ MS_FILTER_SET_FPS , MediaCodecH265EncoderFilterImpl::onSetFpsCall },
{ MS_FILTER_SET_BITRATE , MediaCodecH265EncoderFilterImpl::onSetBitrateCall },
{ MS_FILTER_GET_BITRATE , MediaCodecH265EncoderFilterImpl::onGetBitrateCall },
{ MS_FILTER_GET_FPS , MediaCodecH265EncoderFilterImpl::onGetFpsCall },
{ MS_FILTER_GET_VIDEO_SIZE , MediaCodecH265EncoderFilterImpl::onGetVideoSizeCall },
{ MS_VIDEO_ENCODER_NOTIFY_PLI , MediaCodecH265EncoderFilterImpl::onNotifyPliCall },
{ MS_VIDEO_ENCODER_NOTIFY_FIR , MediaCodecH265EncoderFilterImpl::onNotifyFirCall },
{ MS_FILTER_SET_VIDEO_SIZE , MediaCodecH265EncoderFilterImpl::onSetVideoSizeCall },
{ MS_VIDEO_ENCODER_ENABLE_AVPF , MediaCodecH265EncoderFilterImpl::onEnableAvpfCall },
{ MS_VIDEO_ENCODER_GET_CONFIGURATION_LIST , MediaCodecH265EncoderFilterImpl::onGetVideoConfigurationsCall },
{ MS_VIDEO_ENCODER_SET_CONFIGURATION_LIST , MediaCodecH265EncoderFilterImpl::onSetVideoConfigurationsCall },
{ MS_VIDEO_ENCODER_SET_CONFIGURATION , MediaCodecH265EncoderFilterImpl::onSetConfigurationCall },
{ 0 , nullptr }
};
extern "C" MSFilterDesc ms_mediacodec_h265_enc_desc = {
.id = MS_MEDIACODEC_H265_ENC_ID,
.name = "MSMediaCodecH265Enc",
.text = "A H265 encoder based on MediaCodec API.",
.category = MS_FILTER_ENCODER,
.enc_fmt = "H265",
.ninputs = 1,
.noutputs = 1,
.init = MediaCodecH265EncoderFilterImpl::onFilterInit,
.preprocess = MediaCodecH265EncoderFilterImpl::onFilterPreprocess,
.process = MediaCodecH265EncoderFilterImpl::onFilterProcess,
.postprocess = MediaCodecH265EncoderFilterImpl::onFilterPostprocess,
.uninit = MediaCodecH265EncoderFilterImpl::onFilterUninit,
.methods = mediacodec_h265_enc_methods,
.flags = MS_FILTER_IS_PUMP
};
......@@ -24,7 +24,10 @@
namespace mediastreamer {
class H265NalPacker: NalPacker {
class H265NalPacker: public NalPacker {
public:
H265NalPacker(const MSFactory *factory): NalPacker(new NaluAggregator, new NaluSpliter(), factory) {}
private:
class NaluAggregator: public NaluAggregatorInterface {
public:
......@@ -51,8 +54,6 @@ private:
private:
mblk_t *makeFu(const H265NaluHeader &naluHeader, const H265FuHeader &fuHeader, const uint8_t *payload, size_t length);
};
H265NalPacker(const MSFactory *factory): NalPacker(new NaluAggregator, new NaluSpliter(), factory) {}
};
}
......@@ -102,4 +102,15 @@ void H265NalUnpacker::ApSpliter::feed(mblk_t *packet) {
}
}
NalUnpacker::PacketType H265NalUnpacker::getNaluType(const mblk_t *nalu) const {
H265NaluHeader header(nalu->b_rptr);
if (header.getType() == H265NaluType::Ap) {
return PacketType::AggregationPacket;
} else if (header.getType() == H265NaluType::Fu) {
return PacketType::FragmentationUnit;
} else {
return PacketType::SingleNalUnit;
}
}
} // namespace mediastreamer
......@@ -41,6 +41,8 @@ private:
void feed(mblk_t *packet) override;
MSQueue *getNalus() override {return &_q;}
};
PacketType getNaluType(const mblk_t *nalu) const override;
};
} // namespace mediastreamer
......@@ -201,6 +201,8 @@ extern MSWebCamDesc ms_mire_webcam_desc;
extern MSWebCamDesc ms_android_video_capture_desc;
extern MSFilterDesc ms_mediacodec_h264_dec_desc;
extern MSFilterDesc ms_mediacodec_h264_enc_desc;
extern MSFilterDesc ms_mediacodec_h265_dec_desc;
extern MSFilterDesc ms_mediacodec_h265_enc_desc;
extern bool_t AMediaImage_isAvailable(void);
#endif
......@@ -273,6 +275,8 @@ void ms_factory_init_voip(MSFactory *obj){
ms_factory_register_filter(obj, &ms_mediacodec_h264_dec_desc);
ms_factory_register_filter(obj, &ms_mediacodec_h264_enc_desc);
}
ms_factory_register_filter(obj, &ms_mediacodec_h265_dec_desc);
ms_factory_register_filter(obj, &ms_mediacodec_h265_enc_desc);
#endif
/* register builtin VoIP MSFilter's */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment