Commit 1c5e5565 authored by François Grisez's avatar François Grisez
Browse files

Rewriting of Rfc3984.c into C++

parent ccdacdd9
......@@ -42,27 +42,14 @@ typedef enum{
Rfc3984HasPPS = 1<<6,
Rfc3984HasIDR = 1<<7,
}Rfc3984Status;
typedef struct Rfc3984Context{
MSQueue q;
mblk_t *m;
int maxsz;
unsigned int status; /*bitmask of Rfc3984Status values*/
mblk_t *sps, *pps;
mblk_t *last_sps, *last_pps;
uint32_t last_ts;
uint16_t ref_cseq;
uint8_t mode;
bool_t stap_a_allowed;
bool_t initialized_ref_cseq;
} Rfc3984Context;
typedef void Rfc3984Context;
MS2_DEPRECATED MS2_PUBLIC Rfc3984Context *rfc3984_new(void);
MS2_PUBLIC Rfc3984Context *rfc3984_new_with_factory(MSFactory *factory);
MS2_PUBLIC void rfc3984_destroy(Rfc3984Context *ctx);
void rfc3984_init(Rfc3984Context *ctx);
MS2_PUBLIC void rfc3984_set_mode(Rfc3984Context *ctx, int mode);
......@@ -74,13 +61,6 @@ MS2_PUBLIC void rfc3984_pack(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq,
MS2_PUBLIC void rfc3984_unpack_out_of_band_sps_pps(Rfc3984Context *ctx, mblk_t *sps, mblk_t *pps);
/**
* Process incoming rtp data and output NALUs, whenever possible.
* @return 0 if everything was ok, -1 on error (inconsistencies in sequence numbers for example).
* @note the naluq output argument may be filled with incomplete data even if return value was -1.
* @deprecated use rfc3984_unpack2
**/
MS2_DEPRECATED MS2_PUBLIC int rfc3984_unpack(Rfc3984Context *ctx, mblk_t *im, MSQueue *naluq);
/**
* Process incoming rtp data and output NALUs, whenever possible.
......@@ -92,8 +72,6 @@ MS2_DEPRECATED MS2_PUBLIC int rfc3984_unpack(Rfc3984Context *ctx, mblk_t *im, MS
**/
MS2_PUBLIC unsigned int rfc3984_unpack2(Rfc3984Context *ctx, mblk_t *im, MSQueue *naluq);
void rfc3984_uninit(Rfc3984Context *ctx);
#ifdef __cplusplus
}
#endif
......
......@@ -203,7 +203,9 @@ set(VOIP_SOURCE_FILES_C
voip/ringstream.c
voip/stun.c
)
set(VOIP_SOURCE_FILES_CXX )
set(VOIP_SOURCE_FILES_CXX
voip/rfc3984.cpp
)
set(VOIP_SOURCE_FILES_OBJC )
set(VOIP_SOURCE_FILES_ASM )
......@@ -298,7 +300,6 @@ if(ENABLE_VIDEO)
voip/msvideo.c
voip/nowebcam.h
voip/rfc2429.h
voip/rfc3984.c
voip/video_preset_high_fps.c
voip/videostarter.c
voip/videostream.c
......@@ -392,10 +393,12 @@ if(ENABLE_VIDEO)
utils/ffmpeg-priv.c
utils/ffmpeg-priv.h
utils/swscale.h
videofilters/h264dec.c
videofilters/videodec.c
videofilters/videoenc.c
)
list(APPEND VOIP_SOURCE_FILES_CXX
videofilters/h264dec.cpp
)
if(NOT TURBOJPEG_FOUND)
list(APPEND VOIP_SOURCE_FILES_C
videofilters/ffmpegjpegwriter.c
......@@ -459,10 +462,11 @@ if(ENABLE_VIDEO)
endif()
if(BCMATROSKA2_FOUND)
list(APPEND VOIP_SOURCE_FILES_C
videofilters/mkv.c
utils/mkv_reader.c
voip/rfc2429.h
voip/rfc3984.c
)
list(APPEND VOIP_SOURCE_FILES_CXX
videofilters/mkv.cpp
)
endif()
......@@ -742,7 +746,7 @@ if(FFMPEG_FOUND AND NOT WIN32)
set(NO_DEPRECATED_DECLARATIONS_SOURCE_FILES
videofilters/videoenc.c
videofilters/videodec.c
videofilters/h264dec.c
videofilters/h264dec.cpp
)
if(NOT TURBOJPEG_FOUND)
set(NO_DEPRECATED_DECLARATIONS_SOURCE_FILES
......
......@@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifdef __cplusplus
/*see http://linux.die.net/man/3/uint64_c */
#define __STDC_CONSTANT_MACROS 1
//#define __STDC_CONSTANT_MACROS 1
#endif
#ifdef HAVE_CONFIG_H
......@@ -42,6 +42,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <ortp/port.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(HAVE_LIBAVCODEC_AVCODEC_H)
/* new layout */
# include <libavcodec/avcodec.h>
......@@ -54,6 +59,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# include <libswscale/swscale.h>
#endif
#ifdef __cplusplus
}
#endif
#if defined(HAVE_LIBAVCODEC_AVCODEC_H)
#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(52,24,0)
/*should work as long as nobody uses avformat.h*/
......
......@@ -27,12 +27,19 @@
* Enumeration that lists the different type of NAL unit
*/
typedef enum {
MSH264NaluTypeIDR = 5,
MSH264NaluTypeIDR = 5,
MSH264NaluTypeSEI = 6,
MSH264NaluTypeSPS = 7,
MSH264NaluTypePPS = 8
MSH264NaluTypeSPS = 7,
MSH264NaluTypePPS = 8,
MSH264NaluTypeSTAPA = 24,
MSH264NaluTypeFUA = 28
} MSH264NaluType;
#ifdef __cplusplus
extern "C" {
#endif
/**
* Get the type of a NAL unit
* @param nalu The NAL unit to analyse
......@@ -82,4 +89,8 @@ void ms_h264_stream_to_nalus(const uint8_t *frame, size_t size, MSQueue *nalus,
*/
MSVideoSize ms_h264_sps_get_video_size(const mblk_t* sps);
#ifdef __cplusplus
}
#endif
#endif /* defined(H264_UTILS_H) */
......@@ -83,6 +83,11 @@ typedef struct {
typedef struct _MKVTrackReader MKVTrackReader;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Open a MKV file for reading
* @param filename Name of the file to open
......@@ -163,4 +168,8 @@ void mkv_track_reader_destroy(MKVTrackReader *reader);
*/
void mkv_block_free(MKVBlock *block);
#ifdef __cplusplus
}
#endif
#endif
......@@ -28,26 +28,30 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
typedef struct _MSStreamRegulator MSStreamRegulator;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Create an MSStreamRegulator
* @param ticker Ticker which will be used to synchronise the mblkt
* @param clock_rate Clock rate used to encode timestamp in the mblk_t
* @return The pointer on the created MSStreamRegulator
*/
extern MSStreamRegulator *ms_stream_regulator_new(MSTicker *ticker, int64_t clock_rate);
MSStreamRegulator *ms_stream_regulator_new(MSTicker *ticker, int64_t clock_rate);
/**
* @brief Destroy an MSStreamRegulator
* @param obj Stream regulator to destroy
*/
extern void ms_stream_regulator_free(MSStreamRegulator *obj);
void ms_stream_regulator_free(MSStreamRegulator *obj);
/**
* @brief Put an mblk_t buffer in the waiting queue of the stream regulator
* @param obj MSStreamRegulator
* @param pkt Buffer to store
*/
extern void ms_stream_regulator_push(MSStreamRegulator *obj, mblk_t *pkt);
void ms_stream_regulator_push(MSStreamRegulator *obj, mblk_t *pkt);
/**
* @brief Get the next waiting buffer.
......@@ -56,13 +60,17 @@ extern void ms_stream_regulator_push(MSStreamRegulator *obj, mblk_t *pkt);
* @param obj MSStreamRegulator
* @return Pointer on the unqueued buffer
*/
extern mblk_t *ms_stream_regulator_get(MSStreamRegulator *obj);
mblk_t *ms_stream_regulator_get(MSStreamRegulator *obj);
/**
* @brief Reset the stream regulator
* All waiting buffer are destroyed
* @param obj MSStreamRegulator
*/
extern void ms_stream_regulator_reset(MSStreamRegulator *obj);
void ms_stream_regulator_reset(MSStreamRegulator *obj);
#ifdef __cplusplus
}
#endif
#endif
......@@ -19,9 +19,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/rfc3984.h"
#include "mediastreamer2/msvideo.h"
#include "mediastreamer2/msticker.h"
#include "rfc3984.hpp"
#include "stream_regulator.h"
#if __clang__
......@@ -43,11 +44,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "ortp/b64.h"
using namespace mediastreamer2;
using namespace b64;
typedef struct _DecData{
mblk_t *sps,*pps;
AVFrame* orig;
Rfc3984Context unpacker;
Rfc3984Context *unpacker;
MSVideoSize vsize;
struct SwsContext *sws_ctx;
MSAverageFPS fps;
......@@ -87,13 +90,13 @@ static void dec_init(MSFilter *f){
d->sps=NULL;
d->pps=NULL;
d->sws_ctx=NULL;
rfc3984_init(&d->unpacker);
d->unpacker = new Rfc3984Context();
d->packet_num=0;
dec_open(d);
d->vsize.width=0;
d->vsize.height=0;
d->bitstream_size=65536;
d->bitstream=ms_malloc0(d->bitstream_size);
d->bitstream=reinterpret_cast<uint8_t *>(ms_malloc0(d->bitstream_size));
d->orig = av_frame_alloc();
ms_average_fps_init(&d->fps, "ffmpeg H264 decoder: FPS: %f");
if (!d->orig) {
......@@ -122,7 +125,7 @@ static void dec_postprocess(MSFilter *f) {
static void dec_uninit(MSFilter *f){
DecData *d=(DecData*)f->data;
rfc3984_uninit(&d->unpacker);
delete d->unpacker;
avcodec_close(&d->av_context);
if (d->sps) freemsg(d->sps);
if (d->pps) freemsg(d->pps);
......@@ -215,7 +218,7 @@ static bool_t check_pps_change(DecData *d, mblk_t *pps){
static void enlarge_bitstream(DecData *d, int new_size){
d->bitstream_size=new_size;
d->bitstream=ms_realloc(d->bitstream,d->bitstream_size);
d->bitstream=reinterpret_cast<uint8_t *>(ms_realloc(d->bitstream,d->bitstream_size));
}
static int nalusToFrame(DecData *d, MSQueue *naluq, bool_t *new_sps_pps){
......@@ -285,8 +288,8 @@ static void dec_process(MSFilter *f){
while((im=ms_queue_get(f->inputs[0]))!=NULL){
// Reset all contexts when an empty packet is received
if(msgdsize(im) == 0) {
rfc3984_uninit(&d->unpacker);
rfc3984_init(&d->unpacker);
delete d->unpacker;
d->unpacker = new Rfc3984Context();
dec_reinit(d);
ms_stream_regulator_reset(d->regulator);
freemsg(im);
......@@ -294,13 +297,13 @@ static void dec_process(MSFilter *f){
}
/*push the sps/pps given in sprop-parameter-sets if any*/
if (d->packet_num==0 && d->sps && d->pps){
rfc3984_unpack_out_of_band_sps_pps(&d->unpacker, d->sps, d->pps);
d->unpacker->setOutOfBandSpsPps(d->sps, d->pps);
d->sps=NULL;
d->pps=NULL;
}
ret = rfc3984_unpack2(&d->unpacker,im,&nalus);
ret = d->unpacker->unpack(im,&nalus);
if (ret & Rfc3984FrameAvailable){
if (ret & Rfc3984Context::Status::FrameAvailable){
int size;
uint8_t *p,*end;
bool_t need_reinit=FALSE;
......@@ -336,7 +339,7 @@ static void dec_process(MSFilter *f){
}
p+=len;
}
if (ret & Rfc3984FrameCorrupted) requestPLI = TRUE;
if (ret & Rfc3984Context::Status::FrameCorrupted) requestPLI = TRUE;
}
d->packet_num++;
}
......@@ -422,6 +425,9 @@ static MSFilterMethod h264_dec_methods[]={
{ 0 , NULL }
};
extern "C" {
#ifndef _MSC_VER
MSFilterDesc ms_h264_dec_desc={
......@@ -470,6 +476,8 @@ void __register_ffmpeg_h264_decoder_if_possible(MSFactory *obj) {
}
}
} // extern "C"
#if __clang__
#pragma clang diagnostic pop
#endif
......@@ -18,9 +18,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#define bool_t matroska_bool_t
extern "C" {
#include <matroska/matroska.h>
#include <matroska/matroska_sem.h>
}
#undef bool_t
#undef min
#undef max
#define bool_t ms_bool_t
......@@ -33,7 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifdef VIDEO_ENABLED
#include "mediastreamer2/msvideo.h"
#include "vp8rtpfmt.h"
#include "mediastreamer2/rfc3984.h"
#include "rfc3984.hpp"
#include "h264utils.h"
#endif // ifdef VIDEO_ENABLED
......@@ -41,6 +45,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define bool_t ambigous use ms_bool_t or matroska_bool_t
using namespace mediastreamer2;
static int recorder_close(MSFilter *f, void *arg);
......@@ -165,7 +171,7 @@ static void H264Private_addPPS(H264Private *obj, mblk_t *pps) {
if (it == NULL) {
obj->pps_list = bctbx_list_append(obj->pps_list, dupmsg(pps));
} else if (!_H264Private_msgequal((mblk_t *)it->data, pps)) {
freemsg(it->data);
freemsg((mblk_t *)it->data);
it->data = dupmsg(pps);
obj->broken = TRUE;
}
......@@ -277,22 +283,21 @@ static void H264Private_load(H264Private *obj, const uint8_t *data) {
/* h264 module */
typedef struct {
Rfc3984Context rfc3984Context;
Rfc3984Context *rfc3984Context;
H264Private *codecPrivate;
H264Private *lastCodecPrivate;
} H264Module;
static void *h264_module_new(MSFactory *factory) {
H264Module *mod = bctbx_new0(H264Module, 1);
rfc3984_init(&mod->rfc3984Context);
mod->rfc3984Context.maxsz = ms_factory_get_payload_max_size(factory);
rfc3984_set_mode(&mod->rfc3984Context, 1);
mod->rfc3984Context = new Rfc3984Context(factory);
mod->rfc3984Context->setMode(1);
return mod;
}
static void h264_module_free(void *data) {
H264Module *obj = (H264Module *)data;
rfc3984_uninit(&obj->rfc3984Context);
delete obj->rfc3984Context;
if(obj->codecPrivate != NULL) H264Private_free(obj->codecPrivate);
if(obj->lastCodecPrivate != NULL) H264Private_free(obj->lastCodecPrivate);
bctbx_free(obj);
......@@ -305,7 +310,7 @@ static int h264_module_preprocessing(void *data, MSQueue *input, MSQueue *output
ms_queue_init(&queue);
while((inputBuffer = ms_queue_get(input)) != NULL) {
rfc3984_unpack2(&obj->rfc3984Context, inputBuffer, &queue);
obj->rfc3984Context->unpack(inputBuffer, &queue);
if(!ms_queue_empty(&queue)) {
mblk_t *frame = ms_queue_get(&queue);
mblk_t *end = frame;
......@@ -482,7 +487,7 @@ static void h264_module_reverse(MSFactory* factory, void *data, mblk_t *input, M
curBuff->b_cont = NULL;
ms_queue_put(&queue, curBuff);
}
rfc3984_pack(&obj->rfc3984Context, &queue, output, mblk_get_timestamp_info(input));
obj->rfc3984Context->pack(&queue, output, mblk_get_timestamp_info(input));
freemsg(input);
}
......@@ -996,13 +1001,13 @@ static int ebml_reading_profile(ebml_master *head) {
tchar_t docType[9];
int profile;
int64_t docTypeReadVersion;
tchar_t *matroska_doc_type =
const tchar_t *matroska_doc_type =
#ifdef UNICODE
L"matroska";
#else
"matroska";
#endif
tchar_t *webm_doc_type =
const tchar_t *webm_doc_type =
#ifdef UNICODE
L"webm";
#else
......@@ -2032,7 +2037,7 @@ fail:
}
static void recorder_process(MSFilter *f) {
MKVRecorder *obj = f->data;
MKVRecorder *obj = reinterpret_cast<MKVRecorder *>(f->data);
uint16_t i;
ms_filter_lock(f);
......@@ -2247,6 +2252,9 @@ static MSFilterMethod recorder_methods[] = {
{ 0 , NULL }
};
extern "C" {
#ifdef _MSC_VER
MSFilterDesc ms_mkv_recorder_desc = {
MS_MKV_RECORDER_ID,
......@@ -2283,6 +2291,8 @@ MSFilterDesc ms_mkv_recorder_desc = {
};
#endif
} // extern "C"
MS_FILTER_DESC_EXPORT(ms_mkv_recorder_desc)
......@@ -2767,6 +2777,9 @@ static MSFilterMethod player_methods[] = {
{ 0 , NULL }
};
extern "C" {
#ifdef _MSC_VER
MSFilterDesc ms_mkv_player_desc = {
MS_MKV_PLAYER_ID,
......@@ -2803,4 +2816,6 @@ MSFilterDesc ms_mkv_player_desc = {
};
#endif
} // extern "C"
MS_FILTER_DESC_EXPORT(ms_mkv_player_desc)
This diff is collapsed.
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)
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.
*/
#pragma once
#include "mediastreamer2/mscommon.h"
#include "mediastreamer2/msqueue.h"
#include "mediastreamer2/msfactory.h"
/*
T h*is file declares an API useful to pack/unpack H264 nals as described in RFC3984
It is part of the public API to allow external H264 plugins use this api.
*/
namespace mediastreamer2 {
class Rfc3984Context {
public:
enum class Status {
FrameAvailable = 1,
FrameCorrupted = 1<<1,
IsKeyFrame = 1<<2, // set when a frame has SPS + PPS or IDR (possibly both)
NewSPS = 1<<3,
NewPPS = 1<<4,
HasSPS = 1<<5,
HasPPS = 1<<6,
HasIDR = 1<<7,
};
Rfc3984Context();
Rfc3984Context(MSFactory *factory);
~Rfc3984Context();
void setMode(int mode) {this->mode = mode;}
int getMode() const {return this->mode;}
// some stupid phones don't decode STAP-A packets ...
void enableStapA(bool yesno) {this->stap_a_allowed = yesno;}
bool stapAEnabled() const {return this->stap_a_allowed;}
void setMaxPayloadSize(int size) {this->maxsz = size;}
int getMaxPayloadSize() {return this->maxsz;}
void setOutOfBandSpsPps(mblk_t *sps, mblk_t *pps);
// process NALUs and pack them into rtp payloads
void pack(MSQueue *naluq, MSQueue *rtpq, uint32_t ts);
/**
* Process incoming rtp data and output NALUs, whenever possible.
* @param ctx the Rfc3984Context object
* @param im a new H264 packet to process
* @param naluq a MSQueue into which a frame ready to be decoded will be output, in the form of a sequence of NAL units.
* @return a bitmask of Rfc3984Status values.
* The return value is a bitmask of the #Rfc3984Status enum.
**/
unsigned int unpack(mblk_t *im, MSQueue *naluq);
private:
void packMode0(MSQueue *naluq, MSQueue *rtpq, uint32_t ts);
void packMode1(MSQueue *naluq, MSQueue *rtpq, uint32_t ts);
void fragNaluAndSend(MSQueue *rtpq, uint32_t ts, mblk_t *nalu, bool_t marker, int maxsize);
void sendPacket(MSQueue *rtpq, uint32_t ts, mblk_t *m, bool_t marker);
unsigned int outputFrame(MSQueue *out, unsigned int flags);
void storeNal(mblk_t *nal);
mblk_t *aggregateFUA(mblk_t *im);
static mblk_t *concatNalus(mblk_t *m1, mblk_t *m2);
static mblk_t *prependStapA(mblk_t *m);
static uint8_t nalHeaderGetNri(const uint8_t *h) {return ((*h) >> 5) & 0x3;}
static void nalHeaderInit(uint8_t *h, uint8_t nri, uint8_t type) {*h=((nri&0x3)<<5) | (type & ((1<<5)-1));}
static void putNalSize(mblk_t *m, size_t sz);
static mblk_t *prependFuIndicatorAndHeader(mblk_t *m, uint8_t indicator, bool_t start, bool_t end, uint8_t type);
static int isUniqueISlice(const uint8_t *slice_header);
static bool_t updateParameterSet(mblk_t **last_parameter_set, mblk_t *new_parameter_set);
MSQueue q;
mblk_t *m = nullptr;
int maxsz = MS_DEFAULT_MAX_PAYLOAD_SIZE;
unsigned int status = 0; // bitmask of Rfc3984Status values
mblk_t *sps;
mblk_t *pps;
mblk_t *last_sps = nullptr;
mblk_t *last_pps = nullptr;
uint32_t last_ts = 0x943FEA43;
uint16_t ref_cseq;
uint8_t mode = 0;
bool stap_a_allowed = false;
bool initialized_ref_cseq;
};
unsigned int operator&(unsigned int val1, Rfc3984Context::Status val2);
unsigned int &operator&=(unsigned int &val1, Rfc3984Context::Status val2);
unsigned int operator|(unsigned int val1, Rfc3984Context::Status val2);
unsigned int &operator|=(unsigned int &val1, Rfc3984Context::Status val2);
};
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