mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-10-29 05:40:27 -04:00 
			
		
		
		
	More work on wire protocol
Make separate payload for the header. Make release-fd payloads capture_buffer -> peek_buffer to avoid a copy remove release-buffer, we really need to release each fd in the buffer separately. provide_buffer -> send_buffer so that we can also use this to send the release-fd messages. in pinossrc, send back release-fd messages when the fd is no longer in use.
This commit is contained in:
		
							parent
							
								
									c2cf359076
								
							
						
					
					
						commit
						8d1ad2ea63
					
				
					 10 changed files with 351 additions and 155 deletions
				
			
		|  | @ -55,11 +55,8 @@ Wire | ||||||
| 
 | 
 | ||||||
| Fixed header | Fixed header | ||||||
| 
 | 
 | ||||||
| <flags>      : 4 bytes       : buffer flags | <version>     : 4 bytes       : total message length | ||||||
| <seq>        : 4 bytes       : sequence number | <length>      : 4 bytes       : total message length | ||||||
| <pts>        : 8 bytes       : presentation time |  | ||||||
| <dts-offset> : 8 bytes       : dts-offset |  | ||||||
| <length>     : 8 bytes       : total message length |  | ||||||
| 
 | 
 | ||||||
| Followed by 1 or more type-length-data sections | Followed by 1 or more type-length-data sections | ||||||
| 
 | 
 | ||||||
|  | @ -69,28 +66,36 @@ Followed by 1 or more type-length-data sections | ||||||
| 
 | 
 | ||||||
| Types: | Types: | ||||||
| 
 | 
 | ||||||
|  0: fd-payload section |  1: header | ||||||
|  | 
 | ||||||
|  |    Header for payload | ||||||
|  | 
 | ||||||
|  |    <flags>      : 4 bytes      : buffer flags | ||||||
|  |    <seq>        : 4 bytes      : sequence number | ||||||
|  |    <pts>        : 8 bytes      : presentation time | ||||||
|  |    <dts-offset> : 8 bytes      : dts-offset | ||||||
|  | 
 | ||||||
|  |  2: fd-payload section | ||||||
| 
 | 
 | ||||||
|    Used to send a buffer between client and server. |    Used to send a buffer between client and server. | ||||||
| 
 | 
 | ||||||
|    <id>        : 4 bytes      : id of the fd-payload |    <id>         : 4 bytes      : id of the fd-payload | ||||||
|    <offset>    : 8 bytes      : offset |    <offset>     : 8 bytes      : offset | ||||||
|    <size>      : 8 bytes      : size |    <size>       : 8 bytes      : size | ||||||
|    <fd-index>  : 4 bytes      : index of fd |    <fd-index>   : 4 bytes      : index of fd | ||||||
| 
 | 
 | ||||||
|  1: release fd-payload |  3: release fd-payload | ||||||
| 
 | 
 | ||||||
|    Release a fd-payload with <id> |    Release a fd-payload with <id> | ||||||
| 
 | 
 | ||||||
|    <id>        : 4 bytes      : the id number of the released fd-payload |    <id>         : 4 bytes      : the id number of the released fd-payload | ||||||
| 
 | 
 | ||||||
|  2: format change |  4: format change | ||||||
| 
 | 
 | ||||||
|    <format-id> : 1 byte       : format id |    <format-id>  : 1 byte       : format id | ||||||
|    <format>    : 0-terminated : contains serialized format |    <format>     : 0-terminated : contains serialized format | ||||||
| 
 | 
 | ||||||
| 
 |  5: property changes | ||||||
|  3: property changes |  | ||||||
| 
 | 
 | ||||||
|    <key>       : 0-terminated   : key |    <key>       : 0-terminated   : key | ||||||
|    <value>     : 0-terminated   : value |    <value>     : 0-terminated   : value | ||||||
|  |  | ||||||
|  | @ -72,8 +72,16 @@ pinos_buffer_clear (PinosBuffer *buffer) | ||||||
|   g_clear_object (&sb->message); |   g_clear_object (&sb->message); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const PinosBufferHeader * | /**
 | ||||||
| pinos_buffer_get_header (PinosBuffer *buffer, guint32 *version) |  * pinos_buffer_get_version | ||||||
|  |  * @buffer: a #PinosBuffer | ||||||
|  |  * | ||||||
|  |  * Get the buffer version | ||||||
|  |  * | ||||||
|  |  * Returns: the buffer version. | ||||||
|  |  */ | ||||||
|  | guint32 | ||||||
|  | pinos_buffer_get_version (PinosBuffer *buffer) | ||||||
| { | { | ||||||
|   PinosStackBuffer *sb = PSB (buffer); |   PinosStackBuffer *sb = PSB (buffer); | ||||||
|   PinosStackHeader *hdr; |   PinosStackHeader *hdr; | ||||||
|  | @ -82,10 +90,7 @@ pinos_buffer_get_header (PinosBuffer *buffer, guint32 *version) | ||||||
| 
 | 
 | ||||||
|   hdr = sb->data; |   hdr = sb->data; | ||||||
| 
 | 
 | ||||||
|   if (version) |   return hdr->version; | ||||||
|     *version = hdr->version; |  | ||||||
| 
 |  | ||||||
|   return (const PinosBufferHeader *) &hdr->header; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -134,7 +139,7 @@ not_found: | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * pinos_buffer_steal_data: |  * pinos_buffer_steal: | ||||||
|  * @buffer: a #PinosBuffer |  * @buffer: a #PinosBuffer | ||||||
|  * @size: output size |  * @size: output size | ||||||
|  * @message: output #GSocketControlMessage |  * @message: output #GSocketControlMessage | ||||||
|  | @ -431,25 +436,6 @@ pinos_buffer_builder_end (PinosBufferBuilder *builder, | ||||||
|   sb->magic = 0; |   sb->magic = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 |  | ||||||
|  * pinos_buffer_builder_set_header: |  | ||||||
|  * @builder: a #PinosBufferBuilder |  | ||||||
|  * @header: a #PinosBufferHeader |  | ||||||
|  * |  | ||||||
|  * Set @header in @builder. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| pinos_buffer_builder_set_header (PinosBufferBuilder       *builder, |  | ||||||
|                                  const PinosBufferHeader  *header) |  | ||||||
| { |  | ||||||
|   struct stack_builder *sb = PPSB (builder); |  | ||||||
| 
 |  | ||||||
|   g_return_if_fail (is_valid_builder (builder)); |  | ||||||
|   g_return_if_fail (header != NULL); |  | ||||||
| 
 |  | ||||||
|   sb->sh->header = *header; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * pinos_buffer_builder_add_fd: |  * pinos_buffer_builder_add_fd: | ||||||
|  * @builder: a #PinosBufferBuilder |  * @builder: a #PinosBufferBuilder | ||||||
|  | @ -518,6 +504,58 @@ builder_add_packet (struct stack_builder *sb, PinosPacketType type, gsize size) | ||||||
|   return p; |   return p; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* header packets */ | ||||||
|  | /**
 | ||||||
|  |  * pinos_buffer_iter_get_header: | ||||||
|  |  * @iter: a #PinosBufferIter | ||||||
|  |  * @header: a #PinosPacketHeader | ||||||
|  |  * | ||||||
|  |  * Get the #PinosPacketHeader. @iter must be positioned on a packet of | ||||||
|  |  * type #PINOS_PACKET_TYPE_HEADER | ||||||
|  |  * | ||||||
|  |  * Returns: %TRUE if @header contains valid data. | ||||||
|  |  */ | ||||||
|  | gboolean | ||||||
|  | pinos_buffer_iter_parse_header (PinosBufferIter *iter, | ||||||
|  |                                 PinosPacketHeader *header) | ||||||
|  | { | ||||||
|  |   struct stack_iter *si = PPSI (iter); | ||||||
|  | 
 | ||||||
|  |   g_return_val_if_fail (is_valid_iter (iter), FALSE); | ||||||
|  |   g_return_val_if_fail (si->type == PINOS_PACKET_TYPE_HEADER, FALSE); | ||||||
|  | 
 | ||||||
|  |   if (si->size < sizeof (PinosPacketHeader)) | ||||||
|  |     return FALSE; | ||||||
|  | 
 | ||||||
|  |   *header = *((PinosPacketHeader *) si->data); | ||||||
|  | 
 | ||||||
|  |   return TRUE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * pinos_buffer_builder_add_header: | ||||||
|  |  * @builder: a #PinosBufferBuilder | ||||||
|  |  * @header: a #PinosPacketHeader | ||||||
|  |  * | ||||||
|  |  * Add a #PINOS_PACKET_TYPE_HEADER to @builder with data from @header. | ||||||
|  |  * | ||||||
|  |  * Returns: %TRUE on success. | ||||||
|  |  */ | ||||||
|  | gboolean | ||||||
|  | pinos_buffer_builder_add_header (PinosBufferBuilder *builder, | ||||||
|  |                                  PinosPacketHeader *header) | ||||||
|  | { | ||||||
|  |   struct stack_builder *sb = PPSB (builder); | ||||||
|  |   PinosPacketHeader *h; | ||||||
|  | 
 | ||||||
|  |   g_return_val_if_fail (is_valid_builder (builder), FALSE); | ||||||
|  | 
 | ||||||
|  |   h = builder_add_packet (sb, PINOS_PACKET_TYPE_HEADER, sizeof (PinosPacketHeader)); | ||||||
|  |   *h = *header; | ||||||
|  | 
 | ||||||
|  |   return TRUE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* fd-payload packets */ | /* fd-payload packets */ | ||||||
| /**
 | /**
 | ||||||
|  * pinos_buffer_iter_get_fd_payload: |  * pinos_buffer_iter_get_fd_payload: | ||||||
|  | @ -526,17 +564,24 @@ builder_add_packet (struct stack_builder *sb, PinosPacketType type, gsize size) | ||||||
|  * |  * | ||||||
|  * Get the #PinosPacketFDPayload. @iter must be positioned on a packet of |  * Get the #PinosPacketFDPayload. @iter must be positioned on a packet of | ||||||
|  * type #PINOS_PACKET_TYPE_FD_PAYLOAD |  * type #PINOS_PACKET_TYPE_FD_PAYLOAD | ||||||
|  |  * | ||||||
|  |  * Returns: %TRUE if @payload contains valid data. | ||||||
|  */ |  */ | ||||||
| void | gboolean | ||||||
| pinos_buffer_iter_parse_fd_payload (PinosBufferIter *iter, | pinos_buffer_iter_parse_fd_payload (PinosBufferIter *iter, | ||||||
|                                     PinosPacketFDPayload *payload) |                                     PinosPacketFDPayload *payload) | ||||||
| { | { | ||||||
|   struct stack_iter *si = PPSI (iter); |   struct stack_iter *si = PPSI (iter); | ||||||
| 
 | 
 | ||||||
|   g_return_if_fail (is_valid_iter (iter)); |   g_return_val_if_fail (is_valid_iter (iter), FALSE); | ||||||
|   g_return_if_fail (si->type == PINOS_PACKET_TYPE_FD_PAYLOAD); |   g_return_val_if_fail (si->type == PINOS_PACKET_TYPE_FD_PAYLOAD, FALSE); | ||||||
|  | 
 | ||||||
|  |   if (si->size < sizeof (PinosPacketFDPayload)) | ||||||
|  |     return FALSE; | ||||||
| 
 | 
 | ||||||
|   *payload = *((PinosPacketFDPayload *) si->data); |   *payload = *((PinosPacketFDPayload *) si->data); | ||||||
|  | 
 | ||||||
|  |   return TRUE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -564,3 +609,36 @@ pinos_buffer_builder_add_fd_payload (PinosBufferBuilder *builder, | ||||||
|   return TRUE; |   return TRUE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | gboolean | ||||||
|  | pinos_buffer_iter_parse_release_fd_payload (PinosBufferIter      *iter, | ||||||
|  |                                             PinosPacketReleaseFDPayload *payload) | ||||||
|  | { | ||||||
|  |   struct stack_iter *si = PPSI (iter); | ||||||
|  | 
 | ||||||
|  |   g_return_val_if_fail (is_valid_iter (iter), FALSE); | ||||||
|  |   g_return_val_if_fail (si->type == PINOS_PACKET_TYPE_RELEASE_FD_PAYLOAD, FALSE); | ||||||
|  | 
 | ||||||
|  |   if (si->size < sizeof (PinosPacketReleaseFDPayload)) | ||||||
|  |     return FALSE; | ||||||
|  | 
 | ||||||
|  |   *payload = *((PinosPacketReleaseFDPayload *) si->data); | ||||||
|  | 
 | ||||||
|  |   return TRUE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | gboolean | ||||||
|  | pinos_buffer_builder_add_release_fd_payload (PinosBufferBuilder   *builder, | ||||||
|  |                                              PinosPacketReleaseFDPayload *payload) | ||||||
|  | { | ||||||
|  |   struct stack_builder *sb = PPSB (builder); | ||||||
|  |   PinosPacketReleaseFDPayload *p; | ||||||
|  | 
 | ||||||
|  |   g_return_val_if_fail (is_valid_builder (builder), FALSE); | ||||||
|  | 
 | ||||||
|  |   p = builder_add_packet (sb, | ||||||
|  |                           PINOS_PACKET_TYPE_RELEASE_FD_PAYLOAD, | ||||||
|  |                           sizeof (PinosPacketReleaseFDPayload)); | ||||||
|  |   *p = *payload; | ||||||
|  | 
 | ||||||
|  |   return TRUE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -26,19 +26,11 @@ | ||||||
| G_BEGIN_DECLS | G_BEGIN_DECLS | ||||||
| 
 | 
 | ||||||
| typedef struct _PinosBuffer PinosBuffer; | typedef struct _PinosBuffer PinosBuffer; | ||||||
| typedef struct _PinosBufferInfo PinosBufferInfo; |  | ||||||
| typedef struct _PinosBufferIter PinosBufferIter; | typedef struct _PinosBufferIter PinosBufferIter; | ||||||
| typedef struct _PinosBufferBuilder PinosBufferBuilder; | typedef struct _PinosBufferBuilder PinosBufferBuilder; | ||||||
| 
 | 
 | ||||||
| #define PINOS_BUFFER_VERSION 0 | #define PINOS_BUFFER_VERSION 0 | ||||||
| 
 | 
 | ||||||
| typedef struct { |  | ||||||
|   guint32 flags; |  | ||||||
|   guint32 seq; |  | ||||||
|   gint64 pts; |  | ||||||
|   gint64 dts_offset; |  | ||||||
| } PinosBufferHeader; |  | ||||||
| 
 |  | ||||||
| struct _PinosBuffer { | struct _PinosBuffer { | ||||||
|   /*< private >*/ |   /*< private >*/ | ||||||
|   gsize x[16]; |   gsize x[16]; | ||||||
|  | @ -51,9 +43,7 @@ void               pinos_buffer_init_data        (PinosBuffer       *buffer, | ||||||
| 
 | 
 | ||||||
| void               pinos_buffer_clear            (PinosBuffer       *buffer); | void               pinos_buffer_clear            (PinosBuffer       *buffer); | ||||||
| 
 | 
 | ||||||
| const PinosBufferHeader * | guint32            pinos_buffer_get_version      (PinosBuffer       *buffer); | ||||||
|                    pinos_buffer_get_header       (PinosBuffer       *buffer, |  | ||||||
|                                                   guint32           *version); |  | ||||||
| int                pinos_buffer_get_fd           (PinosBuffer       *buffer, | int                pinos_buffer_get_fd           (PinosBuffer       *buffer, | ||||||
|                                                   gint               index, |                                                   gint               index, | ||||||
|                                                   GError           **error); |                                                   GError           **error); | ||||||
|  | @ -63,12 +53,27 @@ gpointer           pinos_buffer_steal            (PinosBuffer       *buffer, | ||||||
|                                                   GSocketControlMessage **message); |                                                   GSocketControlMessage **message); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * PinosPacketType: | ||||||
|  |  * @PINOS_PACKET_TYPE_INVALID: invalid packet type, ignore | ||||||
|  |  * @PINOS_PACKET_TYPE_HEADER: common packet header | ||||||
|  |  * @PINOS_PACKET_TYPE_FD_PAYLOAD: packet contains fd-payload. An fd-payload contains | ||||||
|  |  *      the media data as a file descriptor | ||||||
|  |  * @PINOS_PACKET_TYPE_RELEASE_FD_PAYLOAD: packet contains release fd-payload. Notifies | ||||||
|  |  *      that a previously received fd-payload is no longer in use. | ||||||
|  |  * @PINOS_PACKET_TYPE_FORMAT_CHANGE: a format change. | ||||||
|  |  * @PINOS_PACKET_TYPE_PROPERTY_CHANGE: one or more property changes. | ||||||
|  |  * | ||||||
|  |  * The possible packet types. | ||||||
|  |  */ | ||||||
| typedef enum { | typedef enum { | ||||||
|   PINOS_PACKET_TYPE_INVALID           = 0, |   PINOS_PACKET_TYPE_INVALID            = 0, | ||||||
| 
 | 
 | ||||||
|   PINOS_PACKET_TYPE_FD_PAYLOAD        = 1, |   PINOS_PACKET_TYPE_HEADER             = 1, | ||||||
|   PINOS_PACKET_TYPE_FORMAT_CHANGE     = 2, |   PINOS_PACKET_TYPE_FD_PAYLOAD         = 2, | ||||||
|   PINOS_PACKET_TYPE_PROPERTY_CHANGE   = 3, |   PINOS_PACKET_TYPE_RELEASE_FD_PAYLOAD = 3, | ||||||
|  |   PINOS_PACKET_TYPE_FORMAT_CHANGE      = 4, | ||||||
|  |   PINOS_PACKET_TYPE_PROPERTY_CHANGE    = 5, | ||||||
| } PinosPacketType; | } PinosPacketType; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -104,11 +109,31 @@ void               pinos_buffer_builder_clear      (PinosBufferBuilder *builder) | ||||||
| void               pinos_buffer_builder_end        (PinosBufferBuilder *builder, | void               pinos_buffer_builder_end        (PinosBufferBuilder *builder, | ||||||
|                                                     PinosBuffer        *buffer); |                                                     PinosBuffer        *buffer); | ||||||
| 
 | 
 | ||||||
| void               pinos_buffer_builder_set_header (PinosBufferBuilder      *builder, |  | ||||||
|                                                     const PinosBufferHeader *header); |  | ||||||
| gint               pinos_buffer_builder_add_fd     (PinosBufferBuilder *builder, | gint               pinos_buffer_builder_add_fd     (PinosBufferBuilder *builder, | ||||||
|                                                     int                 fd, |                                                     int                 fd, | ||||||
|                                                     GError            **error); |                                                     GError            **error); | ||||||
|  | /* header packets */ | ||||||
|  | /**
 | ||||||
|  |  * PinosPacketHeader | ||||||
|  |  * @flags: header flags | ||||||
|  |  * @seq: sequence number | ||||||
|  |  * @pts: presentation timestamp in nanoseconds | ||||||
|  |  * @dts_offset: offset to presentation timestamp in nanoseconds to get decode timestamp | ||||||
|  |  * | ||||||
|  |  * A Packet that contains the header. | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  |   guint32 flags; | ||||||
|  |   guint32 seq; | ||||||
|  |   gint64 pts; | ||||||
|  |   gint64 dts_offset; | ||||||
|  | } PinosPacketHeader; | ||||||
|  | 
 | ||||||
|  | gboolean           pinos_buffer_iter_parse_header      (PinosBufferIter    *iter, | ||||||
|  |                                                         PinosPacketHeader  *header); | ||||||
|  | gboolean           pinos_buffer_builder_add_header     (PinosBufferBuilder *builder, | ||||||
|  |                                                         PinosPacketHeader  *header); | ||||||
|  | 
 | ||||||
| /* fd-payload packets */ | /* fd-payload packets */ | ||||||
| /**
 | /**
 | ||||||
|  * PinosPacketFDPayload: |  * PinosPacketFDPayload: | ||||||
|  | @ -127,10 +152,66 @@ typedef struct { | ||||||
|   guint64 size; |   guint64 size; | ||||||
| } PinosPacketFDPayload; | } PinosPacketFDPayload; | ||||||
| 
 | 
 | ||||||
| void               pinos_buffer_iter_parse_fd_payload   (PinosBufferIter      *iter, | gboolean           pinos_buffer_iter_parse_fd_payload   (PinosBufferIter      *iter, | ||||||
|                                                          PinosPacketFDPayload *payload); |                                                          PinosPacketFDPayload *payload); | ||||||
| gboolean           pinos_buffer_builder_add_fd_payload  (PinosBufferBuilder   *builder, | gboolean           pinos_buffer_builder_add_fd_payload  (PinosBufferBuilder   *builder, | ||||||
|                                                          PinosPacketFDPayload *payload); |                                                          PinosPacketFDPayload *payload); | ||||||
| 
 | 
 | ||||||
|  | /* release fd-payload packets */ | ||||||
|  | /**
 | ||||||
|  |  * PinosPacketReleaseFDPayload: | ||||||
|  |  * @id: the unique id of the fd-payload to release | ||||||
|  |  * | ||||||
|  |  * Release the payload with @id | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  |   guint32 id; | ||||||
|  | } PinosPacketReleaseFDPayload; | ||||||
|  | 
 | ||||||
|  | gboolean           pinos_buffer_iter_parse_release_fd_payload   (PinosBufferIter      *iter, | ||||||
|  |                                                                  PinosPacketReleaseFDPayload *payload); | ||||||
|  | gboolean           pinos_buffer_builder_add_release_fd_payload  (PinosBufferBuilder   *builder, | ||||||
|  |                                                                  PinosPacketReleaseFDPayload *payload); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* format change packets */ | ||||||
|  | /**
 | ||||||
|  |  * PinosPacketFormatChange: | ||||||
|  |  * @id: the id of the new format | ||||||
|  |  * @format: the new format | ||||||
|  |  * | ||||||
|  |  * A new format. | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  |   guint8 id; | ||||||
|  |   gchar *format; | ||||||
|  | } PinosPacketFormatChange; | ||||||
|  | 
 | ||||||
|  | gboolean           pinos_buffer_iter_parse_format_change   (PinosBufferIter      *iter, | ||||||
|  |                                                             PinosPacketFormatChange *payload); | ||||||
|  | gboolean           pinos_buffer_builder_add_format_change  (PinosBufferBuilder   *builder, | ||||||
|  |                                                             PinosPacketFormatChange *payload); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* property change packets */ | ||||||
|  | /**
 | ||||||
|  |  * PinosPacketPropertyChange: | ||||||
|  |  * @key: the key of the property | ||||||
|  |  * @value: the new value | ||||||
|  |  * | ||||||
|  |  * A new property change. | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  |   gchar *key; | ||||||
|  |   gchar *value; | ||||||
|  | } PinosPacketPropertyChange; | ||||||
|  | 
 | ||||||
|  | gboolean           pinos_buffer_iter_parse_property_change  (PinosBufferIter      *iter, | ||||||
|  |                                                              guint                 idx, | ||||||
|  |                                                              PinosPacketPropertyChange *payload); | ||||||
|  | gboolean           pinos_buffer_builder_add_property_change (PinosBufferBuilder   *builder, | ||||||
|  |                                                              PinosPacketPropertyChange *payload); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| #endif /* __PINOS_BUFFER_H__ */ | #endif /* __PINOS_BUFFER_H__ */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -57,7 +57,6 @@ GDBusProxy *           pinos_subscribe_get_proxy_finish   (PinosSubscribe *subsc | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|   PinosBufferHeader header; |  | ||||||
|   guint32 version; |   guint32 version; | ||||||
|   guint32 length; |   guint32 length; | ||||||
| } PinosStackHeader; | } PinosStackHeader; | ||||||
|  |  | ||||||
|  | @ -856,6 +856,10 @@ on_socket_condition (GSocket      *socket, | ||||||
|       priv->buffer.magic = PSB_MAGIC; |       priv->buffer.magic = PSB_MAGIC; | ||||||
| 
 | 
 | ||||||
|       g_signal_emit (stream, signals[SIGNAL_NEW_BUFFER], 0, NULL); |       g_signal_emit (stream, signals[SIGNAL_NEW_BUFFER], 0, NULL); | ||||||
|  | 
 | ||||||
|  |       priv->buffer.magic = 0; | ||||||
|  |       priv->buffer.size = 0; | ||||||
|  |       g_clear_object (&priv->buffer.message); | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|     case G_IO_OUT: |     case G_IO_OUT: | ||||||
|  | @ -1131,18 +1135,18 @@ pinos_stream_stop (PinosStream *stream) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * pinos_stream_capture_buffer: |  * pinos_stream_peek_buffer: | ||||||
|  * @stream: a #PinosStream |  * @stream: a #PinosStream | ||||||
|  * @buffer: a #PinosBuffer |  * @buffer: a #PinosBuffer | ||||||
|  * |  * | ||||||
|  * Capture the next buffer from @stream. This function should be called every |  * Peek the next buffer from @stream. This function should be called from | ||||||
|  * time after the new-buffer callback has been emitted. |  * the new-buffer signal callback. | ||||||
|  * |  * | ||||||
|  * Returns: %TRUE when @buffer contains valid information |  * Returns: %TRUE when @buffer contains valid information | ||||||
|  */ |  */ | ||||||
| gboolean | gboolean | ||||||
| pinos_stream_capture_buffer (PinosStream  *stream, | pinos_stream_peek_buffer (PinosStream  *stream, | ||||||
|                              PinosBuffer  *buffer) |                           PinosBuffer  **buffer) | ||||||
| { | { | ||||||
|   PinosStreamPrivate *priv; |   PinosStreamPrivate *priv; | ||||||
| 
 | 
 | ||||||
|  | @ -1153,65 +1157,29 @@ pinos_stream_capture_buffer (PinosStream  *stream, | ||||||
|   g_return_val_if_fail (priv->state == PINOS_STREAM_STATE_STREAMING, FALSE); |   g_return_val_if_fail (priv->state == PINOS_STREAM_STATE_STREAMING, FALSE); | ||||||
|   g_return_val_if_fail (is_valid_buffer (&priv->buffer), FALSE); |   g_return_val_if_fail (is_valid_buffer (&priv->buffer), FALSE); | ||||||
| 
 | 
 | ||||||
|   memcpy (buffer, &priv->buffer, sizeof (PinosStackBuffer)); |   *buffer = (PinosBuffer *) &priv->buffer; | ||||||
| 
 |  | ||||||
|   priv->buffer.data = NULL; |  | ||||||
|   priv->buffer.allocated_size = 0; |  | ||||||
|   priv->buffer.size = 0; |  | ||||||
|   priv->buffer.message = NULL; |  | ||||||
|   priv->buffer.magic = 0; |  | ||||||
| 
 | 
 | ||||||
|   return TRUE; |   return TRUE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * pinos_stream_release_buffer: |  * pinos_stream_send_buffer: | ||||||
|  * @stream: a #PinosStream |  * @stream: a #PinosStream | ||||||
|  * @buffer: a #PinosBuffer |  * @buffer: a #PinosBuffer | ||||||
|  * |  * | ||||||
|  * Release @buffer back to @stream. This function should be called whenever the |  * Send a buffer to @stream. | ||||||
|  * buffer is processed. @buffer should not be used anymore after calling this |  | ||||||
|  * function. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| pinos_stream_release_buffer (PinosStream  *stream, |  | ||||||
|                              PinosBuffer  *buffer) |  | ||||||
| { |  | ||||||
|   PinosStackBuffer *sb = (PinosStackBuffer *) buffer; |  | ||||||
|   PinosStreamPrivate *priv; |  | ||||||
| 
 |  | ||||||
|   g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE); |  | ||||||
|   g_return_val_if_fail (is_valid_buffer (buffer), FALSE); |  | ||||||
| 
 |  | ||||||
|   priv = stream->priv; |  | ||||||
| 
 |  | ||||||
|   if (priv->buffer.data == NULL) { |  | ||||||
|     priv->buffer.data = sb->data; |  | ||||||
|     priv->buffer.allocated_size = sb->allocated_size; |  | ||||||
|     priv->buffer.size = 0; |  | ||||||
|   } |  | ||||||
|   else |  | ||||||
|     g_free (sb->data); |  | ||||||
| 
 |  | ||||||
|   if (sb->message) |  | ||||||
|     g_object_unref (sb->message); |  | ||||||
| 
 |  | ||||||
|   sb->magic = 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * pinos_stream_provide_buffer: |  | ||||||
|  * @stream: a #PinosStream |  | ||||||
|  * @buffer: a #PinosBuffer |  | ||||||
|  * |  * | ||||||
|  * Provide the next buffer from @stream. This function should be called every |  * For provider streams, this function should be called whenever there is a new frame | ||||||
|  * time a new frame becomes available. |  * available. | ||||||
|  |  * | ||||||
|  |  * For capture streams, this functions should be called for each fd-payload that | ||||||
|  |  * should be released. | ||||||
|  * |  * | ||||||
|  * Returns: %TRUE when @buffer was handled |  * Returns: %TRUE when @buffer was handled | ||||||
|  */ |  */ | ||||||
| gboolean | gboolean | ||||||
| pinos_stream_provide_buffer (PinosStream *stream, | pinos_stream_send_buffer (PinosStream *stream, | ||||||
|                              PinosBuffer *buffer) |                           PinosBuffer *buffer) | ||||||
| { | { | ||||||
|   PinosStreamPrivate *priv; |   PinosStreamPrivate *priv; | ||||||
|   gssize len; |   gssize len; | ||||||
|  | @ -1219,6 +1187,7 @@ pinos_stream_provide_buffer (PinosStream *stream, | ||||||
|   GOutputVector ovec[1]; |   GOutputVector ovec[1]; | ||||||
|   gint flags = 0; |   gint flags = 0; | ||||||
|   GError *error = NULL; |   GError *error = NULL; | ||||||
|  |   gint n_msg; | ||||||
| 
 | 
 | ||||||
|   g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE); |   g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE); | ||||||
|   g_return_val_if_fail (buffer != NULL, FALSE); |   g_return_val_if_fail (buffer != NULL, FALSE); | ||||||
|  | @ -1229,12 +1198,17 @@ pinos_stream_provide_buffer (PinosStream *stream, | ||||||
|   ovec[0].buffer = sb->data; |   ovec[0].buffer = sb->data; | ||||||
|   ovec[0].size = sb->size; |   ovec[0].size = sb->size; | ||||||
| 
 | 
 | ||||||
|  |   if (sb->message) | ||||||
|  |     n_msg = 1; | ||||||
|  |   else | ||||||
|  |     n_msg = 0; | ||||||
|  | 
 | ||||||
|   len = g_socket_send_message (priv->socket, |   len = g_socket_send_message (priv->socket, | ||||||
|                                NULL, |                                NULL, | ||||||
|                                ovec, |                                ovec, | ||||||
|                                1, |                                1, | ||||||
|                                &sb->message, |                                &sb->message, | ||||||
|                                1, |                                n_msg, | ||||||
|                                flags, |                                flags, | ||||||
|                                NULL, |                                NULL, | ||||||
|                                &error); |                                &error); | ||||||
|  |  | ||||||
|  | @ -104,12 +104,9 @@ gboolean         pinos_stream_start             (PinosStream     *stream, | ||||||
|                                                  PinosStreamMode  mode); |                                                  PinosStreamMode  mode); | ||||||
| gboolean         pinos_stream_stop              (PinosStream     *stream); | gboolean         pinos_stream_stop              (PinosStream     *stream); | ||||||
| 
 | 
 | ||||||
| gboolean         pinos_stream_capture_buffer    (PinosStream     *stream, | gboolean         pinos_stream_peek_buffer       (PinosStream     *stream, | ||||||
|                                                  PinosBuffer     *buffer); |                                                  PinosBuffer     **buffer); | ||||||
| void             pinos_stream_release_buffer    (PinosStream     *stream, | gboolean         pinos_stream_send_buffer       (PinosStream     *stream, | ||||||
|                                                  PinosBuffer     *buffer); |  | ||||||
| 
 |  | ||||||
| gboolean         pinos_stream_provide_buffer    (PinosStream     *stream, |  | ||||||
|                                                  PinosBuffer     *buffer); |                                                  PinosBuffer     *buffer); | ||||||
| 
 | 
 | ||||||
| G_END_DECLS | G_END_DECLS | ||||||
|  |  | ||||||
|  | @ -86,17 +86,21 @@ gst_pinos_depay_chain (GstPad *pad, GstObject * parent, GstBuffer * buffer) | ||||||
|   PinosBufferIter it; |   PinosBufferIter it; | ||||||
|   GstNetControlMessageMeta * meta; |   GstNetControlMessageMeta * meta; | ||||||
|   GSocketControlMessage *msg = NULL; |   GSocketControlMessage *msg = NULL; | ||||||
|   const PinosBufferHeader *hdr; |  | ||||||
|   GError *err = NULL; |   GError *err = NULL; | ||||||
| 
 | 
 | ||||||
|   meta = ((GstNetControlMessageMeta*) gst_buffer_get_meta ( |   meta = ((GstNetControlMessageMeta*) gst_buffer_get_meta ( | ||||||
|       buffer, GST_NET_CONTROL_MESSAGE_META_API_TYPE)); |       buffer, GST_NET_CONTROL_MESSAGE_META_API_TYPE)); | ||||||
|   if (meta) { |   if (meta) { | ||||||
|     msg = meta->message; |     msg = g_object_ref (meta->message); | ||||||
|     gst_buffer_remove_meta (buffer, (GstMeta *) meta); |     gst_buffer_remove_meta (buffer, (GstMeta *) meta); | ||||||
|     meta = NULL; |     meta = NULL; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   if (msg == NULL) { | ||||||
|  |     gst_buffer_unref (buffer); | ||||||
|  |     return GST_FLOW_OK; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   outbuf = gst_buffer_new (); |   outbuf = gst_buffer_new (); | ||||||
| 
 | 
 | ||||||
|   gst_buffer_map (buffer, &info, GST_MAP_READ); |   gst_buffer_map (buffer, &info, GST_MAP_READ); | ||||||
|  | @ -105,13 +109,24 @@ gst_pinos_depay_chain (GstPad *pad, GstObject * parent, GstBuffer * buffer) | ||||||
|   pinos_buffer_iter_init (&it, &pbuf); |   pinos_buffer_iter_init (&it, &pbuf); | ||||||
|   while (pinos_buffer_iter_next (&it)) { |   while (pinos_buffer_iter_next (&it)) { | ||||||
|     switch (pinos_buffer_iter_get_type (&it)) { |     switch (pinos_buffer_iter_get_type (&it)) { | ||||||
|  |       case PINOS_PACKET_TYPE_HEADER: | ||||||
|  |       { | ||||||
|  |         PinosPacketHeader hdr; | ||||||
|  | 
 | ||||||
|  |         if (!pinos_buffer_iter_parse_header (&it, &hdr)) | ||||||
|  |           goto error; | ||||||
|  | 
 | ||||||
|  |         GST_BUFFER_OFFSET (outbuf) = hdr.seq; | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|       case PINOS_PACKET_TYPE_FD_PAYLOAD: |       case PINOS_PACKET_TYPE_FD_PAYLOAD: | ||||||
|       { |       { | ||||||
|         GstMemory *fdmem = NULL; |         GstMemory *fdmem = NULL; | ||||||
|         PinosPacketFDPayload p; |         PinosPacketFDPayload p; | ||||||
|         int fd; |         int fd; | ||||||
| 
 | 
 | ||||||
|         pinos_buffer_iter_parse_fd_payload (&it, &p); |         if (!pinos_buffer_iter_parse_fd_payload (&it, &p)) | ||||||
|  |           goto error; | ||||||
|         fd = pinos_buffer_get_fd (&pbuf, p.fd_index, &err); |         fd = pinos_buffer_get_fd (&pbuf, p.fd_index, &err); | ||||||
|         if (fd == -1) |         if (fd == -1) | ||||||
|           goto error; |           goto error; | ||||||
|  | @ -126,8 +141,6 @@ gst_pinos_depay_chain (GstPad *pad, GstObject * parent, GstBuffer * buffer) | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   hdr = pinos_buffer_get_header (&pbuf, NULL); |  | ||||||
|   GST_BUFFER_OFFSET (buffer) = hdr->seq; |  | ||||||
|   pinos_buffer_clear (&pbuf); |   pinos_buffer_clear (&pbuf); | ||||||
|   gst_buffer_unmap (buffer, &info); |   gst_buffer_unmap (buffer, &info); | ||||||
|   gst_buffer_unref (buffer); |   gst_buffer_unref (buffer); | ||||||
|  | @ -139,6 +152,7 @@ error: | ||||||
|     GST_ELEMENT_ERROR (depay, RESOURCE, SETTINGS, (NULL), |     GST_ELEMENT_ERROR (depay, RESOURCE, SETTINGS, (NULL), | ||||||
|         ("can't get fd: %s", err->message)); |         ("can't get fd: %s", err->message)); | ||||||
|     g_clear_error (&err); |     g_clear_error (&err); | ||||||
|  |     gst_buffer_unref (outbuf); | ||||||
|     return GST_FLOW_ERROR; |     return GST_FLOW_ERROR; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -155,7 +155,7 @@ gst_pinos_pay_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) | ||||||
|   GstBuffer *outbuf; |   GstBuffer *outbuf; | ||||||
|   PinosBuffer pbuf; |   PinosBuffer pbuf; | ||||||
|   PinosBufferBuilder builder; |   PinosBufferBuilder builder; | ||||||
|   PinosBufferHeader hdr; |   PinosPacketHeader hdr; | ||||||
|   PinosPacketFDPayload p; |   PinosPacketFDPayload p; | ||||||
|   gsize size; |   gsize size; | ||||||
|   gpointer data; |   gpointer data; | ||||||
|  | @ -167,7 +167,7 @@ gst_pinos_pay_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) | ||||||
|   hdr.dts_offset = 0; |   hdr.dts_offset = 0; | ||||||
| 
 | 
 | ||||||
|   pinos_buffer_builder_init (&builder); |   pinos_buffer_builder_init (&builder); | ||||||
|   pinos_buffer_builder_set_header (&builder, &hdr); |   pinos_buffer_builder_add_header (&builder, &hdr); | ||||||
| 
 | 
 | ||||||
|   fdmem = gst_pinos_pay_get_fd_memory (pay, buffer); |   fdmem = gst_pinos_pay_get_fd_memory (pay, buffer); | ||||||
|   p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (fdmem), &err); |   p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (fdmem), &err); | ||||||
|  |  | ||||||
|  | @ -333,7 +333,7 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer) | ||||||
|   PinosBufferBuilder builder; |   PinosBufferBuilder builder; | ||||||
|   GstMemory *mem = NULL; |   GstMemory *mem = NULL; | ||||||
|   GstClockTime pts, dts, base; |   GstClockTime pts, dts, base; | ||||||
|   PinosBufferHeader hdr; |   PinosPacketHeader hdr; | ||||||
|   PinosPacketFDPayload p; |   PinosPacketFDPayload p; | ||||||
|   gsize size; |   gsize size; | ||||||
|   GError *err = NULL; |   GError *err = NULL; | ||||||
|  | @ -376,7 +376,7 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   pinos_buffer_builder_init (&builder); |   pinos_buffer_builder_init (&builder); | ||||||
|   pinos_buffer_builder_set_header (&builder, &hdr); |   pinos_buffer_builder_add_header (&builder, &hdr); | ||||||
| 
 | 
 | ||||||
|   p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (mem), &err); |   p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (mem), &err); | ||||||
|   if (p.fd_index == -1) |   if (p.fd_index == -1) | ||||||
|  | @ -393,7 +393,7 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer) | ||||||
|   pinos_main_loop_lock (pinossink->loop); |   pinos_main_loop_lock (pinossink->loop); | ||||||
|   if (pinos_stream_get_state (pinossink->stream) != PINOS_STREAM_STATE_STREAMING) |   if (pinos_stream_get_state (pinossink->stream) != PINOS_STREAM_STATE_STREAMING) | ||||||
|     goto streaming_error; |     goto streaming_error; | ||||||
|   pinos_stream_provide_buffer (pinossink->stream, &pbuf); |   pinos_stream_send_buffer (pinossink->stream, &pbuf); | ||||||
|   pinos_buffer_clear (&pbuf); |   pinos_buffer_clear (&pbuf); | ||||||
|   pinos_main_loop_unlock (pinossink->loop); |   pinos_main_loop_unlock (pinossink->loop); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -43,6 +43,7 @@ | ||||||
| #include <gst/allocators/gstfdmemory.h> | #include <gst/allocators/gstfdmemory.h> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | static GQuark fdpayload_data_quark; | ||||||
| 
 | 
 | ||||||
| GST_DEBUG_CATEGORY_STATIC (pinos_src_debug); | GST_DEBUG_CATEGORY_STATIC (pinos_src_debug); | ||||||
| #define GST_CAT_DEFAULT pinos_src_debug | #define GST_CAT_DEFAULT pinos_src_debug | ||||||
|  | @ -190,6 +191,8 @@ gst_pinos_src_class_init (GstPinosSrcClass * klass) | ||||||
| 
 | 
 | ||||||
|   GST_DEBUG_CATEGORY_INIT (pinos_src_debug, "pinossrc", 0, |   GST_DEBUG_CATEGORY_INIT (pinos_src_debug, "pinossrc", 0, | ||||||
|       "Pinos Source"); |       "Pinos Source"); | ||||||
|  | 
 | ||||||
|  |   fdpayload_data_quark = g_quark_from_static_string ("GstPinosSrcFDPayloadQuark"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
|  | @ -246,55 +249,100 @@ gst_pinos_src_src_fixate (GstBaseSrc * bsrc, GstCaps * caps) | ||||||
|   return caps; |   return caps; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | typedef struct { | ||||||
|  |   GstPinosSrc *src; | ||||||
|  |   PinosPacketFDPayload p; | ||||||
|  | } FDPayloadData; | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | fdpayload_data_destroy (gpointer user_data) | ||||||
|  | { | ||||||
|  |   FDPayloadData *data = user_data; | ||||||
|  |   GstPinosSrc *pinossrc = data->src; | ||||||
|  |   PinosBufferBuilder b; | ||||||
|  |   PinosPacketReleaseFDPayload r; | ||||||
|  |   PinosBuffer pbuf; | ||||||
|  | 
 | ||||||
|  |   r.id = data->p.id; | ||||||
|  | 
 | ||||||
|  |   GST_DEBUG_OBJECT (pinossrc, "destroy %d", r.id); | ||||||
|  | 
 | ||||||
|  |   pinos_buffer_builder_init (&b); | ||||||
|  |   pinos_buffer_builder_add_release_fd_payload (&b, &r); | ||||||
|  |   pinos_buffer_builder_end (&b, &pbuf); | ||||||
|  | 
 | ||||||
|  |   GST_OBJECT_LOCK (pinossrc); | ||||||
|  |   if (pinossrc->stream) | ||||||
|  |     pinos_stream_send_buffer (pinossrc->stream, &pbuf); | ||||||
|  |   GST_OBJECT_UNLOCK (pinossrc); | ||||||
|  | 
 | ||||||
|  |   pinos_buffer_clear (&pbuf); | ||||||
|  | 
 | ||||||
|  |   gst_object_unref (pinossrc); | ||||||
|  |   g_slice_free (FDPayloadData, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| on_new_buffer (GObject    *gobject, | on_new_buffer (GObject    *gobject, | ||||||
|                gpointer    user_data) |                gpointer    user_data) | ||||||
| { | { | ||||||
|   GstPinosSrc *pinossrc = user_data; |   GstPinosSrc *pinossrc = user_data; | ||||||
|   PinosBuffer pbuf; |   PinosBuffer *pbuf; | ||||||
|   const PinosBufferHeader *hdr; |  | ||||||
|   PinosBufferIter it; |   PinosBufferIter it; | ||||||
|   GstBuffer *buf; |   GstBuffer *buf; | ||||||
|   GError *error = NULL; |   GError *error = NULL; | ||||||
| 
 | 
 | ||||||
|   GST_LOG_OBJECT (pinossrc, "got new buffer"); |   GST_LOG_OBJECT (pinossrc, "got new buffer"); | ||||||
|   if (!pinos_stream_capture_buffer (pinossrc->stream, &pbuf)) { |   if (!pinos_stream_peek_buffer (pinossrc->stream, &pbuf)) { | ||||||
|     g_warning ("failed to capture buffer"); |     g_warning ("failed to capture buffer"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   buf = gst_buffer_new (); |   buf = gst_buffer_new (); | ||||||
| 
 | 
 | ||||||
|   hdr = pinos_buffer_get_header (&pbuf, NULL); |   pinos_buffer_iter_init (&it, pbuf); | ||||||
| 
 |  | ||||||
|   if (GST_CLOCK_TIME_IS_VALID (hdr->pts)) { |  | ||||||
|     if (hdr->pts > GST_ELEMENT_CAST (pinossrc)->base_time) |  | ||||||
|       GST_BUFFER_PTS (buf) = hdr->pts - GST_ELEMENT_CAST (pinossrc)->base_time; |  | ||||||
| 
 |  | ||||||
|     if (GST_BUFFER_PTS (buf) + hdr->dts_offset > 0) |  | ||||||
|       GST_BUFFER_DTS (buf) = GST_BUFFER_PTS (buf) + hdr->dts_offset; |  | ||||||
|   } |  | ||||||
|   GST_BUFFER_OFFSET (buf) = hdr->seq; |  | ||||||
| 
 |  | ||||||
|   pinos_buffer_iter_init (&it, &pbuf); |  | ||||||
|   while (pinos_buffer_iter_next (&it)) { |   while (pinos_buffer_iter_next (&it)) { | ||||||
|     switch (pinos_buffer_iter_get_type (&it)) { |     switch (pinos_buffer_iter_get_type (&it)) { | ||||||
|  |       case PINOS_PACKET_TYPE_HEADER: | ||||||
|  |       { | ||||||
|  |         PinosPacketHeader hdr; | ||||||
|  | 
 | ||||||
|  |         if (!pinos_buffer_iter_parse_header  (&it, &hdr)) | ||||||
|  |           goto no_fds; | ||||||
|  | 
 | ||||||
|  |         if (GST_CLOCK_TIME_IS_VALID (hdr.pts)) { | ||||||
|  |           if (hdr.pts > GST_ELEMENT_CAST (pinossrc)->base_time) | ||||||
|  |             GST_BUFFER_PTS (buf) = hdr.pts - GST_ELEMENT_CAST (pinossrc)->base_time; | ||||||
|  | 
 | ||||||
|  |           if (GST_BUFFER_PTS (buf) + hdr.dts_offset > 0) | ||||||
|  |             GST_BUFFER_DTS (buf) = GST_BUFFER_PTS (buf) + hdr.dts_offset; | ||||||
|  |         } | ||||||
|  |         GST_BUFFER_OFFSET (buf) = hdr.seq; | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|       case PINOS_PACKET_TYPE_FD_PAYLOAD: |       case PINOS_PACKET_TYPE_FD_PAYLOAD: | ||||||
|       { |       { | ||||||
|         GstMemory *fdmem = NULL; |         GstMemory *fdmem = NULL; | ||||||
|         PinosPacketFDPayload p; |         FDPayloadData data; | ||||||
|         int fd; |         int fd; | ||||||
| 
 | 
 | ||||||
|         GST_DEBUG ("got fd payload"); |         GST_DEBUG ("got fd payload"); | ||||||
|         pinos_buffer_iter_parse_fd_payload  (&it, &p); |         if (!pinos_buffer_iter_parse_fd_payload  (&it, &data.p)) | ||||||
|         fd = pinos_buffer_get_fd (&pbuf, p.fd_index, &error); |           goto no_fds; | ||||||
|  |         fd = pinos_buffer_get_fd (pbuf, data.p.fd_index, &error); | ||||||
|         if (fd == -1) |         if (fd == -1) | ||||||
|           goto no_fds; |           goto no_fds; | ||||||
| 
 | 
 | ||||||
|         fdmem = gst_fd_allocator_alloc (pinossrc->fd_allocator, fd, |         fdmem = gst_fd_allocator_alloc (pinossrc->fd_allocator, fd, | ||||||
|                   p.offset + p.size, GST_FD_MEMORY_FLAG_NONE); |                   data.p.offset + data.p.size, GST_FD_MEMORY_FLAG_NONE); | ||||||
|         gst_memory_resize (fdmem, p.offset, p.size); |         gst_memory_resize (fdmem, data.p.offset, data.p.size); | ||||||
|         gst_buffer_append_memory (buf, fdmem); |         gst_buffer_append_memory (buf, fdmem); | ||||||
|  | 
 | ||||||
|  |         data.src = gst_object_ref (pinossrc); | ||||||
|  |         gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (fdmem), | ||||||
|  |                                    fdpayload_data_quark, | ||||||
|  |                                    g_slice_dup (FDPayloadData, &data), | ||||||
|  |                                    fdpayload_data_destroy); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       default: |       default: | ||||||
|  | @ -305,8 +353,6 @@ on_new_buffer (GObject    *gobject, | ||||||
|     gst_buffer_unref (pinossrc->current); |     gst_buffer_unref (pinossrc->current); | ||||||
|   pinossrc->current = buf; |   pinossrc->current = buf; | ||||||
| 
 | 
 | ||||||
|   pinos_stream_release_buffer (pinossrc->stream, &pbuf); |  | ||||||
| 
 |  | ||||||
|   pinos_main_loop_signal (pinossrc->loop, FALSE); |   pinos_main_loop_signal (pinossrc->loop, FALSE); | ||||||
| 
 | 
 | ||||||
|   return; |   return; | ||||||
|  | @ -678,7 +724,9 @@ gst_pinos_src_close (GstPinosSrc * pinossrc) | ||||||
|   g_clear_object (&pinossrc->loop); |   g_clear_object (&pinossrc->loop); | ||||||
|   g_clear_object (&pinossrc->ctx); |   g_clear_object (&pinossrc->ctx); | ||||||
|   g_main_context_unref (pinossrc->context); |   g_main_context_unref (pinossrc->context); | ||||||
|  |   GST_OBJECT_LOCK (pinossrc); | ||||||
|   g_clear_object (&pinossrc->stream); |   g_clear_object (&pinossrc->stream); | ||||||
|  |   GST_OBJECT_UNLOCK (pinossrc); | ||||||
| 
 | 
 | ||||||
|   if (pinossrc->current) |   if (pinossrc->current) | ||||||
|     gst_buffer_unref (pinossrc->current); |     gst_buffer_unref (pinossrc->current); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Wim Taymans
						Wim Taymans