Commit fbc20157 authored by Simon Morlat's avatar Simon Morlat
Browse files

rework plc for simplification

parent 8e3778f1
......@@ -19,17 +19,42 @@
#ifndef mscodecutils_h
#define mscodecutils_h
#include "ortp/str_utils.h"
#include "mediastreamer2/mscommon.h"
/**
* Helper object for audio decoders to determine whether PLC (packet loss concealment is needed).
**/
typedef struct _MSConcealerContext MSConcealerContext;
MSConcealerContext* ms_concealer_context_new(unsigned int max_plc_count);
void ms_concealer_context_destroy(MSConcealerContext* context);
void ms_concealer_context_set_sampling_time(MSConcealerContext* obj,unsigned long value);
unsigned long ms_concealer_context_get_sampling_time(MSConcealerContext* obj);
unsigned long ms_concealer_context_get_total_number_of_plc(MSConcealerContext* obj);
/* return number of concelad packet since the begening of the concealement period or 0 if not needed*/
unsigned int ms_concealer_context_is_concealement_required(MSConcealerContext* obj,uint64_t current_time);
/**
* Creates a new concealer object.
* @param max_plc_count the number of consecutive milliseconds of PLC allowed.
**/
MS2_PUBLIC MSConcealerContext* ms_concealer_context_new(unsigned int max_plc_count);
/**
* Destroys a concealer object.
**/
MS2_PUBLIC void ms_concealer_context_destroy(MSConcealerContext* context);
/**
* Returns 1 when PLC is needed, 0 otherwise.
* @param obj the concealer object
* @param current_time the current time in milliseconds, as pointed by f->ticker->time .
**/
MS2_PUBLIC unsigned int ms_concealer_context_is_concealement_required(MSConcealerContext* obj,uint64_t current_time);
/**
* Call this function whenever you decoded a packet, for true or in PLC mode, to inform the concealer
* of how the audio stream is going.
* @param obj the concealer object
* @param current_time the current time in milliseconds, as pointed by f->ticker->time.
* @param time_increment the number of milliseconds of audio decoded.
* @param got_packet set to 1 if a real frame was decoded, 0 if it was a PLC frame.
* @returns if a PLC period terminates, returns the duration of this PLC period in milliseconds, 0 otherwise.
**/
MS2_PUBLIC int ms_concealer_inc_sample_time(MSConcealerContext* obj, uint64_t current_time, int time_increment, int got_packet);
/*FEC API*/
......
......@@ -771,10 +771,10 @@ void ms_get_cur_time(MSTimeSpec *ret){
}
struct _MSConcealerContext {
uint64_t sample_time;
int plc_count;
int64_t sample_time;
int64_t plc_start_time;
unsigned long total_number_for_plc;
unsigned int max_plc_count;
unsigned int max_plc_time;
};
/*** plc context begin***/
......@@ -782,39 +782,52 @@ unsigned long ms_concealer_context_get_total_number_of_plc(MSConcealerContext* o
return obj->total_number_for_plc;
}
MSConcealerContext* ms_concealer_context_new(unsigned int max_plc_count){
MSConcealerContext* ms_concealer_context_new(unsigned int max_plc_time){
MSConcealerContext *obj=(MSConcealerContext *) ms_new(MSConcealerContext,1);
obj->sample_time=0;
obj->plc_count=0;
obj->sample_time=-1;
obj->plc_start_time=-1;
obj->total_number_for_plc=0;
obj->max_plc_count=max_plc_count;
obj->max_plc_time=max_plc_time;
return obj;
}
void ms_concealer_context_destroy(MSConcealerContext* context) {
ms_free(context);
}
unsigned long ms_concealer_context_get_sampling_time(MSConcealerContext* obj) {
return obj->sample_time;
}
void ms_concealer_context_set_sampling_time(MSConcealerContext* obj,unsigned long value) {
obj->sample_time=value;
}
int ms_concealer_inc_sample_time(MSConcealerContext* obj, uint64_t current_time, int time_increment, int got_packet){
int plc_duration=0;
if (obj->sample_time==-1){
obj->sample_time=(int64_t)current_time;
}
obj->sample_time+=time_increment;
if (obj->plc_start_time!=-1 && got_packet){
plc_duration=current_time-obj->plc_start_time;
obj->plc_start_time=-1;
if (plc_duration>obj->max_plc_time) plc_duration=obj->max_plc_time;
}
return plc_duration;
}
unsigned int ms_concealer_context_is_concealement_required(MSConcealerContext* obj,uint64_t current_time) {
if(obj->sample_time == 0) return 0; /*no valid value*/
if(obj->sample_time == -1) return 0; /*no valid value*/
if (obj->sample_time < current_time && obj->plc_count<obj->max_plc_count) {
obj->plc_count++;
obj->total_number_for_plc++;
} else {
obj->plc_count=0;
if (obj->plc_count>=obj->max_plc_count) {
/*reset sample time*/
obj->sample_time=0;
if (obj->sample_time < current_time){
int plc_duration;
if (obj->plc_start_time==-1)
obj->plc_start_time=obj->sample_time;
plc_duration=current_time-obj->plc_start_time;
if (plc_duration<obj->max_plc_time) {
obj->total_number_for_plc++;
return 1;
}else{
/*reset sample time, so that we don't do PLC anymore and can resync properly when the stream restarts*/
obj->sample_time=-1;
return 0;
}
}
return obj->plc_count;
return 0;
}
/*** plc context end***/
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