Fixed FFMPEG backend: Do not drop samples for package alignment.
authorArmin Novak <armin.novak@thincast.com>
Thu, 19 Jul 2018 13:17:54 +0000 (15:17 +0200)
committerArmin Novak <armin.novak@thincast.com>
Thu, 19 Jul 2018 13:17:54 +0000 (15:17 +0200)
channels/audin/client/audin_main.c
libfreerdp/codec/dsp_ffmpeg.c

index 5792375..3ebf880 100644 (file)
@@ -385,12 +385,6 @@ static UINT audin_receive_wave_data(const AUDIO_FORMAT* format,
        if (!audin->attached)
                return CHANNEL_RC_OK;
 
-       WLog_Print(audin->log, WLOG_TRACE,
-                  "%s: nChannels: %"PRIu16" nSamplesPerSec: %"PRIu32" "
-                  "nAvgBytesPerSec: %"PRIu32" nBlockAlign: %"PRIu16" wBitsPerSample: %"PRIu16" cbSize: %"PRIu16" [%"PRIdz"]",
-                  rdpsnd_get_audio_tag_string(audin->format->wFormatTag),
-                  audin->format->nChannels, audin->format->nSamplesPerSec, audin->format->nAvgBytesPerSec,
-                  audin->format->nBlockAlign, audin->format->wBitsPerSample, audin->format->cbSize, size);
        Stream_SetPosition(audin->data, 0);
 
        if (!Stream_EnsureRemainingCapacity(audin->data, 1))
@@ -407,34 +401,22 @@ static UINT audin_receive_wave_data(const AUDIO_FORMAT* format,
        }
        else
        {
-               size_t block = audin->FramesPerPacket;
-               size_t rest = audin->FramesPerPacket % audin->format->nBlockAlign;
-
-               if (rest > 0)
-                       block += audin->format->nBlockAlign - rest;
-
-               block *= format->wBitsPerSample / 8 * format->nChannels;
-
-               if (block < size)
-                       size = block;
-
-               Stream_SetPosition(audin->buffer, 0);
-
-               if (!Stream_EnsureRemainingCapacity(audin->buffer, 2 * block))
-                       return CHANNEL_RC_NO_MEMORY;
-
-               Stream_Write(audin->buffer, data, size);
-               Stream_Zero(audin->buffer, block - size);
-               Stream_SealLength(audin->buffer);
-
-               if (!freerdp_dsp_encode(audin->dsp_context, format, Stream_Buffer(audin->buffer),
-                                       Stream_Length(audin->buffer), audin->data))
+               if (!freerdp_dsp_encode(audin->dsp_context, format, data, size, audin->data))
                        return ERROR_INTERNAL_ERROR;
        }
 
+       /* Did not encode anything, skip this, the codec is not ready for output. */
        if (Stream_GetPosition(audin->data) <= 1)
                return CHANNEL_RC_OK;
 
+       WLog_Print(audin->log, WLOG_TRACE,
+                  "%s: nChannels: %"PRIu16" nSamplesPerSec: %"PRIu32" "
+                  "nAvgBytesPerSec: %"PRIu32" nBlockAlign: %"PRIu16" wBitsPerSample: %"PRIu16" cbSize: %"PRIu16" [%"PRIdz"/%"PRIdz"]",
+                  rdpsnd_get_audio_tag_string(audin->format->wFormatTag),
+                  audin->format->nChannels, audin->format->nSamplesPerSec, audin->format->nAvgBytesPerSec,
+                  audin->format->nBlockAlign, audin->format->wBitsPerSample, audin->format->cbSize, size,
+                  Stream_GetPosition(audin->data) - 1);
+
        if ((error = audin_send_incoming_data_pdu(callback)))
        {
                WLog_Print(audin->log, WLOG_ERROR, "audin_send_incoming_data_pdu failed!");
index 752ab71..21c0d11 100644 (file)
@@ -63,8 +63,8 @@ static BOOL ffmpeg_codec_is_filtered(enum AVCodecID id, BOOL encoder)
 #if !defined(WITH_DSP_EXPERIMENTAL)
 
                case AV_CODEC_ID_MP3:
-               case AV_CODEC_ID_GSM_MS:
-               case AV_CODEC_ID_AAC:
+               case AV_CODEC_ID_ADPCM_IMA_WAV:
+               case AV_CODEC_ID_ADPCM_MS:
                        return TRUE;
 #endif
 
@@ -195,6 +195,7 @@ static void ffmpeg_close_context(FREERDP_DSP_CONTEXT* context)
                context->rcontext = NULL;
        }
 }
+
 static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
 {
        int ret;
@@ -235,6 +236,10 @@ static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
                        context->context->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
                        break;
 
+               case AV_CODEC_ID_AAC:
+                       context->context->profile = FF_PROFILE_AAC_MAIN;
+                       break;
+
                default:
                        break;
        }
@@ -366,7 +371,7 @@ static BOOL ffmpeg_encode_frame(AVCodecContext* context, AVFrame* in,
        {
                ret = avcodec_receive_packet(context, packet);
 
-               if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+               if ((ret == AVERROR(EAGAIN)) || (ret == AVERROR_EOF))
                        return TRUE;
                else if (ret < 0)
                {
@@ -522,7 +527,6 @@ BOOL freerdp_dsp_ffmpeg_encode(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT*
                                const BYTE* data, size_t length, wStream* out)
 {
        int rc;
-       int samples, rest;
 
        if (!context || !format || !data || !out || !context->encoder)
                return FALSE;
@@ -547,18 +551,23 @@ BOOL freerdp_dsp_ffmpeg_encode(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT*
        }
        else
        {
+               int samples, rest;
                rest = samples = context->resampled->nb_samples;
 
                do
                {
+                       int restSamples;
+                       int inSamples = samples;
+
                        if (samples + context->bufferedSamples > context->context->frame_size)
-                               samples = context->context->frame_size - context->bufferedSamples;
+                               inSamples = context->context->frame_size - context->bufferedSamples;
 
+                       restSamples = samples - inSamples;
                        rc = av_samples_copy(context->buffered->extended_data, context->resampled->extended_data,
-                                            context->bufferedSamples, 0, samples,
+                                            context->bufferedSamples, 0, inSamples,
                                             context->context->channels, context->context->sample_fmt);
-                       rest -= samples;
-                       context->bufferedSamples += samples;
+                       rest -= inSamples;
+                       context->bufferedSamples += inSamples;
 
                        if (context->context->frame_size <= context->bufferedSamples)
                        {
@@ -569,6 +578,15 @@ BOOL freerdp_dsp_ffmpeg_encode(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT*
 
                                context->bufferedSamples = 0;
                        }
+
+                       if (restSamples > 0)
+                       {
+                               rc = av_samples_copy(context->buffered->extended_data, context->resampled->extended_data,
+                                                    context->bufferedSamples, inSamples, restSamples,
+                                                    context->context->channels, context->context->sample_fmt);
+                               rest -= restSamples;
+                               context->bufferedSamples += restSamples;
+                       }
                }
                while (rest > 0);