Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BC
public
mediastreamer2
Commits
e8172d17
Commit
e8172d17
authored
May 12, 2010
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new video display starts working still with bugs
parent
bc6c0ed4
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
166 additions
and
65 deletions
+166
-65
include/mediastreamer2/msinterfaces.h
include/mediastreamer2/msinterfaces.h
+1
-0
include/mediastreamer2/msqueue.h
include/mediastreamer2/msqueue.h
+4
-0
src/drawdib-display.c
src/drawdib-display.c
+157
-61
tests/videodisplay.c
tests/videodisplay.c
+4
-4
No files found.
include/mediastreamer2/msinterfaces.h
View file @
e8172d17
...
...
@@ -40,4 +40,5 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MS_VIDEO_DISPLAY_GET_NATIVE_WINDOW_ID \
MS_FILTER_METHOD(MSFilterVideoDisplayInterface,3,long)
#endif
include/mediastreamer2/msqueue.h
View file @
e8172d17
...
...
@@ -51,6 +51,10 @@ static inline mblk_t * ms_queue_peek_last(MSQueue *q){
return
qlast
(
&
q
->
q
);
}
static
inline
void
ms_queue_remove
(
MSQueue
*
q
,
mblk_t
*
m
){
remq
(
&
q
->
q
,
m
);
}
static
inline
bool_t
ms_queue_empty
(
MSQueue
*
q
){
return
qempty
(
&
q
->
q
);
}
...
...
src/drawdib-display.c
View file @
e8172d17
...
...
@@ -24,13 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msvideo.h"
/*required for dllexport of win_display_desc */
#define INVIDEOUT_C 1
#include "mediastreamer2/msvideoout.h"
#include "ffmpeg-priv.h"
#define SCALE_FACTOR
4.0
f
#define SCALE_FACTOR
0.1
f
#define SELVIEW_POS_INACTIVE -100.0
#include <Vfw.h>
...
...
@@ -95,13 +91,13 @@ static void yuv2rgb_process(Yuv2RgbCtx *ctx, MSPicture *src, MSVideoSize dstsize
static
void
yuv2rgb_draw
(
Yuv2RgbCtx
*
ctx
,
HDRAWDIB
ddh
,
HDC
hdc
,
int
dstx
,
int
dsty
){
if
(
ctx
->
rgb
){
BITMAPINFOHEADER
bi
;
memset
(
&
bi
,
0
,
sizeof
(
bi
));
bi
.
biSize
=
sizeof
(
bi
);
bi
.
biWidth
=
ctx
->
dsize
.
width
;
bi
.
biHeight
=
ctx
->
dsize
.
height
;
bi
.
biPlanes
=
1
;
bi
.
biBitCount
=
24
;
bi
.
biCompression
=
BI_RGB
;
memset
(
&
bi
,
0
,
sizeof
(
bi
));
bi
.
biSize
=
sizeof
(
bi
);
bi
.
biWidth
=
ctx
->
dsize
.
width
;
bi
.
biHeight
=
ctx
->
dsize
.
height
;
bi
.
biPlanes
=
1
;
bi
.
biBitCount
=
24
;
bi
.
biCompression
=
BI_RGB
;
bi
.
biSizeImage
=
ctx
->
rgblen
;
DrawDibDraw
(
ddh
,
hdc
,
dstx
,
dsty
,
ctx
->
dsize
.
width
,
ctx
->
dsize
.
height
,
&
bi
,
ctx
->
rgb
,
0
,
0
,
ctx
->
dsize
.
width
,
ctx
->
dsize
.
height
,
0
);
...
...
@@ -111,9 +107,11 @@ static void yuv2rgb_draw(Yuv2RgbCtx *ctx, HDRAWDIB ddh, HDC hdc, int dstx, int d
typedef
struct
_DDDisplay
{
HWND
window
;
HDRAWDIB
ddh
;
MSVideoSize
defsize
;
MSVideoSize
vsize
;
MSVideoSize
lsize
;
Yuv2RgbCtx
mainview
;
Yuv2RgbCtx
locview
;
bool_t
need_repaint
;
}
DDDisplay
;
static
LRESULT
CALLBACK
window_proc
(
...
...
@@ -122,6 +120,7 @@ static LRESULT CALLBACK window_proc(
WPARAM
wParam
,
// first message parameter
LPARAM
lParam
)
// second message parameter
{
DDDisplay
*
wd
=
(
DDDisplay
*
)
GetWindowLongPtr
(
hwnd
,
GWLP_USERDATA
);
switch
(
uMsg
){
case
WM_DESTROY
:
break
;
...
...
@@ -129,9 +128,9 @@ static LRESULT CALLBACK window_proc(
if
(
wParam
==
SIZE_RESTORED
){
int
h
=
(
lParam
>>
16
)
&
0xffff
;
int
w
=
lParam
&
0xffff
;
DDDisplay
*
wd
;
ms_message
(
"Resized to %i,%i"
,
w
,
h
);
wd
=
(
DDDisplay
*
)
GetWindowLongPtr
(
hwnd
,
GWLP_USERDATA
);
if
(
wd
!=
NULL
){
//wd->window_size.width=w;
//wd->window_size.height=h;
...
...
@@ -140,6 +139,11 @@ static LRESULT CALLBACK window_proc(
}
}
break
;
case
WM_PAINT
:
ms_message
(
"Need repaint"
);
if
(
wd
!=
NULL
){
wd
->
need_repaint
=
TRUE
;
}
default:
return
DefWindowProc
(
hwnd
,
uMsg
,
wParam
,
lParam
);
}
...
...
@@ -187,25 +191,20 @@ static HWND create_window(int w, int h)
static
void
dd_display_init
(
MSFilter
*
f
){
DDDisplay
*
obj
=
(
DDDisplay
*
)
ms_new0
(
DDDisplay
,
1
);
obj
->
defsize
.
width
=
MS_VIDEO_SIZE_CIF_W
;
obj
->
defsize
.
height
=
MS_VIDEO_SIZE_CIF_H
;
obj
->
vsize
.
width
=
MS_VIDEO_SIZE_CIF_W
;
obj
->
vsize
.
height
=
MS_VIDEO_SIZE_CIF_H
;
obj
->
lsize
.
width
=
MS_VIDEO_SIZE_CIF_W
;
obj
->
lsize
.
height
=
MS_VIDEO_SIZE_CIF_H
;
yuv2rgb_init
(
&
obj
->
mainview
);
yuv2rgb_init
(
&
obj
->
locview
);
obj
->
need_repaint
=
FALSE
;
f
->
data
=
obj
;
}
static
void
dd_display_uninit
(
MSFilter
*
f
){
DDDisplay
*
obj
=
(
DDDisplay
*
)
f
->
data
;
yuv2rgb_uninit
(
&
obj
->
mainview
);
yuv2rgb_uninit
(
&
obj
->
locview
);
ms_free
(
obj
);
}
static
void
dd_display_prepare
(
MSFilter
*
f
){
DDDisplay
*
dd
=
(
DDDisplay
*
)
f
->
data
;
if
(
dd
->
window
==
NULL
){
dd
->
window
=
create_window
(
dd
->
def
size
.
width
,
dd
->
def
size
.
height
);
dd
->
window
=
create_window
(
dd
->
v
size
.
width
,
dd
->
v
size
.
height
);
SetWindowLong
(
dd
->
window
,
GWL_USERDATA
,(
long
)
dd
);
dd
->
ddh
=
DrawDibOpen
();
}
...
...
@@ -219,71 +218,168 @@ static void dd_display_unprepare(MSFilter *f){
}
if
(
dd
->
ddh
!=
NULL
){
DrawDibClose
(
dd
->
ddh
);
dd
->
ddh
=
NULL
;
}
}
static
void
dd_display_uninit
(
MSFilter
*
f
){
DDDisplay
*
obj
=
(
DDDisplay
*
)
f
->
data
;
dd_display_unprepare
(
f
);
yuv2rgb_uninit
(
&
obj
->
mainview
);
yuv2rgb_uninit
(
&
obj
->
locview
);
ms_free
(
obj
);
}
static
void
dd_display_preprocess
(
MSFilter
*
f
){
dd_display_prepare
(
f
);
}
/* compute the ideal placement of the video within a window of size wsize,
given that the original video has size vsize. Put the result in rect*/
static
void
center_with_ratio
(
MSVideoSize
wsize
,
MSVideoSize
vsize
,
MSRect
*
rect
){
int
w
,
h
;
w
=
wsize
.
width
&
~
0x1
;
h
=
((
w
*
vsize
.
height
)
/
vsize
.
width
)
&
~
0x1
;
if
(
h
>
wsize
.
height
){
/*the height doesn't fit, so compute the width*/
h
=
wsize
.
height
&
~
0x1
;
w
=
((
h
*
vsize
.
width
)
/
vsize
.
height
)
&
~
0x1
;
}
rect
->
x
=
(
wsize
.
width
-
w
)
/
2
;
rect
->
y
=
(
wsize
.
height
-
h
)
/
2
;
rect
->
w
=
w
;
rect
->
h
=
h
;
}
static
void
compute_layout
(
MSVideoSize
wsize
,
MSVideoSize
vsize
,
MSVideoSize
orig_psize
,
MSRect
*
mainrect
,
MSRect
*
localrect
){
MSVideoSize
psize
;
center_with_ratio
(
wsize
,
vsize
,
mainrect
);
psize
.
width
=
wsize
.
width
*
SCALE_FACTOR
;
psize
.
height
=
wsize
.
height
*
SCALE_FACTOR
;
center_with_ratio
(
psize
,
orig_psize
,
localrect
);
localrect
->
x
=
wsize
.
width
-
localrect
->
w
;
localrect
->
y
=
wsize
.
height
-
localrect
->
h
;
ms_message
(
"Compute layout result for
\n
window size=%ix%i
\n
video orig size=%ix%i
\n
local size=%ix%i
\n
local orig size=%ix%i
\n
"
"mainrect=%i,%i,%i,%i
\t
localrect=%i,%i,%i,%i"
,
wsize
.
width
,
wsize
.
height
,
vsize
.
width
,
vsize
.
height
,
psize
.
width
,
psize
.
height
,
orig_psize
.
width
,
orig_psize
.
height
,
mainrect
->
x
,
mainrect
->
y
,
mainrect
->
w
,
mainrect
->
h
,
localrect
->
x
,
localrect
->
y
,
localrect
->
w
,
localrect
->
h
);
}
static
void
draw_background
(
HDC
hdc
,
MSVideoSize
wsize
,
MSRect
mainrect
){
HBRUSH
brush
;
RECT
brect
;
brush
=
CreateSolidBrush
(
RGB
(
0
,
0
,
0
));
if
(
mainrect
.
x
>
0
){
brect
.
left
=
0
;
brect
.
top
=
0
;
brect
.
right
=
mainrect
.
x
;
brect
.
bottom
=
wsize
.
height
;
FillRect
(
hdc
,
&
brect
,
brush
);
brect
.
left
=
mainrect
.
x
+
mainrect
.
w
;
brect
.
top
=
0
;
brect
.
right
=
wsize
.
width
;
brect
.
bottom
=
wsize
.
height
;
FillRect
(
hdc
,
&
brect
,
brush
);
}
if
(
mainrect
.
y
>
0
){
brect
.
left
=
0
;
brect
.
top
=
0
;
brect
.
right
=
wsize
.
width
;
brect
.
bottom
=
mainrect
.
y
;
FillRect
(
hdc
,
&
brect
,
brush
);
brect
.
left
=
0
;
brect
.
top
=
mainrect
.
y
+
mainrect
.
h
;
brect
.
right
=
wsize
.
width
;
brect
.
bottom
=
wsize
.
height
;
FillRect
(
hdc
,
&
brect
,
brush
);
}
if
(
mainrect
.
w
==
0
&&
mainrect
.
h
==
0
){
/*no image yet, black everything*/
brect
.
left
=
brect
.
top
=
0
;
brect
.
right
=
wsize
.
width
;
brect
.
bottom
=
wsize
.
height
;
FillRect
(
hdc
,
&
brect
,
brush
);
}
DeleteObject
(
brush
);
}
static
void
dd_display_process
(
MSFilter
*
f
){
DDDisplay
*
obj
=
(
DDDisplay
*
)
f
->
data
;
mblk_t
*
inm
;
RECT
rect
;
MSVideoSize
wsize
;
MSVideoSize
vsize
;
MSVideoSize
p
size
;
/*preview size*/
MSVideoSize
l
size
;
/*
local
preview size*/
HDC
hdc
;
MSRect
mainrect
;
MSRect
localrect
;
bool_t
update_local
=
FALSE
;
bool_t
update_main
=
FALSE
;
MSPicture
mainpic
;
MSPicture
localpic
;
mblk_t
*
main_im
=
NULL
;
mblk_t
*
local_im
=
NULL
;
GetClientRect
(
obj
->
window
,
&
rect
);
wsize
.
width
=
rect
.
right
;
wsize
.
height
=
rect
.
bottom
;
vsize
.
width
=
rect
.
right
;
vsize
.
height
=
rect
.
bottom
;
psize
.
width
=
vsize
.
width
*
SCALE_FACTOR
;
psize
.
height
=
vsize
.
height
*
SCALE_FACTOR
;
localrect
.
x
=
wsize
.
width
-
(
wsize
.
width
*
SCALE_FACTOR
);
localrect
.
y
=
wsize
.
height
-
(
wsize
.
height
*
SCALE_FACTOR
);
/*get most recent message and draw it*/
if
(
f
->
inputs
[
1
]
!=
NULL
&&
(
inm
=
ms_queue_peek_last
(
f
->
inputs
[
1
]))
!=
0
)
{
MSPicture
src
;
if
(
yuv_buf_init_from_mblk
(
&
src
,
inm
)
==
0
){
yuv2rgb_process
(
&
obj
->
locview
,
&
src
,
psize
);
update_local
=
TRUE
;
if
(
f
->
inputs
[
1
]
!=
NULL
&&
(
local_im
=
ms_queue_peek_last
(
f
->
inputs
[
1
]))
!=
NULL
)
{
if
(
yuv_buf_init_from_mblk
(
&
localpic
,
local_im
)
==
0
){
obj
->
lsize
.
width
=
localpic
.
w
;
obj
->
lsize
.
height
=
localpic
.
h
;
}
ms_queue_flush
(
f
->
inputs
[
1
]);
}
if
(
f
->
inputs
[
0
]
!=
NULL
&&
(
inm
=
ms_queue_peek_last
(
f
->
inputs
[
0
]))
!=
0
)
{
MSPicture
src
;
if
(
yuv_buf_init_from_mblk
(
&
src
,
inm
)
==
0
){
yuv2rgb_process
(
&
obj
->
mainview
,
&
src
,
vsize
);
update_main
=
TRUE
;
update_local
=
TRUE
;
if
(
f
->
inputs
[
0
]
!=
NULL
&&
(
main_im
=
ms_queue_peek_last
(
f
->
inputs
[
0
]))
!=
NULL
)
{
if
(
yuv_buf_init_from_mblk
(
&
mainpic
,
main_im
)
==
0
){
obj
->
vsize
.
width
=
mainpic
.
w
;
obj
->
vsize
.
height
=
mainpic
.
h
;
}
ms_queue_flush
(
f
->
inputs
[
0
]);
ms_message
(
"Got new image of size %ix%i to display on a window of size %ix%i"
,
src
.
w
,
src
.
h
,
vsize
.
width
,
vsize
.
height
);
}
hdc
=
GetDC
(
obj
->
window
);
if
(
hdc
==
NULL
)
{
ms_error
(
"Could not get window dc"
);
return
;
}
if
(
update_main
){
yuv2rgb_draw
(
&
obj
->
mainview
,
obj
->
ddh
,
hdc
,
0
,
0
);
compute_layout
(
wsize
,
obj
->
vsize
,
obj
->
lsize
,
&
mainrect
,
&
localrect
);
vsize
.
width
=
mainrect
.
w
;
vsize
.
height
=
mainrect
.
h
;
lsize
.
width
=
localrect
.
w
;
lsize
.
height
=
localrect
.
h
;
if
(
local_im
!=
NULL
)
yuv2rgb_process
(
&
obj
->
locview
,
&
localpic
,
lsize
);
if
(
main_im
!=
NULL
)
yuv2rgb_process
(
&
obj
->
mainview
,
&
mainpic
,
vsize
);
hdc
=
GetDC
(
obj
->
window
);
if
(
hdc
==
NULL
)
{
ms_error
(
"Could not get window dc"
);
return
;
}
if
(
main_im
){
yuv2rgb_draw
(
&
obj
->
mainview
,
obj
->
ddh
,
hdc
,
mainrect
.
x
,
mainrect
.
y
);
}
if
(
update_
local
){
if
(
local
_im
){
yuv2rgb_draw
(
&
obj
->
locview
,
obj
->
ddh
,
hdc
,
localrect
.
x
,
localrect
.
y
);
}
if
(
obj
->
need_repaint
){
draw_background
(
hdc
,
wsize
,
mainrect
);
obj
->
need_repaint
=
FALSE
;
}
ReleaseDC
(
NULL
,
hdc
);
if
(
main_im
!=
NULL
)
ms_queue_flush
(
f
->
inputs
[
0
]);
if
(
local_im
!=
NULL
)
ms_queue_flush
(
f
->
inputs
[
1
]);
}
static
int
get_native_window_id
(
MSFilter
*
f
,
void
*
data
){
DDDisplay
*
obj
=
(
DDDisplay
*
)
f
->
data
;
*
(
long
*
)
data
=
(
long
)
obj
->
window
;
return
0
;
}
static
MSFilterMethod
methods
[]
=
{
{
MS_VIDEO_DISPLAY_GET_NATIVE_WINDOW_ID
,
get_native_window_id
},
{
0
,
NULL
}
};
...
...
tests/videodisplay.c
View file @
e8172d17
...
...
@@ -76,22 +76,22 @@ int main(int argc, char *argv[]){
if
(
n
==
500
)
{
int
corner
=
1
;
ms_filter_call_method
(
vs
->
output
,
MS_VIDEO_
OUT_SET
_CORNER
,
&
corner
);
ms_filter_call_method
(
vs
->
output
,
MS_VIDEO_
DISPLAY_SET_LOCAL_VIEW
_CORNER
,
&
corner
);
}
if
(
n
==
600
)
{
int
corner
=
2
;
ms_filter_call_method
(
vs
->
output
,
MS_VIDEO_
OUT_SET
_CORNER
,
&
corner
);
ms_filter_call_method
(
vs
->
output
,
MS_VIDEO_
DISPLAY_SET_LOCAL_VIEW
_CORNER
,
&
corner
);
}
if
(
n
==
700
)
{
int
corner
=
3
;
ms_filter_call_method
(
vs
->
output
,
MS_VIDEO_
OUT_SET
_CORNER
,
&
corner
);
ms_filter_call_method
(
vs
->
output
,
MS_VIDEO_
DISPLAY_SET_LOCAL_VIEW
_CORNER
,
&
corner
);
}
if
(
n
==
800
)
{
int
corner
=-
1
;
ms_filter_call_method
(
vs
->
output
,
MS_VIDEO_
OUT_SET
_CORNER
,
&
corner
);
ms_filter_call_method
(
vs
->
output
,
MS_VIDEO_
DISPLAY_SET_LOCAL_VIEW
_CORNER
,
&
corner
);
}
if
(
n
==
900
)
{
...
...
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