Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (6)
/*****************************************************************************
* vlc_ancillary.h: ancillary management functions
*****************************************************************************
* Copyright (C) 2021 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_ANCILLARY_H
#define VLC_ANCILLARY_H 1
/**
* \defgroup ancillary Ancillary
* \ingroup input
*
* Ancillary that can be attached to any vlc_frame_t or picture_t.
*
* Ancillaries can be created from:
* - packetized demuxer modules,
* - packetizer modules,
* - decoder modules.
*
* @warning Ancillaries should not be attached from a non packetized demuxer
* module since the attachment to the vlc_frame will be lost by the packetizer
* module that will be automatically inserted.
*
* Ancillaries are automatically forwarded from a vlc_frame_t to an other
* vlc_frame_t and from a picture_t to an other picture_t. This allow to keep
* ancillaries untouched when audio filters or video filters are used (these
* filters don't have to know about the ancillary).
*
* Ancillary readers can be either:
* - A decoder module,
* - An audio output,
* - A video output,
* - A video or audio filter.
*
* @{
* \file
* Ancillary definition and functions
*/
/**
* Ancillary opaque struct, refcounted struct that hold user data with a free
* callback.
*/
struct vlc_ancillary;
/**
* ID of an ancillary. Each ancillary user can create its own unique ID via
* VLC_ANCILLARY_ID.
*/
typedef uint32_t vlc_ancillary_id;
#define VLC_ANCILLARY_ID(a,b,c,d) VLC_FOURCC(a,b,c,d)
/**
* Callback to free an ancillary data
*/
typedef void (*vlc_ancillary_free_cb)(void *data);
/**
* Create an ancillary
*
* @param data an opaque ancillary, can't be NULL
* @param id id of ancillary
* @param free_cb callback to release the data, can be NULL
* @return a valid vlc_ancillary pointer or NULL in case of allocation error
*/
VLC_API struct vlc_ancillary *
vlc_ancillary_CreateWithFreeCb(void *data, vlc_ancillary_id id,
vlc_ancillary_free_cb free_cb);
/**
* Helper to create an ancillary holding an allocated data
*/
static inline struct vlc_ancillary *
vlc_ancillary_Create(void *data, vlc_ancillary_id id)
{
return vlc_ancillary_CreateWithFreeCb(data, id, free);
}
/**
* Release an ancillary
*
* If the refcount reachs 0, the free_cb provided by
* vlc_ancillary_CreateWithFreeCb() is called.
*
* @param ancillary ancillary to release
*/
VLC_API void
vlc_ancillary_Release(struct vlc_ancillary *ancillary);
/**
* Hold an ancillary
*
* @param ancillary ancillary to hold
* @return the same ancillary
*/
VLC_API struct vlc_ancillary *
vlc_ancillary_Hold(struct vlc_ancillary *ancillary);
VLC_API void *
vlc_ancillary_GetData(const struct vlc_ancillary *ancillary);
/** @} */
/** @} */
#endif /* VLC_ANCILLARY_H */
......@@ -23,6 +23,9 @@
#ifndef VLC_FRAME_H
#define VLC_FRAME_H 1
struct vlc_ancillary;
typedef uint32_t vlc_ancillary_id;
/**
* \defgroup frame Frames
* \ingroup input
......@@ -131,6 +134,10 @@ struct vlc_frame_t
vlc_tick_t i_dts;
vlc_tick_t i_length;
/** Private ancillary struct. Don't use it directly, but use it via
* vlc_frame_AttachAncillary() and vlc_frame_GetAncillary(). */
struct vlc_ancillary **priv_ancillaries;
const struct vlc_frame_callbacks *cbs;
};
......@@ -204,14 +211,44 @@ VLC_API vlc_frame_t *vlc_frame_Realloc(vlc_frame_t *, ssize_t pre, size_t body)
*/
VLC_API void vlc_frame_Release(vlc_frame_t *frame);
static inline void vlc_frame_CopyProperties( vlc_frame_t *dst, const vlc_frame_t *src )
{
dst->i_flags = src->i_flags;
dst->i_nb_samples = src->i_nb_samples;
dst->i_dts = src->i_dts;
dst->i_pts = src->i_pts;
dst->i_length = src->i_length;
}
/**
* Attach an ancillary to the frame
*
* @warning the ancillary will be released only if the frame is allocated from
* a vlc_frame Alloc function (vlc_frame_Alloc(), vlc_frame_mmap_Alloc()...).
*
* @note Several ancillaries can be attached to a frame, but if two ancillaries
* are identified by the same ID, only the last one take precedence.
*
* @param frame the frame to attach an ancillary
* @param ancillary ancillary that will be held by the frame, can't be NULL
* @return VLC_SUCCESS in case of success, VLC_ENOMEM in case of alloc error
*/
VLC_API int
vlc_frame_AttachAncillary(vlc_frame_t *frame, struct vlc_ancillary *ancillary);
/**
* Return the ancillary identified by an ID
*
* @param id id of ancillary to request
* @return the ancillary or NULL if the ancillary for that particular id is
* not present
*/
VLC_API struct vlc_ancillary *
vlc_frame_GetAncillary(vlc_frame_t *frame, vlc_ancillary_id id);
/**
* Copy frame properties from src to dst
*
* Copy i_flags, i_nb_samples, i_dts, i_pts, and i_length.
*
* @note if src has an ancillary, the ancillary will be copied and refcounted
* to dst.
*
* @param dst the frame to copy properties into
* @param src the frame to copy properties from
*/
VLC_API void vlc_frame_CopyProperties( vlc_frame_t *dst, const vlc_frame_t *src );
/**
* Duplicates a frame.
......
......@@ -28,6 +28,9 @@
#include <assert.h>
#include <vlc_atomic.h>
struct vlc_ancillary;
typedef uint32_t vlc_ancillary_id;
/**
* \defgroup picture Generic picture API
* \ingroup output
......@@ -411,6 +414,33 @@ VLC_API void picture_Copy( picture_t *p_dst, const picture_t *p_src );
*/
VLC_API picture_t *picture_Clone(picture_t *pic);
/**
* Attach an ancillary to the picture
*
* @warning the ancillary will be released only if the picture is created from
* picture_New(), and picture_Clone().
*
* @note Several ancillaries can be attached to a picture, but if two
* ancillaries are identified by the same ID, only the last one take
* precedence.
*
* @param pic the picture to attach an ancillary
* @param ancillary ancillary that will be held by the frame, can't be NULL
* @return VLC_SUCCESS in case of success, VLC_ENOMEM in case of alloc error
*/
VLC_API int
picture_AttachAncillary(picture_t *pic, struct vlc_ancillary *ancillary);
/**
* Return the ancillary identified by an ID
*
* @param id id of ancillary to request
* @return the ancillary or NULL if the ancillary for that particular id is
* not present
*/
VLC_API struct vlc_ancillary *
picture_GetAncillary(picture_t *pic, vlc_ancillary_id id);
/**
* This function will export a picture to an encoded bitstream.
*
......
......@@ -25,6 +25,7 @@ pluginsinclude_HEADERS = \
../include/vlc_access.h \
../include/vlc_actions.h \
../include/vlc_addons.h \
../include/vlc_ancillary.h \
../include/vlc_aout.h \
../include/vlc_aout_volume.h \
../include/vlc_arrays.h \
......@@ -359,6 +360,8 @@ libvlccore_la_SOURCES = \
text/iso_lang.c \
text/iso-639_def.h \
misc/actions.c \
misc/ancillary.h \
misc/ancillary.c \
misc/executor.c \
misc/md5.c \
misc/probe.c \
......
......@@ -29,6 +29,10 @@ aout_FiltersPlay
aout_FiltersAdjustResampling
aout_Hold
aout_Release
vlc_ancillary_CreateWithFreeCb
vlc_ancillary_Release
vlc_ancillary_Hold
vlc_ancillary_GetData
vlc_audio_meter_Init
vlc_audio_meter_Destroy
vlc_audio_meter_Reset
......@@ -41,8 +45,11 @@ vlc_fifo_New
vlc_fifo_Release
vlc_fifo_Show
vlc_frame_Alloc
vlc_frame_AttachAncillary
vlc_frame_CopyProperties
vlc_frame_File
vlc_frame_FilePath
vlc_frame_GetAncillary
vlc_frame_heap_Alloc
vlc_frame_Init
vlc_frame_mmap_Alloc
......@@ -301,6 +308,7 @@ net_Read
net_SetCSCov
net_Write
NTPtime64
picture_AttachAncillary
picture_BlendSubpicture
picture_Clone
picture_CopyPixels
......@@ -314,6 +322,7 @@ picture_fifo_New
picture_fifo_IsEmpty
picture_fifo_Pop
picture_fifo_Push
picture_GetAncillary
picture_New
picture_NewFromFormat
picture_NewFromResource
......
/*****************************************************************************
* ancillary.c: ancillary management functions
*****************************************************************************
* Copyright (C) 2021 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_atomic.h>
#include "ancillary.h"
struct vlc_ancillary
{
vlc_atomic_rc_t rc;
vlc_ancillary_id id;
void *data;
vlc_ancillary_free_cb free_cb;
};
struct vlc_ancillary *
vlc_ancillary_CreateWithFreeCb(void *data,
vlc_ancillary_id id,
vlc_ancillary_free_cb free_cb)
{
struct vlc_ancillary *ancillary = malloc(sizeof(*ancillary));
if (ancillary == NULL)
return NULL;
vlc_atomic_rc_init(&ancillary->rc);
ancillary->id = id;
ancillary->data = data;
ancillary->free_cb = free_cb;
return ancillary;
}
void
vlc_ancillary_Release(struct vlc_ancillary *ancillary)
{
if (vlc_atomic_rc_dec(&ancillary->rc))
{
if (ancillary->free_cb != NULL)
ancillary->free_cb(ancillary->data);
free(ancillary);
}
}
struct vlc_ancillary *
vlc_ancillary_Hold(struct vlc_ancillary *ancillary)
{
vlc_atomic_rc_inc(&ancillary->rc);
return ancillary;
}
void *
vlc_ancillary_GetData(const struct vlc_ancillary *ancillary)
{
return ancillary->data;
}
void
vlc_ancillary_array_Clear(struct vlc_ancillary ***array)
{
if (*array != NULL)
{
for (struct vlc_ancillary **ancillary = *array;
*ancillary != NULL; ancillary++)
{
vlc_ancillary_Release(*ancillary);
}
free(*array);
*array = NULL;
}
}
static size_t
vlc_ancillary_array_Count(struct vlc_ancillary **array)
{
size_t count = 0;
for (struct vlc_ancillary **ancillary = array;
*ancillary != NULL; ancillary++)
{
count++;
}
return count;
}
int
vlc_ancillary_array_Dup(struct vlc_ancillary ***dst_arrayp,
struct vlc_ancillary ** const*src_arrayp)
{
if (unlikely(*dst_arrayp != NULL))
vlc_ancillary_array_Clear(dst_arrayp);
if (*src_arrayp == NULL)
return VLC_SUCCESS;
struct vlc_ancillary **src_array = *src_arrayp;
size_t count = vlc_ancillary_array_Count(src_array);
struct vlc_ancillary **dst_array =
vlc_alloc(count + 1, sizeof(struct vlc_ancillary *));
if (dst_array == NULL)
return VLC_ENOMEM;
for (size_t i = 0; i < count; ++i)
{
dst_array[i] = vlc_ancillary_Hold(src_array[i]);
assert(dst_array[i] != NULL);
}
dst_array[count] = NULL;
*dst_arrayp = dst_array;
return VLC_SUCCESS;
}
int
vlc_ancillary_array_Insert(struct vlc_ancillary ***arrayp,
struct vlc_ancillary *ancillary)
{
/* First case: the array is empty */
if (*arrayp == NULL)
{
struct vlc_ancillary **array = vlc_alloc(2, sizeof(struct vlc_ancillary *));
if (array == NULL)
return VLC_ENOMEM;
array[0] = vlc_ancillary_Hold(ancillary);
array[1] = NULL;
*arrayp = array;
return VLC_SUCCESS;
}
struct vlc_ancillary **array = *arrayp;
size_t count = vlc_ancillary_array_Count(array);
/* Second case: the array has already an ancillary of the same id (very
* unlikely) */
for (size_t i = 0; i < count; ++i)
{
if (array[i]->id == ancillary->id)
{
vlc_ancillary_Release(array[i]);
array[i] = vlc_ancillary_Hold(ancillary);
return VLC_SUCCESS;
}
}
/* Third case: realloc the array to add the new ancillary */
array = vlc_reallocarray(array, count + 2, sizeof(struct vlc_ancillary *));
if (array == NULL)
return VLC_ENOMEM;
array[count] = vlc_ancillary_Hold(ancillary);
array[count + 1] = NULL;
*arrayp = array;
return VLC_SUCCESS;
}
struct vlc_ancillary *
vlc_ancillary_array_Get(struct vlc_ancillary ** const*arrayp,
vlc_ancillary_id id)
{
if (*arrayp == NULL)
return NULL;
struct vlc_ancillary **array = *arrayp;
for (struct vlc_ancillary **ancillary = array;
*ancillary != NULL; ancillary++)
{
if ((*ancillary)->id == id)
return *ancillary;
}
return NULL;
}
/*****************************************************************************
* ancillary.h: helpers to manage ancillaries from a frame or a picture
*****************************************************************************
* Copyright (C) 2021 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_ANCILLARY_INTERNAL_H
#define VLC_ANCILLARY_INTERNAL_H 1
#include <vlc_ancillary.h>
/*
* A NULL terminated array of struct vlc_ancillary *. We don't use a
* vlc_vector here in orer to gain few bytes (2 * size_t) for each
* ancillary users (each vlc_frame_t/picture_t). Users will likely have one
* or zero ancillary so the optimisations of the vlc_vector are not
* important here.
*/
static inline void
vlc_ancillary_array_Init(struct vlc_ancillary ***array)
{
*array = NULL;
}
void
vlc_ancillary_array_Clear(struct vlc_ancillary ***array);
int
vlc_ancillary_array_Dup(struct vlc_ancillary ***dst_array,
struct vlc_ancillary ** const*src_array);
int
vlc_ancillary_array_Insert(struct vlc_ancillary ***array,
struct vlc_ancillary *ancillary);
struct vlc_ancillary *
vlc_ancillary_array_Get(struct vlc_ancillary ** const*array,
vlc_ancillary_id id);
#endif /* VLC_ANCILLARY_INTERNAL_H */
......@@ -32,9 +32,12 @@
#include <fcntl.h>
#include <vlc_common.h>
#include <vlc_atomic.h>
#include <vlc_frame.h>
#include <vlc_fs.h>
#include "ancillary.h"
#ifndef NDEBUG
static void vlc_frame_Check (vlc_frame_t *frame)
{
......@@ -57,6 +60,18 @@ static void vlc_frame_Check (vlc_frame_t *frame)
# define vlc_frame_Check(b) ((void)(b))
#endif
void vlc_frame_CopyProperties(vlc_frame_t *restrict dst, const vlc_frame_t *src)
{
vlc_ancillary_array_Dup(&dst->priv_ancillaries,
&src->priv_ancillaries);
dst->i_flags = src->i_flags;
dst->i_nb_samples = src->i_nb_samples;
dst->i_dts = src->i_dts;
dst->i_pts = src->i_pts;
dst->i_length = src->i_length;
}
vlc_frame_t *vlc_frame_Init(vlc_frame_t *restrict f, const struct vlc_frame_callbacks *cbs,
void *buf, size_t size)
{
......@@ -71,6 +86,7 @@ vlc_frame_t *vlc_frame_Init(vlc_frame_t *restrict f, const struct vlc_frame_call
f->i_pts =
f->i_dts = VLC_TICK_INVALID;
f->i_length = 0;
vlc_ancillary_array_Init(&f->priv_ancillaries);
f->cbs = cbs;
return f;
}
......@@ -87,16 +103,6 @@ static const struct vlc_frame_callbacks vlc_frame_generic_cbs =
vlc_frame_generic_Release,
};
static void BlockMetaCopy( vlc_frame_t *restrict out, const vlc_frame_t *in )
{
out->p_next = in->p_next;
out->i_nb_samples = in->i_nb_samples;
out->i_dts = in->i_dts;
out->i_pts = in->i_pts;
out->i_flags = in->i_flags;
out->i_length = in->i_length;
}
/** Initial memory alignment of data frame.
* @note This must be a multiple of sizeof(void*) and a power of two.
* libavcodec AVX optimizations require at least 32-bytes. */
......@@ -138,6 +144,8 @@ void vlc_frame_Release(vlc_frame_t *frame)
frame->p_next = NULL;
vlc_frame_Check (frame);
#endif
vlc_ancillary_array_Clear(&frame->priv_ancillaries);
frame->cbs->free(frame);
}
......@@ -149,7 +157,10 @@ static vlc_frame_t *vlc_frame_ReallocDup( vlc_frame_t *frame, ssize_t i_prebody,
if( frame->i_buffer > 0 )
memcpy( p_rea->p_buffer + i_prebody, frame->p_buffer, frame->i_buffer );
BlockMetaCopy( p_rea, frame );
p_rea->p_next = frame->p_next;
vlc_frame_CopyProperties( p_rea, frame );
vlc_frame_Release( frame );
return p_rea;
}
......@@ -502,3 +513,15 @@ vlc_frame_t *vlc_frame_FilePath(const char *path, bool write)
vlc_close (fd);
return frame;
}
int
vlc_frame_AttachAncillary(vlc_frame_t *frame, struct vlc_ancillary *ancillary)
{
return vlc_ancillary_array_Insert(&frame->priv_ancillaries, ancillary);
}
struct vlc_ancillary *
vlc_frame_GetAncillary(vlc_frame_t *frame, vlc_ancillary_id id)
{
return vlc_ancillary_array_Get(&frame->priv_ancillaries, id);
}
......@@ -38,6 +38,8 @@
#include <vlc_image.h>
#include <vlc_block.h>
#include "ancillary.h"
static void PictureDestroyContext( picture_t *p_picture )
{
picture_context_t *ctx = p_picture->context;
......@@ -98,6 +100,9 @@ void picture_Reset( picture_t *p_picture )
p_picture->i_nb_fields = 2;
p_picture->b_top_field_first = false;
PictureDestroyContext( p_picture );
picture_priv_t *priv = container_of(p_picture, picture_priv_t, picture);
vlc_ancillary_array_Clear(&priv->ancillaries);
}
/*****************************************************************************
......@@ -220,6 +225,8 @@ static bool picture_InitPrivate(const video_format_t *restrict p_fmt,
else
priv->gc.destroy = picture_DestroyDummy;
vlc_ancillary_array_Init(&priv->ancillaries);
return true;
}
......@@ -344,6 +351,7 @@ void picture_Destroy(picture_t *picture)
picture_priv_t *priv = container_of(picture, picture_priv_t, picture);
assert(priv->gc.destroy != NULL);
priv->gc.destroy(picture);
vlc_ancillary_array_Clear(&priv->ancillaries);
free(priv);
}
......@@ -395,6 +403,10 @@ void picture_CopyProperties( picture_t *p_dst, const picture_t *p_src )
p_dst->b_progressive = p_src->b_progressive;
p_dst->i_nb_fields = p_src->i_nb_fields;
p_dst->b_top_field_first = p_src->b_top_field_first;
const picture_priv_t *src_priv = container_of(p_src, picture_priv_t, picture);
picture_priv_t *dst_priv = container_of(p_dst, picture_priv_t, picture);
vlc_ancillary_array_Dup(&dst_priv->ancillaries, &src_priv->ancillaries);
}
void picture_CopyPixels( picture_t *p_dst, const picture_t *p_src )
......@@ -453,9 +465,27 @@ picture_t *picture_InternalClone(picture_t *picture,
picture_t *picture_Clone(picture_t *picture)
{
picture_t *clone = picture_InternalClone(picture, picture_DestroyClone, picture);
const picture_priv_t *priv = container_of(picture, picture_priv_t, picture);
picture_priv_t *clone_priv = container_of(clone, picture_priv_t, picture);
vlc_ancillary_array_Dup(&clone_priv->ancillaries, &priv->ancillaries);
return clone;
}
int
picture_AttachAncillary(picture_t *pic, struct vlc_ancillary *ancillary)
{
picture_priv_t *priv = container_of(pic, picture_priv_t, picture);
return vlc_ancillary_array_Insert(&priv->ancillaries, ancillary);
}
struct vlc_ancillary *
picture_GetAncillary(picture_t *pic, vlc_ancillary_id id)
{
picture_priv_t *priv = container_of(pic, picture_priv_t, picture);
return vlc_ancillary_array_Get(&priv->ancillaries, id);
}
/*****************************************************************************
*
*****************************************************************************/
......
......@@ -22,6 +22,7 @@
#include <stddef.h>
#include <vlc_picture.h>
struct vlc_ancillary;
typedef struct
{
......@@ -31,6 +32,10 @@ typedef struct
void (*destroy)(picture_t *);
void *opaque;
} gc;
/** Private ancillary struct. Don't use it directly, but use it via
* picture_AttachAncillary() and picture_GetAncillary(). */
struct vlc_ancillary **ancillaries;
} picture_priv_t;
void *picture_Allocate(int *, size_t);
......
......@@ -23,6 +23,7 @@ check_PROGRAMS = \
test_libvlc_renderer_discoverer \
test_libvlc_slaves \
test_src_config_chain \
test_src_misc_ancillary \
test_src_misc_variables \
test_src_input_stream \
test_src_input_stream_fifo \
......@@ -103,6 +104,8 @@ test_libvlc_slaves_SOURCES = libvlc/slaves.c
test_libvlc_slaves_LDADD = $(LIBVLCCORE) $(LIBVLC)
test_libvlc_meta_SOURCES = libvlc/meta.c
test_libvlc_meta_LDADD = $(LIBVLCCORE) $(LIBVLC)
test_src_misc_ancillary_SOURCES = src/misc/ancillary.c
test_src_misc_ancillary_LDADD = $(LIBVLCCORE) $(LIBVLC)
test_src_misc_variables_SOURCES = src/misc/variables.c
test_src_misc_variables_LDADD = $(LIBVLCCORE) $(LIBVLC)
test_src_config_chain_SOURCES = src/config/chain.c
......
/*****************************************************************************
* ancillary.c: test for ancillary
*****************************************************************************
* Copyright (C) 2021 the VideoLAN team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_frame.h>
#include <vlc_picture.h>
#include <vlc_ancillary.h>
#include <assert.h>
static void
ancillary_free(void *data)
{
assert(strncmp(data, "test", 4) == 0);
free(data);
}
int main( void )
{
vlc_frame_t *frame = vlc_frame_Alloc(1);
assert(frame);
int ret;
struct vlc_ancillary *ancillary;
/* Create and try to attach 3 ancillaries to the frame, only 2 will be
* attached. */
for (size_t i = 0; i < 3; ++i)
{
char *data;
ret = asprintf(&data, "test%zu", i);
assert(ret > 0);
vlc_ancillary_id id;
switch (i)
{
case 0:
/* Check that only one ancillary of the same id is added (the
* last one take precedence). */
case 1: id = VLC_ANCILLARY_ID('t','s','t','1'); break;
case 2: id = VLC_ANCILLARY_ID('t','s','t','2'); break;
default: vlc_assert_unreachable();
}
ancillary = vlc_ancillary_CreateWithFreeCb(data, id, ancillary_free);
assert(ancillary);
ret = vlc_frame_AttachAncillary(frame, ancillary);
assert(ret == VLC_SUCCESS);
vlc_ancillary_Release(ancillary);
}
/* Check that ancillaries are copied via a vlc_frame_CopyProperties() (done
* by vlc_frame_Duplicate()). */
vlc_frame_t *copy_frame = vlc_frame_Duplicate(frame);
assert(copy_frame);
vlc_frame_Release(frame);
frame = copy_frame;
picture_t *picture = picture_New(VLC_CODEC_NV12, 1, 1, 1, 1);
assert(picture);
/* Manually attach both ancillaries to a newly allocated picture. */
ancillary = vlc_frame_GetAncillary(frame, VLC_ANCILLARY_ID('t','s','t','1'));
assert(ancillary);
picture_AttachAncillary(picture, ancillary);
ancillary = vlc_frame_GetAncillary(frame, VLC_ANCILLARY_ID('t','s','t','2'));
assert(ancillary);
picture_AttachAncillary(picture, ancillary);
vlc_frame_Release(frame);
/* Check that ancillaries are copied via a picture_Clone(). */
picture_t *clone = picture_Clone(picture);
assert(clone);
picture_Release(picture);
/* Check that ancillaries are copied via a picture_Copy(). */
picture_t *copy = picture_New(VLC_CODEC_I420, 1, 1, 1, 1);
assert(copy);
picture_Copy(copy, clone);
picture_Release(clone);
/* Check that ancillaries are still valid. */
ancillary = picture_GetAncillary(copy, VLC_ANCILLARY_ID('t','s','t','1'));
assert(ancillary);
assert(strcmp("test1", vlc_ancillary_GetData(ancillary)) == 0);
ancillary = picture_GetAncillary(copy, VLC_ANCILLARY_ID('t','s','t','2'));
assert(ancillary);
assert(strcmp("test2", vlc_ancillary_GetData(ancillary)) == 0);
picture_Release(copy);
return 0;
}