VLC 4.0.0-dev
Loading...
Searching...
No Matches
vlc_frame.h
Go to the documentation of this file.
1/*****************************************************************************
2 * vlc_frame.h: frame management functions
3 *****************************************************************************
4 * Copyright (C) 2003 VLC authors and VideoLAN
5 *
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
22
23#ifndef VLC_FRAME_H
24#define VLC_FRAME_H 1
25
26#include <vlc_tick.h>
27#include <vlc_ancillary.h>
28
29
30/**
31 * \defgroup frame Frames
32 * \ingroup input
33 *
34 * Frames of binary data.
35 *
36 * @ref vlc_frame_t is a generic structure to represent a binary blob within VLC.
37 * The primary goal of the structure is to avoid memory copying as data is
38 * passed around. It is notably used between the \ref demux, the packetizer
39 * (if present) and the \ref decoder, and for audio, between the \ref decoder,
40 * the audio filters, and the \ref audio_output.
41 *
42 * @{
43 * \file
44 * Frames definition and functions
45 */
46
47#include <sys/types.h> /* for ssize_t */
48
49/****************************************************************************
50 * frame:
51 ****************************************************************************
52 * - i_flags may not always be set (ie could be 0, even for a key frame
53 * it depends where you receive the buffer (before/after a packetizer
54 * and the demux/packetizer implementations.
55 * - i_dts/i_pts could be VLC_TICK_INVALID, it means no pts/dts
56 * - i_length: length in microsecond of the packet, can be null except in the
57 * sout where it is mandatory.
58 *
59 * - i_buffer number of valid data pointed by p_buffer
60 * you can freely decrease it but never increase it yourself
61 * (use vlc_frame_Realloc)
62 * - p_buffer: pointer over data. You should never overwrite it, you can
63 * only increment it to skip data, in others cases use vlc_frame_Realloc
64 * (don't duplicate yourself in a bigger buffer, vlc_frame_Realloc is
65 * optimised for preheader/postdata increase)
66 ****************************************************************************/
67
68typedef struct vlc_frame_t vlc_frame_t;
70/** The content doesn't follow the last frame, possible some frames in between
71 * have been lost */
72#define VLC_FRAME_FLAG_DISCONTINUITY 0x0001
73/** Intra frame */
74#define VLC_FRAME_FLAG_TYPE_I 0x0002
75/** Inter frame with backward reference only */
76#define VLC_FRAME_FLAG_TYPE_P 0x0004
77/** Inter frame with backward and forward reference */
78#define VLC_FRAME_FLAG_TYPE_B 0x0008
79/** For inter frame when you don't know the real type */
80#define VLC_FRAME_FLAG_TYPE_PB 0x0010
81/** Warn that this frame is a header one */
82#define VLC_FRAME_FLAG_HEADER 0x0020
83/** This frame contains the last part of a sequence */
84#define VLC_FRAME_FLAG_END_OF_SEQUENCE 0x0040
85/** This frame is scrambled */
86#define VLC_FRAME_FLAG_SCRAMBLED 0x0100
87/** This frame has to be decoded but not be displayed */
88#define VLC_FRAME_FLAG_PREROLL 0x0200
89/** This frame is corrupted and/or there is data loss */
90#define VLC_FRAME_FLAG_CORRUPTED 0x0400
91/** This frame is last of its access unit */
92#define VLC_FRAME_FLAG_AU_END 0x0800
93/** This frame contains an interlaced picture with top field stored first */
94#define VLC_FRAME_FLAG_TOP_FIELD_FIRST 0x1000
95/** This frame contains an interlaced picture with bottom field stored first */
96#define VLC_FRAME_FLAG_BOTTOM_FIELD_FIRST 0x2000
97/** This frame contains a single field from interlaced picture. */
98#define VLC_FRAME_FLAG_SINGLE_FIELD 0x4000
100/** This frame contains an interlaced picture */
101#define VLC_FRAME_FLAG_INTERLACED_MASK \
102 (VLC_FRAME_FLAG_TOP_FIELD_FIRST|VLC_FRAME_FLAG_BOTTOM_FIELD_FIRST|VLC_FRAME_FLAG_SINGLE_FIELD)
103
104#define VLC_FRAME_FLAG_TYPE_MASK \
105 (VLC_FRAME_FLAG_TYPE_I|VLC_FRAME_FLAG_TYPE_P|VLC_FRAME_FLAG_TYPE_B|VLC_FRAME_FLAG_TYPE_PB)
106
107/* These are for input core private usage only */
108#define VLC_FRAME_FLAG_CORE_PRIVATE_MASK 0x00ff0000
109#define VLC_FRAME_FLAG_CORE_PRIVATE_SHIFT 16
111/* These are for module private usage only */
112#define VLC_FRAME_FLAG_PRIVATE_MASK 0xff000000
113#define VLC_FRAME_FLAG_PRIVATE_SHIFT 24
117 void (*free)(vlc_frame_t *);
119
120struct vlc_frame_t
124 uint8_t *p_buffer; /**< Payload start */
125 size_t i_buffer; /**< Payload length */
126 uint8_t *p_start; /**< Buffer start */
127 size_t i_size; /**< Buffer total size */
129 uint32_t i_flags;
130 unsigned i_nb_samples; /* Used for audio */
138 const struct vlc_frame_callbacks *cbs;
140
141/**
142 * Initializes a custom frame.
143 *
144 * This function initialize a frame of timed data allocated by custom means.
145 * This allows passing data without copying even if the data has been allocated
146 * with unusual means or outside of LibVLC.
147 *
148 * Normally, frames are allocated and initialized by vlc_frame_Alloc() instead.
149 *
150 * @param frame allocated frame structure to initialize
151 * @param cbs structure of custom callbacks to handle the frame [IN]
152 * @param base start address of the frame data
153 * @param length byte length of the frame data
154 *
155 * @return @c frame (this function cannot fail)
156 */
158 const struct vlc_frame_callbacks *cbs,
159 void *base, size_t length);
160
161/**
162 * Creates a custom frame.
163 *
164 * This function initialize a frame of timed data allocated by custom means.
165 * This allows passing data without copying even if the data has been allocated
166 * with unusual means or outside of LibVLC.
167 *
168 * Normally, frames are allocated and initialized by vlc_frame_Alloc() instead.
169 *
170 * @param cbs structure of custom callbacks to handle the frame [IN]
171 * @param base start address of the frame data
172 * @param length byte length of the frame data
173 *
174 * @return the created frame, or NULL on memory error.
175 */
177 void *base, size_t length);
178
179/**
180 * Allocates a frame.
181 *
182 * Creates a new frame with the requested size.
183 * The frame must be released with vlc_frame_Release().
184 *
185 * @param size size in bytes (possibly zero)
186 * @return the created frame, or NULL on memory error.
187 */
189
190VLC_API vlc_frame_t *vlc_frame_TryRealloc(vlc_frame_t *, ssize_t pre, size_t body) VLC_USED;
191
192/**
193 * Reallocates a frame.
194 *
195 * This function expands, shrinks or moves a data frame.
196 * In many cases, this function can return without any memory allocation by
197 * reusing spare buffer space. Otherwise, a new frame is created and data is
198 * copied.
199 *
200 * @param frame the frame to realloc, which will be freed after the call to
201 * this function
202 * @param pre count of bytes to prepend if positive,
203 * count of leading bytes to discard if negative
204 * @param body new bytes size of the frame
205 *
206 * @return the reallocated frame on success, NULL on error.
207 *
208 * @note Skipping leading bytes can be achieved directly by subtracting from
209 * vlc_frame_t.i_buffer and adding vlc_frame_t.p_buffer.
210 * @note Discard trailing bytes can be achieved directly by subtracting from
211 * vlc_frame_t.i_buffer.
212 * @note On error, the frame is discarded.
213 * To avoid that, use vlc_frame_TryRealloc() instead.
214 */
216vlc_frame_Realloc(vlc_frame_t *frame, ssize_t pre, size_t body) VLC_USED;
217
218/**
219 * Releases a frame.
220 *
221 * This function works for any @ref vlc_frame_t frame, regardless of the way it was
222 * allocated.
223 *
224 * @note
225 * If the frame is in a chain, this function does <b>not</b> release any
226 * subsequent frame in the chain. Use vlc_frame_ChainRelease() for that purpose.
227 *
228 * @param frame frame to release (cannot be NULL)
229 */
231
232/**
233 * Merge two ancillary arrays
234 *
235 * @param frame the frame that hold the destination ancillary array
236 * @param src_array pointer to an ancillary array
237 * @return VLC_SUCCESS in case of success, VLC_ENOMEM in case of alloc error
238 */
239static inline int
241 const vlc_ancillary_array *src_array)
242{
243 return vlc_ancillary_array_Merge(&frame->ancillaries, src_array);
244}
245
246/**
247 * Merge and clear two ancillary arrays
248 *
249 * @param frame the frame that hold the destination ancillary array
250 * @param src_array pointer to the source ancillary array, will point to empty
251 * data after this call.
252 * @return VLC_SUCCESS in case of success, VLC_ENOMEM in case of alloc error
253 */
254static inline int
257{
258 return vlc_ancillary_array_MergeAndClear(&frame->ancillaries, src_array);
259}
260
261/**
262 * Attach an ancillary to the frame
263 *
264 * @warning the ancillary will be released only if the frame is allocated from
265 * a vlc_frame Alloc function (vlc_frame_Alloc(), vlc_frame_mmap_Alloc()...).
266 *
267 * @note Several ancillaries can be attached to a frame, but if two ancillaries
268 * are identified by the same ID, only the last one take precedence.
269 *
270 * @param frame the frame to attach an ancillary
271 * @param ancillary ancillary that will be held by the frame, can't be NULL
272 * @return VLC_SUCCESS in case of success, VLC_ENOMEM in case of alloc error
273 */
274static inline int
275vlc_frame_AttachAncillary(vlc_frame_t *frame, struct vlc_ancillary *ancillary)
277 return vlc_ancillary_array_Insert(&frame->ancillaries, ancillary);
278}
279
280/**
281 * Return the ancillary identified by an ID
282 *
283 * @param frame the frame to read the ancillary from
284 * @param id id of ancillary to request
285 * @return the ancillary or NULL if the ancillary for that particular id is
286 * not present
287 */
288static inline struct vlc_ancillary *
291 return vlc_ancillary_array_Get(&frame->ancillaries, id);
292}
293
294/**
295 * Copy frame properties from src to dst
296 *
297 * Copy i_flags, i_nb_samples, i_dts, i_pts, and i_length.
298 *
299 * @note if src has an ancillary, the ancillary will be copied and refcounted
300 * to dst.
301 *
302 * @param dst the frame to copy properties into
303 * @param src the frame to copy properties from
304 */
307/**
308 * Duplicates a frame.
309 *
310 * Creates a writeable duplicate of a frame.
311 *
312 * @return the duplicate on success, NULL on error.
313 */
315static inline vlc_frame_t *vlc_frame_Duplicate( const vlc_frame_t *frame )
317 vlc_frame_t *p_dup = vlc_frame_Alloc( frame->i_buffer );
318 if( p_dup == NULL )
319 return NULL;
320
321 vlc_frame_CopyProperties( p_dup, frame );
322 memcpy( p_dup->p_buffer, frame->p_buffer, frame->i_buffer );
323
324 return p_dup;
325}
326
327/**
328 * Wraps heap in a frame.
329 *
330 * Creates a @ref vlc_frame_t out of an existing heap allocation.
331 * This is provided by LibVLC so that manually heap-allocated frames can safely
332 * be deallocated even after the origin plugin has been unloaded from memory.
333 *
334 * When vlc_frame_Release() is called, VLC will free() the specified pointer.
335 *
336 * @param addr base address of the heap allocation (will be free()'d)
337 * @param length bytes length of the heap allocation
338 * @return NULL in case of error (ptr free()'d in that case), or a valid
339 * vlc_frame_t pointer.
340 */
342
343/**
344 * Wraps a memory mapping in a frame
345 *
346 * Creates a @ref vlc_frame_t from a virtual address memory mapping (mmap).
347 * This is provided by LibVLC so that mmap frames can safely be deallocated
348 * even after the allocating plugin has been unloaded from memory.
349 *
350 * @param addr base address of the mapping (as returned by mmap)
351 * @param length length (bytes) of the mapping (as passed to mmap)
352 * @return NULL if addr is MAP_FAILED, or an error occurred (in the later
353 * case, munmap(addr, length) is invoked before returning).
354 */
356
357/**
358 * Wraps a System V memory segment in a frame
359 *
360 * Creates a @ref vlc_frame_t from a System V shared memory segment (shmget()).
361 * This is provided by LibVLC so that segments can safely be deallocated
362 * even after the allocating plugin has been unloaded from memory.
363 *
364 * @param addr base address of the segment (as returned by shmat())
365 * @param length length (bytes) of the segment (as passed to shmget())
366 * @return NULL if an error occurred (in that case, shmdt(addr) is invoked
367 * before returning NULL).
368 */
369VLC_API vlc_frame_t * vlc_frame_shm_Alloc(void *addr, size_t length) VLC_USED VLC_MALLOC;
370
371/**
372 * Maps a file handle in memory.
373 *
374 * Loads a file into a frame of memory through a file descriptor.
375 * If possible a private file mapping is created. Otherwise, the file is read
376 * normally. This function is a cancellation point.
377 *
378 * @note On 32-bits platforms,
379 * this function will not work for very large files,
380 * due to memory space constraints.
381 *
382 * @param fd file descriptor to load from
383 * @param write If true, request a read/write private mapping.
384 * If false, request a read-only potentially shared mapping.
385 *
386 * @return a new frame with the file content at p_buffer, and file length at
387 * i_buffer (release it with vlc_frame_Release()), or NULL upon error (see errno).
388 */
390
391/**
392 * Maps a file in memory.
393 *
394 * Loads a file into a frame of memory from a path to the file.
395 * See also vlc_frame_File().
396 *
397 * @param path the file path to load the memory block from
398 * @param write If true, request a read/write private mapping.
399 * If false, request a read-only potentially shared mapping.
400 */
402vlc_frame_FilePath(const char *path, bool write)
404
405static inline void vlc_frame_Cleanup (void *frame)
408}
409#define vlc_frame_cleanup_push( frame ) vlc_cleanup_push (vlc_frame_Cleanup, frame)
411/**
412 * \defgroup vlc_frame_chain Frame chain
413 * @{
414 */
415
416/**
417 * Appends a @ref vlc_frame_t to the chain
418 *
419 * The given frame is appended to the last frame of the given chain.
420 *
421 * @attention
422 * Using this function on long chains or repeatedly calling it
423 * to append a lot of frames can be slow, as it has to iterate the
424 * whole chain to append the frame.
425 * In these cases @ref vlc_frame_ChainLastAppend should be used.
426 *
427 * @param pp_list Pointer to the vlc_frame_t chain
428 * @param frame The vlc_frame_t to append (can be NULL)
429 *
430 * @see vlc_frame_ChainLastAppend()
431 *
432 * Example:
433 * @code{.c}
434 * vlc_frame_t *p_chain = NULL;
435 *
436 * vlc_frame_ChainAppend(&p_chain, p_frame);
437 * @endcode
438 */
439static inline void vlc_frame_ChainAppend( vlc_frame_t **pp_list, vlc_frame_t *frame )
441 if( *pp_list == NULL )
442 {
443 *pp_list = frame;
444 }
445 else
446 {
447 vlc_frame_t *p = *pp_list;
448
449 while( p->p_next ) p = p->p_next;
450 p->p_next = frame;
451 }
452}
453
454/**
455 * Appends a @ref vlc_frame_t to the last frame pointer and update it
456 *
457 * Uses a pointer over a pointer to p_next of the last frame of the frame chain
458 * to append a frame at the end of the chain and updates the pointer to the new
459 * last frame's @c p_next. If the appended frame is itself a chain, it is iterated
460 * till the end to correctly update @c ppp_last.
461 *
462 * @param[in,out] ppp_last Pointer to pointer to the end of the chain
463 * (The vlc_frame_t::p_next of the last vlc_frame_t in the chain)
464 * @param frame The vlc_frame_t to append
465 *
466 * Example:
467 * @code{.c}
468 * vlc_frame_t *p_frame = NULL;
469 * vlc_frame_t **pp_frame_last = &p_frame;
470 *
471 * vlc_frame_ChainLastAppend(&pp_frame_last, p_other_frame);
472 * @endcode
473 */
474static inline void vlc_frame_ChainLastAppend( vlc_frame_t ***ppp_last, vlc_frame_t *frame )
476 vlc_frame_t *p_last = frame;
477
478 **ppp_last = frame;
479
480 while( p_last->p_next ) p_last = p_last->p_next;
481 *ppp_last = &p_last->p_next;
482}
483
484/**
485 * Releases a chain of blocks
486 *
487 * The frame pointed to by frame and all following frames in the
488 * chain are released.
489 *
490 * @param frame Pointer to first vlc_frame_t of the chain to release
491 *
492 * @see vlc_frame_Release()
493 */
494static inline void vlc_frame_ChainRelease( vlc_frame_t *frame )
496 while( frame )
497 {
498 vlc_frame_t *p_next = frame->p_next;
499 vlc_frame_Release( frame );
500 frame = p_next;
501 }
502}
503
504/**
505 * Extracts data from a chain of frames
506 *
507 * Copies the specified amount of data from the chain into the given buffer.
508 * If the data in the chain is less than the maximum amount given, the remainder
509 * of the buffer is not modified.
510 *
511 * @param p_list Pointer to the first vlc_frame_t of the chain to copy from
512 * @param[out] p_data Destination buffer to copy the data to
513 * @param i_max Number of bytes to copy
514 * @return Number of bytes actually copied
515 *
516 * @see vlc_frame_ChainGather()
517 */
518static size_t vlc_frame_ChainExtract( vlc_frame_t *p_list, void *p_data, size_t i_max )
520 size_t i_total = 0;
521 uint8_t *p = (uint8_t*)p_data;
522
523 while( p_list && i_max )
524 {
525 size_t i_copy = __MIN( i_max, p_list->i_buffer );
526 memcpy( p, p_list->p_buffer, i_copy );
527 i_max -= i_copy;
528 i_total += i_copy;
529 p += i_copy;
530
531 p_list = p_list->p_next;
532 }
533 return i_total;
534}
535
536/**
537 * Retrieves chain properties
538 *
539 * Can be used to retrieve count of frames, number of bytes and the duration
540 * of the chain.
541 *
542 * @param p_list Pointer to the first vlc_frame_t of the chain
543 * @param[out] pi_count Pointer to count of frames in the chain (may be NULL)
544 * @param[out] pi_size Pointer to number of bytes in the chain (may be NULL)
545 * @param[out] pi_length Pointer to length (duration) of the chain (may be NULL)
546 */
547static inline void vlc_frame_ChainProperties( const vlc_frame_t *p_list, int *pi_count, size_t *pi_size, vlc_tick_t *pi_length )
549 size_t i_size = 0;
550 vlc_tick_t i_length = 0;
551 int i_count = 0;
552
553 while( p_list )
554 {
555 i_size += p_list->i_buffer;
556 i_length += p_list->i_length;
557 i_count++;
558
559 p_list = p_list->p_next;
560 }
561
562 if( pi_size )
563 *pi_size = i_size;
564 if( pi_length )
565 *pi_length = i_length;
566 if( pi_count )
567 *pi_count = i_count;
568}
569
570/**
571 * Gathers a chain into a single vlc_frame_t
572 *
573 * All frames in the chain are gathered into a single vlc_frame_t and the
574 * original chain is released.
575 *
576 * @param p_list Pointer to the first vlc_frame_t of the chain to gather
577 * @return Returns a pointer to a new vlc_frame_t or NULL if the frame can not
578 * be allocated, in which case the original chain is not released.
579 * If the chain pointed to by p_list is already gathered, a pointer
580 * to it is returned and no new frame will be allocated.
581 *
582 * @see vlc_frame_ChainExtract()
583 */
584static inline vlc_frame_t *vlc_frame_ChainGather( vlc_frame_t *p_list )
586 size_t i_total = 0;
587 vlc_tick_t i_length = 0;
588 vlc_frame_t *g;
589
590 if( p_list->p_next == NULL )
591 return p_list; /* Already gathered */
592
593 vlc_frame_ChainProperties( p_list, NULL, &i_total, &i_length );
594
595 g = vlc_frame_Alloc( i_total );
596 if( !g )
597 return NULL;
598 vlc_frame_ChainExtract( p_list, g->p_buffer, g->i_buffer );
599
600 g->i_flags = p_list->i_flags;
601 g->i_pts = p_list->i_pts;
602 g->i_dts = p_list->i_dts;
603 g->i_length = i_length;
604
605 /* free p_list */
606 vlc_frame_ChainRelease( p_list );
607 return g;
608}
609
610/**
611 * @}
612 * \defgroup block_fifo Block FIFO
613 * Thread-safe block queue functions
614 * @{
615 */
616
617#include <vlc_queue.h>
618
619/**
620 * Creates a thread-safe FIFO queue of blocks.
621 *
622 * See also vlc_fifo_Put() and vlc_fifo_Get().
623 * The created queue must be deleted with vlc_fifo_Delete().
624 *
625 * @return the FIFO or NULL on memory error
626 */
628
629/**
630 * Delete a FIFO created by vlc_fifo_New().
631 *
632 * @note Any queued blocks are also deleted.
633 * @warning No other threads may be using the FIFO when this function is
634 * called. Otherwise, undefined behaviour will occur.
635 */
637
638/**
639 * Dequeue the first block from the FIFO. If necessary, wait until there is
640 * one block in the queue. This function is (always) cancellation point.
641 *
642 * @return a valid block
643 */
645
646/**
647 * Peeks the first block in the FIFO.
648 *
649 * @warning This function leaves the block in the FIFO.
650 * You need to protect against concurrent threads who could dequeue the block.
651 * Preferably, there should be only one thread reading from the FIFO.
652 *
653 * @warning This function is undefined if the FIFO is empty.
654 *
655 * @return a valid block.
656 */
658
659static inline vlc_queue_t *vlc_fifo_queue(const vlc_fifo_t *fifo)
661 return (vlc_queue_t *)fifo;
662}
663
664/**
665 * Locks a block FIFO.
666 *
667 * No more than one thread can lock the FIFO at any given
668 * time, and no other thread can modify the FIFO while it is locked.
669 * vlc_fifo_Unlock() releases the lock.
670 *
671 * @note If the FIFO is already locked by another thread, this function waits.
672 * This function is not a cancellation point.
673 *
674 * @warning Recursively locking a single FIFO is undefined. Locking more than
675 * one FIFO at a time may lead to lock inversion; mind the locking order.
676 */
677static inline void vlc_fifo_Lock(vlc_fifo_t *fifo)
680}
681
682/**
683 * Unlocks a block FIFO.
684 *
685 * The calling thread must have locked the FIFO previously with
686 * vlc_fifo_Lock(). Otherwise, the behaviour is undefined.
687 *
688 * @note This function is not a cancellation point.
689 */
690static inline void vlc_fifo_Unlock(vlc_fifo_t *fifo)
693}
694
695/**
696 * Wakes up one thread waiting on the FIFO, if any.
697 *
698 * @note This function is not a cancellation point.
699 *
700 * @warning For race-free operations, the FIFO should be locked by the calling
701 * thread. The function can be called on a unlocked FIFO however.
702 */
703static inline void vlc_fifo_Signal(vlc_fifo_t *fifo)
706}
707
708/**
709 * Waits on the FIFO.
710 *
711 * Atomically unlocks the FIFO and waits until one thread signals the FIFO,
712 * then locks the FIFO again. A signal can be sent by queueing a block to the
713 * previously empty FIFO or by calling vlc_fifo_Signal() directly.
714 * This function may also return spuriously at any moment.
715 *
716 * @note This function is a cancellation point. In case of cancellation, the
717 * the FIFO will be locked before cancellation cleanup handlers are processed.
718 */
719static inline void vlc_fifo_Wait(vlc_fifo_t *fifo)
722}
723
724static inline void vlc_fifo_WaitCond(vlc_fifo_t *fifo, vlc_cond_t *condvar)
726 vlc_queue_t *q = vlc_fifo_queue(fifo);
727
728 vlc_cond_wait(condvar, &q->lock);
729}
730
731/**
732 * Queues a linked-list of blocks into a locked FIFO.
733 *
734 * @param fifo a fifo object locked with ::vlc_fifo_Lock()
735 * @param block the head of the list of blocks
736 * (if NULL, this function has no effects)
737 *
738 * @note This function is not a cancellation point.
739 *
740 * @warning The FIFO must be locked by the calling thread using
741 * vlc_fifo_Lock(). Otherwise behaviour is undefined.
742 */
744
745/**
746 * Dequeues the first block from a locked FIFO, if any.
747 *
748 * @note This function is not a cancellation point.
749 *
750 * @warning The FIFO must be locked by the calling thread using
751 * vlc_fifo_Lock(). Otherwise behaviour is undefined.
752 *
753 * @return the first block in the FIFO or NULL if the FIFO is empty
754 */
756
757/**
758 * Dequeues the all blocks from a locked FIFO.
759 *
760 * This is equivalent to calling vlc_fifo_DequeueUnlocked() repeatedly until
761 * the FIFO is emptied, but this function is much faster.
762 *
763 * @note This function is not a cancellation point.
764 *
765 * @warning The FIFO must be locked by the calling thread using
766 * vlc_fifo_Lock(). Otherwise behaviour is undefined.
767 *
768 * @return a linked-list of all blocks in the FIFO (possibly NULL)
769 */
771
772/**
773 * Counts blocks in a FIFO.
774 *
775 * Checks how many blocks are queued in a locked FIFO.
776 *
777 * @note This function is not cancellation point.
778 *
779 * @warning The FIFO must be locked by the calling thread using
780 * vlc_fifo_Lock(). Otherwise behaviour is undefined.
781 *
782 * @return the number of blocks in the FIFO (zero if it is empty)
783 */
785
786/**
787 * Counts bytes in a FIFO.
788 *
789 * Checks how many bytes are queued in a locked FIFO.
790 *
791 * @note This function is not cancellation point.
792 *
793 * @warning The FIFO must be locked by the calling thread using
794 * vlc_fifo_Lock(). Otherwise behaviour is undefined.
795 *
796 * @return the total number of bytes
797 *
798 * @note Zero bytes does not necessarily mean that the FIFO is empty since
799 * a block could contain zero bytes. Use vlc_fifo_GetCount() to determine if
800 * a FIFO is empty.
801 */
803
804/**
805 * Checks whether the vlc_fifo_t object is being locked.
806 *
807 * This function checks if the calling thread holds a given vlc_fifo_t
808 * object. It has no side effects and is essentially intended for run-time
809 * debugging.
810 *
811 * @note This function is the vlc_fifo_t equivalent of vlc_mutex_held.
812 *
813 * @note To assert that the calling thread holds a lock, the helper macro
814 * vlc_fifo_Assert() should be used instead of this function.
815 *
816 * @retval false the fifo is not locked by the calling thread
817 * @retval true the fifo is locked by the calling thread
818 */
819VLC_API bool vlc_fifo_Held(const vlc_fifo_t *fifo) VLC_USED;
820
821/**
822 * Asserts that a vlc_fifo_t is locked by the calling thread.
823 */
824#define vlc_fifo_Assert(fifo) assert(vlc_fifo_Held(fifo))
826VLC_USED static inline bool vlc_fifo_IsEmpty(const vlc_fifo_t *fifo)
828 return vlc_queue_IsEmpty(vlc_fifo_queue(fifo));
829}
830
831static inline void vlc_fifo_Cleanup(void *fifo)
834}
835#define vlc_fifo_CleanupPush(fifo) vlc_cleanup_push(vlc_fifo_Cleanup, fifo)
837/**
838 * Clears all blocks in a FIFO.
839 */
840static inline void vlc_fifo_Empty(vlc_fifo_t *fifo)
842 vlc_frame_t *block;
843
844 vlc_fifo_Lock(fifo);
845 block = vlc_fifo_DequeueAllUnlocked(fifo);
846 vlc_fifo_Unlock(fifo);
848}
849
850/**
851 * Immediately queue one block at the end of a FIFO.
852 *
853 * @param fifo queue
854 * @param block head of a block list to queue (may be NULL)
855 */
856static inline void vlc_fifo_Put(vlc_fifo_t *fifo, vlc_frame_t *block)
858 vlc_fifo_Lock(fifo);
859 vlc_fifo_QueueUnlocked(fifo, block);
860 vlc_fifo_Unlock(fifo);
861}
862
863/* FIXME: not (really) thread-safe */
865static inline size_t vlc_fifo_Size (vlc_fifo_t *fifo)
867 size_t size;
868
869 vlc_fifo_Lock(fifo);
870 size = vlc_fifo_GetBytes(fifo);
871 vlc_fifo_Unlock(fifo);
872 return size;
873}
874
875/* FIXME: not (really) thread-safe */
877static inline size_t vlc_fifo_Count (vlc_fifo_t *fifo)
879 size_t depth;
880
881 vlc_fifo_Lock(fifo);
882 depth = vlc_fifo_GetCount(fifo);
883 vlc_fifo_Unlock(fifo);
884 return depth;
885}
886
887/** @} */
888
889/** @} */
890
891#endif /* VLC_FRAME_H */
#define VLC_USED
Definition fourcc_gen.c:32
#define VLC_API
Definition fourcc_gen.c:31
#define p(t)
uint32_t vlc_ancillary_id
ID of an ancillary.
Definition vlc_ancillary.h:74
int vlc_ancillary_array_Insert(vlc_ancillary_array *array, struct vlc_ancillary *ancillary)
Insert a new ancillary in the array.
Definition ancillary.c:122
int vlc_ancillary_array_Merge(vlc_ancillary_array *dst_array, const vlc_ancillary_array *src_array)
Merge two ancillary arrays.
Definition ancillary.c:91
int vlc_ancillary_array_MergeAndClear(vlc_ancillary_array *dst_array, vlc_ancillary_array *src_array)
Merge and clear two ancillary arrays.
Definition ancillary.c:105
struct vlc_ancillary * vlc_ancillary_array_Get(const vlc_ancillary_array *array, vlc_ancillary_id id)
Get a specific ancillary from the array.
Definition ancillary.c:147
static void vlc_fifo_Empty(vlc_fifo_t *fifo)
Clears all blocks in a FIFO.
Definition vlc_frame.h:841
vlc_fifo_t * vlc_fifo_New(void)
Creates a thread-safe FIFO queue of blocks.
Definition fifo.c:95
static size_t vlc_fifo_Size(vlc_fifo_t *fifo)
Definition vlc_frame.h:866
static void vlc_fifo_Lock(vlc_fifo_t *fifo)
Locks a block FIFO.
Definition vlc_frame.h:678
static void vlc_fifo_WaitCond(vlc_fifo_t *fifo, vlc_cond_t *condvar)
Definition vlc_frame.h:725
size_t vlc_fifo_GetBytes(const vlc_fifo_t *)
Counts bytes in a FIFO.
Definition fifo.c:58
vlc_frame_t * vlc_fifo_Show(vlc_fifo_t *)
Peeks the first block in the FIFO.
Definition fifo.c:133
static void vlc_fifo_Wait(vlc_fifo_t *fifo)
Waits on the FIFO.
Definition vlc_frame.h:720
static void vlc_fifo_Unlock(vlc_fifo_t *fifo)
Unlocks a block FIFO.
Definition vlc_frame.h:691
bool vlc_fifo_Held(const vlc_fifo_t *fifo)
Checks whether the vlc_fifo_t object is being locked.
Definition fifo.c:47
vlc_frame_t * vlc_fifo_DequeueUnlocked(vlc_fifo_t *)
Dequeues the first block from a locked FIFO, if any.
Definition fifo.c:74
static vlc_queue_t * vlc_fifo_queue(const vlc_fifo_t *fifo)
Definition vlc_frame.h:660
void vlc_fifo_QueueUnlocked(vlc_fifo_t *fifo, vlc_frame_t *block)
Queues a linked-list of blocks into a locked FIFO.
Definition fifo.c:64
static void vlc_fifo_Put(vlc_fifo_t *fifo, vlc_frame_t *block)
Immediately queue one block at the end of a FIFO.
Definition vlc_frame.h:857
size_t vlc_fifo_GetCount(const vlc_fifo_t *)
Counts blocks in a FIFO.
Definition fifo.c:52
static void vlc_fifo_Signal(vlc_fifo_t *fifo)
Wakes up one thread waiting on the FIFO, if any.
Definition vlc_frame.h:704
vlc_frame_t * vlc_fifo_Get(vlc_fifo_t *)
Dequeue the first block from the FIFO.
Definition fifo.c:114
static size_t vlc_fifo_Count(vlc_fifo_t *fifo)
Definition vlc_frame.h:878
void vlc_fifo_Delete(vlc_fifo_t *)
Delete a FIFO created by vlc_fifo_New().
Definition fifo.c:108
vlc_frame_t * vlc_fifo_DequeueAllUnlocked(vlc_fifo_t *)
Dequeues the all blocks from a locked FIFO.
Definition fifo.c:88
static bool vlc_fifo_IsEmpty(const vlc_fifo_t *fifo)
Definition vlc_frame.h:827
static void vlc_fifo_Cleanup(void *fifo)
Definition vlc_frame.h:832
#define VLC_MALLOC
Definition vlc_common.h:157
#define VLC_DEPRECATED
Definition vlc_common.h:158
void vlc_cond_wait(vlc_cond_t *cond, vlc_mutex_t *mutex)
Waits on a condition variable.
Definition threads.c:280
void vlc_frame_Release(vlc_frame_t *frame)
Releases a frame.
Definition frame.c:158
vlc_frame_t * vlc_frame_Alloc(size_t size)
Allocates a frame.
Definition frame.c:119
static vlc_frame_t * vlc_frame_Duplicate(const vlc_frame_t *frame)
Duplicates a frame.
Definition vlc_frame.h:316
vlc_frame_t * vlc_frame_FilePath(const char *path, bool write)
Maps a file in memory.
Definition frame.c:549
vlc_frame_t * vlc_frame_shm_Alloc(void *addr, size_t length)
Wraps a System V memory segment in a frame.
Definition frame.c:386
static void vlc_frame_Cleanup(void *frame)
Definition vlc_frame.h:406
vlc_frame_t * vlc_frame_New(const struct vlc_frame_callbacks *cbs, void *base, size_t length)
Creates a custom frame.
Definition frame.c:78
static int vlc_frame_MergeAndClearAncillaries(vlc_frame_t *frame, vlc_ancillary_array *src_array)
Merge and clear two ancillary arrays.
Definition vlc_frame.h:256
vlc_frame_t * vlc_frame_Init(vlc_frame_t *frame, const struct vlc_frame_callbacks *cbs, void *base, size_t length)
Initializes a custom frame.
static struct vlc_ancillary * vlc_frame_GetAncillary(vlc_frame_t *frame, vlc_ancillary_id id)
Return the ancillary identified by an ID.
Definition vlc_frame.h:290
void vlc_frame_CopyProperties(vlc_frame_t *dst, const vlc_frame_t *src)
Copy frame properties from src to dst.
vlc_frame_t * vlc_frame_Realloc(vlc_frame_t *frame, ssize_t pre, size_t body)
Reallocates a frame.
Definition frame.c:260
vlc_frame_t * vlc_frame_heap_Alloc(void *addr, size_t length)
Wraps heap in a frame.
Definition frame.c:279
vlc_frame_t * vlc_frame_mmap_Alloc(void *addr, size_t length)
Wraps a memory mapping in a frame.
Definition frame.c:320
static int vlc_frame_MergeAncillaries(vlc_frame_t *frame, const vlc_ancillary_array *src_array)
Merge two ancillary arrays.
Definition vlc_frame.h:241
vlc_frame_t * vlc_frame_File(int fd, bool write)
Maps a file handle in memory.
Definition frame.c:402
static int vlc_frame_AttachAncillary(vlc_frame_t *frame, struct vlc_ancillary *ancillary)
Attach an ancillary to the frame.
Definition vlc_frame.h:276
vlc_frame_t * vlc_frame_TryRealloc(vlc_frame_t *, ssize_t pre, size_t body)
Definition frame.c:185
static void vlc_queue_Lock(vlc_queue_t *q)
Locks a queue.
Definition vlc_queue.h:88
static void vlc_queue_Wait(vlc_queue_t *q)
Waits for a queue entry.
Definition vlc_queue.h:122
static void vlc_queue_Signal(vlc_queue_t *q)
Wakes one thread waiting for a queue entry up.
Definition vlc_queue.h:108
static void vlc_queue_Unlock(vlc_queue_t *q)
Unlocks a queue.
Definition vlc_queue.h:100
static bool vlc_queue_IsEmpty(const vlc_queue_t *q)
Checks if a queue is empty (without locking).
Definition vlc_queue.h:179
static void vlc_frame_ChainLastAppend(vlc_frame_t ***ppp_last, vlc_frame_t *frame)
Appends a vlc_frame_t to the last frame pointer and update it.
Definition vlc_frame.h:475
static void vlc_frame_ChainProperties(const vlc_frame_t *p_list, int *pi_count, size_t *pi_size, vlc_tick_t *pi_length)
Retrieves chain properties.
Definition vlc_frame.h:548
static void vlc_frame_ChainAppend(vlc_frame_t **pp_list, vlc_frame_t *frame)
Appends a vlc_frame_t to the chain.
Definition vlc_frame.h:440
static void vlc_frame_ChainRelease(vlc_frame_t *frame)
Releases a chain of blocks.
Definition vlc_frame.h:495
static size_t vlc_frame_ChainExtract(vlc_frame_t *p_list, void *p_data, size_t i_max)
Extracts data from a chain of frames.
Definition vlc_frame.h:519
static vlc_frame_t * vlc_frame_ChainGather(vlc_frame_t *p_list)
Gathers a chain into a single vlc_frame_t.
Definition vlc_frame.h:585
Definition vlc_ancillary.h:67
Definition ancillary.c:31
Condition variable.
Definition vlc_threads.h:270
Internal state for block queues.
Definition fifo.c:39
Definition vlc_frame.h:117
void(* free)(vlc_frame_t *)
Definition vlc_frame.h:118
Definition vlc_frame.h:122
uint8_t * p_start
Buffer start.
Definition vlc_frame.h:127
vlc_tick_t i_dts
Definition vlc_frame.h:134
vlc_frame_t * p_next
Definition vlc_frame.h:123
vlc_tick_t i_length
Definition vlc_frame.h:135
uint8_t * p_buffer
Payload start.
Definition vlc_frame.h:125
vlc_ancillary_array ancillaries
Definition vlc_frame.h:137
vlc_tick_t i_pts
Definition vlc_frame.h:133
unsigned i_nb_samples
Definition vlc_frame.h:131
uint32_t i_flags
Definition vlc_frame.h:130
size_t i_size
Buffer total size.
Definition vlc_frame.h:128
const struct vlc_frame_callbacks * cbs
Definition vlc_frame.h:139
size_t i_buffer
Payload length.
Definition vlc_frame.h:126
Thread-safe queue (a.k.a.
Definition vlc_queue.h:46
vlc_mutex_t lock
Definition vlc_queue.h:50
Ancillary definition and functions.
This file is a collection of common definitions and types.
int64_t vlc_tick_t
High precision date or time interval.
Definition vlc_tick.h:48