1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2016 RĂ©mi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
30 #include <vlc_common.h>
31 #include <vlc_block.h>
32 #include <vlc_queue.h>
33 #include <vlc_stream.h>
37 struct vlc_stream_fifo
{
42 struct vlc_stream_fifo_private
{
43 vlc_stream_fifo_t
*writer
;
46 static vlc_stream_fifo_t
*vlc_stream_fifo_Writer(stream_t
*s
)
48 struct vlc_stream_fifo_private
*sys
= vlc_stream_Private(s
);
53 static void vlc_stream_fifo_Destroy(stream_t
*s
)
55 struct vlc_stream_fifo
*writer
= vlc_stream_fifo_Writer(s
);
59 vlc_queue_Lock(&writer
->queue
);
60 block
= vlc_queue_DequeueAllUnlocked(&writer
->queue
);
63 vlc_queue_Unlock(&writer
->queue
);
65 block_ChainRelease(block
);
68 /* Destroy shared state if write end is already closed */
72 static block_t
*vlc_stream_fifo_Block(stream_t
*s
, bool *restrict eof
)
74 struct vlc_stream_fifo
*sys
= vlc_stream_fifo_Writer(s
);
75 block_t
*block
= vlc_queue_DequeueKillable(&sys
->queue
, &sys
->eof
);
83 static int vlc_stream_fifo_Control(stream_t
*s
, int query
, va_list ap
)
90 case STREAM_CAN_FASTSEEK
:
91 case STREAM_CAN_PAUSE
:
92 case STREAM_CAN_CONTROL_PACE
:
93 *va_arg(ap
, bool *) = false;
96 case STREAM_GET_PTS_DELAY
:
97 *va_arg(ap
, vlc_tick_t
*) = DEFAULT_PTS_DELAY
;
106 vlc_stream_fifo_t
*vlc_stream_fifo_New(vlc_object_t
*parent
, stream_t
**reader
)
108 struct vlc_stream_fifo
*writer
= malloc(sizeof (*writer
));
109 if (unlikely(writer
== NULL
))
112 vlc_queue_Init(&writer
->queue
, offsetof (block_t
, p_next
));
115 struct vlc_stream_fifo_private
*sys
;
116 stream_t
*s
= vlc_stream_CustomNew(parent
, vlc_stream_fifo_Destroy
,
117 sizeof (*sys
), "stream");
118 if (unlikely(s
== NULL
)) {
123 sys
= vlc_stream_Private(s
);
124 sys
->writer
= writer
;
125 s
->pf_block
= vlc_stream_fifo_Block
;
127 s
->pf_control
= vlc_stream_fifo_Control
;
132 int vlc_stream_fifo_Queue(vlc_stream_fifo_t
*writer
, block_t
*block
)
134 vlc_queue_Lock(&writer
->queue
);
135 if (likely(!writer
->eof
))
137 vlc_queue_EnqueueUnlocked(&writer
->queue
, block
);
140 vlc_queue_Unlock(&writer
->queue
);
142 if (unlikely(block
!= NULL
))
144 block_Release(block
);
151 ssize_t
vlc_stream_fifo_Write(vlc_stream_fifo_t
*writer
,
152 const void *buf
, size_t len
)
154 block_t
*block
= block_Alloc(len
);
155 if (unlikely(block
== NULL
))
158 memcpy(block
->p_buffer
, buf
, len
);
159 return vlc_stream_fifo_Queue(writer
, block
) ? -1 : (ssize_t
)len
;
162 void vlc_stream_fifo_Close(vlc_stream_fifo_t
*writer
)
166 vlc_queue_Lock(&writer
->queue
);
167 closed
= writer
->eof
;
169 vlc_queue_Signal(&writer
->queue
);
170 vlc_queue_Unlock(&writer
->queue
);
173 /* Destroy shared state if read end is already closed */