123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997 |
- #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;
- int x;
- int y;
- int cx;
- int cy;
- int fps_num;
- int fps_den;
- int width;
- int height;
- 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;
- 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;
-
- int min_cache_size;
- int max_cache_size;
- videoplayer_on_pull on_pull;
- videoplayer_free_frame free_frame;
- void *user_data;
- char name[16];
- #ifdef _WIN32
- HWND hWndVideo;
- WNDPROC oldWndProc;
- CRITICAL_SECTION q_lock;
- HDRAWDIB hdib;
- #endif
- };
- #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 {
- bool bdisplayed = false;
- //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);
- bdisplayed = 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 (!bdisplayed) {
- 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;
- }
|