Allow NetEQ to use real packet durations.
This is a copy of http://review.webrtc.org/864014/
This adds a FuncDurationEst to each codec instance which estimates
the duration of a packet given the packet contents and the duration
of the previous packet. By default, this simply returns the
duration of the previous packet (which is what is currently assumed
to be the duration of all future packets). This patch also provides
an initial implementation of this function for G.711 which returns
the actual number of samples in the packet.
BUG=issue1015
Review URL: https://webrtc-codereview.appspot.com/935016
git-svn-id: http://webrtc.googlecode.com/svn/trunk@3129 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_coding/neteq/packet_buffer.c b/webrtc/modules/audio_coding/neteq/packet_buffer.c
index 74a4903..e8ee40c 100644
--- a/webrtc/modules/audio_coding/neteq/packet_buffer.c
+++ b/webrtc/modules/audio_coding/neteq/packet_buffer.c
@@ -491,36 +491,79 @@
return 0;
}
-WebRtc_Word32 WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t *bufferInst)
-{
- int i, count;
- WebRtc_Word32 sizeSamples;
+int WebRtcNetEQ_PacketBufferGetPacketSize(const PacketBuf_t* buffer_inst,
+ int buffer_pos,
+ const CodecDbInst_t* codec_database,
+ int codec_pos, int last_duration) {
+ if (codec_database->funcDurationEst[codec_pos] == NULL) {
+ return last_duration;
+ }
+ return (*codec_database->funcDurationEst[codec_pos])(
+ codec_database->codec_state[codec_pos],
+ (const uint8_t *)buffer_inst->payloadLocation[buffer_pos],
+ buffer_inst->payloadLengthBytes[buffer_pos]);
+}
- count = 0;
+WebRtc_Word32 WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t* buffer_inst,
+ const CodecDbInst_t*
+ codec_database) {
+ int i, count;
+ int last_duration;
+ int last_codec_pos;
+ int last_payload_type;
+ WebRtc_Word32 size_samples;
- /* Loop through all slots in the buffer */
- for (i = 0; i < bufferInst->maxInsertPositions; i++)
- {
- /* Only count the packets with non-zero size */
- if (bufferInst->payloadLengthBytes[i] != 0)
- {
- count++;
+ count = 0;
+ last_duration = buffer_inst->packSizeSamples;
+ last_codec_pos = -1;
+ last_payload_type = -1;
+ size_samples = 0;
+
+ /* Loop through all slots in the buffer */
+ for (i = 0; i < buffer_inst->maxInsertPositions; i++) {
+ /* Only count the packets with non-zero size */
+ if (buffer_inst->payloadLengthBytes[i] != 0) {
+ int payload_type;
+ int codec_pos;
+ /* Figure out the codec database entry for this payload_type. */
+ payload_type = buffer_inst->payloadType[i];
+ /* Remember the last one, to avoid the database search. */
+ if(payload_type == last_payload_type) {
+ codec_pos = last_codec_pos;
+ }
+ else {
+ codec_pos = WebRtcNetEQ_DbGetCodec(codec_database,
+ payload_type);
+ if (codec_pos >= 0) {
+ codec_pos = codec_database->position[codec_pos];
}
+ }
+ last_codec_pos = codec_pos;
+ last_payload_type = payload_type;
+ if (codec_pos >= 0) {
+ /*
+ * Right now WebRtcNetEQ_PacketBufferGetPacketSize either always
+ * returns last_duration or always computes the real duration without
+ * looking at last_duration. If an implementation really wanted to use
+ * last_duration to compute a changing duration, we would have to
+ * iterate through the packets in chronological order by timestamp.
+ */
+ last_duration = WebRtcNetEQ_PacketBufferGetPacketSize(
+ buffer_inst, i, codec_database, codec_pos,
+ last_duration);
+ }
+ /* Add in the size of this packet. */
+ size_samples += last_duration;
+ count++;
}
+ }
- /*
- * Calculate buffer size as number of packets times packet size
- * (packet size is that of the latest decoded packet)
- */
- sizeSamples = WEBRTC_SPL_MUL_16_16(bufferInst->packSizeSamples, count);
+ /* Sanity check; size cannot be negative */
+ if (size_samples < 0) {
+ size_samples = 0;
+ }
- /* Sanity check; size cannot be negative */
- if (sizeSamples < 0)
- {
- sizeSamples = 0;
- }
-
- return sizeSamples;
+ return size_samples;
}
void WebRtcNetEQ_IncrementWaitingTimes(PacketBuf_t *buffer_inst) {