Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
5f296f9b
Kaydet (Commit)
5f296f9b
authored
May 20, 2015
tarafından
Stephan Bergmann
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fix reporting missing GStreamer plugins
Change-Id: I99b5994b53a5768b4c0aa8dbd6f54b13b23b333a
üst
bc0266c4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
201 additions
and
25 deletions
+201
-25
Library_avmediagst.mk
avmedia/Library_avmediagst.mk
+1
-0
Library_avmediagst_0_10.mk
avmedia/Library_avmediagst_0_10.mk
+1
-0
gstplayer.cxx
avmedia/source/gstreamer/gstplayer.cxx
+199
-25
No files found.
avmedia/Library_avmediagst.mk
Dosyayı görüntüle @
5f296f9b
...
...
@@ -27,6 +27,7 @@ $(eval $(call gb_Library_use_libraries,avmediagst,\
cppu \
cppuhelper \
sal \
salhelper \
tl \
vcl \
$(gb_UWINAPI) \
...
...
avmedia/Library_avmediagst_0_10.mk
Dosyayı görüntüle @
5f296f9b
...
...
@@ -29,6 +29,7 @@ $(eval $(call gb_Library_use_libraries,avmediagst_0_10,\
cppu \
cppuhelper \
sal \
salhelper \
tl \
vcl \
$(gb_UWINAPI) \
...
...
avmedia/source/gstreamer/gstplayer.cxx
Dosyayı görüntüle @
5f296f9b
...
...
@@ -19,14 +19,19 @@
#include <sal/config.h>
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <cppuhelper/supportsservice.hxx>
#include <rtl/string.hxx>
#include <salhelper/thread.hxx>
#include <vcl/svapp.hxx>
#include <vcl/syschild.hxx>
#include <vcl/sysdata.hxx>
...
...
@@ -66,46 +71,183 @@ namespace avmedia { namespace gstreamer {
namespace
{
class
FlagGuard
{
public
:
explicit
FlagGuard
(
bool
&
flag
)
:
flag_
(
flag
)
{
flag_
=
true
;
}
~
FlagGuard
()
{
flag_
=
false
;
}
private
:
bool
&
flag_
;
};
class
MissingPluginInstallerThread
:
public
salhelper
::
Thread
{
public
:
MissingPluginInstallerThread
()
:
Thread
(
"MissingPluginInstaller"
)
{}
private
:
void
execute
()
SAL_OVERRIDE
;
};
class
MissingPluginInstaller
{
friend
MissingPluginInstallerThread
;
public
:
void
report
(
GstMessage
*
message
);
MissingPluginInstaller
()
:
launchNewThread_
(
true
),
inCleanUp_
(
false
)
{}
~
MissingPluginInstaller
();
void
report
(
rtl
::
Reference
<
Player
>
const
&
source
,
GstMessage
*
message
);
// Player::~Player calls Player::disposing calls
// MissingPluginInstaller::detach, so do not take Player by rtl::Reference
// here (which would bump its refcount back from 0 to 1):
void
detach
(
Player
const
*
source
);
private
:
DECL_STATIC_LINK
(
MissingPluginInstaller
,
install
,
rtl_String
*
);
void
processQueue
();
DECL_STATIC_LINK
(
MissingPluginInstaller
,
launchUi
,
MissingPluginInstallerThread
*
);
osl
::
Mutex
mutex_
;
std
::
set
<
OString
>
reported_
;
std
::
map
<
OString
,
std
::
set
<
rtl
::
Reference
<
Player
>>>
queued_
;
rtl
::
Reference
<
MissingPluginInstallerThread
>
currentThread_
;
std
::
vector
<
OString
>
currentDetails_
;
std
::
set
<
rtl
::
Reference
<
Player
>>
currentSources_
;
bool
launchNewThread_
;
bool
inCleanUp_
;
};
void
MissingPluginInstaller
::
report
(
GstMessage
*
message
)
{
MissingPluginInstaller
::~
MissingPluginInstaller
()
{
osl
::
MutexGuard
g
(
mutex_
);
SAL_WARN_IF
(
currentThread_
.
is
(),
"avmedia.gstreamer"
,
"unjoined thread"
);
inCleanUp_
=
true
;
}
void
MissingPluginInstaller
::
report
(
rtl
::
Reference
<
Player
>
const
&
source
,
GstMessage
*
message
)
{
// assert(gst_is_missing_plugin_message(message));
gchar
*
det
=
gst_missing_plugin_message_get_installer_detail
(
message
);
if
(
det
!=
nullptr
)
{
std
::
size_t
len
=
std
::
strlen
(
det
);
if
(
len
<=
sal_uInt32
(
SAL_MAX_INT32
))
{
OString
detStr
(
det
,
len
);
if
(
reported_
.
insert
(
detStr
).
second
)
{
rtl_string_acquire
(
detStr
.
pData
);
Application
::
PostUserEvent
(
LINK
(
nullptr
,
MissingPluginInstaller
,
install
),
detStr
.
pData
);
}
}
else
{
SAL_WARN
(
"avmedia.gstreamer"
,
"detail string too long"
);
}
g_free
(
det
);
}
else
{
if
(
det
==
nullptr
)
{
SAL_WARN
(
"avmedia.gstreamer"
,
"gst_missing_plugin_message_get_installer_detail failed"
);
return
;
}
std
::
size_t
len
=
std
::
strlen
(
det
);
if
(
len
>
sal_uInt32
(
SAL_MAX_INT32
))
{
SAL_WARN
(
"avmedia.gstreamer"
,
"detail string too long"
);
g_free
(
det
);
return
;
}
OString
detStr
(
det
,
len
);
g_free
(
det
);
rtl
::
Reference
<
MissingPluginInstallerThread
>
join
;
rtl
::
Reference
<
MissingPluginInstallerThread
>
launch
;
{
osl
::
MutexGuard
g
(
mutex_
);
if
(
reported_
.
find
(
detStr
)
!=
reported_
.
end
())
{
return
;
}
auto
&
i
=
queued_
[
detStr
];
bool
fresh
=
i
.
empty
();
i
.
insert
(
source
);
if
(
!
(
fresh
&&
launchNewThread_
))
{
return
;
}
join
=
currentThread_
;
currentThread_
=
new
MissingPluginInstallerThread
;
{
FlagGuard
f
(
inCleanUp_
);
currentSources_
.
clear
();
}
processQueue
();
launchNewThread_
=
false
;
launch
=
currentThread_
;
}
if
(
join
.
is
())
{
join
->
join
();
}
launch
->
acquire
();
Application
::
PostUserEvent
(
LINK
(
this
,
MissingPluginInstaller
,
launchUi
),
launch
.
get
());
}
IMPL_STATIC_LINK
(
MissingPluginInstaller
,
install
,
rtl_String
*
,
data
)
{
OString
res
(
data
,
SAL_NO_ACQUIRE
);
gst_pb_utils_init
();
// not thread safe
char
*
args
[]{
const_cast
<
char
*>
(
res
.
getStr
()),
nullptr
};
gst_install_plugins_sync
(
args
,
nullptr
);
void
eraseSource
(
std
::
set
<
rtl
::
Reference
<
Player
>>
&
set
,
Player
const
*
source
)
{
auto
i
=
std
::
find_if
(
set
.
begin
(),
set
.
end
(),
[
source
](
rtl
::
Reference
<
Player
>
const
&
el
)
{
return
el
.
get
()
==
source
;
});
if
(
i
!=
set
.
end
())
{
set
.
erase
(
i
);
}
}
void
MissingPluginInstaller
::
detach
(
Player
const
*
source
)
{
rtl
::
Reference
<
MissingPluginInstallerThread
>
join
;
{
osl
::
MutexGuard
g
(
mutex_
);
if
(
inCleanUp_
)
{
// Guard against ~MissingPluginInstaller with erroneously un-joined
// currentThread_ (thus non-empty currentSources_) calling
// destructor of currentSources_, calling ~Player, calling here,
// which would use currentSources_ while it is already being
// destroyed:
return
;
}
for
(
auto
i
=
queued_
.
begin
();
i
!=
queued_
.
end
();)
{
eraseSource
(
i
->
second
,
source
);
if
(
i
->
second
.
empty
())
{
i
=
queued_
.
erase
(
i
);
}
else
{
++
i
;
}
}
if
(
currentThread_
.
is
())
{
assert
(
!
currentSources_
.
empty
());
eraseSource
(
currentSources_
,
source
);
if
(
currentSources_
.
empty
())
{
join
=
currentThread_
;
currentThread_
.
clear
();
launchNewThread_
=
true
;
}
}
}
if
(
join
.
is
())
{
// missing cancelability of gst_install_plugins_sync
join
->
join
();
}
}
void
MissingPluginInstaller
::
processQueue
()
{
assert
(
!
queued_
.
empty
());
assert
(
currentDetails_
.
empty
());
for
(
auto
i
=
queued_
.
begin
();
i
!=
queued_
.
end
();
++
i
)
{
reported_
.
insert
(
i
->
first
);
currentDetails_
.
push_back
(
i
->
first
);
currentSources_
.
insert
(
i
->
second
.
begin
(),
i
->
second
.
end
());
}
queued_
.
clear
();
}
IMPL_STATIC_LINK
(
MissingPluginInstaller
,
launchUi
,
MissingPluginInstallerThread
*
,
thread
)
{
rtl
::
Reference
<
MissingPluginInstallerThread
>
ref
(
thread
,
SAL_NO_ACQUIRE
);
gst_pb_utils_init
();
// not thread safe; hopefully fine to consistently call from our event
// loop (which is the only reason to have this
// Application::PostUserEvent diversion, in case
// MissingPluginInstaller::report might be called from outside our event
// loop), and hopefully fine to call gst_is_missing_plugin_message and
// gst_missing_plugin_message_get_installer_detail before calling
// gst_pb_utils_init
ref
->
launch
();
return
0
;
}
...
...
@@ -113,6 +255,32 @@ struct TheMissingPluginInstaller:
public
rtl
::
Static
<
MissingPluginInstaller
,
TheMissingPluginInstaller
>
{};
void
MissingPluginInstallerThread
::
execute
()
{
MissingPluginInstaller
&
inst
=
TheMissingPluginInstaller
::
get
();
for
(;;)
{
std
::
vector
<
OString
>
details
;
{
osl
::
MutexGuard
g
(
inst
.
mutex_
);
assert
(
!
inst
.
currentDetails_
.
empty
());
details
.
swap
(
inst
.
currentDetails_
);
}
std
::
vector
<
char
*>
args
;
for
(
auto
const
&
i
:
details
)
{
args
.
push_back
(
const_cast
<
char
*>
(
i
.
getStr
()));
}
args
.
push_back
(
nullptr
);
gst_install_plugins_sync
(
args
.
data
(),
nullptr
);
{
osl
::
MutexGuard
g
(
inst
.
mutex_
);
if
(
inst
.
queued_
.
empty
()
||
inst
.
launchNewThread_
)
{
inst
.
launchNewThread_
=
true
;
break
;
}
inst
.
processQueue
();
}
}
}
}
// - Player -
...
...
@@ -166,6 +334,8 @@ Player::~Player()
void
SAL_CALL
Player
::
disposing
()
{
TheMissingPluginInstaller
::
get
().
detach
(
this
);
::
osl
::
MutexGuard
aGuard
(
m_aMutex
);
stop
();
...
...
@@ -387,7 +557,11 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
}
#endif
}
else
if
(
gst_is_missing_plugin_message
(
message
))
{
TheMissingPluginInstaller
::
get
().
report
(
message
);
TheMissingPluginInstaller
::
get
().
report
(
this
,
message
);
if
(
mnWidth
==
0
)
{
// an error occurred, set condition so that OOo thread doesn't wait for us
maSizeCondition
.
set
();
}
}
else
if
(
GST_MESSAGE_TYPE
(
message
)
==
GST_MESSAGE_ERROR
)
{
DBG
(
"Error !
\n
"
);
if
(
mnWidth
==
0
)
{
...
...
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