Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
57b3b292
Commit
57b3b292
authored
Jun 08, 2022
by
Rémi Bernon
Committed by
Alexandre Julliard
Jun 13, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winegstreamer: Split wg_sample wrapper helpers to a separate source.
Signed-off-by:
Rémi Bernon
<
rbernon@codeweavers.com
>
parent
0c792806
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
204 additions
and
176 deletions
+204
-176
Makefile.in
dlls/winegstreamer/Makefile.in
+1
-0
mfplat.c
dlls/winegstreamer/mfplat.c
+0
-176
wg_sample.c
dlls/winegstreamer/wg_sample.c
+203
-0
No files found.
dlls/winegstreamer/Makefile.in
View file @
57b3b292
...
...
@@ -17,6 +17,7 @@ C_SRCS = \
wg_allocator.c
\
wg_format.c
\
wg_parser.c
\
wg_sample.c
\
wg_transform.c
\
wm_asyncreader.c
\
wm_reader.c
\
...
...
dlls/winegstreamer/mfplat.c
View file @
57b3b292
...
...
@@ -958,179 +958,3 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
else
FIXME
(
"Unrecognized major type %s.
\n
"
,
debugstr_guid
(
&
major_type
));
}
struct
wg_sample_queue
{
CRITICAL_SECTION
cs
;
struct
list
samples
;
};
struct
mf_sample
{
IMFSample
*
sample
;
IMFMediaBuffer
*
media_buffer
;
struct
wg_sample
wg_sample
;
struct
list
entry
;
};
HRESULT
wg_sample_create_mf
(
IMFSample
*
sample
,
struct
wg_sample
**
out
)
{
DWORD
current_length
,
max_length
;
struct
mf_sample
*
mf_sample
;
BYTE
*
buffer
;
HRESULT
hr
;
if
(
!
(
mf_sample
=
calloc
(
1
,
sizeof
(
*
mf_sample
))))
return
E_OUTOFMEMORY
;
if
(
FAILED
(
hr
=
IMFSample_ConvertToContiguousBuffer
(
sample
,
&
mf_sample
->
media_buffer
)))
goto
out
;
if
(
FAILED
(
hr
=
IMFMediaBuffer_Lock
(
mf_sample
->
media_buffer
,
&
buffer
,
&
max_length
,
&
current_length
)))
goto
out
;
IMFSample_AddRef
((
mf_sample
->
sample
=
sample
));
mf_sample
->
wg_sample
.
data
=
buffer
;
mf_sample
->
wg_sample
.
size
=
current_length
;
mf_sample
->
wg_sample
.
max_size
=
max_length
;
TRACE
(
"Created mf_sample %p for sample %p.
\n
"
,
mf_sample
,
sample
);
*
out
=
&
mf_sample
->
wg_sample
;
return
S_OK
;
out:
if
(
mf_sample
->
media_buffer
)
IMFMediaBuffer_Release
(
mf_sample
->
media_buffer
);
free
(
mf_sample
);
return
hr
;
}
void
wg_sample_release
(
struct
wg_sample
*
wg_sample
)
{
struct
mf_sample
*
mf_sample
=
CONTAINING_RECORD
(
wg_sample
,
struct
mf_sample
,
wg_sample
);
if
(
InterlockedOr
(
&
wg_sample
->
refcount
,
0
))
{
ERR
(
"Sample %p is still in use, trouble ahead!
\n
"
,
wg_sample
);
return
;
}
IMFMediaBuffer_Unlock
(
mf_sample
->
media_buffer
);
IMFMediaBuffer_Release
(
mf_sample
->
media_buffer
);
IMFSample_Release
(
mf_sample
->
sample
);
free
(
mf_sample
);
}
static
void
wg_sample_queue_begin_append
(
struct
wg_sample_queue
*
queue
,
struct
wg_sample
*
wg_sample
)
{
struct
mf_sample
*
mf_sample
=
CONTAINING_RECORD
(
wg_sample
,
struct
mf_sample
,
wg_sample
);
/* make sure a concurrent wg_sample_queue_flush call won't release the sample until we're done */
InterlockedIncrement
(
&
wg_sample
->
refcount
);
mf_sample
->
wg_sample
.
flags
|=
WG_SAMPLE_FLAG_HAS_REFCOUNT
;
EnterCriticalSection
(
&
queue
->
cs
);
list_add_tail
(
&
queue
->
samples
,
&
mf_sample
->
entry
);
LeaveCriticalSection
(
&
queue
->
cs
);
}
static
void
wg_sample_queue_end_append
(
struct
wg_sample_queue
*
queue
,
struct
wg_sample
*
wg_sample
)
{
/* release temporary ref taken in wg_sample_queue_begin_append */
InterlockedDecrement
(
&
wg_sample
->
refcount
);
wg_sample_queue_flush
(
queue
,
false
);
}
void
wg_sample_queue_flush
(
struct
wg_sample_queue
*
queue
,
bool
all
)
{
struct
mf_sample
*
mf_sample
,
*
next
;
EnterCriticalSection
(
&
queue
->
cs
);
LIST_FOR_EACH_ENTRY_SAFE
(
mf_sample
,
next
,
&
queue
->
samples
,
struct
mf_sample
,
entry
)
{
if
(
!
InterlockedOr
(
&
mf_sample
->
wg_sample
.
refcount
,
0
)
||
all
)
{
list_remove
(
&
mf_sample
->
entry
);
wg_sample_release
(
&
mf_sample
->
wg_sample
);
}
}
LeaveCriticalSection
(
&
queue
->
cs
);
}
HRESULT
wg_sample_queue_create
(
struct
wg_sample_queue
**
out
)
{
struct
wg_sample_queue
*
queue
;
if
(
!
(
queue
=
calloc
(
1
,
sizeof
(
*
queue
))))
return
E_OUTOFMEMORY
;
InitializeCriticalSection
(
&
queue
->
cs
);
queue
->
cs
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": cs"
);
list_init
(
&
queue
->
samples
);
TRACE
(
"Created sample queue %p
\n
"
,
queue
);
*
out
=
queue
;
return
S_OK
;
}
void
wg_sample_queue_destroy
(
struct
wg_sample_queue
*
queue
)
{
wg_sample_queue_flush
(
queue
,
true
);
queue
->
cs
.
DebugInfo
->
Spare
[
0
]
=
0
;
InitializeCriticalSection
(
&
queue
->
cs
);
free
(
queue
);
}
HRESULT
wg_transform_push_mf
(
struct
wg_transform
*
transform
,
struct
wg_sample
*
wg_sample
,
struct
wg_sample_queue
*
queue
)
{
struct
mf_sample
*
mf_sample
=
CONTAINING_RECORD
(
wg_sample
,
struct
mf_sample
,
wg_sample
);
LONGLONG
time
,
duration
;
UINT32
value
;
HRESULT
hr
;
if
(
SUCCEEDED
(
IMFSample_GetSampleTime
(
mf_sample
->
sample
,
&
time
)))
{
mf_sample
->
wg_sample
.
flags
|=
WG_SAMPLE_FLAG_HAS_PTS
;
mf_sample
->
wg_sample
.
pts
=
time
;
}
if
(
SUCCEEDED
(
IMFSample_GetSampleDuration
(
mf_sample
->
sample
,
&
duration
)))
{
mf_sample
->
wg_sample
.
flags
|=
WG_SAMPLE_FLAG_HAS_DURATION
;
mf_sample
->
wg_sample
.
duration
=
duration
;
}
if
(
SUCCEEDED
(
IMFSample_GetUINT32
(
mf_sample
->
sample
,
&
MFSampleExtension_CleanPoint
,
&
value
))
&&
value
)
mf_sample
->
wg_sample
.
flags
|=
WG_SAMPLE_FLAG_SYNC_POINT
;
wg_sample_queue_begin_append
(
queue
,
wg_sample
);
hr
=
wg_transform_push_data
(
transform
,
wg_sample
);
wg_sample_queue_end_append
(
queue
,
wg_sample
);
return
hr
;
}
HRESULT
wg_transform_read_mf
(
struct
wg_transform
*
transform
,
struct
wg_sample
*
wg_sample
,
struct
wg_format
*
format
)
{
struct
mf_sample
*
mf_sample
=
CONTAINING_RECORD
(
wg_sample
,
struct
mf_sample
,
wg_sample
);
HRESULT
hr
;
if
(
FAILED
(
hr
=
wg_transform_read_data
(
transform
,
wg_sample
,
format
)))
return
hr
;
IMFMediaBuffer_SetCurrentLength
(
mf_sample
->
media_buffer
,
wg_sample
->
size
);
if
(
wg_sample
->
flags
&
WG_SAMPLE_FLAG_HAS_PTS
)
IMFSample_SetSampleTime
(
mf_sample
->
sample
,
wg_sample
->
pts
);
if
(
wg_sample
->
flags
&
WG_SAMPLE_FLAG_HAS_DURATION
)
IMFSample_SetSampleDuration
(
mf_sample
->
sample
,
wg_sample
->
duration
);
if
(
wg_sample
->
flags
&
WG_SAMPLE_FLAG_SYNC_POINT
)
IMFSample_SetUINT32
(
mf_sample
->
sample
,
&
MFSampleExtension_CleanPoint
,
1
);
return
S_OK
;
}
dlls/winegstreamer/wg_sample.c
0 → 100644
View file @
57b3b292
/*
* Copyright 2022 Rémi Bernon for CodeWeavers
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "gst_private.h"
#include "wmcodecdsp.h"
#include "mfapi.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
mfplat
);
struct
wg_sample_queue
{
CRITICAL_SECTION
cs
;
struct
list
samples
;
};
struct
sample
{
IMFSample
*
sample
;
IMFMediaBuffer
*
media_buffer
;
struct
wg_sample
wg_sample
;
struct
list
entry
;
};
HRESULT
wg_sample_create_mf
(
IMFSample
*
mf_sample
,
struct
wg_sample
**
out
)
{
DWORD
current_length
,
max_length
;
struct
sample
*
sample
;
BYTE
*
buffer
;
HRESULT
hr
;
if
(
!
(
sample
=
calloc
(
1
,
sizeof
(
*
sample
))))
return
E_OUTOFMEMORY
;
if
(
FAILED
(
hr
=
IMFSample_ConvertToContiguousBuffer
(
mf_sample
,
&
sample
->
media_buffer
)))
goto
fail
;
if
(
FAILED
(
hr
=
IMFMediaBuffer_Lock
(
sample
->
media_buffer
,
&
buffer
,
&
max_length
,
&
current_length
)))
goto
fail
;
IMFSample_AddRef
((
sample
->
sample
=
mf_sample
));
sample
->
wg_sample
.
data
=
buffer
;
sample
->
wg_sample
.
size
=
current_length
;
sample
->
wg_sample
.
max_size
=
max_length
;
*
out
=
&
sample
->
wg_sample
;
TRACE_
(
mfplat
)(
"Created wg_sample %p for IMFSample %p.
\n
"
,
*
out
,
mf_sample
);
return
S_OK
;
fail:
if
(
sample
->
media_buffer
)
IMFMediaBuffer_Release
(
sample
->
media_buffer
);
free
(
sample
);
return
hr
;
}
void
wg_sample_release
(
struct
wg_sample
*
wg_sample
)
{
struct
sample
*
sample
=
CONTAINING_RECORD
(
wg_sample
,
struct
sample
,
wg_sample
);
if
(
InterlockedOr
(
&
wg_sample
->
refcount
,
0
))
{
ERR
(
"wg_sample %p is still in use, trouble ahead!
\n
"
,
wg_sample
);
return
;
}
IMFMediaBuffer_Unlock
(
sample
->
media_buffer
);
IMFMediaBuffer_Release
(
sample
->
media_buffer
);
IMFSample_Release
(
sample
->
sample
);
free
(
sample
);
}
static
void
wg_sample_queue_begin_append
(
struct
wg_sample_queue
*
queue
,
struct
wg_sample
*
wg_sample
)
{
struct
sample
*
sample
=
CONTAINING_RECORD
(
wg_sample
,
struct
sample
,
wg_sample
);
/* make sure a concurrent wg_sample_queue_flush call won't release the sample until we're done */
InterlockedIncrement
(
&
wg_sample
->
refcount
);
sample
->
wg_sample
.
flags
|=
WG_SAMPLE_FLAG_HAS_REFCOUNT
;
EnterCriticalSection
(
&
queue
->
cs
);
list_add_tail
(
&
queue
->
samples
,
&
sample
->
entry
);
LeaveCriticalSection
(
&
queue
->
cs
);
}
static
void
wg_sample_queue_end_append
(
struct
wg_sample_queue
*
queue
,
struct
wg_sample
*
wg_sample
)
{
/* release temporary ref taken in wg_sample_queue_begin_append */
InterlockedDecrement
(
&
wg_sample
->
refcount
);
wg_sample_queue_flush
(
queue
,
false
);
}
void
wg_sample_queue_flush
(
struct
wg_sample_queue
*
queue
,
bool
all
)
{
struct
sample
*
sample
,
*
next
;
EnterCriticalSection
(
&
queue
->
cs
);
LIST_FOR_EACH_ENTRY_SAFE
(
sample
,
next
,
&
queue
->
samples
,
struct
sample
,
entry
)
{
if
(
!
InterlockedOr
(
&
sample
->
wg_sample
.
refcount
,
0
)
||
all
)
{
list_remove
(
&
sample
->
entry
);
wg_sample_release
(
&
sample
->
wg_sample
);
}
}
LeaveCriticalSection
(
&
queue
->
cs
);
}
HRESULT
wg_sample_queue_create
(
struct
wg_sample_queue
**
out
)
{
struct
wg_sample_queue
*
queue
;
if
(
!
(
queue
=
calloc
(
1
,
sizeof
(
*
queue
))))
return
E_OUTOFMEMORY
;
InitializeCriticalSection
(
&
queue
->
cs
);
queue
->
cs
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": cs"
);
list_init
(
&
queue
->
samples
);
TRACE
(
"Created wg_sample_queue %p.
\n
"
,
queue
);
*
out
=
queue
;
return
S_OK
;
}
void
wg_sample_queue_destroy
(
struct
wg_sample_queue
*
queue
)
{
wg_sample_queue_flush
(
queue
,
true
);
queue
->
cs
.
DebugInfo
->
Spare
[
0
]
=
0
;
InitializeCriticalSection
(
&
queue
->
cs
);
free
(
queue
);
}
HRESULT
wg_transform_push_mf
(
struct
wg_transform
*
transform
,
struct
wg_sample
*
wg_sample
,
struct
wg_sample_queue
*
queue
)
{
struct
sample
*
sample
=
CONTAINING_RECORD
(
wg_sample
,
struct
sample
,
wg_sample
);
LONGLONG
time
,
duration
;
UINT32
value
;
HRESULT
hr
;
if
(
SUCCEEDED
(
IMFSample_GetSampleTime
(
sample
->
sample
,
&
time
)))
{
sample
->
wg_sample
.
flags
|=
WG_SAMPLE_FLAG_HAS_PTS
;
sample
->
wg_sample
.
pts
=
time
;
}
if
(
SUCCEEDED
(
IMFSample_GetSampleDuration
(
sample
->
sample
,
&
duration
)))
{
sample
->
wg_sample
.
flags
|=
WG_SAMPLE_FLAG_HAS_DURATION
;
sample
->
wg_sample
.
duration
=
duration
;
}
if
(
SUCCEEDED
(
IMFSample_GetUINT32
(
sample
->
sample
,
&
MFSampleExtension_CleanPoint
,
&
value
))
&&
value
)
sample
->
wg_sample
.
flags
|=
WG_SAMPLE_FLAG_SYNC_POINT
;
wg_sample_queue_begin_append
(
queue
,
wg_sample
);
hr
=
wg_transform_push_data
(
transform
,
wg_sample
);
wg_sample_queue_end_append
(
queue
,
wg_sample
);
return
hr
;
}
HRESULT
wg_transform_read_mf
(
struct
wg_transform
*
transform
,
struct
wg_sample
*
wg_sample
,
struct
wg_format
*
format
)
{
struct
sample
*
sample
=
CONTAINING_RECORD
(
wg_sample
,
struct
sample
,
wg_sample
);
HRESULT
hr
;
if
(
FAILED
(
hr
=
wg_transform_read_data
(
transform
,
wg_sample
,
format
)))
return
hr
;
IMFMediaBuffer_SetCurrentLength
(
sample
->
media_buffer
,
wg_sample
->
size
);
if
(
wg_sample
->
flags
&
WG_SAMPLE_FLAG_HAS_PTS
)
IMFSample_SetSampleTime
(
sample
->
sample
,
wg_sample
->
pts
);
if
(
wg_sample
->
flags
&
WG_SAMPLE_FLAG_HAS_DURATION
)
IMFSample_SetSampleDuration
(
sample
->
sample
,
wg_sample
->
duration
);
if
(
wg_sample
->
flags
&
WG_SAMPLE_FLAG_SYNC_POINT
)
IMFSample_SetUINT32
(
sample
->
sample
,
&
MFSampleExtension_CleanPoint
,
1
);
return
S_OK
;
}
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