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