mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	Improve upload
Only send a buffer when we have received a NEED_DATA message. Add a signal to pulla buffer from the sink. Restructure the sink to use a queue like the source and only push a buffer when we can. Improve SpaData. Offset and size should be between 0 and maxsize, make sure we clamp correctly when needed. node_process_output completes the processing of the output after receiving HAVE_OUTPUT for async elements. It instructs the node that it now can produce more output.
This commit is contained in:
		
							parent
							
								
									8ce3f949e2
								
							
						
					
					
						commit
						5b0b9c43d0
					
				
					 18 changed files with 201 additions and 112 deletions
				
			
		| 
						 | 
					@ -192,6 +192,7 @@ pinos_stream_new (PinosContext    *context,
 | 
				
			||||||
  pinos_signal_init (&this->add_buffer);
 | 
					  pinos_signal_init (&this->add_buffer);
 | 
				
			||||||
  pinos_signal_init (&this->remove_buffer);
 | 
					  pinos_signal_init (&this->remove_buffer);
 | 
				
			||||||
  pinos_signal_init (&this->new_buffer);
 | 
					  pinos_signal_init (&this->new_buffer);
 | 
				
			||||||
 | 
					  pinos_signal_init (&this->need_buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  this->state = PINOS_STREAM_STATE_UNCONNECTED;
 | 
					  this->state = PINOS_STREAM_STATE_UNCONNECTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -473,6 +474,9 @@ on_rtsocket_condition (SpaSource    *source,
 | 
				
			||||||
        handle_rtnode_event (stream, ev);
 | 
					        handle_rtnode_event (stream, ev);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (cmd & PINOS_TRANSPORT_CMD_NEED_DATA) {
 | 
				
			||||||
 | 
					      pinos_signal_emit (&stream->need_buffer, stream);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1080,16 +1084,15 @@ pinos_stream_send_buffer (PinosStream     *stream,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PinosStreamImpl *impl = SPA_CONTAINER_OF (stream, PinosStreamImpl, this);
 | 
					  PinosStreamImpl *impl = SPA_CONTAINER_OF (stream, PinosStreamImpl, this);
 | 
				
			||||||
  BufferId *bid;
 | 
					  BufferId *bid;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if ((bid = find_buffer (stream, id))) {
 | 
					 | 
				
			||||||
  uint8_t cmd = PINOS_TRANSPORT_CMD_HAVE_DATA;
 | 
					  uint8_t cmd = PINOS_TRANSPORT_CMD_HAVE_DATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ((bid = find_buffer (stream, id))) {
 | 
				
			||||||
    bid->used = true;
 | 
					    bid->used = true;
 | 
				
			||||||
    impl->trans->outputs[0].buffer_id = id;
 | 
					    impl->trans->outputs[0].buffer_id = id;
 | 
				
			||||||
    impl->trans->outputs[0].status = SPA_RESULT_OK;
 | 
					    impl->trans->outputs[0].status = SPA_RESULT_OK;
 | 
				
			||||||
    write (impl->rtfd, &cmd, 1);
 | 
					    if (write (impl->rtfd, &cmd, 1) < 1)
 | 
				
			||||||
    return true;
 | 
					      perror ("write");
 | 
				
			||||||
  } else {
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,6 +91,8 @@ struct _PinosStream {
 | 
				
			||||||
  PINOS_SIGNAL (new_buffer,    (PinosListener *listener,
 | 
					  PINOS_SIGNAL (new_buffer,    (PinosListener *listener,
 | 
				
			||||||
                                PinosStream   *stream,
 | 
					                                PinosStream   *stream,
 | 
				
			||||||
                                uint32_t       id));
 | 
					                                uint32_t       id));
 | 
				
			||||||
 | 
					  PINOS_SIGNAL (need_buffer,   (PinosListener *listener,
 | 
				
			||||||
 | 
					                                PinosStream   *stream));
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PinosStream *    pinos_stream_new               (PinosContext    *context,
 | 
					PinosStream *    pinos_stream_new               (PinosContext    *context,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,6 +75,7 @@ acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GST_OBJECT_LOCK (pool);
 | 
					  GST_OBJECT_LOCK (pool);
 | 
				
			||||||
  while (p->available.length == 0) {
 | 
					  while (p->available.length == 0) {
 | 
				
			||||||
 | 
					    GST_WARNING ("queue empty");
 | 
				
			||||||
    g_cond_wait (&p->cond, GST_OBJECT_GET_LOCK (pool));
 | 
					    g_cond_wait (&p->cond, GST_OBJECT_GET_LOCK (pool));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  *buffer = g_queue_pop_head (&p->available);
 | 
					  *buffer = g_queue_pop_head (&p->available);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -230,6 +230,8 @@ gst_pinos_sink_init (GstPinosSink * sink)
 | 
				
			||||||
  sink->buf_ids = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
 | 
					  sink->buf_ids = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
 | 
				
			||||||
      (GDestroyNotify) gst_buffer_unref);
 | 
					      (GDestroyNotify) gst_buffer_unref);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_queue_init (&sink->queue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sink->loop = pinos_loop_new ();
 | 
					  sink->loop = pinos_loop_new ();
 | 
				
			||||||
  sink->main_loop = pinos_thread_main_loop_new (sink->loop, "pinos-sink-loop");
 | 
					  sink->main_loop = pinos_thread_main_loop_new (sink->loop, "pinos-sink-loop");
 | 
				
			||||||
  GST_DEBUG ("loop %p %p", sink->loop, sink->main_loop);
 | 
					  GST_DEBUG ("loop %p %p", sink->loop, sink->main_loop);
 | 
				
			||||||
| 
						 | 
					@ -347,6 +349,7 @@ typedef struct {
 | 
				
			||||||
  SpaBuffer *buf;
 | 
					  SpaBuffer *buf;
 | 
				
			||||||
  SpaMetaHeader *header;
 | 
					  SpaMetaHeader *header;
 | 
				
			||||||
  guint flags;
 | 
					  guint flags;
 | 
				
			||||||
 | 
					  goffset offset;
 | 
				
			||||||
} ProcessMemData;
 | 
					} ProcessMemData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -403,13 +406,15 @@ on_add_buffer (PinosListener *listener,
 | 
				
			||||||
      case SPA_DATA_TYPE_DMABUF:
 | 
					      case SPA_DATA_TYPE_DMABUF:
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        gmem = gst_fd_allocator_alloc (pinossink->allocator, dup (d->fd),
 | 
					        gmem = gst_fd_allocator_alloc (pinossink->allocator, dup (d->fd),
 | 
				
			||||||
                  d->size, GST_FD_MEMORY_FLAG_NONE);
 | 
					                  d->mapoffset + d->maxsize, GST_FD_MEMORY_FLAG_NONE);
 | 
				
			||||||
        gst_memory_resize (gmem, d->chunk->offset, d->chunk->size);
 | 
					        gst_memory_resize (gmem, d->chunk->offset + d->mapoffset, d->chunk->size);
 | 
				
			||||||
 | 
					        data.offset = d->mapoffset;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      case SPA_DATA_TYPE_MEMPTR:
 | 
					      case SPA_DATA_TYPE_MEMPTR:
 | 
				
			||||||
        gmem = gst_memory_new_wrapped (0, d->data, d->size, d->chunk->offset,
 | 
					        gmem = gst_memory_new_wrapped (0, d->data, d->maxsize, d->chunk->offset,
 | 
				
			||||||
                                       d->chunk->size, NULL, NULL);
 | 
					                                       d->chunk->size, NULL, NULL);
 | 
				
			||||||
 | 
					        data.offset = 0;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
| 
						 | 
					@ -466,6 +471,51 @@ on_new_buffer (PinosListener *listener,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					do_send_buffer (GstPinosSink *pinossink)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  GstBuffer *buffer;
 | 
				
			||||||
 | 
					  ProcessMemData *data;
 | 
				
			||||||
 | 
					  gboolean res;
 | 
				
			||||||
 | 
					  guint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  buffer = g_queue_pop_head (&pinossink->queue);
 | 
				
			||||||
 | 
					  if (buffer == NULL)
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  data = gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buffer),
 | 
				
			||||||
 | 
					                                    process_mem_data_quark);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (data->header) {
 | 
				
			||||||
 | 
					    data->header->seq = GST_BUFFER_OFFSET (buffer);
 | 
				
			||||||
 | 
					    data->header->pts = GST_BUFFER_PTS (buffer);
 | 
				
			||||||
 | 
					    data->header->dts_offset = GST_BUFFER_DTS (buffer);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  for (i = 0; i < data->buf->n_datas; i++) {
 | 
				
			||||||
 | 
					    SpaData *d = &data->buf->datas[i];
 | 
				
			||||||
 | 
					    GstMemory *mem = gst_buffer_peek_memory (buffer, i);
 | 
				
			||||||
 | 
					    d->chunk->offset = mem->offset - data->offset;
 | 
				
			||||||
 | 
					    d->chunk->size = mem->size;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!(res = pinos_stream_send_buffer (pinossink->stream, data->id)))
 | 
				
			||||||
 | 
					    g_warning ("can't send buffer");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinossink->need_ready--;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_need_buffer (PinosListener *listener,
 | 
				
			||||||
 | 
					                PinosStream   *stream)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  GstPinosSink *pinossink = SPA_CONTAINER_OF (listener, GstPinosSink, stream_need_buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinossink->need_ready++;
 | 
				
			||||||
 | 
					  GST_DEBUG ("need buffer %u", pinossink->need_ready);
 | 
				
			||||||
 | 
					  do_send_buffer (pinossink);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
on_state_changed (PinosListener *listener,
 | 
					on_state_changed (PinosListener *listener,
 | 
				
			||||||
                  PinosStream   *stream)
 | 
					                  PinosStream   *stream)
 | 
				
			||||||
| 
						 | 
					@ -610,9 +660,6 @@ static GstFlowReturn
 | 
				
			||||||
gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
 | 
					gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GstPinosSink *pinossink;
 | 
					  GstPinosSink *pinossink;
 | 
				
			||||||
  gboolean res;
 | 
					 | 
				
			||||||
  ProcessMemData *data;
 | 
					 | 
				
			||||||
  guint i;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinossink = GST_PINOS_SINK (bsink);
 | 
					  pinossink = GST_PINOS_SINK (bsink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -633,25 +680,11 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
 | 
				
			||||||
    buffer = b;
 | 
					    buffer = b;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  data = gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buffer),
 | 
					 | 
				
			||||||
                                    process_mem_data_quark);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (data->header) {
 | 
					 | 
				
			||||||
    data->header->seq = GST_BUFFER_OFFSET (buffer);
 | 
					 | 
				
			||||||
    data->header->pts = GST_BUFFER_PTS (buffer);
 | 
					 | 
				
			||||||
    data->header->dts_offset = GST_BUFFER_DTS (buffer);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  for (i = 0; i < data->buf->n_datas; i++) {
 | 
					 | 
				
			||||||
    SpaData *d = &data->buf->datas[i];
 | 
					 | 
				
			||||||
    GstMemory *mem = gst_buffer_peek_memory (buffer, i);
 | 
					 | 
				
			||||||
    d->chunk->offset = mem->offset;
 | 
					 | 
				
			||||||
    d->chunk->size = mem->size;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  gst_buffer_ref (buffer);
 | 
					  gst_buffer_ref (buffer);
 | 
				
			||||||
 | 
					  g_queue_push_tail (&pinossink->queue, buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!(res = pinos_stream_send_buffer (pinossink->stream, data->id)))
 | 
					  if (pinossink->need_ready)
 | 
				
			||||||
    g_warning ("can't send buffer");
 | 
					    do_send_buffer (pinossink);
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
  pinos_thread_main_loop_unlock (pinossink->main_loop);
 | 
					  pinos_thread_main_loop_unlock (pinossink->main_loop);
 | 
				
			||||||
| 
						 | 
					@ -707,6 +740,7 @@ gst_pinos_sink_start (GstBaseSink * basesink)
 | 
				
			||||||
  pinos_signal_add (&pinossink->stream->add_buffer, &pinossink->stream_add_buffer, on_add_buffer);
 | 
					  pinos_signal_add (&pinossink->stream->add_buffer, &pinossink->stream_add_buffer, on_add_buffer);
 | 
				
			||||||
  pinos_signal_add (&pinossink->stream->remove_buffer, &pinossink->stream_remove_buffer, on_remove_buffer);
 | 
					  pinos_signal_add (&pinossink->stream->remove_buffer, &pinossink->stream_remove_buffer, on_remove_buffer);
 | 
				
			||||||
  pinos_signal_add (&pinossink->stream->new_buffer, &pinossink->stream_new_buffer, on_new_buffer);
 | 
					  pinos_signal_add (&pinossink->stream->new_buffer, &pinossink->stream_new_buffer, on_new_buffer);
 | 
				
			||||||
 | 
					  pinos_signal_add (&pinossink->stream->need_buffer, &pinossink->stream_need_buffer, on_need_buffer);
 | 
				
			||||||
  pinos_thread_main_loop_unlock (pinossink->main_loop);
 | 
					  pinos_thread_main_loop_unlock (pinossink->main_loop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return TRUE;
 | 
					  return TRUE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,6 +89,7 @@ struct _GstPinosSink {
 | 
				
			||||||
  PinosListener stream_add_buffer;
 | 
					  PinosListener stream_add_buffer;
 | 
				
			||||||
  PinosListener stream_remove_buffer;
 | 
					  PinosListener stream_remove_buffer;
 | 
				
			||||||
  PinosListener stream_new_buffer;
 | 
					  PinosListener stream_new_buffer;
 | 
				
			||||||
 | 
					  PinosListener stream_need_buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GstAllocator *allocator;
 | 
					  GstAllocator *allocator;
 | 
				
			||||||
  GstStructure *properties;
 | 
					  GstStructure *properties;
 | 
				
			||||||
| 
						 | 
					@ -96,6 +97,8 @@ struct _GstPinosSink {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GstPinosPool *pool;
 | 
					  GstPinosPool *pool;
 | 
				
			||||||
  GHashTable *buf_ids;
 | 
					  GHashTable *buf_ids;
 | 
				
			||||||
 | 
					  GQueue queue;
 | 
				
			||||||
 | 
					  guint need_ready;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct _GstPinosSinkClass {
 | 
					struct _GstPinosSinkClass {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,13 +173,19 @@ clock_disabled:
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					clear_queue (GstPinosSrc *pinossrc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_queue_foreach (&pinossrc->queue, (GFunc) gst_mini_object_unref, NULL);
 | 
				
			||||||
 | 
					  g_queue_clear (&pinossrc->queue);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
gst_pinos_src_finalize (GObject * object)
 | 
					gst_pinos_src_finalize (GObject * object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GstPinosSrc *pinossrc = GST_PINOS_SRC (object);
 | 
					  GstPinosSrc *pinossrc = GST_PINOS_SRC (object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_queue_foreach (&pinossrc->queue, (GFunc) gst_mini_object_unref, NULL);
 | 
					  clear_queue (pinossrc);
 | 
				
			||||||
  g_queue_clear (&pinossrc->queue);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinos_thread_main_loop_destroy (pinossrc->main_loop);
 | 
					  pinos_thread_main_loop_destroy (pinossrc->main_loop);
 | 
				
			||||||
  pinossrc->main_loop = NULL;
 | 
					  pinossrc->main_loop = NULL;
 | 
				
			||||||
| 
						 | 
					@ -340,6 +346,7 @@ typedef struct {
 | 
				
			||||||
  SpaBuffer *buf;
 | 
					  SpaBuffer *buf;
 | 
				
			||||||
  SpaMetaHeader *header;
 | 
					  SpaMetaHeader *header;
 | 
				
			||||||
  guint flags;
 | 
					  guint flags;
 | 
				
			||||||
 | 
					  goffset offset;
 | 
				
			||||||
} ProcessMemData;
 | 
					} ProcessMemData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -417,13 +424,15 @@ on_add_buffer (PinosListener *listener,
 | 
				
			||||||
      case SPA_DATA_TYPE_DMABUF:
 | 
					      case SPA_DATA_TYPE_DMABUF:
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        gmem = gst_fd_allocator_alloc (pinossrc->fd_allocator, dup (d->fd),
 | 
					        gmem = gst_fd_allocator_alloc (pinossrc->fd_allocator, dup (d->fd),
 | 
				
			||||||
                  d->size, GST_FD_MEMORY_FLAG_NONE);
 | 
					                  d->maxsize, GST_FD_MEMORY_FLAG_NONE);
 | 
				
			||||||
        gst_memory_resize (gmem, d->chunk->offset, d->chunk->size);
 | 
					        gst_memory_resize (gmem, d->chunk->offset + d->mapoffset, d->chunk->size);
 | 
				
			||||||
 | 
					        data.offset = d->mapoffset;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      case SPA_DATA_TYPE_MEMPTR:
 | 
					      case SPA_DATA_TYPE_MEMPTR:
 | 
				
			||||||
        gmem = gst_memory_new_wrapped (0, d->data, d->size, d->chunk->offset,
 | 
					        gmem = gst_memory_new_wrapped (0, d->data, d->maxsize, d->chunk->offset + d->mapoffset,
 | 
				
			||||||
                  d->chunk->size, NULL, NULL);
 | 
					                  d->chunk->size, NULL, NULL);
 | 
				
			||||||
 | 
					        data.offset = 0;
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -488,7 +497,7 @@ on_new_buffer (PinosListener *listener,
 | 
				
			||||||
  for (i = 0; i < data->buf->n_datas; i++) {
 | 
					  for (i = 0; i < data->buf->n_datas; i++) {
 | 
				
			||||||
    SpaData *d = &data->buf->datas[i];
 | 
					    SpaData *d = &data->buf->datas[i];
 | 
				
			||||||
    GstMemory *mem = gst_buffer_peek_memory (buf, i);
 | 
					    GstMemory *mem = gst_buffer_peek_memory (buf, i);
 | 
				
			||||||
    mem->offset = d->chunk->offset;
 | 
					    mem->offset = d->chunk->offset + data->offset;
 | 
				
			||||||
    mem->size = d->chunk->size;
 | 
					    mem->size = d->chunk->size;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  g_queue_push_tail (&pinossrc->queue, buf);
 | 
					  g_queue_push_tail (&pinossrc->queue, buf);
 | 
				
			||||||
| 
						 | 
					@ -937,13 +946,6 @@ gst_pinos_src_start (GstBaseSrc * basesrc)
 | 
				
			||||||
  return TRUE;
 | 
					  return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
clear_queue (GstPinosSrc *pinossrc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  g_queue_foreach (&pinossrc->queue, (GFunc) gst_mini_object_unref, NULL);
 | 
					 | 
				
			||||||
  g_queue_clear (&pinossrc->queue);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
gst_pinos_src_stop (GstBaseSrc * basesrc)
 | 
					gst_pinos_src_stop (GstBaseSrc * basesrc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -195,6 +195,11 @@ spa_proxy_node_send_command (SpaNode        *node,
 | 
				
			||||||
                                   PINOS_MESSAGE_NODE_COMMAND,
 | 
					                                   PINOS_MESSAGE_NODE_COMMAND,
 | 
				
			||||||
                                   &cnc,
 | 
					                                   &cnc,
 | 
				
			||||||
                                   true);
 | 
					                                   true);
 | 
				
			||||||
 | 
					      if (command->type == SPA_NODE_COMMAND_START) {
 | 
				
			||||||
 | 
					        uint8_t cmd = PINOS_TRANSPORT_CMD_NEED_DATA;
 | 
				
			||||||
 | 
					        write (this->data_source.fd, &cmd, 1);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      res = SPA_RESULT_RETURN_ASYNC (cnc.seq);
 | 
					      res = SPA_RESULT_RETURN_ASYNC (cnc.seq);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -686,8 +691,8 @@ spa_proxy_node_port_use_buffers (SpaNode         *node,
 | 
				
			||||||
          am.type = d->type;
 | 
					          am.type = d->type;
 | 
				
			||||||
          am.memfd = d->fd;
 | 
					          am.memfd = d->fd;
 | 
				
			||||||
          am.flags = d->flags;
 | 
					          am.flags = d->flags;
 | 
				
			||||||
          am.offset = d->offset;
 | 
					          am.offset = d->mapoffset;
 | 
				
			||||||
          am.size = d->size;
 | 
					          am.size = d->maxsize;
 | 
				
			||||||
          pinos_resource_send_message (this->resource,
 | 
					          pinos_resource_send_message (this->resource,
 | 
				
			||||||
                                       PINOS_MESSAGE_ADD_MEM,
 | 
					                                       PINOS_MESSAGE_ADD_MEM,
 | 
				
			||||||
                                       &am,
 | 
					                                       &am,
 | 
				
			||||||
| 
						 | 
					@ -698,7 +703,7 @@ spa_proxy_node_port_use_buffers (SpaNode         *node,
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case SPA_DATA_TYPE_MEMPTR:
 | 
					        case SPA_DATA_TYPE_MEMPTR:
 | 
				
			||||||
          b->buffer.datas[j].data = SPA_INT_TO_PTR (b->size);
 | 
					          b->buffer.datas[j].data = SPA_INT_TO_PTR (b->size);
 | 
				
			||||||
          b->size += d->size;
 | 
					          b->size += d->maxsize;
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
          b->buffer.datas[j].type = SPA_DATA_TYPE_INVALID;
 | 
					          b->buffer.datas[j].type = SPA_DATA_TYPE_INVALID;
 | 
				
			||||||
| 
						 | 
					@ -863,8 +868,6 @@ static SpaResult
 | 
				
			||||||
spa_proxy_node_process_input (SpaNode *node)
 | 
					spa_proxy_node_process_input (SpaNode *node)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  SpaProxy *this;
 | 
					  SpaProxy *this;
 | 
				
			||||||
  unsigned int i;
 | 
					 | 
				
			||||||
  bool have_error = false;
 | 
					 | 
				
			||||||
  uint8_t cmd;
 | 
					  uint8_t cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (node == NULL)
 | 
					  if (node == NULL)
 | 
				
			||||||
| 
						 | 
					@ -872,6 +875,11 @@ spa_proxy_node_process_input (SpaNode *node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  this = SPA_CONTAINER_OF (node, SpaProxy, node);
 | 
					  this = SPA_CONTAINER_OF (node, SpaProxy, node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    unsigned int i;
 | 
				
			||||||
 | 
					    bool have_error = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < this->n_inputs; i++) {
 | 
					    for (i = 0; i < this->n_inputs; i++) {
 | 
				
			||||||
      SpaProxyPort *port = &this->in_ports[i];
 | 
					      SpaProxyPort *port = &this->in_ports[i];
 | 
				
			||||||
      SpaPortInput *input;
 | 
					      SpaPortInput *input;
 | 
				
			||||||
| 
						 | 
					@ -888,6 +896,8 @@ spa_proxy_node_process_input (SpaNode *node)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (have_error)
 | 
					    if (have_error)
 | 
				
			||||||
      return SPA_RESULT_ERROR;
 | 
					      return SPA_RESULT_ERROR;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cmd = PINOS_TRANSPORT_CMD_HAVE_DATA;
 | 
					  cmd = PINOS_TRANSPORT_CMD_HAVE_DATA;
 | 
				
			||||||
  write (this->data_source.fd, &cmd, 1);
 | 
					  write (this->data_source.fd, &cmd, 1);
 | 
				
			||||||
| 
						 | 
					@ -899,14 +909,18 @@ static SpaResult
 | 
				
			||||||
spa_proxy_node_process_output (SpaNode *node)
 | 
					spa_proxy_node_process_output (SpaNode *node)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  SpaProxy *this;
 | 
					  SpaProxy *this;
 | 
				
			||||||
  unsigned int i;
 | 
					  uint8_t cmd;
 | 
				
			||||||
  bool have_error = false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (node == NULL)
 | 
					  if (node == NULL)
 | 
				
			||||||
    return SPA_RESULT_INVALID_ARGUMENTS;
 | 
					    return SPA_RESULT_INVALID_ARGUMENTS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  this = SPA_CONTAINER_OF (node, SpaProxy, node);
 | 
					  this = SPA_CONTAINER_OF (node, SpaProxy, node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    unsigned int i;
 | 
				
			||||||
 | 
					    bool have_error = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < this->n_outputs; i++) {
 | 
					    for (i = 0; i < this->n_outputs; i++) {
 | 
				
			||||||
      SpaProxyPort *port = &this->out_ports[i];
 | 
					      SpaProxyPort *port = &this->out_ports[i];
 | 
				
			||||||
      SpaPortOutput *output;
 | 
					      SpaPortOutput *output;
 | 
				
			||||||
| 
						 | 
					@ -921,6 +935,11 @@ spa_proxy_node_process_output (SpaNode *node)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (have_error)
 | 
					    if (have_error)
 | 
				
			||||||
      return SPA_RESULT_ERROR;
 | 
					      return SPA_RESULT_ERROR;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  cmd = PINOS_TRANSPORT_CMD_NEED_DATA;
 | 
				
			||||||
 | 
					  write (this->data_source.fd, &cmd, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return SPA_RESULT_OK;
 | 
					  return SPA_RESULT_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1052,6 +1071,17 @@ proxy_on_data_fd_events (SpaSource *source)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (cmd & PINOS_TRANSPORT_CMD_HAVE_DATA) {
 | 
					    if (cmd & PINOS_TRANSPORT_CMD_HAVE_DATA) {
 | 
				
			||||||
      SpaNodeEventHaveOutput ho;
 | 
					      SpaNodeEventHaveOutput ho;
 | 
				
			||||||
 | 
					      unsigned int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (i = 0; i < this->n_outputs; i++) {
 | 
				
			||||||
 | 
					        SpaProxyPort *port = &this->out_ports[i];
 | 
				
			||||||
 | 
					        SpaPortOutput *output;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((output = port->io) == NULL)
 | 
				
			||||||
 | 
					          continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copy_meta_in (this, port, output->buffer_id);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      ho.event.type = SPA_NODE_EVENT_TYPE_HAVE_OUTPUT;
 | 
					      ho.event.type = SPA_NODE_EVENT_TYPE_HAVE_OUTPUT;
 | 
				
			||||||
      ho.event.size = sizeof (ho);
 | 
					      ho.event.size = sizeof (ho);
 | 
				
			||||||
      ho.port_id = 0;
 | 
					      ho.port_id = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -324,10 +324,10 @@ alloc_buffers (PinosLink      *this,
 | 
				
			||||||
        d->type = SPA_DATA_TYPE_MEMFD;
 | 
					        d->type = SPA_DATA_TYPE_MEMFD;
 | 
				
			||||||
        d->flags = 0;
 | 
					        d->flags = 0;
 | 
				
			||||||
        d->fd = mem->fd;
 | 
					        d->fd = mem->fd;
 | 
				
			||||||
        d->offset = 0;
 | 
					        d->mapoffset = SPA_PTRDIFF (ddp, mem->ptr);
 | 
				
			||||||
        d->size = mem->size;
 | 
					        d->maxsize = data_sizes[j];
 | 
				
			||||||
        d->data = mem->ptr;
 | 
					        d->data = SPA_MEMBER (mem->ptr, d->mapoffset, void);
 | 
				
			||||||
        d->chunk->offset = SPA_PTRDIFF (ddp, d->data);
 | 
					        d->chunk->offset = 0;
 | 
				
			||||||
        d->chunk->size = data_sizes[j];
 | 
					        d->chunk->size = data_sizes[j];
 | 
				
			||||||
        d->chunk->stride = data_strides[j];
 | 
					        d->chunk->stride = data_strides[j];
 | 
				
			||||||
        ddp += data_sizes[j];
 | 
					        ddp += data_sizes[j];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -328,11 +328,6 @@ on_node_event (SpaNode *node, SpaNodeEvent *event, void *user_data)
 | 
				
			||||||
      PinosPort *port = this->output_port_map[ho->port_id];
 | 
					      PinosPort *port = this->output_port_map[ho->port_id];
 | 
				
			||||||
      PinosLink *link;
 | 
					      PinosLink *link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if ((res = spa_node_process_output (node)) < 0) {
 | 
					 | 
				
			||||||
        pinos_log_warn ("node %p: got pull error %d, %d", this, res, po->status);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      spa_list_for_each (link, &port->rt.links, rt.output_link) {
 | 
					      spa_list_for_each (link, &port->rt.links, rt.output_link) {
 | 
				
			||||||
        size_t offset;
 | 
					        size_t offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -356,6 +351,10 @@ on_node_event (SpaNode *node, SpaNodeEvent *event, void *user_data)
 | 
				
			||||||
        if ((res = spa_node_port_reuse_buffer (node, ho->port_id, po->buffer_id)) < 0)
 | 
					        if ((res = spa_node_port_reuse_buffer (node, ho->port_id, po->buffer_id)) < 0)
 | 
				
			||||||
          pinos_log_warn ("node %p: error reuse buffer: %d", node, res);
 | 
					          pinos_log_warn ("node %p: error reuse buffer: %d", node, res);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      if ((res = spa_node_process_output (node)) < 0) {
 | 
				
			||||||
 | 
					        pinos_log_warn ("node %p: got pull error %d, %d", this, res, po->status);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SPA_NODE_EVENT_TYPE_REUSE_BUFFER:
 | 
					    case SPA_NODE_EVENT_TYPE_REUSE_BUFFER:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -174,8 +174,8 @@ typedef struct {
 | 
				
			||||||
  SpaDataType    type;
 | 
					  SpaDataType    type;
 | 
				
			||||||
  int            flags;
 | 
					  int            flags;
 | 
				
			||||||
  int            fd;
 | 
					  int            fd;
 | 
				
			||||||
  off_t          offset;
 | 
					  off_t          mapoffset;
 | 
				
			||||||
  size_t         size;
 | 
					  size_t         maxsize;
 | 
				
			||||||
  void          *data;
 | 
					  void          *data;
 | 
				
			||||||
  SpaChunk      *chunk;
 | 
					  SpaChunk      *chunk;
 | 
				
			||||||
} SpaData;
 | 
					} SpaData;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -196,11 +196,11 @@ spa_debug_buffer (const SpaBuffer *buffer)
 | 
				
			||||||
    fprintf (stderr, "   flags:   %d\n", d->flags);
 | 
					    fprintf (stderr, "   flags:   %d\n", d->flags);
 | 
				
			||||||
    fprintf (stderr, "   data:    %p\n", d->data);
 | 
					    fprintf (stderr, "   data:    %p\n", d->data);
 | 
				
			||||||
    fprintf (stderr, "   fd:      %d\n", d->fd);
 | 
					    fprintf (stderr, "   fd:      %d\n", d->fd);
 | 
				
			||||||
    fprintf (stderr, "   offset:  %zd\n", d->offset);
 | 
					    fprintf (stderr, "   offset:  %zd\n", d->mapoffset);
 | 
				
			||||||
    fprintf (stderr, "   maxsize: %zd\n", d->size);
 | 
					    fprintf (stderr, "   maxsize: %zu\n", d->maxsize);
 | 
				
			||||||
    fprintf (stderr, "   chunk:   %p\n", d->chunk);
 | 
					    fprintf (stderr, "   chunk:   %p\n", d->chunk);
 | 
				
			||||||
    fprintf (stderr, "    offset: %zd\n", d->chunk->offset);
 | 
					    fprintf (stderr, "    offset: %zd\n", d->chunk->offset);
 | 
				
			||||||
    fprintf (stderr, "    size:   %zd\n", d->chunk->size);
 | 
					    fprintf (stderr, "    size:   %zu\n", d->chunk->size);
 | 
				
			||||||
    fprintf (stderr, "    stride: %zd\n", d->chunk->stride);
 | 
					    fprintf (stderr, "    stride: %zd\n", d->chunk->stride);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return SPA_RESULT_OK;
 | 
					  return SPA_RESULT_OK;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -268,22 +268,35 @@ pull_frames_queue (SpaALSAState *state,
 | 
				
			||||||
                   snd_pcm_uframes_t offset,
 | 
					                   snd_pcm_uframes_t offset,
 | 
				
			||||||
                   snd_pcm_uframes_t frames)
 | 
					                   snd_pcm_uframes_t frames)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  if (spa_list_is_empty (&state->ready)) {
 | 
				
			||||||
 | 
					    SpaNodeEventNeedInput ni;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ni.event.type = SPA_NODE_EVENT_TYPE_NEED_INPUT;
 | 
				
			||||||
 | 
					    ni.event.size = sizeof (ni);
 | 
				
			||||||
 | 
					    ni.port_id = 0;
 | 
				
			||||||
 | 
					    state->event_cb (&state->node, &ni.event, state->user_data);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  if (!spa_list_is_empty (&state->ready)) {
 | 
					  if (!spa_list_is_empty (&state->ready)) {
 | 
				
			||||||
    uint8_t *src, *dst;
 | 
					    uint8_t *src, *dst;
 | 
				
			||||||
    size_t n_bytes;
 | 
					    size_t n_bytes, size;
 | 
				
			||||||
 | 
					    off_t offs;
 | 
				
			||||||
    SpaALSABuffer *b;
 | 
					    SpaALSABuffer *b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    b = spa_list_first (&state->ready, SpaALSABuffer, list);
 | 
					    b = spa_list_first (&state->ready, SpaALSABuffer, list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    src = SPA_MEMBER (b->outbuf->datas[0].data, b->outbuf->datas[0].offset + state->ready_offset, uint8_t);
 | 
					    offs = SPA_MIN (b->outbuf->datas[0].chunk->offset, b->outbuf->datas[0].maxsize);
 | 
				
			||||||
 | 
					    src = SPA_MEMBER (b->outbuf->datas[0].data, offs, uint8_t);
 | 
				
			||||||
 | 
					    size = SPA_MIN (b->outbuf->datas[0].chunk->size, b->outbuf->datas[0].maxsize - offs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    src = SPA_MEMBER (src, state->ready_offset, uint8_t);
 | 
				
			||||||
    dst = SPA_MEMBER (my_areas[0].addr, offset * state->frame_size, uint8_t);
 | 
					    dst = SPA_MEMBER (my_areas[0].addr, offset * state->frame_size, uint8_t);
 | 
				
			||||||
    n_bytes = SPA_MIN (b->outbuf->datas[0].size - state->ready_offset, frames * state->frame_size);
 | 
					    n_bytes = SPA_MIN (size - state->ready_offset, frames * state->frame_size);
 | 
				
			||||||
    frames = SPA_MIN (frames, n_bytes / state->frame_size);
 | 
					    frames = SPA_MIN (frames, n_bytes / state->frame_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memcpy (dst, src, n_bytes);
 | 
					    memcpy (dst, src, n_bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    state->ready_offset += n_bytes;
 | 
					    state->ready_offset += n_bytes;
 | 
				
			||||||
    if (state->ready_offset >= b->outbuf->datas[0].size) {
 | 
					    if (state->ready_offset >= size) {
 | 
				
			||||||
      SpaNodeEventReuseBuffer rb;
 | 
					      SpaNodeEventReuseBuffer rb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      spa_list_remove (&b->list);
 | 
					      spa_list_remove (&b->list);
 | 
				
			||||||
| 
						 | 
					@ -298,7 +311,7 @@ pull_frames_queue (SpaALSAState *state,
 | 
				
			||||||
      state->ready_offset = 0;
 | 
					      state->ready_offset = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    spa_log_warn (state->log, "underrun");
 | 
					    spa_log_warn (state->log, "underrun, want %zd frames", frames);
 | 
				
			||||||
    snd_pcm_areas_silence (my_areas, offset, state->channels, frames, state->format);
 | 
					    snd_pcm_areas_silence (my_areas, offset, state->channels, frames, state->format);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return frames;
 | 
					  return frames;
 | 
				
			||||||
| 
						 | 
					@ -318,7 +331,7 @@ pull_frames_ringbuffer (SpaALSAState *state,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  b = state->ringbuffer;
 | 
					  b = state->ringbuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  src = SPA_MEMBER (b->outbuf->datas[0].data, b->outbuf->datas[0].offset, void);
 | 
					  src = b->outbuf->datas[0].data;
 | 
				
			||||||
  dst = SPA_MEMBER (my_areas[0].addr, offset * state->frame_size, uint8_t);
 | 
					  dst = SPA_MEMBER (my_areas[0].addr, offset * state->frame_size, uint8_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  avail = spa_ringbuffer_get_read_areas (&b->rb->ringbuffer, areas);
 | 
					  avail = spa_ringbuffer_get_read_areas (&b->rb->ringbuffer, areas);
 | 
				
			||||||
| 
						 | 
					@ -442,8 +455,8 @@ mmap_read (SpaALSAState *state)
 | 
				
			||||||
    b = spa_list_first (&state->free, SpaALSABuffer, list);
 | 
					    b = spa_list_first (&state->free, SpaALSABuffer, list);
 | 
				
			||||||
    spa_list_remove (&b->list);
 | 
					    spa_list_remove (&b->list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dest = SPA_MEMBER (b->outbuf->datas[0].data, b->outbuf->datas[0].offset, void);
 | 
					    dest = b->outbuf->datas[0].data;
 | 
				
			||||||
    destsize = b->outbuf->datas[0].size;
 | 
					    destsize = b->outbuf->datas[0].maxsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (b->h) {
 | 
					    if (b->h) {
 | 
				
			||||||
      b->h->seq = state->sample_count;
 | 
					      b->h->seq = state->sample_count;
 | 
				
			||||||
| 
						 | 
					@ -484,7 +497,9 @@ mmap_read (SpaALSAState *state)
 | 
				
			||||||
    SpaData *d;
 | 
					    SpaData *d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    d = b->outbuf->datas;
 | 
					    d = b->outbuf->datas;
 | 
				
			||||||
    d[0].size = avail * state->frame_size;
 | 
					    d[0].chunk->offset = 0;
 | 
				
			||||||
 | 
					    d[0].chunk->size = avail * state->frame_size;
 | 
				
			||||||
 | 
					    d[0].chunk->stride = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    spa_list_insert (state->ready.prev, &b->list);
 | 
					    spa_list_insert (state->ready.prev, &b->list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -598,12 +598,12 @@ add_port_data (SpaAudioMixer *this, SpaBuffer *out, SpaAudioMixerPort *port)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  while (true) {
 | 
					  while (true) {
 | 
				
			||||||
    if (op == NULL) {
 | 
					    if (op == NULL) {
 | 
				
			||||||
      op = (uint8_t*)odatas[oi].data + odatas[oi].offset;
 | 
					      op = (uint8_t*)odatas[oi].data + odatas[oi].chunk->offset;
 | 
				
			||||||
      os = odatas[oi].size;
 | 
					      os = odatas[oi].chunk->size;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (ip == NULL) {
 | 
					    if (ip == NULL) {
 | 
				
			||||||
      ip = (uint8_t*)idatas[port->buffer_index].data + idatas[port->buffer_index].offset;
 | 
					      ip = (uint8_t*)idatas[port->buffer_index].data + idatas[port->buffer_index].chunk->offset;
 | 
				
			||||||
      is = idatas[port->buffer_index].size;
 | 
					      is = idatas[port->buffer_index].chunk->size;
 | 
				
			||||||
      ip += port->buffer_offset;
 | 
					      ip += port->buffer_offset;
 | 
				
			||||||
      is -= port->buffer_offset;
 | 
					      is -= port->buffer_offset;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -690,8 +690,8 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode         *node,
 | 
				
			||||||
          spa_log_error (this->log, "audiotestsrc %p: invalid memory on buffer %p", this, buffers[i]);
 | 
					          spa_log_error (this->log, "audiotestsrc %p: invalid memory on buffer %p", this, buffers[i]);
 | 
				
			||||||
          continue;
 | 
					          continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        b->ptr = SPA_MEMBER (d[0].data, d[0].offset, void);
 | 
					        b->ptr = d[0].data;
 | 
				
			||||||
        b->size = d[0].size;
 | 
					        b->size = d[0].maxsize;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,7 +117,7 @@ spa_v4l2_clear_buffers (SpaV4l2Source *this)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (b->allocated) {
 | 
					    if (b->allocated) {
 | 
				
			||||||
      if (b->outbuf->datas[0].data)
 | 
					      if (b->outbuf->datas[0].data)
 | 
				
			||||||
        munmap (b->outbuf->datas[0].data, b->outbuf->datas[0].size);
 | 
					        munmap (b->outbuf->datas[0].data, b->outbuf->datas[0].maxsize);
 | 
				
			||||||
      if (b->outbuf->datas[0].fd != -1)
 | 
					      if (b->outbuf->datas[0].fd != -1)
 | 
				
			||||||
        close (b->outbuf->datas[0].fd);
 | 
					        close (b->outbuf->datas[0].fd);
 | 
				
			||||||
      b->outbuf->datas[0].type = SPA_DATA_TYPE_INVALID;
 | 
					      b->outbuf->datas[0].type = SPA_DATA_TYPE_INVALID;
 | 
				
			||||||
| 
						 | 
					@ -973,7 +973,7 @@ spa_v4l2_use_buffers (SpaV4l2Source *this, SpaBuffer **buffers, uint32_t n_buffe
 | 
				
			||||||
          continue;
 | 
					          continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        b->v4l2_buffer.m.userptr = (unsigned long) d[0].data;
 | 
					        b->v4l2_buffer.m.userptr = (unsigned long) d[0].data;
 | 
				
			||||||
        b->v4l2_buffer.length = d[0].size;
 | 
					        b->v4l2_buffer.length = d[0].maxsize;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case SPA_DATA_TYPE_DMABUF:
 | 
					      case SPA_DATA_TYPE_DMABUF:
 | 
				
			||||||
        b->v4l2_buffer.m.fd = d[0].fd;
 | 
					        b->v4l2_buffer.m.fd = d[0].fd;
 | 
				
			||||||
| 
						 | 
					@ -1047,8 +1047,8 @@ mmap_init (SpaV4l2Source   *this,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    d = buffers[i]->datas;
 | 
					    d = buffers[i]->datas;
 | 
				
			||||||
    d[0].offset = 0;
 | 
					    d[0].mapoffset = 0;
 | 
				
			||||||
    d[0].size = b->v4l2_buffer.length;
 | 
					    d[0].maxsize = b->v4l2_buffer.length;
 | 
				
			||||||
    d[0].chunk->offset = 0;
 | 
					    d[0].chunk->offset = 0;
 | 
				
			||||||
    d[0].chunk->size = b->v4l2_buffer.length;
 | 
					    d[0].chunk->size = b->v4l2_buffer.length;
 | 
				
			||||||
    d[0].chunk->stride = state->fmt.fmt.pix.bytesperline;
 | 
					    d[0].chunk->stride = state->fmt.fmt.pix.bytesperline;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -657,7 +657,7 @@ spa_videotestsrc_node_port_use_buffers (SpaNode         *node,
 | 
				
			||||||
          spa_log_error (this->log, "videotestsrc %p: invalid memory on buffer %p", this, buffers[i]);
 | 
					          spa_log_error (this->log, "videotestsrc %p: invalid memory on buffer %p", this, buffers[i]);
 | 
				
			||||||
          continue;
 | 
					          continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        b->ptr = SPA_MEMBER (d[0].data, d[0].offset, void);
 | 
					        b->ptr = SPA_MEMBER (d[0].data, d[0].chunk->offset, void);
 | 
				
			||||||
        b->stride = d[0].chunk->stride;
 | 
					        b->stride = d[0].chunk->stride;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -582,10 +582,10 @@ spa_volume_node_process_output (SpaNode *node)
 | 
				
			||||||
    sd = &sbuf->datas[si];
 | 
					    sd = &sbuf->datas[si];
 | 
				
			||||||
    dd = &dbuf->datas[di];
 | 
					    dd = &dbuf->datas[di];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    src = (uint16_t*) ((uint8_t*)sd->data + sd->offset + soff);
 | 
					    src = (uint16_t*) ((uint8_t*)sd->data + sd->chunk->offset + soff);
 | 
				
			||||||
    dst = (uint16_t*) ((uint8_t*)dd->data + dd->offset + doff);
 | 
					    dst = (uint16_t*) ((uint8_t*)dd->data + dd->chunk->offset + doff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    n_bytes = SPA_MIN (sd->size - soff, dd->size - doff);
 | 
					    n_bytes = SPA_MIN (sd->chunk->size - soff, dd->chunk->size - doff);
 | 
				
			||||||
    n_samples = n_bytes / sizeof (uint16_t);
 | 
					    n_samples = n_bytes / sizeof (uint16_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < n_samples; i++)
 | 
					    for (i = 0; i < n_samples; i++)
 | 
				
			||||||
| 
						 | 
					@ -594,11 +594,11 @@ spa_volume_node_process_output (SpaNode *node)
 | 
				
			||||||
    soff += n_bytes;
 | 
					    soff += n_bytes;
 | 
				
			||||||
    doff += n_bytes;
 | 
					    doff += n_bytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (soff >= sd->size) {
 | 
					    if (soff >= sd->chunk->size) {
 | 
				
			||||||
      si++;
 | 
					      si++;
 | 
				
			||||||
      soff = 0;
 | 
					      soff = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (doff >= dd->size) {
 | 
					    if (doff >= dd->chunk->size) {
 | 
				
			||||||
      di++;
 | 
					      di++;
 | 
				
			||||||
      doff = 0;
 | 
					      doff = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue