1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000 |
- #include "precompile.h"
- #include "videoplayer.h"
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <vfw.h>
- #include <assert.h>
- #define av_always_inline __inline
- #define inline __inline
- #include <libswscale\swscale.h>
- #include "video_common/ffmpeg_api_adapter.h"
- #define WM_MSG_INIT (WM_APP+1)
- #define WM_MSG_CLEAR (WM_APP+2)
- #define WM_MSG_FRAME (WM_APP+3)
- #define FRAME_MIN_CACHE_MSEC 125
- #define FRAME_MAX_CACHE_MSEC 500
- #define FRAME_QUEUE_LEGNTH 50
- enum eVideoSizeMode{
- eNormalSize,
- eDoubleSize,
- eZoomOutSize
- };
- typedef enum eVideoSizeMode eVideoSizeMode;
- typedef struct frame_entry
- {
- video_frame *raw_frame;
- videoplayer_free_frame free_frame;
- void *free_frame_user_data;
- DWORD dwTick;
- }frame_entry;
- #pragma pack(push,1)
- struct winthunk_t
- {
- DWORD m_mov;
- DWORD m_this;
- BYTE m_jmp;
- DWORD m_relproc;
- };
- #pragma pack(pop)
- struct videoplayer_t
- {
- struct winthunk_t thunk;
- HWND hWndVideo;
- int x;
- int y;
- int cx;
- int cy;
- int fps_num;
- int fps_den;
- int width;
- int height;
- WNDPROC oldWndProc;
- int flags;
- eVideoSizeMode esizemode; // double size mode
- struct SwsContext *double_size_sws_context;
- LPVOID double_size_data;
- struct SwsContext *zoomout_size_sws_context;
- LPVOID zoomout_size_data;
- frame_entry current_frame;
- CRITICAL_SECTION q_lock;
- frame_entry frames[FRAME_QUEUE_LEGNTH];
- int q_head;
- int q_tail;
- int q_caching;
- LPVOID black_frame_data;
- LPVOID res_frame_data;
- struct SwsContext *sws_context;
- DWORD dwPlayTimer;
- HDRAWDIB hdib;
- int min_cache_size;
- int max_cache_size;
- videoplayer_on_pull on_pull;
- videoplayer_free_frame free_frame;
- void *user_data;
- char name[16];
- };
- #ifndef SMALL_RECORD_VIDEO_WIDTH
- #define SMALL_RECORD_VIDEO_WIDTH 244
- #endif
- #ifndef SMALL_RECORD_VIDEO_HEIGHT
- #define SMALL_RECORD_VIDEO_HEIGHT 138
- #endif
- // use thunk tech
- #define QUEUE_SIZE(head, tail, length) (((tail)+(length)-(head))%(length))
- #define QUEUE_INC(x, length) (((x) + 1) % (length))
- int nWindowState = 0;
- int bMove = 0;
- static RECT g_Rect;
- int IsHideRemoteWin = 0;
- int IsHideLocalWin = 0;
- static void Dbg(const char *fmt, ...)
- {
- int n;
- va_list arg;
- va_start(arg, fmt);
- n = _vscprintf(fmt, arg);
- if (n > 0) {
- char *buf = (char*)_alloca(n+3);
- vsprintf(buf, fmt, arg);
- strcat(buf, "\r\n");
- OutputDebugStringA(buf);
- }
- va_end(arg);
- }
- static __inline int InRectangle(int xPos, int yPos, int x0, int y0, int cx, int cy)
- {
- return xPos >= x0 && xPos <= x0+cx && yPos >= y0 && yPos <= y0+cy;
- }
- static __inline void free_frame_entry(videoplayer_t *player, struct frame_entry *entry)
- {
- if (entry && entry->raw_frame) {
- (*entry->free_frame)(player, entry->free_frame_user_data, entry->raw_frame);
- }
- }
- static int init_thunk(struct winthunk_t *thunk, DWORD_PTR proc, videoplayer_t *player)
- {
- thunk->m_mov = 0x042444C7;
- thunk->m_this = (DWORD)player;
- thunk->m_jmp = 0xe9;
- thunk->m_relproc = (DWORD)((INT_PTR)proc - ((INT_PTR)player+sizeof(struct winthunk_t)));
- FlushInstructionCache(GetCurrentProcess(), thunk, sizeof(struct winthunk_t));
- return 0;
- }
- static void display_frame_entry(videoplayer_t *player, video_frame *frame);
- static BOOL is_parent_window_of(HWND x, HWND y)
- {
- HWND t = GetParent(y);
- while (t) {
- if (t == x)
- return TRUE;
- t = GetParent(t);
- }
- return FALSE;
- }
- static void check_on_top(videoplayer_t *player)
- {
- RECT rc;
- if (GetWindowRect(player->hWndVideo, &rc)) {
- HWND hWnd;
- POINT t;
- t.x = (rc.left + rc.right) >> 1;
- t.y = (rc.top + rc.bottom) >> 1;
- hWnd = WindowFromPoint(t);
- if (hWnd && hWnd != player->hWndVideo) {
- //if (!is_parent_window_of(hWnd, player->hWndVideo) && !is_parent_window_of(player->hWndVideo, hWnd)) {
- BringWindowToTop(player->hWndVideo);
- //MessageBeep(MB_OK);
- //}
- }
- }
- }
- static void OnMsgFrame(videoplayer_t *player, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- frame_entry *entry = (frame_entry*)wParam;
- display_frame_entry(player, entry->raw_frame);
- free_frame_entry(player, &player->current_frame);
- player->current_frame.raw_frame = entry->raw_frame;
- player->current_frame.free_frame = entry->free_frame;
- player->current_frame.free_frame_user_data = entry->free_frame_user_data;
- player->current_frame.dwTick = entry->dwTick;
- entry->raw_frame = NULL;
- free(entry);
- }
- static void display_frame_entry(videoplayer_t *player, video_frame *frame)
- {
- if (NULL == player || NULL == frame){
- return;
- }
- if (player->flags & VIDEOPLAYER_FLAG_CHECKTOP) {
- check_on_top(player);
- }
- if (player->hdib) {
- HDC hdc;
- hdc = GetDC(player->hWndVideo);
- if (hdc) {
- if (eDoubleSize == player->esizemode) {
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- unsigned char *src_data[4] = {frame->data[0], NULL, NULL, NULL};
- int src_linesize[4] = {player->width*3, 0, 0, 0};
- unsigned char *dst_data[4] = {player->double_size_data, NULL, NULL, NULL};
- int dst_linesize[4] = {player->cx*2*3, 0, 0, 0};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;//pr->bpp;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy<<1;
- bmpheader.biWidth = player->cx<<1;
- sws_scale(player->double_size_sws_context, src_data, src_linesize,
- 0, player->height, dst_data, dst_linesize);
- DrawDibDraw(player->hdib, hdc, 0, 0, -1, -1, &bmpheader, player->double_size_data, 0, 0, player->cx<<1, player->cy<<1, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- else if(eZoomOutSize == player->esizemode){
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- unsigned char *src_data[4] = {frame->data[0], NULL, NULL, NULL};
- int src_linesize[4] = {player->width*3, 0, 0, 0};
- unsigned char *dst_data[4] = {player->zoomout_size_data, NULL, NULL, NULL};
- int dst_linesize[4] = {SMALL_RECORD_VIDEO_WIDTH*3, 0, 0, 0};
- //{
- // static int icount = 0;
- // if (icount == 0)
- // {
- // video_frame frame;
- // video_frame_alloc(320, 240, VIDEO_FORMAT_RGB24, &frame);
- // video_frame_fill_black(&frame);
- // frame.data[0] = src_data[0];
- // frame.linesize[0] = src_linesize[0];
- // video_frame_save_bmpfile("d:\\src.bmp", &frame);
- // icount++;
- // }
- //}
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;//pr->bpp;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = SMALL_RECORD_VIDEO_HEIGHT;
- bmpheader.biWidth = SMALL_RECORD_VIDEO_WIDTH;
- sws_scale(player->zoomout_size_sws_context, src_data, src_linesize,
- 0, player->height, dst_data, dst_linesize);
- //{
- // static int icount = 0;
- // if (icount == 0)
- // {
- // video_frame frame;
- // video_frame_alloc(SMALL_RECORD_VIDEO_WIDTH, SMALL_RECORD_VIDEO_HEIGHT, VIDEO_FORMAT_RGB24, &frame);
- // video_frame_fill_black(&frame);
- // frame.data[0] = /*dst_data[0];*/ (unsigned char*)player->zoomout_size_data;
- // frame.linesize[0] = dst_linesize[0];
- // video_frame_save_bmpfile("d:\\dest.bmp", &frame);
- // icount++;
- // }
- //}
- DrawDibDraw(player->hdib, hdc, 0, 0, -1, -1, &bmpheader, player->zoomout_size_data, 0, 0, SMALL_RECORD_VIDEO_WIDTH, SMALL_RECORD_VIDEO_HEIGHT, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- else{
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;//pr->bpp;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy;
- bmpheader.biWidth = player->cx;
- if (player->sws_context) {
- unsigned char *src_data[4] = {frame->data[0], NULL, NULL, NULL};
- int src_linesize[4] = {player->width*3, 0, 0, 0};
- unsigned char *dst_data[4] = {player->res_frame_data, NULL, NULL, NULL};
- int dst_linesize[4] = {player->cx*3, 0, 0, 0};
- sws_scale(player->sws_context, src_data, src_linesize,
- 0, player->height, dst_data, dst_linesize);
- DrawDibDraw(player->hdib, hdc, 0, 0, -1, -1, &bmpheader, player->res_frame_data, 0, 0, player->cx, player->cy, DDF_SAME_DRAW|DDF_SAME_HDC);
- } else {
- DrawDibDraw(player->hdib, hdc, 0, 0, -1, -1, &bmpheader, frame->data[0], 0, 0, player->cx, player->cy, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- }
- ReleaseDC(player->hWndVideo, hdc);
- }
- }
- }
- static void display_black_frame(videoplayer_t *player)
- {
- if (player->flags & VIDEOPLAYER_FLAG_CHECKTOP) {
- check_on_top(player);
- }
- if (player->hdib) {
- HDC hdc;
- hdc = GetDC(player->hWndVideo);
- if (hdc) {
- if (eDoubleSize == player->esizemode) {
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- unsigned char *src_data[4] = {player->black_frame_data, NULL, NULL, NULL};
- int src_linesize[4] = {player->cx*3, 0, 0, 0};
- unsigned char *dst_data[4] = {player->double_size_data, NULL, NULL, NULL};
- int dst_linesize[4] = {player->cx*2*3, 0, 0, 0};
- sws_scale(player->double_size_sws_context, src_data, src_linesize,
- 0, player->height, dst_data, dst_linesize);
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;//pr->bpp;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy<<1;
- bmpheader.biWidth = player->cx<<1;
- DrawDibDraw(player->hdib, hdc, 0, 0, -1, -1, &bmpheader, player->double_size_data, 0, 0, player->cx<<1, player->cy<<1, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- else if(eZoomOutSize == player->esizemode){
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- unsigned char *src_data[4] = {player->black_frame_data, NULL, NULL, NULL};
- int src_linesize[4] = {player->cx*3, 0, 0, 0};
- unsigned char *dst_data[4] = {player->zoomout_size_data, NULL, NULL, NULL};
- int dst_linesize[4] = {SMALL_RECORD_VIDEO_WIDTH*3, 0, 0, 0};
- sws_scale(player->zoomout_size_sws_context, src_data, src_linesize,
- 0, player->height, dst_data, dst_linesize);
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;//pr->bpp;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = SMALL_RECORD_VIDEO_HEIGHT;
- bmpheader.biWidth = SMALL_RECORD_VIDEO_WIDTH;
- DrawDibDraw(player->hdib, hdc, 0, 0, -1, -1, &bmpheader, player->zoomout_size_data, 0, 0, SMALL_RECORD_VIDEO_WIDTH, SMALL_RECORD_VIDEO_HEIGHT, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- else{
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;//pr->bpp;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy;
- bmpheader.biWidth = player->cx;
- DrawDibDraw(player->hdib, hdc, 0, 0, -1, -1, &bmpheader, player->black_frame_data, 0, 0, player->cx, player->cy, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- ReleaseDC(player->hWndVideo, hdc);
- }
- }
- }
- static void OnMsgTimer_PushMode(videoplayer_t *player, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- DWORD dwNow = GetTickCount();
- EnterCriticalSection(&player->q_lock);
- //获取窗口显示状态
- nWindowState = player->on_pull(player, player->user_data,NULL);
- if (player->q_caching) {
- OutputDebugStringA("caching\n");
- while (player->q_tail != player->q_head) {
- frame_entry *entry = &player->frames[player->q_head];
- if (dwNow - entry->dwTick > 3000) {
- player->q_head = QUEUE_INC(player->q_head, FRAME_QUEUE_LEGNTH);
- free_frame_entry(player, entry);
- } else {
- break;
- }
- }
- } else {
- int displayed = 0;
- //if (player->q_head == player->q_tail)
- while (player->q_tail != player->q_head) {
- frame_entry *entry = &player->frames[player->q_head];
- player->q_head = QUEUE_INC(player->q_head, FRAME_QUEUE_LEGNTH);
- if (dwNow - entry->dwTick > 3000) {
- //Dbg("clear frame");
- free_frame_entry(player, entry);
- } else {
- //Dbg("display frame");
- display_frame_entry(player, entry->raw_frame);
- displayed = TRUE;
- free_frame_entry(player, &player->current_frame);
- player->current_frame.raw_frame = entry->raw_frame;
- player->current_frame.free_frame = entry->free_frame;
- player->current_frame.free_frame_user_data = entry->free_frame_user_data;
- player->current_frame.dwTick = entry->dwTick;
- entry->raw_frame = NULL;
- break;
- }
- }
- if (!displayed) {
- player->q_caching = TRUE;
- Dbg("recaching");
- }
- }
- LeaveCriticalSection(&player->q_lock);
- }
- static void OnMsgTimer_PullMode(videoplayer_t *player, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- video_frame *frame = NULL;
- nWindowState = player->on_pull(player, player->user_data, &frame);
- display_frame_entry(player, frame);
- player->free_frame(player, player->user_data, frame);
- }
- static void OnMsgInit(videoplayer_t *player, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- HDC hdc;
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy;
- bmpheader.biWidth = player->cx;
- player->hdib = DrawDibOpen();
- if (!player->hdib)
- return;
- hdc = GetDC(hWnd);
- if (!DrawDibBegin(player->hdib, hdc, player->cx, player->cy, &bmpheader,
- player->cx, player->cy, DDF_SAME_DRAW|DDF_SAME_HDC)) {
- DrawDibClose(player->hdib);
- player->hdib = NULL;
- ReleaseDC(hWnd, hdc);
- return;
- }
- ReleaseDC(hWnd, hdc);
- player->q_head = player->q_tail = 0;
- player->q_caching = 1;
- player->black_frame_data = malloc(player->cx*player->cy*3);
- memset(player->black_frame_data, 0, player->cx*player->cy*3);
- if (player->cx != player->width || player->cy != player->height) {
- player->res_frame_data = malloc(player->cx*player->cy*3);
- player->sws_context = sws_getCachedContext(
- NULL,
- player->width,
- player->height,
- PIX_FMT_BGR24,
- player->cx,
- player->cy,
- PIX_FMT_BGR24,
- SWS_LANCZOS,
- NULL,
- NULL,
- NULL);
- }
- if (player->flags & VIDEOPLAYER_FLAG_DOUBLESIZE) {
- player->double_size_data = malloc(player->cx * player->cy * 4 * 3);
- player->double_size_sws_context = sws_getCachedContext(
- NULL,
- player->width,
- player->height,
- PIX_FMT_BGR24,
- 2 * player->cx,
- 2 * player->cy,
- PIX_FMT_BGR24,
- SWS_LANCZOS,
- NULL,
- NULL,
- NULL);
- }
- if (player->flags & VIDEOPLAYER_FLAG_ZOOMOUTSIZE) {
- player->zoomout_size_data = malloc(SMALL_RECORD_VIDEO_WIDTH*SMALL_RECORD_VIDEO_HEIGHT*3);
- player->zoomout_size_sws_context = sws_getCachedContext(
- NULL,
- player->width,
- player->height,
- PIX_FMT_BGR24,
- SMALL_RECORD_VIDEO_WIDTH,
- SMALL_RECORD_VIDEO_HEIGHT,
- PIX_FMT_BGR24,
- SWS_LANCZOS,
- NULL,
- NULL,
- NULL);
- }
- if (!(player->flags & VIDEOPLAYER_FLAG_NOTIMER)) {
- player->dwPlayTimer = SetTimer(hWnd, 3, 1000*player->fps_den/player->fps_num, NULL);
- }
- }
- static void OnMsgClear(videoplayer_t *player, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- if (player->dwPlayTimer != 0) {
- KillTimer(hWnd, player->dwPlayTimer);
- }
- display_black_frame(player);
- free(player->black_frame_data);
- player->black_frame_data = NULL;
- while (QUEUE_SIZE(player->q_head, player->q_tail, FRAME_QUEUE_LEGNTH)) {
- frame_entry *entry = &player->frames[player->q_head];
- player->q_head = QUEUE_INC(player->q_head, FRAME_QUEUE_LEGNTH);
- free_frame_entry(player, entry);
- }
- assert(player->q_head == player->q_tail);
- if (player->sws_context) {
- free(player->res_frame_data);
- player->res_frame_data = NULL;
- sws_freeContext(player->sws_context);
- player->sws_context = NULL;
- }
- if (player->double_size_sws_context) {
- free(player->double_size_data);
- player->double_size_data = NULL;
- sws_freeContext(player->double_size_sws_context);
- player->double_size_sws_context = NULL;
- }
- if (player->zoomout_size_sws_context) {
- free(player->zoomout_size_data);
- player->zoomout_size_data = NULL;
- sws_freeContext(player->zoomout_size_sws_context);
- player->zoomout_size_sws_context = NULL;
- }
- free_frame_entry(player, &player->current_frame);
- player->q_caching = 0;
- }
- static LRESULT VideoWndProc(videoplayer_t *player, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- {
- char tmp[128];
- sprintf(tmp, "%s, msg=%d, wparam=%d,lparam=%d\n", player->name, msg, wParam, lParam);
- OutputDebugStringA(tmp);
- }
- switch (msg) {
- case WM_MSG_FRAME:
- OnMsgFrame(player, hWnd, msg, wParam, lParam);
- break;
- case WM_MSG_INIT:
- OnMsgInit(player, hWnd, msg, wParam, lParam);
- break;
- case WM_MSG_CLEAR:
- OnMsgClear(player, hWnd, msg, wParam, lParam);
- break;
- case WM_TIMER:
- //是否隐藏本地视频窗口
- if (player->flags & VIDEOPLAYER_FLAG_PULL)
- {
- if ((nWindowState == 2)||(nWindowState == 4))
- {
- if (IsHideLocalWin==0)
- {
- ShowWindow(hWnd,SW_HIDE);
- IsHideLocalWin = 1;
- }
- }
- else if((nWindowState == 0)||(nWindowState == 1)||(nWindowState == 3))
- {
- if (IsHideLocalWin==1)
- {
- ShowWindow(hWnd,SW_SHOW);
- IsHideLocalWin = 0;
- }
- }
- }
- //是否隐藏远端视频窗口
- if (player->flags & VIDEOPLAYER_FLAG_PUSH)
- {
- if (nWindowState == 2)
- {
- if (IsHideRemoteWin==0)
- {
- ShowWindow(hWnd,SW_HIDE);
- IsHideRemoteWin = 1;
- }
- }
- else if((nWindowState == 0)||(nWindowState == 1)||(nWindowState == 3)||(nWindowState == 4))
- {
- if (IsHideRemoteWin==1)
- {
- ShowWindow(hWnd,SW_SHOW);
- IsHideRemoteWin = 0;
- }
- }
- }
- //是否将本地窗口放大显示
- if (((nWindowState==1 && player->cx != 960)&&(bMove==0))&&(player->flags & VIDEOPLAYER_FLAG_PULL)&&(player->flags & VIDEOPLAYER_FLAG_DOUBLESIZE)&&(IsHideLocalWin==0))
- {
- GetWindowRect(hWnd, &g_Rect);
- MoveWindow(hWnd, g_Rect.left, g_Rect.top, player->cx<<1, player->cy<<1, TRUE);
- player->esizemode = eDoubleSize;
- if (player->flags & VIDEOPLAYER_FLAG_DOUBLESIZE)
- {
- int xPos = LOWORD(lParam);
- int yPos = HIWORD(lParam);
- HDC hdc = GetDC(hWnd);
- if (hdc) {
- if (player->hdib) {
- if (eDoubleSize == player->esizemode)
- {
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy<<1;
- bmpheader.biWidth = player->cx<<1;
- DrawDibBegin(player->hdib, hdc, player->cx<<1, player->cy<<1, &bmpheader, player->cx<<1, player->cy<<1, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- else if(eNormalSize == player->esizemode)
- {
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy;
- bmpheader.biWidth = player->cx;
- DrawDibBegin(player->hdib, hdc, player->cx, player->cy, &bmpheader, player->cx, player->cy, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- }
- ReleaseDC(hWnd, hdc);
- }
- }
- bMove = 1;
- }
- else if ((nWindowState==0)&&bMove&&(player->flags & VIDEOPLAYER_FLAG_PULL)&&(player->flags & VIDEOPLAYER_FLAG_DOUBLESIZE || player->flags & VIDEOPLAYER_FLAG_ZOOMOUTSIZE)&&(IsHideLocalWin==0))
- {
- MoveWindow(hWnd, g_Rect.left, g_Rect.top, player->cx, player->cy, TRUE);
- player->esizemode = eNormalSize;
- bMove = 0;
- if (player->flags & VIDEOPLAYER_FLAG_DOUBLESIZE||player->flags & VIDEOPLAYER_FLAG_ZOOMOUTSIZE)
- {
- int xPos = LOWORD(lParam);
- int yPos = HIWORD(lParam);
- HDC hdc = GetDC(hWnd);
- if (hdc) {
- if (player->hdib) {
- if (eDoubleSize == player->esizemode)
- {
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy<<1;
- bmpheader.biWidth = player->cx<<1;
- DrawDibBegin(player->hdib, hdc, player->cx<<1, player->cy<<1, &bmpheader, player->cx<<1, player->cy<<1, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- else if(eNormalSize == player->esizemode)
- {
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy;
- bmpheader.biWidth = player->cx;
- DrawDibBegin(player->hdib, hdc, player->cx, player->cy, &bmpheader, player->cx, player->cy, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- }
- ReleaseDC(hWnd, hdc);
- }
- }
- }
- if ((nWindowState==5)&&(player->flags&VIDEOPLAYER_FLAG_ZOOMOUTSIZE))
- {
- //Dbg("zoom out size video echo.");
- GetWindowRect(hWnd, &g_Rect);
- MoveWindow(hWnd, g_Rect.left, g_Rect.top, SMALL_RECORD_VIDEO_WIDTH, SMALL_RECORD_VIDEO_HEIGHT, TRUE);
- player->esizemode = eZoomOutSize;
- if (player->flags&VIDEOPLAYER_FLAG_ZOOMOUTSIZE)
- {
- HDC hdc = GetDC(hWnd);
- if (hdc){
- if (player->hdib) {
- if (eZoomOutSize == player->esizemode)
- {
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = SMALL_RECORD_VIDEO_HEIGHT;
- bmpheader.biWidth = SMALL_RECORD_VIDEO_WIDTH;
- DrawDibBegin(player->hdib, hdc, SMALL_RECORD_VIDEO_WIDTH, SMALL_RECORD_VIDEO_HEIGHT, &bmpheader, SMALL_RECORD_VIDEO_WIDTH, SMALL_RECORD_VIDEO_HEIGHT, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- else if(eNormalSize == player->esizemode)
- {
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy;
- bmpheader.biWidth = player->cx;
- DrawDibBegin(player->hdib, hdc, player->cx, player->cy, &bmpheader, player->cx, player->cy, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- }
- ReleaseDC(hWnd, hdc);
- }
- }
- bMove = 1;
- }
- if (wParam == player->dwPlayTimer)
- {
- if (player->flags & VIDEOPLAYER_FLAG_PUSH)
- {
- OnMsgTimer_PushMode(player, hWnd, msg, wParam, lParam);
- }
- else if (player->flags & VIDEOPLAYER_FLAG_PULL)
- {
- OnMsgTimer_PullMode(player, hWnd, msg, wParam, lParam);
- }
- }
- break;
- case WM_LBUTTONDOWN:
- if((player->flags & VIDEOPLAYER_FLAG_DOUBLESIZE)&&!(player->flags & VIDEOPLAYER_FLAG_PULL))
- {
- eVideoSizeMode old = player->esizemode;
- if (eNormalSize == player->esizemode)
- {
- player->esizemode = eDoubleSize;
- }
- if (old != player->esizemode)
- {
- RECT rc;
- GetWindowRect(hWnd, &rc);
- if (eDoubleSize == player->esizemode)
- {
- MoveWindow(hWnd, rc.left, rc.top, player->cx<<1, player->cy<<1, TRUE);
- }
- else
- {
- MoveWindow(hWnd, rc.left, rc.top, player->cx, player->cy, TRUE);
- }
- }
- }
- else
- {
- return CallWindowProcA(player->oldWndProc, hWnd, msg, wParam, lParam);
- }
- break;
- case WM_LBUTTONUP:
- if ((player->flags & VIDEOPLAYER_FLAG_DOUBLESIZE)&&!(player->flags & VIDEOPLAYER_FLAG_PULL))
- {
- eVideoSizeMode old = player->esizemode;
- if (eDoubleSize == player->esizemode) {
- player->esizemode = eNormalSize;
- }
- if (old != player->esizemode) {
- RECT rc;
- GetWindowRect(hWnd, &rc);
- if (eDoubleSize == player->esizemode)
- {
- MoveWindow(hWnd, rc.left, rc.top, player->cx<<1, player->cy<<1, TRUE);
- }
- else
- {
- MoveWindow(hWnd, rc.left, rc.top, player->cx, player->cy, TRUE);
- }
- }
- } else {
- return CallWindowProcA(player->oldWndProc, hWnd, msg, wParam, lParam);
- }
- break;
- case WM_MOUSEMOVE:
- if ((player->flags & VIDEOPLAYER_FLAG_DOUBLESIZE)&&!(player->flags & VIDEOPLAYER_FLAG_PULL))
- {
- eVideoSizeMode old = player->esizemode;
- if (eDoubleSize == player->esizemode) {
- POINT pt = {LOWORD(lParam), HIWORD(lParam)};
- RECT rc;
- GetWindowRect(hWnd, &rc);
- ClientToScreen(hWnd, &pt);
- if (!InRectangle(pt.x, pt.y, rc.left, rc.top, player->cx, player->cy)) { // once out of rectangle, taken as LBUTTONUP
- player->esizemode = eNormalSize;
- }
- }
- if (old != player->esizemode) {
- RECT rc;
- GetWindowRect(hWnd, &rc);
- if (eDoubleSize == player->esizemode) {
- MoveWindow(hWnd, rc.left, rc.top, player->cx<<1, player->cy<<1, TRUE);
- } else {
- MoveWindow(hWnd, rc.left, rc.top, player->cx, player->cy, TRUE);
- }
- }
- } else {
- return CallWindowProcA(player->oldWndProc, hWnd, msg, wParam, lParam);
- }
- break;
- case WM_SIZE:
- if (player->flags & VIDEOPLAYER_FLAG_DOUBLESIZE || player->flags & VIDEOPLAYER_FLAG_ZOOMOUTSIZE)
- {
- int xPos = LOWORD(lParam);
- int yPos = HIWORD(lParam);
- HDC hdc = GetDC(hWnd);
- if (hdc) {
- if (player->hdib) {
- if (eDoubleSize == player->esizemode) {
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy<<1;
- bmpheader.biWidth = player->cx<<1;
- DrawDibBegin(player->hdib, hdc, player->cx<<1, player->cy<<1, &bmpheader, player->cx<<1, player->cy<<1, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- else if(eZoomOutSize == player->esizemode){
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = SMALL_RECORD_VIDEO_HEIGHT;
- bmpheader.biWidth = SMALL_RECORD_VIDEO_WIDTH;
- DrawDibBegin(player->hdib, hdc, SMALL_RECORD_VIDEO_WIDTH, SMALL_RECORD_VIDEO_HEIGHT, &bmpheader, SMALL_RECORD_VIDEO_WIDTH, SMALL_RECORD_VIDEO_HEIGHT, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- else{
- BITMAPINFOHEADER bmpheader = {sizeof(BITMAPINFOHEADER)};
- bmpheader.biPlanes = 1;
- bmpheader.biBitCount = 24;
- bmpheader.biCompression = BI_RGB;
- bmpheader.biHeight = player->cy;
- bmpheader.biWidth = player->cx;
- DrawDibBegin(player->hdib, hdc, player->cx, player->cy, &bmpheader, player->cx, player->cy, DDF_SAME_DRAW|DDF_SAME_HDC);
- }
- }
- ReleaseDC(hWnd, hdc);
- }
- } else {
- return CallWindowProcA(player->oldWndProc, hWnd, msg, wParam, lParam);
- }
- break;
- case WM_PAINT:
- if (player->flags & VIDEOPLAYER_FLAG_DOUBLESIZE || player->flags & VIDEOPLAYER_FLAG_ZOOMOUTSIZE)
- {
- if (player->current_frame.raw_frame) {
- display_frame_entry(player, player->current_frame.raw_frame);
- ValidateRect(hWnd, NULL);
- return 0;
- }
- }
- else
- {
- ValidateRect(hWnd, NULL);
- return 0;
- }
- return CallWindowProcA(player->oldWndProc, hWnd, msg, wParam, lParam);
- default:
- return CallWindowProcA(player->oldWndProc, hWnd, msg, wParam, lParam);
- }
- return 0;
- }
- static LRESULT CALLBACK __VideoWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- videoplayer_t *player = (videoplayer_t*)hWnd;
- return VideoWndProc(player, player->hWndVideo, msg, wParam, lParam);
- }
- static int hook_window(videoplayer_t *player)
- {
- init_thunk(&player->thunk, (DWORD_PTR)&__VideoWndProc, player);
- player->oldWndProc = SetWindowLongA(player->hWndVideo, GWL_WNDPROC, (LONG)&player->thunk);
- SendMessageA(player->hWndVideo, WM_MSG_INIT, 0, 0);
- return 0;
- }
- static void unhook_window(videoplayer_t *player)
- {
- SendMessageA(player->hWndVideo, WM_MSG_CLEAR, 0, 0);
- SetWindowLongA(player->hWndVideo, GWL_WNDPROC, (LONG)player->oldWndProc);
- }
- int videoplayer_create(HWND hWndVideo,
- int x, int y, int cx, int cy,
- int fps_num,int fps_den,
- int width, int height, int flags, const char *name,
- videoplayer_on_pull on_pull,
- videoplayer_free_frame free_frame,
- void *user_data,
- videoplayer_t **p_player)
- {
- videoplayer_t *player = (videoplayer_t*)VirtualAlloc(NULL, sizeof(videoplayer_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- if (player) {
- memset(player, 0, sizeof(videoplayer_t));
- assert(fps_den != 0);
- assert(fps_num < FRAME_QUEUE_LEGNTH * fps_den);
- player->hWndVideo = hWndVideo;
- player->x = x;
- player->y = y;
- player->cx = cx;
- player->cy = cy;
- player->fps_den = fps_den;
- player->fps_num = fps_num;
- player->width = width;
- player->height = height;
- player->min_cache_size = FRAME_MIN_CACHE_MSEC * fps_num / 1000 * fps_den;
- player->max_cache_size = FRAME_MAX_CACHE_MSEC * fps_num / 1000 * fps_den;
- player->res_frame_data = player->black_frame_data = NULL;
- player->sws_context = NULL;
- player->esizemode = eNormalSize;
- player->double_size_sws_context = NULL;
- player->double_size_data = NULL;
- player->zoomout_size_sws_context = NULL;
- player->zoomout_size_data = NULL;
- player->current_frame.raw_frame = NULL;
- player->flags = flags;
- player->hdib = NULL;
- player->on_pull = on_pull;
- player->free_frame = free_frame;
- player->user_data = user_data;
- strncpy(player->name, name, sizeof(player->name)-1);
- player->name[sizeof(player->name)-1] = 0;
- InitializeCriticalSection(&player->q_lock);
- if (hook_window(player) != 0) {
- VirtualFree(player, sizeof(videoplayer_t), MEM_RELEASE);
- return -1;
- }
- *p_player = player;
- } else {
- return -1;
- }
- //初始化窗口状态
- nWindowState = 0;
- bMove = 0;
- IsHideRemoteWin = 0;
- IsHideLocalWin = 0;
- return 0;
- }
- void videoplayer_destroy(videoplayer_t *player)
- {
- MSG msg;
- while (PeekMessageA(&msg, player->hWndVideo, WM_MSG_FRAME, WM_MSG_FRAME, PM_REMOVE)) {
- frame_entry *entry = (frame_entry *)msg.wParam;
- free_frame_entry(player, entry);
- free(entry);
- }
- unhook_window(player);
- DeleteCriticalSection(&player->q_lock);
- VirtualFree(player, 0, MEM_RELEASE|MEM_DECOMMIT);
- }
- int videoplayer_queue_frame(videoplayer_t *player, video_frame *frame, videoplayer_free_frame free_frame, void *free_frame_user_data)
- {
- assert(frame->format == VIDEO_FORMAT_RGB24);
- if (player && player->hWndVideo && (player->flags&VIDEOPLAYER_FLAG_PUSH)) {
- if (player->flags & VIDEOPLAYER_FLAG_NOTIMER) {
- frame_entry *entry = (frame_entry*)malloc(sizeof(frame_entry));
- entry->free_frame = free_frame;
- entry->free_frame_user_data = free_frame_user_data;
- entry->raw_frame = frame;
- entry->dwTick = GetTickCount();
- if (!PostMessageA(player->hWndVideo, WM_MSG_FRAME, (WPARAM)entry, 0))
- {
- free(entry);
- return -1;
- }
- } else {
- EnterCriticalSection(&player->q_lock);
- player->frames[player->q_tail].raw_frame = frame;
- player->frames[player->q_tail].free_frame = free_frame;
- player->frames[player->q_tail].free_frame_user_data = free_frame_user_data;
- player->frames[player->q_tail].dwTick = GetTickCount();
- player->q_tail = QUEUE_INC(player->q_tail, FRAME_QUEUE_LEGNTH);
- if (player->q_caching) {
- int qlen = QUEUE_SIZE(player->q_head, player->q_tail, FRAME_QUEUE_LEGNTH);
- Dbg("qlen:%d, %d, %d", qlen, player->min_cache_size, player->max_cache_size);
- if (qlen >= player->min_cache_size)
- player->q_caching = 0;
- }
- while (QUEUE_SIZE(player->q_head, player->q_tail, FRAME_QUEUE_LEGNTH) > player->max_cache_size) {
- int qlen = QUEUE_SIZE(player->q_head, player->q_tail, FRAME_QUEUE_LEGNTH);
- Dbg("erase qlen:%d", qlen);
- free_frame_entry(player, &player->frames[player->q_head]);
- player->q_head = QUEUE_INC(player->q_head, FRAME_QUEUE_LEGNTH);
- }
- LeaveCriticalSection(&player->q_lock);
- }
- } else {
- return -1;
- }
- return 0;
- }
|