Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
327ffd12
Commit
327ffd12
authored
Jan 19, 2012
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Thread safe picture_t refcounting.
parent
7090b8ef
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
63 additions
and
66 deletions
+63
-66
include/vlc_picture.h
include/vlc_picture.h
+8
-4
src/misc/picture.c
src/misc/picture.c
+17
-21
src/misc/picture_pool.c
src/misc/picture_pool.c
+38
-41
No files found.
include/vlc_picture.h
View file @
327ffd12
...
...
@@ -56,10 +56,11 @@ typedef struct plane_t
*/
#define PICTURE_PLANE_MAX (VOUT_MAX_PLANES)
/**
* A private definition to help overloading picture release
*/
typedef
struct
picture_
release_sys_t
picture_release
_sys_t
;
typedef
struct
picture_
gc_sys_t
picture_gc
_sys_t
;
/**
* Video picture
...
...
@@ -79,7 +80,6 @@ struct picture_t
* These properties can be modified using the video output thread API,
* but should never be written directly */
/**@{*/
unsigned
i_refcount
;
/**< link reference counter */
mtime_t
date
;
/**< display date */
bool
b_force
;
/**@}*/
...
...
@@ -101,8 +101,12 @@ struct picture_t
picture_sys_t
*
p_sys
;
/** This way the picture_Release can be overloaded */
void
(
*
pf_release
)(
picture_t
*
);
picture_release_sys_t
*
p_release_sys
;
struct
{
vlc_atomic_t
refcount
;
void
(
*
pf_destroy
)(
picture_t
*
);
picture_gc_sys_t
*
p_sys
;
}
gc
;
/** Next picture in a FIFO a pictures */
struct
picture_t
*
p_next
;
...
...
src/misc/picture.c
View file @
327ffd12
...
...
@@ -37,6 +37,7 @@
#include <vlc_picture.h>
#include <vlc_image.h>
#include <vlc_block.h>
#include <vlc_atomic.h>
/**
* Allocate a new picture in the heap.
...
...
@@ -92,10 +93,11 @@ static int AllocatePicture( picture_t *p_pic,
/*****************************************************************************
*
*****************************************************************************/
static
void
picture_Delete
(
picture_t
*
p_picture
)
static
void
PictureDestroy
(
picture_t
*
p_picture
)
{
assert
(
p_picture
&&
p_picture
->
i_refcount
==
0
);
assert
(
p_picture
->
p_release_sys
==
NULL
);
assert
(
p_picture
&&
vlc_atomic_get
(
&
p_picture
->
gc
.
refcount
)
==
0
&&
p_picture
->
gc
.
p_sys
==
NULL
);
free
(
p_picture
->
p_q
);
vlc_free
(
p_picture
->
p_data_orig
);
...
...
@@ -103,13 +105,6 @@ static void picture_Delete( picture_t *p_picture )
free
(
p_picture
);
}
static
void
PictureReleaseCallback
(
picture_t
*
p_picture
)
{
if
(
--
p_picture
->
i_refcount
>
0
)
return
;
picture_Delete
(
p_picture
);
}
/*****************************************************************************
*
*****************************************************************************/
...
...
@@ -148,9 +143,9 @@ int picture_Setup( picture_t *p_picture, vlc_fourcc_t i_chroma,
p
->
i_pixel_pitch
=
0
;
}
p_picture
->
pf_release
=
NULL
;
p_picture
->
p_release_sys
=
NULL
;
p_picture
->
i_refcount
=
0
;
vlc_atomic_set
(
&
p_picture
->
gc
.
refcount
,
0
)
;
p_picture
->
gc
.
pf_destroy
=
NULL
;
p_picture
->
gc
.
p_sys
=
NULL
;
p_picture
->
i_nb_fields
=
2
;
...
...
@@ -255,8 +250,10 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r
}
/* */
p_picture
->
format
=
fmt
;
p_picture
->
i_refcount
=
1
;
p_picture
->
pf_release
=
PictureReleaseCallback
;
vlc_atomic_set
(
&
p_picture
->
gc
.
refcount
,
1
);
p_picture
->
gc
.
pf_destroy
=
PictureDestroy
;
p_picture
->
gc
.
p_sys
=
NULL
;
return
p_picture
;
}
...
...
@@ -281,21 +278,20 @@ picture_t *picture_New( vlc_fourcc_t i_chroma, int i_width, int i_height, int i_
picture_t
*
picture_Hold
(
picture_t
*
p_picture
)
{
if
(
p_picture
->
pf_release
)
p_picture
->
i_refcount
++
;
vlc_atomic_inc
(
&
p_picture
->
gc
.
refcount
);
return
p_picture
;
}
void
picture_Release
(
picture_t
*
p_picture
)
{
/* FIXME why do we let pf_release handle the i_refcount ? */
if
(
p_picture
->
pf_release
)
p_picture
->
pf_release
(
p_picture
);
if
(
vlc_atomic_dec
(
&
p_picture
->
gc
.
refcount
)
==
0
&&
p_picture
->
gc
.
pf_destroy
)
p_picture
->
gc
.
pf_destroy
(
p_picture
);
}
bool
picture_IsReferenced
(
picture_t
*
p_picture
)
{
return
p_picture
->
i_refcount
>
1
;
return
vlc_atomic_get
(
&
p_picture
->
gc
.
refcount
)
>
1
;
}
/*****************************************************************************
...
...
src/misc/picture_pool.c
View file @
327ffd12
...
...
@@ -33,14 +33,15 @@
#include <vlc_common.h>
#include <vlc_picture_pool.h>
#include <vlc_atomic.h>
/*****************************************************************************
*
*****************************************************************************/
struct
picture_
release
_sys_t
{
struct
picture_
gc
_sys_t
{
/* Saved release */
void
(
*
release
)(
picture_t
*
);
picture_release_sys_t
*
release
_sys
;
void
(
*
destroy
)(
picture_t
*
);
void
*
destroy
_sys
;
/* */
int
(
*
lock
)(
picture_t
*
);
...
...
@@ -60,7 +61,7 @@ struct picture_pool_t {
bool
*
picture_reserved
;
};
static
void
Release
(
picture_t
*
);
static
void
Destroy
(
picture_t
*
);
static
int
Lock
(
picture_t
*
);
static
void
Unlock
(
picture_t
*
);
...
...
@@ -94,22 +95,22 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg
picture_t
*
picture
=
cfg
->
picture
[
i
];
/* The pool must be the only owner of the picture */
assert
(
picture
->
i_refcount
==
1
);
assert
(
!
picture_IsReferenced
(
picture
)
);
/* Install the new release callback */
picture_
release_sys_t
*
release_sys
=
malloc
(
sizeof
(
*
release
_sys
));
if
(
!
release
_sys
)
picture_
gc_sys_t
*
gc_sys
=
malloc
(
sizeof
(
*
gc
_sys
));
if
(
!
gc
_sys
)
abort
();
release_sys
->
release
=
picture
->
pf_release
;
release_sys
->
release_sys
=
picture
->
p_release
_sys
;
release
_sys
->
lock
=
cfg
->
lock
;
release
_sys
->
unlock
=
cfg
->
unlock
;
release
_sys
->
tick
=
0
;
gc_sys
->
destroy
=
picture
->
gc
.
pf_destroy
;
gc_sys
->
destroy_sys
=
picture
->
gc
.
p
_sys
;
gc
_sys
->
lock
=
cfg
->
lock
;
gc
_sys
->
unlock
=
cfg
->
unlock
;
gc
_sys
->
tick
=
0
;
/* */
picture
->
i_refcount
=
0
;
picture
->
pf_release
=
Release
;
picture
->
p_release_sys
=
release
_sys
;
vlc_atomic_set
(
&
picture
->
gc
.
refcount
,
0
)
;
picture
->
gc
.
pf_destroy
=
Destroy
;
picture
->
gc
.
p_sys
=
gc
_sys
;
/* */
pool
->
picture
[
i
]
=
picture
;
...
...
@@ -165,7 +166,7 @@ picture_pool_t *picture_pool_Reserve(picture_pool_t *master, int count)
if
(
master
->
picture_reserved
[
i
])
continue
;
assert
(
master
->
picture
[
i
]
->
i_refcount
==
0
);
assert
(
vlc_atomic_get
(
&
master
->
picture
[
i
]
->
gc
.
refcount
)
==
0
);
master
->
picture_reserved
[
i
]
=
true
;
pool
->
picture
[
found
]
=
master
->
picture
[
i
];
...
...
@@ -189,19 +190,19 @@ void picture_pool_Delete(picture_pool_t *pool)
pool
->
master
->
picture_reserved
[
j
]
=
false
;
}
}
else
{
picture_
release_sys_t
*
release_sys
=
picture
->
p_release
_sys
;
picture_
gc_sys_t
*
gc_sys
=
picture
->
gc
.
p
_sys
;
assert
(
picture
->
i_refcount
==
0
);
assert
(
vlc_atomic_get
(
&
picture
->
gc
.
refcount
)
==
0
);
assert
(
!
pool
->
picture_reserved
[
i
]);
/* Restore old release callback */
picture
->
i_refcount
=
1
;
picture
->
pf_release
=
release_sys
->
release
;
picture
->
p_release_sys
=
release_sys
->
release
_sys
;
vlc_atomic_set
(
&
picture
->
gc
.
refcount
,
1
)
;
picture
->
gc
.
pf_destroy
=
gc_sys
->
destroy
;
picture
->
gc
.
p_sys
=
gc_sys
->
destroy
_sys
;
picture_Release
(
picture
);
free
(
release
_sys
);
free
(
gc
_sys
);
}
}
free
(
pool
->
picture_reserved
);
...
...
@@ -216,7 +217,7 @@ picture_t *picture_pool_Get(picture_pool_t *pool)
continue
;
picture_t
*
picture
=
pool
->
picture
[
i
];
if
(
picture
->
i_refcount
>
0
)
if
(
vlc_atomic_get
(
&
picture
->
gc
.
refcount
)
>
0
)
continue
;
if
(
Lock
(
picture
))
...
...
@@ -224,7 +225,7 @@ picture_t *picture_pool_Get(picture_pool_t *pool)
/* */
picture
->
p_next
=
NULL
;
picture
->
p_release
_sys
->
tick
=
pool
->
tick
++
;
picture
->
gc
.
p
_sys
->
tick
=
pool
->
tick
++
;
picture_Hold
(
picture
);
return
picture
;
}
...
...
@@ -241,19 +242,19 @@ void picture_pool_NonEmpty(picture_pool_t *pool, bool reset)
picture_t
*
picture
=
pool
->
picture
[
i
];
if
(
reset
)
{
if
(
picture
->
i_refcount
>
0
)
if
(
vlc_atomic_get
(
&
picture
->
gc
.
refcount
)
>
0
)
Unlock
(
picture
);
picture
->
i_refcount
=
0
;
}
else
if
(
picture
->
i_refcount
==
0
)
{
vlc_atomic_set
(
&
picture
->
gc
.
refcount
,
0
)
;
}
else
if
(
vlc_atomic_get
(
&
picture
->
gc
.
refcount
)
==
0
)
{
return
;
}
else
if
(
!
old
||
picture
->
p_release_sys
->
tick
<
old
->
p_release
_sys
->
tick
)
{
}
else
if
(
!
old
||
picture
->
gc
.
p_sys
->
tick
<
old
->
gc
.
p
_sys
->
tick
)
{
old
=
picture
;
}
}
if
(
!
reset
&&
old
)
{
if
(
old
->
i_refcount
>
0
)
if
(
vlc_atomic_get
(
&
old
->
gc
.
refcount
)
>
0
)
Unlock
(
old
);
old
->
i_refcount
=
0
;
vlc_atomic_set
(
&
old
->
gc
.
refcount
,
0
)
;
}
}
int
picture_pool_GetSize
(
picture_pool_t
*
pool
)
...
...
@@ -261,26 +262,22 @@ int picture_pool_GetSize(picture_pool_t *pool)
return
pool
->
picture_count
;
}
static
void
Release
(
picture_t
*
picture
)
static
void
Destroy
(
picture_t
*
picture
)
{
assert
(
picture
->
i_refcount
>
0
);
if
(
--
picture
->
i_refcount
>
0
)
return
;
Unlock
(
picture
);
}
static
int
Lock
(
picture_t
*
picture
)
{
picture_
release_sys_t
*
release_sys
=
picture
->
p_release
_sys
;
if
(
release
_sys
->
lock
)
return
release
_sys
->
lock
(
picture
);
picture_
gc_sys_t
*
gc_sys
=
picture
->
gc
.
p
_sys
;
if
(
gc
_sys
->
lock
)
return
gc
_sys
->
lock
(
picture
);
return
VLC_SUCCESS
;
}
static
void
Unlock
(
picture_t
*
picture
)
{
picture_
release_sys_t
*
release_sys
=
picture
->
p_release
_sys
;
if
(
release
_sys
->
unlock
)
release
_sys
->
unlock
(
picture
);
picture_
gc_sys_t
*
gc_sys
=
picture
->
gc
.
p
_sys
;
if
(
gc
_sys
->
unlock
)
gc
_sys
->
unlock
(
picture
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment