Advertisement
dragonbane

[CryVideo] CryVideoOpenCV.dll

Feb 24th, 2018
206
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 42.44 KB | None | 0 0
  1. CryVideoOpenCV.cpp
  2.  
  3. /*************************************************************************
  4.   Cry Video Source File.
  5.   Copyright (C), Marwin Misselhorn 2012
  6.  -------------------------------------------------------------------------
  7. *************************************************************************/
  8.  
  9. #include "StdAfx.h"
  10. #include "CryVideoOpenCV.h"
  11. #include <CryLibrary.h>
  12. #include <IGameFramework.h>
  13. #include <IRenderer.h>
  14.  
  15. #include <windows.h>
  16. #include <iostream>
  17.  
  18. #include <opencv/cxcore.h>
  19. #include <opencv/cv.h>
  20. #include <opencv/highgui.h>
  21. #include "pixfc-sse.h"
  22. #include <pthread.h>
  23.  
  24. //Test Network Sound
  25. /*
  26. #include <SDL.h>
  27. #include <SDL_thread.h>
  28.  
  29. extern "C" {
  30.     #include <libavformat/avformat.h>
  31.     #include <libavcodec/avcodec.h>
  32. }
  33.  
  34. #define SDL_AUDIO_BUFFER_SIZE 1024
  35.  
  36. typedef struct PacketQueue
  37. {
  38.   AVPacketList *first_pkt, *last_pkt;
  39.   int nb_packets;
  40.   int size;
  41.   SDL_mutex *mutex;
  42.   SDL_cond *cond;
  43. } PacketQueue;
  44. PacketQueue audioq;
  45.  
  46. int audioStream = -1;
  47. int videoStream = -1;
  48. int quit = 0;
  49.  
  50. SDL_Surface* screen = NULL;
  51. SDL_Surface* surface = NULL;
  52.  
  53. AVFormatContext* pFormatCtx = NULL;
  54. AVCodecContext* aCodecCtx = NULL;
  55. AVCodecContext* pCodecCtx = NULL;
  56.  
  57. AVCodecContext *aCodec = NULL;
  58. */
  59.  
  60.  
  61. /*
  62. #include <SDL.h>
  63. #include <GL/glew.h>
  64. #include <GL/wglew.h>
  65. */
  66.  
  67. // We need shell api for Current Root Extraction.
  68. #include "shlwapi.h"
  69. #pragma comment(lib, "shlwapi.lib")
  70.  
  71. using namespace std;
  72. using namespace cv;
  73.  
  74.  
  75. //Multi-Threading support
  76. typedef unsigned char byte;
  77.  
  78. typedef struct _work_t {
  79.         struct PixFcSSE *pixfc;
  80.         byte *in, *out;
  81.         uint32_t startIndex;
  82.  
  83.     } work_t;
  84.  
  85. void* Thread(void *arg)
  86. {
  87.     work_t *param = (work_t*) arg;
  88.     param->pixfc->convert(param->pixfc, param->in, param->out, param->startIndex);
  89.     return NULL;
  90. }
  91.  
  92.  
  93. //Test Network Sound
  94. /*
  95. void show_frame(IplImage* img)
  96. {
  97.     if (!screen)
  98.     {
  99.         screen = SDL_SetVideoMode(img->width, img->height, 0, 0);
  100.         if (!screen)
  101.         {
  102.             fprintf(stderr, "SDL: could not set video mode - exiting\n");
  103.             exit(1);
  104.         }
  105.     }
  106.  
  107.     // Assuming IplImage packed as BGR 24bits
  108.     SDL_Surface* surface = SDL_CreateRGBSurfaceFrom((void*)img->imageData,
  109.                 img->width,
  110.                 img->height,
  111.                 img->depth * img->nChannels,
  112.                 img->widthStep,
  113.                 0xff0000, 0x00ff00, 0x0000ff, 0
  114.                 );
  115.  
  116.     SDL_BlitSurface(surface, 0, screen, 0);
  117.  
  118.     SDL_Flip(screen);
  119. }
  120.  
  121.  
  122. void packet_queue_init(PacketQueue *q)
  123. {
  124.     memset(q, 0, sizeof(PacketQueue));
  125.     q->mutex = SDL_CreateMutex();
  126.     q->cond = SDL_CreateCond();
  127. }
  128.  
  129. int packet_queue_put(PacketQueue *q, AVPacket *pkt)
  130. {
  131.     AVPacketList *pkt1;
  132.     if (av_dup_packet(pkt) < 0)
  133.     {
  134.         return -1;
  135.     }
  136.  
  137.     //pkt1 = (AVPacketList*) av_malloc(sizeof(AVPacketList));
  138.     pkt1 = (AVPacketList*) malloc(sizeof(AVPacketList));
  139.     if (!pkt1) return -1;
  140.     pkt1->pkt = *pkt;
  141.     pkt1->next = NULL;
  142.  
  143.     SDL_LockMutex(q->mutex);
  144.  
  145.     if (!q->last_pkt)
  146.         q->first_pkt = pkt1;
  147.     else
  148.         q->last_pkt->next = pkt1;
  149.  
  150.     q->last_pkt = pkt1;
  151.     q->nb_packets++;
  152.     q->size += pkt1->pkt.size;
  153.     SDL_CondSignal(q->cond);
  154.  
  155.     SDL_UnlockMutex(q->mutex);
  156.     return 0;
  157. }
  158.  
  159. static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
  160. {
  161.     AVPacketList *pkt1;
  162.     int ret;
  163.  
  164.     SDL_LockMutex(q->mutex);
  165.  
  166.     for (;;)
  167.     {      
  168.         if( quit)
  169.         {
  170.             ret = -1;
  171.             break;
  172.         }
  173.  
  174.         pkt1 = q->first_pkt;
  175.         if (pkt1)
  176.         {
  177.             q->first_pkt = pkt1->next;
  178.             if (!q->first_pkt)
  179.                 q->last_pkt = NULL;
  180.  
  181.                 q->nb_packets--;
  182.             q->size -= pkt1->pkt.size;
  183.             *pkt = pkt1->pkt;
  184.             //av_free(pkt1);
  185.             free(pkt1);
  186.             ret = 1;
  187.             break;
  188.         }
  189.         else if (!block)
  190.         {
  191.             ret = 0;
  192.             break;
  193.         }
  194.         else
  195.         {
  196.             SDL_CondWait(q->cond, q->mutex);
  197.         }
  198.     }
  199.  
  200.     SDL_UnlockMutex(q->mutex);
  201.     return ret;
  202. }
  203.  
  204. int audio_decode_frame(AVCodecContext *aCodecCtx, uint8_t *audio_buf, int buf_size)
  205. {
  206.     static AVPacket pkt;
  207.     static uint8_t *audio_pkt_data = NULL;
  208.     static int audio_pkt_size = 0;
  209.  
  210.     int len1, data_size;
  211.  
  212.     for (;;)
  213.     {
  214.         while (audio_pkt_size > 0)
  215.         {
  216.             data_size = buf_size;
  217.             len1 = avcodec_decode_audio2(aCodecCtx, (int16_t*)audio_buf, &data_size,
  218.                                         audio_pkt_data, audio_pkt_size);
  219.             if (len1 < 0)
  220.             {
  221.                 // if error, skip frame
  222.                 audio_pkt_size = 0;
  223.                 break;
  224.             }
  225.             audio_pkt_data += len1;
  226.             audio_pkt_size -= len1;
  227.             if (data_size <= 0)
  228.             {
  229.                 // No data yet, get more frames
  230.                 continue;
  231.             }
  232.             // We have data, return it and come back for more later
  233.             return data_size;
  234.         }
  235.  
  236.             if (pkt.data)
  237.             av_free_packet(&pkt);
  238.  
  239.         if (quit) return -1;
  240.  
  241.         if (packet_queue_get(&audioq, &pkt, 1) < 0) return -1;
  242.  
  243.         audio_pkt_data = pkt.data;
  244.         audio_pkt_size = pkt.size;
  245.     }
  246. }
  247.  
  248. void audio_callback(void *userdata, Uint8 *stream, int len)
  249. {
  250.    
  251. }
  252.  
  253. void setup_ffmpeg(char* filename)
  254. {
  255.     if (av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL) != 0)
  256.     {
  257.         fprintf(stderr, "FFmpeg failed to open file %s!\n", filename);
  258.         exit(-1);
  259.     }
  260.  
  261.     if (av_find_stream_info(pFormatCtx) < 0)
  262.     {
  263.         fprintf(stderr, "FFmpeg failed to retrieve stream info!\n");
  264.         exit(-1);
  265.     }
  266.  
  267.     // Dump information about file onto standard error
  268.     dump_format(pFormatCtx, 0, filename, 0);
  269.  
  270.     // Find the first video stream
  271.     int i = 0;
  272.     for (i; i < pFormatCtx->nb_streams; i++)
  273.     {
  274.         if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO && videoStream < 0)
  275.         {
  276.             videoStream = i;
  277.         }
  278.  
  279.         if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO && audioStream < 0)
  280.         {
  281.             audioStream = i;
  282.         }
  283.     }
  284.  
  285.     if (videoStream == -1)
  286.     {
  287.         fprintf(stderr, "No video stream found in %s!\n", filename);
  288.         exit(-1);
  289.     }  
  290.  
  291.     if (audioStream == -1)
  292.     {
  293.         fprintf(stderr, "No audio stream found in %s!\n", filename);
  294.         exit(-1);
  295.     }  
  296.  
  297.     // Get a pointer to the codec context for the audio stream
  298.     aCodecCtx = pFormatCtx->streams[audioStream]->codec;
  299.  
  300.     // Set audio settings from codec info
  301.     SDL_AudioSpec wanted_spec;
  302.     wanted_spec.freq = aCodecCtx->sample_rate;
  303.     wanted_spec.format = AUDIO_S16SYS;
  304.     wanted_spec.channels = aCodecCtx->channels;
  305.     wanted_spec.silence = 0;
  306.     wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
  307.     wanted_spec.callback = audio_callback;
  308.     wanted_spec.userdata = aCodecCtx;
  309.  
  310.     aCodec = aCodecCtx;
  311.  
  312.     SDL_AudioSpec spec;
  313.     //if (SDL_OpenAudio(&wanted_spec, &spec) < 0)
  314.     //{
  315.        // fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
  316.         //exit(-1);
  317.     //}
  318.  
  319.     AVCodec* aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
  320.     if (!aCodec)
  321.     {
  322.         fprintf(stderr, "Unsupported codec!\n");
  323.         exit(-1);
  324.     }
  325.     avcodec_open(aCodecCtx, aCodec);
  326.  
  327.     // audio_st = pFormatCtx->streams[index]
  328.     packet_queue_init(&audioq);
  329.     //SDL_PauseAudio(0);
  330.  
  331.     // Get a pointer to the codec context for the video stream
  332.     pCodecCtx = pFormatCtx->streams[videoStream]->codec;
  333.  
  334.     // Find the decoder for the video stream
  335.     AVCodec* pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
  336.     if (pCodec == NULL)
  337.     {
  338.         fprintf(stderr, "Unsupported codec!\n");
  339.         exit(-1); // Codec not found
  340.     }
  341.  
  342.     // Open codec
  343.     if (avcodec_open(pCodecCtx, pCodec) < 0)
  344.     {
  345.         fprintf(stderr, "Unsupported codec!\n");
  346.         exit(-1); // Could not open codec
  347.     }
  348. }
  349.  
  350. int TestFunc2(char* fileName)
  351. {
  352.     AVFormatContext *pFormatCtx;
  353.     AVCodec *pCodec_audio;
  354.     AVCodecContext *aCodecCtx_audio = NULL;
  355.     AVPacket packet;
  356.     char* outfilename = "D:\\CryVideo_CE3_Build3.4.0\\Game\\Videos\\output.wav";
  357.     int audioStream;
  358.     int out_size, len, size;
  359.     FILE *outfile;
  360.     int16_t *outbuf;
  361.     uint8_t inbuf[4096 + FF_INPUT_BUFFER_PADDING_SIZE];
  362.  
  363.     avcodec_init();
  364.     // register all the codecs
  365.     av_register_all();
  366.  
  367.     if(av_open_input_file(&pFormatCtx, fileName, NULL, 0, NULL) != 0) {
  368.         cerr << "Archivo no encontrado" << endl;
  369.         return -1; // Couldn't open file
  370.     }
  371.  
  372.     if(av_find_stream_info(pFormatCtx) < 0) {
  373.         cerr << " No encontro el stream de info" << endl;
  374.         return -1;// Couldn't find stream information
  375.     }
  376.  
  377.     dump_format(pFormatCtx, 0, fileName, 0);
  378.  
  379.     for(unsigned int i=0; i < pFormatCtx->nb_streams; i++)
  380.     if(pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
  381.         audioStream = i;
  382.  
  383.     aCodecCtx_audio = pFormatCtx->streams[audioStream]->codec;
  384.     pCodec_audio = avcodec_find_decoder(aCodecCtx_audio->codec_id);
  385.     if(pCodec_audio == NULL) {
  386.         cerr<< "Unsupported codec!" << endl;
  387.         return -1; // Codec not found
  388.     }
  389.  
  390.     if(avcodec_open(aCodecCtx_audio, pCodec_audio) < 0) {
  391.         cerr << "No se pudo abrir el codec de audio" << endl;
  392.         return -1;
  393.     }
  394.  
  395.     outbuf = (int16_t*) av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
  396.  
  397.     outfile = fopen(outfilename, "wb");
  398.     if (!outfile) {
  399.         exit(1);
  400.     }
  401.  
  402.     av_init_packet(&packet);
  403.     packet.data = inbuf;
  404.     while(av_read_frame(pFormatCtx, &packet) == 0) {
  405.         if(packet.stream_index == audioStream) {
  406.             size = packet.size;
  407.             if (size == 0) {
  408.                 cerr << "Size = 0 " << endl;
  409.                 break;
  410.             }
  411.             while(size > 0) {
  412.                 out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
  413.                 len = avcodec_decode_audio3(aCodecCtx_audio, outbuf, &out_size , &packet);
  414.                 //av_free_packet(&packet);
  415.                 cout << len << endl;
  416.                 if(len == -1) {
  417.                     cerr << "Error while decoding" << endl;
  418.                     return 1;
  419.                 }
  420.                 if(out_size > 0) {
  421.                     fwrite(outbuf, 1, out_size, outfile);
  422.                 }
  423.                 size -= len;
  424.                 packet.data += len;
  425.             }
  426.         }
  427.     }
  428.     av_free_packet(&packet);
  429.  
  430.     fclose(outfile);
  431.     free(outbuf);
  432.     cout << "END CODE" << endl;
  433.     avcodec_close(aCodecCtx_audio);
  434.     av_free(aCodecCtx_audio);
  435.  
  436.     return 0;
  437. }
  438.  
  439. int TestFunc(char* fileName)
  440. {
  441.     av_register_all();
  442.  
  443.     // Init SDL
  444.     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
  445.     {
  446.         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
  447.         return -1;
  448.     }
  449.    
  450.     // Init ffmpeg and setup some SDL stuff related to Audio
  451.     setup_ffmpeg(fileName);
  452.  
  453.     VideoCapture cap(fileName);
  454.     if (!cap.isOpened())  // check if we succeeded
  455.     {
  456.         std::cout << "Failed to load file!" << std::endl;
  457.             return -1;
  458.     }
  459.  
  460.     return 0;
  461. }
  462. */
  463.  
  464.  
  465. //////////////////////////////////////////////////////////////////////////
  466. // Initializes Root folder of the game.
  467. //////////////////////////////////////////////////////////////////////////
  468. void InitRootDir()
  469. {
  470. #ifdef WIN32
  471.     WCHAR szExeFileName[_MAX_PATH];
  472.  
  473.     GetModuleFileNameW( GetModuleHandle(NULL), szExeFileName, sizeof(szExeFileName));
  474.     PathRemoveFileSpecW(szExeFileName);
  475.  
  476.     // Remove Bin32/Bin64 folder/
  477.     WCHAR* lpPath = StrStrIW(szExeFileName,L"\\Bin32");
  478.     if (lpPath)
  479.         *lpPath = 0;
  480.     lpPath = StrStrIW(szExeFileName,L"\\Bin64");
  481.     if (lpPath)
  482.         *lpPath = 0;
  483.  
  484.     SetCurrentDirectoryW( szExeFileName );
  485.  
  486. #endif
  487. }
  488.  
  489. CCryVideoOpenCV::CCryVideoOpenCV()
  490. {
  491.     started = false;
  492.     g_pCryVideoOpenCV = this;
  493.    
  494.     g_pCryVideo = 0;
  495.     swapBGRA = false;
  496.     renderToWindow = false;
  497.     manual_conversion = false;
  498.     manual_conversion_OpenCV = false;
  499.     force_manual_conversion = false;
  500.     mode = 0;
  501.     videoFileName = "";
  502.  
  503.     video_capture = NULL;
  504.     source_image = NULL;
  505.     dest_image = NULL;
  506.     width = 0;
  507.     height = 0;
  508.     sizeTotal = 0;
  509.     pixfc = NULL;
  510.     pixfcOpenCV = NULL;
  511.     yuv = NULL;
  512.     rgb = NULL;
  513.     rgba = NULL;
  514.     pid = NULL;
  515.     job = NULL;
  516.     numThreads = 0;
  517.     YUVSize = 0;
  518.     RGBSize = 0;
  519.  
  520.  
  521.     InitRootDir();
  522. }
  523.  
  524. CCryVideoOpenCV::~CCryVideoOpenCV()
  525. {
  526.     //if (m_pCryVideoWebM && mode == 2 || mode == 1)
  527.         //CloseVideoFile();
  528.  
  529.     //Free WebM instance
  530.     //if (m_pCryVideoWebM)
  531.         //SAFE_DELETE(m_pCryVideoWebM);
  532.  
  533.     /*
  534.     //Cleanup OpenGL
  535.     glUseProgramObjectARB(0);
  536.     if (PHandle)
  537.         glDeleteObjectARB(PHandle);
  538.  
  539.     if (mhRC)
  540.     {
  541.         wglMakeCurrent( NULL, NULL );
  542.         wglDeleteContext( mhRC );
  543.     }
  544.     if (mhWnd && mhDC)
  545.     {
  546.         ReleaseDC( mhWnd, mhDC );
  547.     }
  548.     mhWnd = NULL;
  549.     mhDC = NULL;
  550.     mhRC = NULL;
  551.     */
  552.  
  553.     //SAFE_DELETE(videoFileName);
  554.  
  555.     //if (pixfc)
  556.         //destroy_pixfc(pixfc);
  557.  
  558.     //if (pixfcOpenCV)
  559.         //destroy_pixfc(pixfcOpenCV);
  560.        
  561.  
  562.     g_pCryVideoOpenCV = 0;
  563. }
  564.  
  565. bool CCryVideoOpenCV::Init(ISystem *pSystem, IGameFramework *pGameFramework, ICryVideo* pCryVideo)
  566. {
  567.     started = false;
  568.     gEnv = pSystem->GetGlobalEnvironment();
  569.     m_pFramework = pGameFramework;
  570.     g_pCryVideo = pCryVideo;
  571.  
  572.     //Test Network Sound
  573.     //TestFunc("D:\\CryVideo_CE3_Build3.4.0\\Game\\Videos\\Library\\FahrenheitJadeVision.avi");
  574.  
  575.     //Create new WebM instance
  576.     m_pCryVideoWebM = pCryVideo->CreateWebMInstance();
  577.  
  578.     //Init YUV-RGB conversion process
  579.     //1. SSSE3 Only+Fast   = max. 59-61fps (Intel Quad)
  580.     //2. SSSE3 Only+Slow   = max. 59fps (Intel Quad)
  581.     //3. SSE2  Only+Fast   = max. 58fps (Intel Quad)
  582.     //4. NOSSE     +Fast   = max. 53fps (Intel Quad)
  583.     //5. Hamers conversion = max. 50fps (Intel Quad)
  584.  
  585.     PixFcPixelFormat input_format = PixFcYUV420P;
  586.     PixFcPixelFormat output_format;
  587.     width = 1280;
  588.     height = 720;
  589.  
  590.     manual_conversion = false;
  591.  
  592.     if (g_pCryVideo->IsRGB8Usable())
  593.     {
  594.         output_format = PixFcBGR24;
  595.     }
  596.     else
  597.     {
  598.         output_format = PixFcBGRA; 
  599.     }
  600.  
  601.     // Create struct pixfc WebM
  602.     int result = create_pixfc(&pixfc, input_format, output_format, width, height, PixFcFlag_SSSE3OnlyNNb);
  603.     if (result != 0)
  604.     {
  605.         result = create_pixfc(&pixfc, input_format, output_format, width, height, PixFcFlag_SSSE3Only);
  606.         if (result != 0)
  607.         {
  608.             GameWarning("No SSSE3 support for WebM videos! Playback might be slower.");
  609.                
  610.             result = create_pixfc(&pixfc, input_format, output_format, width, height, PixFcFlag_SSE2OnlyNNb);
  611.             if (result != 0)
  612.             {
  613.                 GameWarning("No SSE2 support for WebM videos!! Playback is going to be slower.");
  614.  
  615.                 result = create_pixfc(&pixfc, input_format, output_format, width, height, PixFcFlag_NoSSE);
  616.                 if (result != 0)
  617.                 {
  618.                     GameWarning("No SSE support for WebM videos!!! Doing manual conversion instead...");
  619.  
  620.                     manual_conversion = true;
  621.                 }
  622.             }
  623.         }
  624.     }
  625.  
  626.     // Create struct pixfc OpenCV
  627.     PixFcPixelFormat input_formatOpenCV = PixFcBGR24;
  628.     PixFcPixelFormat output_formatOpenCV;
  629.  
  630.     manual_conversion_OpenCV = false;
  631.  
  632.     //Check CVar
  633.     ICVar* swapChannels = gEnv->pConsole->GetCVar("cv_swapBGRA");
  634.  
  635.     if (swapChannels && swapChannels->GetIVal() == 1)
  636.         swapBGRA = true;
  637.     else
  638.         swapBGRA = false;
  639.  
  640.     if (swapBGRA)
  641.     {
  642.         output_formatOpenCV = PixFcARGB;
  643.     }
  644.     else
  645.     {
  646.         output_formatOpenCV = PixFcBGRA;   
  647.     }
  648.  
  649.     result = create_pixfc(&pixfcOpenCV, input_formatOpenCV, output_formatOpenCV, width, height, PixFcFlag_SSSE3OnlyNNb);
  650.     if (result != 0)
  651.     {
  652.         result = create_pixfc(&pixfcOpenCV, input_formatOpenCV, output_formatOpenCV, width, height, PixFcFlag_SSSE3Only);
  653.         if (result != 0)
  654.         {
  655.             GameWarning("No SSSE3 support for AVI videos! Playback might be slower.");
  656.                
  657.             result = create_pixfc(&pixfcOpenCV, input_formatOpenCV, output_formatOpenCV, width, height, PixFcFlag_SSE2OnlyNNb);
  658.             if (result != 0)
  659.             {
  660.                 GameWarning("No SSE2 support for AVI videos!! Playback is going to be slower.");
  661.  
  662.                 result = create_pixfc(&pixfcOpenCV, input_formatOpenCV, output_formatOpenCV, width, height, PixFcFlag_NoSSE);
  663.                 if (result != 0)
  664.                 {
  665.                     GameWarning("No SSE support for AVI videos!!! Doing manual conversion instead...");
  666.  
  667.                     manual_conversion_OpenCV = true;
  668.                 }
  669.             }
  670.         }
  671.     }
  672.  
  673.  
  674.  
  675.     //Detect number of Cores
  676.     SYSTEM_INFO sysinfo;
  677.     GetSystemInfo( &sysinfo );
  678.  
  679.     numThreads = sysinfo.dwNumberOfProcessors;
  680.  
  681.     CryLogAlways("CryVideo: Use %i thread(s) for conversion!", numThreads);
  682.  
  683.     if (numThreads < 4)
  684.         numThreadsAVI = 1;
  685.     else
  686.         numThreadsAVI = numThreads;
  687.  
  688.     /*
  689.     //Init OpenGL
  690.     mhWnd =(HWND)gEnv->pRenderer->GetHWND();
  691.  
  692.     //get the device context (DC)
  693.     mhDC = GetDC( mhWnd );
  694.  
  695.     // set the pixel format for the DC
  696.     PIXELFORMATDESCRIPTOR pfd;
  697.     ZeroMemory( &pfd, sizeof( pfd ) );
  698.     pfd.nSize = sizeof( pfd );
  699.     pfd.nVersion = 1;
  700.     pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
  701.                  PFD_DOUBLEBUFFER;
  702.     //pfd.iPixelType = PFD_TYPE_RGBA;
  703.     pfd.cColorBits = 24;
  704.     pfd.cDepthBits = 16;
  705.     pfd.iLayerType = PFD_MAIN_PLANE;
  706.     int format = ChoosePixelFormat( mhDC, &pfd );
  707.     SetPixelFormat( mhDC, format, &pfd );
  708.  
  709.     //create the render context (RC)
  710.     mhRC = wglCreateContext( mhDC );
  711.  
  712.     //make it the current render context
  713.     wglMakeCurrent( mhDC, mhRC );
  714.  
  715.     GLenum err = glewInit();
  716.     if (GLEW_OK != err)
  717.     {
  718.         // Problem: glewInit failed, something is seriously wrong.
  719.         CryLogAlways("Error: %s\n", glewGetErrorString(err));
  720.     }
  721.     wglMakeCurrent( NULL, NULL );
  722.     */
  723.  
  724.     started = true;
  725.  
  726.     return true;
  727. }
  728.  
  729. bool CCryVideoOpenCV::LoadVideoFile(const char* fileName, int format)
  730. {
  731.     mode = format;
  732.  
  733.     //Check Debug CVars
  734.     ICVar* renderToSecondWindow = gEnv->pConsole->GetCVar("cv_renderToSecondWindow");
  735.  
  736.     if (renderToSecondWindow && renderToSecondWindow->GetIVal() == 1)
  737.         renderToWindow = true;
  738.     else
  739.         renderToWindow = false;
  740.  
  741.     //ICVar* forceConversion = gEnv->pConsole->GetCVar("cv_forceManualConversion");
  742.  
  743.     //if (forceConversion && forceConversion->GetIVal() == 1)
  744.         //force_manual_conversion = true;
  745.     //else
  746.         //force_manual_conversion = false;
  747.  
  748.  
  749.  
  750.     if (mode == 1) //AVI
  751.     {
  752.         if (video_capture)
  753.             CloseVideoFile();
  754.  
  755.         videoFileName = (char*)fileName;
  756.  
  757.         try
  758.         {
  759.             video_capture = cvCreateFileCapture(fileName);
  760.  
  761.             if (!video_capture)
  762.             {
  763.                 CryLogAlways("OpenCV: Couldn't create file capture. Something is wrong with the video file. Maybe the right codec is not installed on the system?");
  764.                 return false;
  765.             }
  766.  
  767.             source_image = cvCreateImage(cvGetSize(cvQueryFrame(video_capture)),IPL_DEPTH_8U,3);
  768.  
  769.             if (g_pCryVideo->IsRGB8Usable())
  770.             {
  771.                 dest_image = cvCreateImage(cvGetSize(source_image),IPL_DEPTH_8U,3);
  772.             }
  773.             else
  774.             {
  775.                 dest_image =  cvCreateImage(cvGetSize(source_image),IPL_DEPTH_8U,4);
  776.             }
  777.  
  778.             cvSetCaptureProperty(video_capture, CV_CAP_PROP_POS_AVI_RATIO, 0);
  779.  
  780.             return true;
  781.         }
  782.         catch (...)
  783.         {
  784.  
  785.         }
  786.     }
  787.     else //WebM
  788.     {
  789.         m_pCryVideoWebM->CloseWebMFile();
  790.  
  791.         videoFileName = (char*)fileName;
  792.  
  793.         bool swapuv = false;
  794.         if (gEnv->pRenderer->GetRenderType() == eRT_DX11)
  795.             swapuv = true;
  796.  
  797.         bool result = m_pCryVideoWebM->LoadWebMFile(fileName, swapuv);
  798.  
  799.         if (result)
  800.             return true;
  801.     }
  802.  
  803.     return false;
  804. }
  805.  
  806. bool CCryVideoOpenCV::CloseVideoFile()
  807. {
  808.     if (mode == 1) //AVI
  809.     {
  810.         try
  811.         {
  812.             if (video_capture)
  813.             {
  814.                 cvReleaseCapture(&video_capture);
  815.             }
  816.         }
  817.         catch (...)
  818.         {
  819.         }
  820.  
  821.         //Render to Window
  822.         ICVar* renderWindow = gEnv->pConsole->GetCVar("cv_renderToSecondWindow");
  823.         if (renderWindow && renderWindow->GetIVal() == 1)
  824.             cvDestroyAllWindows();
  825.  
  826.         video_capture = NULL;
  827.         videoFileName = NULL;
  828.  
  829.         try
  830.         {
  831.             delete(rgb);
  832.             delete(rgba);
  833.             delete(job);
  834.             delete(pid);
  835.             delete(source_image);
  836.             delete(dest_image);
  837.         }
  838.         catch (...)
  839.         {
  840.         }
  841.  
  842.         return true;
  843.     }
  844.     else //WebM
  845.     {
  846.         bool result = m_pCryVideoWebM->CloseWebMFile();
  847.         videoFileName = NULL;
  848.  
  849.         //Render to Window
  850.         ICVar* renderWindow = gEnv->pConsole->GetCVar("cv_renderToSecondWindow");
  851.         if (renderWindow && renderWindow->GetIVal() == 1)
  852.             cvDestroyAllWindows();
  853.  
  854.         /*
  855.         //Cleanup OpenGL
  856.         glUseProgramObjectARB(0);
  857.         if (PHandle)
  858.             glDeleteObjectARB(PHandle);
  859.  
  860.         if (mhRC)
  861.             wglMakeCurrent( NULL, NULL );
  862.         */
  863.        
  864.         try
  865.         {
  866.             delete(yuv);
  867.             delete(rgba);
  868.             delete(job);
  869.             delete(pid);
  870.         }
  871.         catch (...)
  872.         {
  873.         }
  874.  
  875.         if (result)
  876.             return true;
  877.     }
  878.  
  879.     return false;
  880. }
  881.  
  882. char* CCryVideoOpenCV::StartPlayback()
  883. {
  884.     char* imageData = NULL;
  885.  
  886.     if (mode == 1) //AVI
  887.     {
  888.         CryLogAlways("OpenCV: Schedule AVI Playback");
  889.         try
  890.         {
  891.             source_image=cvQueryFrame(video_capture);
  892.  
  893.             width = source_image->width;
  894.             height = source_image->height;
  895.  
  896.             //Prepare CVars
  897.             rgb = new char[(width*height)*3];
  898.             rgba = new char[(width*height)*4];
  899.  
  900.             //Update conversion pointer
  901.             pixfcOpenCV->width = width;
  902.             pixfc->height = height/numThreadsAVI;
  903.  
  904.             pixfcOpenCV->pixel_count = pixfcOpenCV->width * pixfc->height;
  905.  
  906.             YUVSize = pixfcOpenCV->pixel_count*3;
  907.             RGBSize = pixfcOpenCV->pixel_count*4;
  908.  
  909.             //Create multi thread object
  910.             job = new work_t[numThreadsAVI];
  911.             pid = new pthread_t[numThreadsAVI];
  912.  
  913.             for (int k=0;k<numThreadsAVI;k++)
  914.             {  
  915.                 job[k].pixfc = pixfcOpenCV;
  916.                 job[k].startIndex = 0;
  917.  
  918.                 job[k].out = (byte*)rgba + (k*RGBSize);
  919.             }
  920.  
  921.             if (g_pCryVideo->IsRGB8Usable())
  922.             {
  923.                 if (swapBGRA)
  924.                     cvCvtColor(source_image, dest_image, CV_BGR2RGB);
  925.             }
  926.             else
  927.             {
  928.                 if (manual_conversion_OpenCV || force_manual_conversion)
  929.                 {
  930.                     if (swapBGRA)
  931.                         cvCvtColor(source_image, dest_image, CV_BGR2RGBA);
  932.                     else
  933.                         cvCvtColor(source_image, dest_image, CV_BGR2BGRA);
  934.                 }
  935.                 else
  936.                 {
  937.                     rgb = source_image->imageData;
  938.                     pixfcOpenCV->convert(pixfcOpenCV, rgb, rgba, 0);
  939.                 }
  940.             }
  941.  
  942.             cvSetCaptureProperty(video_capture, CV_CAP_PROP_POS_AVI_RATIO, 0);
  943.  
  944.             if (manual_conversion_OpenCV || force_manual_conversion || g_pCryVideo->IsRGB8Usable())
  945.                 if (!g_pCryVideo->IsRGB8Usable() || swapBGRA)
  946.                     imageData = dest_image->imageData;
  947.                 else
  948.                     imageData = source_image->imageData;
  949.             else
  950.                 imageData = rgba;
  951.  
  952.  
  953.             cvReleaseCapture(&video_capture);
  954.  
  955.             video_capture = cvCreateFileCapture(videoFileName);
  956.  
  957.             //Render to Window
  958.             if (renderToWindow)
  959.             {
  960.                 cvNamedWindow("CryVideo Player",CV_WINDOW_FREERATIO);
  961.                 cvResizeWindow("CryVideo Player", gEnv->pRenderer->GetWidth() / 2, gEnv->pRenderer->GetHeight() / 2);
  962.                 cvMoveWindow("CryVideo Player", 0,0);
  963.             }
  964.  
  965.             if (!video_capture)
  966.             {
  967.                 CryLogAlways("OpenCV: Couldn't create file capture. Something is wrong with the video file. Maybe the right codec is not installed on the system?");
  968.                 imageData = NULL;
  969.             }
  970.         }
  971.         catch (...)
  972.         {
  973.             imageData = NULL;
  974.         }
  975.     }
  976.     else //WebM
  977.     {
  978.         CryLogAlways("OpenCV: Schedule WebM Playback");
  979.  
  980.         width = GetVideoWidth();
  981.         height = GetVideoHeight();
  982.  
  983.         sizeTotal = width * height;
  984.  
  985.         //Init YUV-RGB Vars
  986.         yuv = new char[sizeTotal + ((sizeTotal / 4) * 2)];
  987.  
  988.         if (!g_pCryVideo->IsRGB8Usable())
  989.             rgba = new char[sizeTotal * 4];
  990.         else
  991.             rgba = new char[sizeTotal * 3];
  992.        
  993.  
  994.         //Render to Window
  995.         if (renderToWindow)
  996.         {
  997.             cvNamedWindow("CryVideo Player",CV_WINDOW_FREERATIO);
  998.             cvResizeWindow("CryVideo Player", gEnv->pRenderer->GetWidth() / 2, gEnv->pRenderer->GetHeight() / 2);
  999.             cvMoveWindow("CryVideo Player", 0,0);
  1000.         }
  1001.  
  1002.         //Update conversion pointer
  1003.         pixfc->width = width;
  1004.         pixfc->height = height/numThreads;
  1005.  
  1006.         pixfc->pixel_count = sizeTotal;
  1007.  
  1008.         YUVSize = (uint32_t)(sizeTotal/numThreads);
  1009.         RGBSize = (sizeTotal*4)/numThreads;
  1010.  
  1011.         //Create multi thread object
  1012.         job = new work_t[numThreads];
  1013.         pid = new pthread_t[numThreads];
  1014.  
  1015.         for (int k=0;k<numThreads;k++)
  1016.         {  
  1017.             job[k].pixfc = pixfc;
  1018.             job[k].startIndex = k*YUVSize;
  1019.  
  1020.             job[k].out = (byte*)rgba + (k*RGBSize);
  1021.         }
  1022.  
  1023.         //Get first frame
  1024.         imageData = GetNextFrame();
  1025.  
  1026.         //Re-init file
  1027.         m_pCryVideoWebM->CloseWebMFile();
  1028.  
  1029.         bool swapuv = false;
  1030.         if (gEnv->pRenderer->GetRenderType() == eRT_DX11)
  1031.             swapuv = true;
  1032.  
  1033.         m_pCryVideoWebM->LoadWebMFile(videoFileName, swapuv);
  1034.     }
  1035.  
  1036.     /*
  1037.     //Setup OpenGL
  1038.         useOpenGL = false;
  1039.  
  1040.         ICVar* OpenGL = gEnv->pConsole->GetCVar("cv_useOpenGL");
  1041.         if (OpenGL && OpenGL->GetIVal() == 1)
  1042.             useOpenGL = true;
  1043.  
  1044.         //make it the current render context
  1045.         wglMakeCurrent( mhDC, mhRC );
  1046.  
  1047.         GLhandleARB FSHandle;
  1048.  
  1049.         char *FProgram=
  1050.         "uniform sampler2D Ytex;\n"
  1051.         "void main(void) {\n"
  1052.         "   float nx, ny, r, g, b, y, u, v;\n"
  1053.         "   float u1,u2,v1,v2;\n"
  1054.  
  1055.         "   nx = gl_TexCoord[0].x;\n"
  1056.         "   ny = gl_TexCoord[0].y;\n"
  1057.  
  1058.         "   y = texture2D(Ytex, vec2( (nx), (ny)*(4.0/6.0) )).r;\n"
  1059.         "   u1 = texture2D(Ytex, vec2( (nx/2.0), (ny+4.0)/6.0 )).r;\n"
  1060.         "   u2 = texture2D(Ytex, vec2( (nx/2.0)+0.5, (ny+4.0)/6.0 )).r;\n"
  1061.         "   v1 = texture2D(Ytex, vec2( (nx/2.0), (ny+5.0)/6.0 )).r;\n"
  1062.         "   v2 = texture2D(Ytex, vec2( (nx/2.0)+0.5, (ny+5.0)/6.0 )).r;\n"
  1063.  
  1064.         "   y = 1.1643 * (y - 0.0625);\n"
  1065.         "   u = (u1+u2)/2.0 - 0.5;\n"
  1066.         "   v = (v1+v2)/2.0 - 0.5;\n"
  1067.  
  1068.         "   r = y + 1.5958 * v;\n"
  1069.         "   g = y - 0.39173 * u - 0.8129 * v;\n"
  1070.         "   b = y + 2.017 * u;\n"
  1071.  
  1072.         "   gl_FragColor=vec4(r,g,b,1.0);\n"
  1073.         "}\n";
  1074.  
  1075.         glMatrixMode(GL_PROJECTION);
  1076.         glLoadIdentity();
  1077.         glOrtho(-width,width,-height,height,-1,1);
  1078.         glViewport(0,0,width,height);
  1079.         glClearColor(0,0,0,0);
  1080.         glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
  1081.  
  1082.         // Set up program objects.
  1083.         PHandle=glCreateProgramObjectARB();
  1084.         FSHandle= glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
  1085.  
  1086.         // Compile the shader.
  1087.         glShaderSourceARB(FSHandle,1,(const GLcharARB**)&FProgram,NULL);
  1088.         glCompileShaderARB(FSHandle);
  1089.  
  1090.         // Create a complete program object.
  1091.         glAttachObjectARB(PHandle,FSHandle);
  1092.         glLinkProgramARB(PHandle);
  1093.  
  1094.         // Finally, use the program.
  1095.         glUseProgramObjectARB(PHandle);
  1096.  
  1097.         // This might not be required, but should not hurt.
  1098.         glEnable(GL_TEXTURE_2D);
  1099.    
  1100.         glGenTextures(1, &texture); // Generate the YUV 4:2:0 handle
  1101.         glBindTexture(GL_TEXTURE_2D, texture); // and use it
  1102.         //glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE); // note that GL_REPLACE is certainly not the best thing for video mixing ...
  1103.         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_DECAL);
  1104.         //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtering seem a good compromise between speed/quality
  1105.         //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // this seem the same thing for the magnification and minification
  1106.    
  1107.         if (mhRC)
  1108.             wglMakeCurrent( NULL, NULL );
  1109.  
  1110.         */
  1111.  
  1112.  
  1113.     //Test Network Sound
  1114.     /*
  1115.     AVPacket packet;
  1116.     VideoCapture cap("D:\\CryVideo_CE3_Build3.4.0\\Game\\Videos\\Library\\FahrenheitJadeVision.avi");
  1117.  
  1118.     bool exit = false;
  1119.    
  1120.     while (exit == false)
  1121.     {
  1122.         if (av_read_frame(pFormatCtx, &packet) >= 0)
  1123.         {
  1124.             if (packet.stream_index == videoStream)
  1125.             {
  1126.                 // Actually this is were SYNC between audio/video would happen.
  1127.                 // Right now I assume that every VIDEO packet contains an entire video frame, and that's not true. A video frame can be made by multiple packets!
  1128.                 // But for the time being, assume 1 video frame == 1 video packet,
  1129.                 // so instead of reading the frame through ffmpeg, I read it through OpenCV.
  1130.  
  1131.                 Mat frame;
  1132.                 cap >> frame; // get a new frame from camera
  1133.  
  1134.                 // do some processing on the frame, either as a Mat or as IplImage.
  1135.                 // For educational purposes, applying a lame grayscale conversion
  1136.                 IplImage ipl_frame = frame;
  1137.                 for (int i = 0; i < ipl_frame.width * ipl_frame.height * ipl_frame.nChannels; i += ipl_frame.nChannels)
  1138.                 {
  1139.                         ipl_frame.imageData[i] = (ipl_frame.imageData[i] + ipl_frame.imageData[i+1] + ipl_frame.imageData[i+2])/3;   //B
  1140.                         ipl_frame.imageData[i+1] = (ipl_frame.imageData[i] + ipl_frame.imageData[i+1] + ipl_frame.imageData[i+2])/3; //G
  1141.                         ipl_frame.imageData[i+2] = (ipl_frame.imageData[i] + ipl_frame.imageData[i+1] + ipl_frame.imageData[i+2])/3; //R
  1142.                 }
  1143.  
  1144.                 // Display it on SDL window
  1145.                 show_frame(&ipl_frame);
  1146.  
  1147.                 av_free_packet(&packet);
  1148.             }  
  1149.             else if (packet.stream_index == audioStream)
  1150.             {
  1151.                 packet_queue_put(&audioq, &packet);
  1152.                 exit = true;
  1153.             }  
  1154.             else
  1155.             {
  1156.              av_free_packet(&packet);
  1157.             }
  1158.  
  1159.             SDL_Event event;
  1160.             SDL_PollEvent(&event);
  1161.         }
  1162.     }
  1163.  
  1164.     EntityId playerId = gEnv->pGame->GetIGameFramework()->GetClientActorId();
  1165.  
  1166.     CryLogAlways("OpenCV: Playback should now be ready");
  1167.  
  1168.     //ISound *pNetworkSound = gEnv->pSoundSystem->CreateNetworkSound(this, 16, 44100, SDL_AUDIO_BUFFER_SIZE, playerId);
  1169.     ISound *pNetworkSound = gEnv->pSoundSystem->CreateNetworkSound(this, 16, 3000, SDL_AUDIO_BUFFER_SIZE, playerId);
  1170.     if (pNetworkSound)
  1171.     {
  1172.         CryLogAlways("Netzwerk Sound wird gestartet!");
  1173.         pNetworkSound->Play();
  1174.     }
  1175.     */
  1176.  
  1177.    
  1178.  
  1179.     return imageData;
  1180. }
  1181.  
  1182.  
  1183. //Test Network Sound
  1184. /*
  1185. bool CCryVideoOpenCV::FillDataBuffer(unsigned int nBitsPerSample, unsigned int nSamplesPerSecond, unsigned int nNumSamples, void* pData )
  1186. {
  1187.     CryLogAlways("Audio Data requested!");
  1188.     CryLogAlways("Number Samples: %i!", nNumSamples);
  1189.  
  1190.     Uint8 *stream = new Uint8[nNumSamples*nBitsPerSample];
  1191.  
  1192.     CryLogAlways("Fill in Data!");
  1193.  
  1194.     AVCodecContext *aCodecCtx = aCodec;
  1195.     int len1, audio_size;
  1196.  
  1197.     static uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
  1198.     static unsigned int audio_buf_size = 0;
  1199.     static unsigned int audio_buf_index = 0;
  1200.  
  1201.     while (nNumSamples > 0)
  1202.     {
  1203.         if (audio_buf_index >= audio_buf_size)
  1204.         {
  1205.             // We have already sent all our data; get more
  1206.             audio_size = audio_decode_frame(aCodecCtx, audio_buf, sizeof(audio_buf));
  1207.             if(audio_size < 0)
  1208.             {
  1209.                 // If error, output silence
  1210.                 audio_buf_size = 1024; // arbitrary?
  1211.                 memset(audio_buf, 0, audio_buf_size);
  1212.             }
  1213.             else
  1214.             {
  1215.                 audio_buf_size = audio_size;
  1216.             }
  1217.             audio_buf_index = 0;
  1218.         }
  1219.         len1 = audio_buf_size - audio_buf_index;
  1220.         if (len1 > nNumSamples)
  1221.             len1 = nNumSamples;
  1222.  
  1223.             memcpy(stream, (uint8_t *)audio_buf + audio_buf_index, len1);
  1224.         nNumSamples -= len1;
  1225.         stream += len1;
  1226.         audio_buf_index += len1;
  1227.     }
  1228.  
  1229.     CryLogAlways("Send Data!");
  1230.  
  1231.     pData = stream;
  1232.  
  1233.     CryLogAlways("Free Var!");
  1234.  
  1235.     free(stream);
  1236.  
  1237.     CryLogAlways("Finished!");
  1238.  
  1239.     return true;
  1240. }
  1241. */
  1242.  
  1243. void CCryVideoOpenCV::SkipFrame()
  1244. {
  1245.     if (mode == 1) //AVI
  1246.     {
  1247.         cvGrabFrame(video_capture);
  1248.     }
  1249.     else //WebM
  1250.     {
  1251.         m_pCryVideoWebM->GetNextFrame();
  1252.     }
  1253. }
  1254.  
  1255. int CCryVideoOpenCV::GetVideoWidth()
  1256. {
  1257.     if (mode == 1) //AVI
  1258.     {
  1259.         int width = (int)cvGetCaptureProperty(video_capture, CV_CAP_PROP_FRAME_WIDTH);
  1260.         return width;
  1261.     }
  1262.     else //WebM
  1263.     {
  1264.         int width = m_pCryVideoWebM->GetVideoWidth();
  1265.         return width;
  1266.     }
  1267. }
  1268.  
  1269. int CCryVideoOpenCV::GetVideoHeight()
  1270. {
  1271.     if (mode == 1) //AVI
  1272.     {
  1273.         int height = (int)cvGetCaptureProperty(video_capture, CV_CAP_PROP_FRAME_HEIGHT);
  1274.         return height;
  1275.     }
  1276.     else //WebM
  1277.     {
  1278.         int height = m_pCryVideoWebM->GetVideoHeight();
  1279.         return height;
  1280.     }
  1281. }
  1282.  
  1283. float CCryVideoOpenCV::GetVideoFrameRate()
  1284. {
  1285.     if (mode == 1) //AVI
  1286.     {
  1287.         float frameRate = (float)cvGetCaptureProperty(video_capture, CV_CAP_PROP_FPS);
  1288.         return frameRate;
  1289.     }
  1290.     else //WebM
  1291.     {
  1292.         float frameRate = m_pCryVideoWebM->GetVideoFrameRate();
  1293.         return frameRate;
  1294.     }
  1295. }
  1296.  
  1297. int CCryVideoOpenCV::GetFrameCount()
  1298. {
  1299.     if (mode == 1) //AVI
  1300.     {
  1301.         int frameCount = (int)cvGetCaptureProperty(video_capture, CV_CAP_PROP_FRAME_COUNT);
  1302.         return frameCount;
  1303.     }
  1304.     else //WebM
  1305.     {
  1306.         return -1;
  1307.     }
  1308. }
  1309.  
  1310. char* CCryVideoOpenCV::GetNextFrame()
  1311. {
  1312.     char* imageData = NULL;
  1313.  
  1314.     //CryLogAlways("Get Next Frame!");
  1315.  
  1316.     //Test Network Sound
  1317.     /*
  1318.     AVPacket packet;
  1319.     VideoCapture cap("D:\\CryVideo_CE3_Build3.4.0\\Game\\Videos\\Library\\FahrenheitJadeVision.avi");
  1320.  
  1321.     bool exit = false;
  1322.     while (exit == false)
  1323.     {
  1324.         if (av_read_frame(pFormatCtx, &packet) >= 0)
  1325.         {
  1326.             if (packet.stream_index == videoStream)
  1327.             {
  1328.                 // Actually this is were SYNC between audio/video would happen.
  1329.                 // Right now I assume that every VIDEO packet contains an entire video frame, and that's not true. A video frame can be made by multiple packets!
  1330.                 // But for the time being, assume 1 video frame == 1 video packet,
  1331.                 // so instead of reading the frame through ffmpeg, I read it through OpenCV.
  1332.  
  1333.                 Mat frame;
  1334.                 cap >> frame; // get a new frame from camera
  1335.  
  1336.                 // do some processing on the frame, either as a Mat or as IplImage.
  1337.                 // For educational purposes, applying a lame grayscale conversion
  1338.                 IplImage ipl_frame = frame;
  1339.                 for (int i = 0; i < ipl_frame.width * ipl_frame.height * ipl_frame.nChannels; i += ipl_frame.nChannels)
  1340.                 {
  1341.                         ipl_frame.imageData[i] = (ipl_frame.imageData[i] + ipl_frame.imageData[i+1] + ipl_frame.imageData[i+2])/3;   //B
  1342.                         ipl_frame.imageData[i+1] = (ipl_frame.imageData[i] + ipl_frame.imageData[i+1] + ipl_frame.imageData[i+2])/3; //G
  1343.                         ipl_frame.imageData[i+2] = (ipl_frame.imageData[i] + ipl_frame.imageData[i+1] + ipl_frame.imageData[i+2])/3; //R
  1344.                 }
  1345.  
  1346.                 // Display it on SDL window
  1347.                 show_frame(&ipl_frame);
  1348.  
  1349.                 av_free_packet(&packet);
  1350.             }  
  1351.             else if (packet.stream_index == audioStream)
  1352.             {
  1353.                 packet_queue_put(&audioq, &packet);
  1354.                 exit = true;
  1355.             }  
  1356.             else
  1357.             {
  1358.              av_free_packet(&packet);
  1359.             }
  1360.  
  1361.             SDL_Event event;
  1362.             SDL_PollEvent(&event);
  1363.         }
  1364.         else
  1365.         {
  1366.             SDL_FreeSurface(surface);
  1367.             SDL_Quit();
  1368.  
  1369.             // the camera will be deinitialized automatically in VideoCapture destructor
  1370.  
  1371.             // Close the codec
  1372.             avcodec_close(pCodecCtx);
  1373.  
  1374.             // Close the video file
  1375.             av_close_input_file(pFormatCtx);
  1376.  
  1377.             break;
  1378.         }
  1379.     }
  1380.     */
  1381.  
  1382.     if (mode == 1) //AVI
  1383.     {
  1384.         source_image=cvQueryFrame(video_capture);
  1385.         if (source_image)
  1386.         {
  1387.             if (g_pCryVideo->IsRGB8Usable())
  1388.             {
  1389.                 if (swapBGRA)
  1390.                 {
  1391.                     cvCvtColor(source_image, dest_image, CV_BGR2RGB);
  1392.                     imageData = dest_image->imageData;
  1393.  
  1394.                     if (renderToWindow)
  1395.                         cvShowImage("CryVideo Player",dest_image);
  1396.                 }
  1397.                 else
  1398.                 {
  1399.                     imageData = source_image->imageData;
  1400.  
  1401.                     if (renderToWindow)
  1402.                         cvShowImage("CryVideo Player",source_image);
  1403.                 }
  1404.             }
  1405.             else
  1406.             {
  1407.                 if (manual_conversion_OpenCV || force_manual_conversion)
  1408.                 {
  1409.                     if (swapBGRA)
  1410.                     {
  1411.                         cvCvtColor(source_image, dest_image, CV_BGR2RGBA);
  1412.                     }
  1413.                     else
  1414.                     {
  1415.                         cvCvtColor(source_image, dest_image, CV_BGR2BGRA);
  1416.                     }
  1417.  
  1418.                     imageData = dest_image->imageData;
  1419.                 }
  1420.                 else
  1421.                 {
  1422.                     rgb = source_image->imageData;
  1423.                     //pixfcOpenCV->convert(pixfcOpenCV, rgb, rgba, 0);
  1424.  
  1425.                     for (int k=0;k<numThreadsAVI;k++)
  1426.                     {
  1427.                         job[k].in = (byte*)rgb + (k*YUVSize);
  1428.  
  1429.                         pthread_create(&pid[k], NULL, Thread, &job[k]);
  1430.                     }
  1431.  
  1432.                     // Join all the threads
  1433.                     for (int k=0;k<numThreadsAVI;k++)
  1434.                     {
  1435.                         pthread_join(pid[k], NULL);
  1436.                     }
  1437.  
  1438.                     imageData = rgba;
  1439.                 }
  1440.  
  1441.                 if (renderToWindow)
  1442.                     cvShowImage("CryVideo Player",dest_image);
  1443.             }
  1444.         }
  1445.     }
  1446.     else //WebM
  1447.     {
  1448.         //CryLogAlways("GetNextFrame!");
  1449.         bool success = m_pCryVideoWebM->GetNextFrame();
  1450.         if (success)
  1451.         {
  1452.             if (renderToWindow)
  1453.                 if (!g_pCryVideo->IsRGB8Usable())
  1454.                     dest_image = cvCreateImage(cvSize(width, height),IPL_DEPTH_8U,4);
  1455.                 else
  1456.                     dest_image = cvCreateImage(cvSize(width, height),IPL_DEPTH_8U,3);
  1457.  
  1458.             //Retrieve Next Frame
  1459.             bool result = m_pCryVideoWebM->RetrieveNextFrame(NULL, NULL, NULL, true, yuv);
  1460.    
  1461.             if (!result)
  1462.                 goto fail;
  1463.  
  1464.             /*
  1465.             if (useOpenGL)
  1466.             {
  1467.                 //make it the current render context
  1468.                 wglMakeCurrent( mhDC, mhRC );
  1469.  
  1470.                 glActiveTexture(texture);
  1471.                 glBindTexture(GL_TEXTURE_2D, texture); // update the YUV video texturing unit
  1472.  
  1473.                 //Update texture
  1474.                 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, (height*3/2), 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv);
  1475.    
  1476.                 const GLfloat vertexCoord[8] = {
  1477.                     -width, +height,
  1478.                     +width, +height,
  1479.                     -width, -height,
  1480.                     +width, -height,
  1481.                 };
  1482.  
  1483.                 const GLfloat textureCoord[8] = {
  1484.                     0, 1,
  1485.                     1, 1,
  1486.                     0, 0,
  1487.                     1, 0,
  1488.                 };
  1489.  
  1490.                 glEnableClientState(GL_VERTEX_ARRAY);
  1491.                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  1492.                 glVertexPointer(2, GL_FLOAT, 0, vertexCoord);
  1493.                 glTexCoordPointer(2, GL_FLOAT, 0, textureCoord);
  1494.  
  1495.  
  1496.                 //Draw image
  1497.                 glClear(GL_COLOR_BUFFER_BIT);
  1498.                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  1499.  
  1500.                 glReadPixels(0,0,width,height,GL_BGRA,GL_UNSIGNED_BYTE,rgba);
  1501.  
  1502.                 if (mhRC)
  1503.                     wglMakeCurrent( NULL, NULL );
  1504.  
  1505.                 goto end;
  1506.             }*/
  1507.  
  1508.  
  1509.             // Do conversion
  1510.             if (!manual_conversion && !force_manual_conversion)
  1511.             {
  1512.                 //pixfc->convert(pixfc, yuv, rgba);
  1513.        
  1514.                 for (int k=0;k<numThreads;k++)
  1515.                 {
  1516.                     job[k].in = (byte*)yuv;
  1517.  
  1518.                     pthread_create(&pid[k], NULL, Thread, &job[k]);
  1519.                 }
  1520.  
  1521.                 // Join all the threads
  1522.                 for (int k=0;k<numThreads;k++)
  1523.                 {
  1524.                     pthread_join(pid[k], NULL);
  1525.                 }
  1526.             }
  1527.             else
  1528.             {
  1529.                 if (!g_pCryVideo->IsRGB8Usable()) //RGBA || BGRA
  1530.                 {
  1531.                     long currentPos;
  1532.                     int widthHelper;
  1533.                     long sizeTotalHelper;
  1534.                     unsigned char y2,u,v;
  1535.                     int r,g,b,c,d,e;
  1536.  
  1537.                     widthHelper = width / 2;
  1538.                     sizeTotalHelper = sizeTotal + (sizeTotal / 4);
  1539.  
  1540.                     for (int y=0; y < height; y=y+2)
  1541.                     {
  1542.                         for (int x=0; x < width; x=x+2)
  1543.                         {
  1544.                             //x=0; y=0
  1545.                             y2 = yuv[y * width + x];
  1546.                             u = yuv[(y / 2) * widthHelper + (x / 2) + sizeTotalHelper];
  1547.                             v = yuv[(y / 2) * widthHelper + (x / 2) + sizeTotal];
  1548.            
  1549.                             c = y2 - 16;
  1550.                             d = u - 128;
  1551.                             e = v - 128;
  1552.  
  1553.                             r = ( 298 * c + 409 * e + 128) >> 8;
  1554.                             g = ( 298 * c - 100 * d - 208 * e + 128) >> 8;
  1555.                             b = ( 298 * c + 516 * d + 128) >> 8;
  1556.  
  1557.                             if (r < 0) r = 0;
  1558.                             else if (r > 255) r = 255;
  1559.                             if (g < 0) g = 0;
  1560.                             else if (g > 255) g = 255;
  1561.                             if (b < 0) b = 0;
  1562.                             else if (b > 255) b = 255;
  1563.        
  1564.                             currentPos = (y*width)*4 + (x*4);
  1565.  
  1566.                             rgba[currentPos+0] = r;
  1567.                             rgba[currentPos+1] = g;
  1568.                             rgba[currentPos+2] = b;
  1569.                             rgba[currentPos+3] = 255;
  1570.            
  1571.                             //x=0; y=1
  1572.                             y2 = yuv[(y+1) * width + x];
  1573.    
  1574.                             c = y2 - 16;
  1575.  
  1576.                             r = ( 298 * c + 409 * e + 128) >> 8;
  1577.                             g = ( 298 * c - 100 * d - 208 * e + 128) >> 8;
  1578.                             b = ( 298 * c + 516 * d + 128) >> 8;
  1579.  
  1580.                             if (r < 0) r = 0;
  1581.                             else if (r > 255) r = 255;
  1582.                             if (g < 0) g = 0;
  1583.                             else if (g > 255) g = 255;
  1584.                             if (b < 0) b = 0;
  1585.                             else if (b > 255) b = 255;
  1586.  
  1587.  
  1588.                             currentPos = ((y+1)*width)*4 + (x*4);
  1589.  
  1590.                             rgba[currentPos+0] = r;
  1591.                             rgba[currentPos+1] = g;
  1592.                             rgba[currentPos+2] = b;
  1593.                             rgba[currentPos+3] = 255;
  1594.  
  1595.  
  1596.                             //x=1; y=0
  1597.                             y2 = yuv[y * width + (x+1)];
  1598.    
  1599.                             c = y2 - 16;
  1600.  
  1601.  
  1602.                             r = ( 298 * c + 409 * e + 128) >> 8;
  1603.                             g = ( 298 * c - 100 * d - 208 * e + 128) >> 8;
  1604.                             b = ( 298 * c + 516 * d + 128) >> 8;
  1605.  
  1606.  
  1607.                             if (r < 0) r = 0;
  1608.                             else if (r > 255) r = 255;
  1609.                             if (g < 0) g = 0;
  1610.                             else if (g > 255) g = 255;
  1611.                             if (b < 0) b = 0;
  1612.                             else if (b > 255) b = 255;
  1613.  
  1614.  
  1615.                             currentPos = (y*width)*4 + ((x+1)*4);
  1616.  
  1617.                             rgba[currentPos+0] = r;
  1618.                             rgba[currentPos+1] = g;
  1619.                             rgba[currentPos+2] = b;
  1620.                             rgba[currentPos+3] = 255;
  1621.  
  1622.                             //x=1; y=1
  1623.                             y2 = yuv[(y+1) * width + (x+1)];
  1624.    
  1625.                             c = y2 - 16;
  1626.            
  1627.                             r = ( 298 * c + 409 * e + 128) >> 8;
  1628.                             g = ( 298 * c - 100 * d - 208 * e + 128) >> 8;
  1629.                             b = ( 298 * c + 516 * d + 128) >> 8;
  1630.            
  1631.                             if (r < 0) r = 0;
  1632.                             else if (r > 255) r = 255;
  1633.                             if (g < 0) g = 0;
  1634.                             else if (g > 255) g = 255;
  1635.                             if (b < 0) b = 0;
  1636.                             else if (b > 255) b = 255;
  1637.  
  1638.                             currentPos = ((y+1)*width)*4 + ((x+1)*4);
  1639.  
  1640.                             rgba[currentPos+0] = r;
  1641.                             rgba[currentPos+1] = g;
  1642.                             rgba[currentPos+2] = b;
  1643.                             rgba[currentPos+3] = 255;
  1644.                         }
  1645.                     }
  1646.                 }
  1647.                 else //RGB  || BGR
  1648.                 {
  1649.                     long currentPos;
  1650.                     int widthHelper;
  1651.                     long sizeTotalHelper;
  1652.                     unsigned char y2,u,v;
  1653.                     int r,g,b,c,d,e;
  1654.  
  1655.                     widthHelper = width / 2;
  1656.                     sizeTotalHelper = sizeTotal + (sizeTotal / 4);
  1657.  
  1658.                     for (int y=0; y < height; y=y+2)
  1659.                     {
  1660.                         for (int x=0; x < width; x=x+2)
  1661.                         {
  1662.                             //x=0; y=0
  1663.                             y2 = yuv[y * width + x];
  1664.                             u = yuv[(y / 2) * widthHelper + (x / 2) + sizeTotalHelper];
  1665.                             v = yuv[(y / 2) * widthHelper + (x / 2) + sizeTotal];
  1666.            
  1667.                             c = y2 - 16;
  1668.                             d = u - 128;
  1669.                             e = v - 128;
  1670.  
  1671.                             r = ( 298 * c + 409 * e + 128) >> 8;
  1672.                             g = ( 298 * c - 100 * d - 208 * e + 128) >> 8;
  1673.                             b = ( 298 * c + 516 * d + 128) >> 8;
  1674.  
  1675.                             if (r < 0) r = 0;
  1676.                             else if (r > 255) r = 255;
  1677.                             if (g < 0) g = 0;
  1678.                             else if (g > 255) g = 255;
  1679.                             if (b < 0) b = 0;
  1680.                             else if (b > 255) b = 255;
  1681.        
  1682.                             currentPos = (y*width)*3 + (x*3);
  1683.  
  1684.                             rgba[currentPos+0] = r;
  1685.                             rgba[currentPos+1] = g;
  1686.                             rgba[currentPos+2] = b;
  1687.            
  1688.                             //x=0; y=1
  1689.                             y2 = yuv[(y+1) * width + x];
  1690.    
  1691.                             c = y2 - 16;
  1692.  
  1693.                             r = ( 298 * c + 409 * e + 128) >> 8;
  1694.                             g = ( 298 * c - 100 * d - 208 * e + 128) >> 8;
  1695.                             b = ( 298 * c + 516 * d + 128) >> 8;
  1696.  
  1697.                             if (r < 0) r = 0;
  1698.                             else if (r > 255) r = 255;
  1699.                             if (g < 0) g = 0;
  1700.                             else if (g > 255) g = 255;
  1701.                             if (b < 0) b = 0;
  1702.                             else if (b > 255) b = 255;
  1703.  
  1704.  
  1705.                             currentPos = ((y+1)*width)*3 + (x*3);
  1706.  
  1707.                             rgba[currentPos+0] = r;
  1708.                             rgba[currentPos+1] = g;
  1709.                             rgba[currentPos+2] = b;
  1710.  
  1711.  
  1712.                             //x=1; y=0
  1713.                             y2 = yuv[y * width + (x+1)];
  1714.    
  1715.                             c = y2 - 16;
  1716.  
  1717.  
  1718.                             r = ( 298 * c + 409 * e + 128) >> 8;
  1719.                             g = ( 298 * c - 100 * d - 208 * e + 128) >> 8;
  1720.                             b = ( 298 * c + 516 * d + 128) >> 8;
  1721.  
  1722.  
  1723.                             if (r < 0) r = 0;
  1724.                             else if (r > 255) r = 255;
  1725.                             if (g < 0) g = 0;
  1726.                             else if (g > 255) g = 255;
  1727.                             if (b < 0) b = 0;
  1728.                             else if (b > 255) b = 255;
  1729.  
  1730.  
  1731.                             currentPos = (y*width)*3 + ((x+1)*3);
  1732.  
  1733.                             rgba[currentPos+0] = r;
  1734.                             rgba[currentPos+1] = g;
  1735.                             rgba[currentPos+2] = b;
  1736.  
  1737.                             //x=1; y=1
  1738.                             y2 = yuv[(y+1) * width + (x+1)];
  1739.    
  1740.                             c = y2 - 16;
  1741.            
  1742.                             r = ( 298 * c + 409 * e + 128) >> 8;
  1743.                             g = ( 298 * c - 100 * d - 208 * e + 128) >> 8;
  1744.                             b = ( 298 * c + 516 * d + 128) >> 8;
  1745.            
  1746.                             if (r < 0) r = 0;
  1747.                             else if (r > 255) r = 255;
  1748.                             if (g < 0) g = 0;
  1749.                             else if (g > 255) g = 255;
  1750.                             if (b < 0) b = 0;
  1751.                             else if (b > 255) b = 255;
  1752.  
  1753.                             currentPos = ((y+1)*width)*3 + ((x+1)*3);
  1754.  
  1755.                             rgba[currentPos+0] = r;
  1756.                             rgba[currentPos+1] = g;
  1757.                             rgba[currentPos+2] = b;
  1758.                         }
  1759.                     }
  1760.                 }
  1761.             }
  1762.  
  1763.             imageData = rgba;
  1764.            
  1765.             if (renderToWindow)
  1766.             {
  1767.                 dest_image->imageData = imageData;
  1768.                 cvShowImage("CryVideo Player",dest_image);
  1769.  
  1770.                 cvReleaseImage(&dest_image);
  1771.             }
  1772.         }
  1773.         else
  1774.         {
  1775. fail:
  1776.             imageData = NULL;
  1777.         }
  1778.     }
  1779.  
  1780.     return imageData;
  1781. }
  1782.  
  1783. void CCryVideoOpenCV::Shutdown()
  1784. {
  1785.     this->~CCryVideoOpenCV();
  1786. }
  1787.  
  1788. void CCryVideoOpenCV::GetMemoryStatistics(ICrySizer * s) const
  1789. {
  1790.     s->Add(*this);
  1791. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement