Re: [PATCH spice-server 08/28] mjpeg_encoder: move the control over frame drops to mjpeg_encoder

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 04/14/2013 09:21 AM, Alon Levy wrote:
On Tue, Feb 26, 2013 at 01:03:54PM -0500, Yonit Halperin wrote:

ACK with one comment.

---
  server/mjpeg_encoder.c | 20 +++++++++-----------
  server/mjpeg_encoder.h | 21 ++++++++++++++-------
  server/red_worker.c    | 21 ++++++++++++++++-----
  3 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/server/mjpeg_encoder.c b/server/mjpeg_encoder.c
index 70b6338..c124286 100644
--- a/server/mjpeg_encoder.c
+++ b/server/mjpeg_encoder.c
@@ -641,9 +641,15 @@ int mjpeg_encoder_start_frame(MJpegEncoder *encoder, SpiceBitmapFmt format,
          MJpegEncoderRateControl *rate_control = &encoder->rate_control;
          struct timespec time;
          uint64_t now;
+        uint64_t interval;

          clock_gettime(CLOCK_MONOTONIC, &time);
          now = ((uint64_t) time.tv_sec) * 1000000000 + time.tv_nsec;
+        interval = (now - rate_control->bit_rate_info.last_frame_time);
+
+        if (interval < (1000*1000*1000) / rate_control->fps) {
+            return MJPEG_ENCODER_FRAME_DROP;
+        }

          mjpeg_encoder_adjust_params_to_bit_rate(encoder);

@@ -690,14 +696,14 @@ int mjpeg_encoder_start_frame(MJpegEncoder *encoder, SpiceBitmapFmt format,
          break;
      default:
          spice_warning("unsupported format %d", format);
-        return FALSE;
+        return MJPEG_ENCODER_FRAME_UNSUPPORTED;
      }

      if (encoder->pixel_converter != NULL) {
          unsigned int stride = width * 3;
          /* check for integer overflow */
          if (stride < width) {
-            return FALSE;
+            return MJPEG_ENCODER_FRAME_UNSUPPORTED;
          }
          if (encoder->row_size < stride) {
              encoder->row = spice_realloc(encoder->row, stride);
@@ -715,7 +721,7 @@ int mjpeg_encoder_start_frame(MJpegEncoder *encoder, SpiceBitmapFmt format,
      jpeg_set_quality(&encoder->cinfo, quality, TRUE);
      jpeg_start_compress(&encoder->cinfo, encoder->first_frame);

-    return TRUE;
+    return MJPEG_ENCODER_FRAME_ENCODE_START;
  }

  int mjpeg_encoder_encode_scanline(MJpegEncoder *encoder, uint8_t *src_pixels,
@@ -773,14 +779,6 @@ size_t mjpeg_encoder_end_frame(MJpegEncoder *encoder)
      return encoder->rate_control.last_enc_size;
  }

-uint32_t mjpeg_encoder_get_fps(MJpegEncoder *encoder)
-{
-    if (!encoder->rate_control_is_active) {
-        spice_warning("bit rate control is not active");
-    }
-    return encoder->rate_control.fps;
-}
-
  static void mjpeg_encoder_quality_eval_stop(MJpegEncoder *encoder)
  {
      MJpegEncoderRateControl *rate_control = &encoder->rate_control;
diff --git a/server/mjpeg_encoder.h b/server/mjpeg_encoder.h
index f9ae43c..0ee2e96 100644
--- a/server/mjpeg_encoder.h
+++ b/server/mjpeg_encoder.h
@@ -21,6 +21,12 @@

  #include "red_common.h"

+enum {
+    MJPEG_ENCODER_FRAME_UNSUPPORTED = -1,
+    MJPEG_ENCODER_FRAME_DROP,
+    MJPEG_ENCODER_FRAME_ENCODE_START,
+};
+
  typedef struct MJpegEncoder MJpegEncoder;

  /*
@@ -44,8 +50,15 @@ void mjpeg_encoder_destroy(MJpegEncoder *encoder);
  uint8_t mjpeg_encoder_get_bytes_per_pixel(MJpegEncoder *encoder);

  /*
- * *dest must be either NULL or allocated by malloc, since it might be freed
+ * dest must be either NULL or allocated by malloc, since it might be freed
   * during the encoding, if its size is too small.
+ *
+ * return:
+ *  MJPEG_ENCODER_FRAME_UNSUPPORTED : frame cannot be encoded
+ *  MJPEG_ENCODER_FRAME_DROP        : frame should be dropped. This value can only be returned
+ *                                    if mjpeg rate control is active.
+ *  MJPEG_ENCODER_FRAME_ENCODE_START: frame encoding started. Continue with
+ *                                    mjpeg_encoder_encode_scanline.
   */
  int mjpeg_encoder_start_frame(MJpegEncoder *encoder, SpiceBitmapFmt format,
                                int width, int height,
@@ -60,12 +73,6 @@ size_t mjpeg_encoder_end_frame(MJpegEncoder *encoder);
   */

  /*
- * The recommended output frame rate (per second) for the
- * current available bit rate.
- */
-uint32_t mjpeg_encoder_get_fps(MJpegEncoder *encoder);
-
-/*
   * Data that should be periodically obtained from the client. The report contains:
   * num_frames         : the number of frames that reached the client during the time
   *                      the report is referring to.
diff --git a/server/red_worker.c b/server/red_worker.c
index 568b8e5..a390629 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -8352,6 +8352,7 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
      RedWorker *worker = dcc->common.worker;
      int n;
      int width, height;
+    int ret;

      if (!stream) {
          spice_assert(drawable->sized_stream);
@@ -8389,13 +8390,23 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
      }

      outbuf_size = dcc->send_data.stream_outbuf_size;
-    if (!mjpeg_encoder_start_frame(agent->mjpeg_encoder, image->u.bitmap.format,
-                                   width, height,
-                                   &dcc->send_data.stream_outbuf,
-                                   &outbuf_size,
-                                   drawable->red_drawable->mm_time)) {
+    ret = mjpeg_encoder_start_frame(agent->mjpeg_encoder, image->u.bitmap.format,
+                                    width, height,
+                                    &dcc->send_data.stream_outbuf,
+                                    &outbuf_size,
+                                    drawable->red_drawable->mm_time);
+    switch (ret) {
+    case MJPEG_ENCODER_FRAME_DROP:
+        spice_warning("mjpeg rate control is not supported yet");
+        return TRUE;
+    case MJPEG_ENCODER_FRAME_UNSUPPORTED:
          return FALSE;
+    case MJPEG_ENCODER_FRAME_ENCODE_START:
+        break;
+    default:
+        spice_error("bad return value (%d) from mjpeg_encoder_start_frame", ret);

Why don't we return here?

Just forgot. I Will add it.
      }
+
      if (!encode_frame(dcc, &drawable->red_drawable->u.copy.src_area,
                        &image->u.bitmap, stream)) {
          return FALSE;
--
1.8.1

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]