Advertisement
Guest User

Untitled

a guest
May 8th, 2025
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.18 KB | None | 0 0
  1. #include "clVideo.h"
  2.  
  3. extern "C"
  4. {
  5. #include "libavformat/avformat.h"
  6. #include "libavcodec/avcodec.h"
  7. #include "libswscale/swscale.h"
  8. #include "libavutil/imgutils.h"
  9. #include "clThreading.h"
  10. }
  11.  
  12. #pragma comment(lib, "Secur32.lib")
  13. #pragma comment(lib, "Bcrypt.lib")
  14. #pragma comment(lib, "Ws2_32.lib")
  15.  
  16. #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/swresample.lib")
  17. #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/avformat.lib")
  18. #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/avfilter.lib")
  19. #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/avdevice.lib")
  20. #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/avcodec.lib")
  21. #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/swscale.lib")
  22. #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/avutil.lib")
  23.  
  24. clVideo::clVideo(clPath mediaFile, bool swapRedAndBlue)
  25. {
  26.   destFormat = swapRedAndBlue ? AV_PIX_FMT_RGBA : AV_PIX_FMT_BGRA;
  27.   av_register_all();
  28.   pFC = avformat_alloc_context();
  29.   if (avformat_open_input(&pFC, mediaFile.Path().c_str(), nullptr, nullptr) != 0) clRelFail("Unable to open video");
  30.  
  31.   // Identify Video Stream
  32.   avformat_find_stream_info(pFC, nullptr);
  33.   video_stream_index = -1;
  34.   for (int i = 0; i < (int)pFC->nb_streams; ++i)
  35.     if (pFC->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
  36.     {
  37.       video_stream_index = i;
  38.       break;
  39.     }
  40.  
  41.   AVCodecParameters *codecpar = pFC->streams[video_stream_index]->codecpar;
  42.   AVCodec *pCodec = avcodec_find_decoder(codecpar->codec_id);
  43.   pCC = avcodec_alloc_context3(pCodec);
  44.   avcodec_parameters_to_context(pCC, codecpar);
  45.   avcodec_open2(pCC, pCodec, nullptr);
  46.  
  47.   // Allocate Frame Buffer
  48.   pF = av_frame_alloc();
  49.   pP = av_packet_alloc();
  50.  
  51.   // Allocate RGBA frame
  52.   pCF = av_frame_alloc();
  53.   av_image_alloc(pCF->data, pCF->linesize, pCC->width, pCC->height, (AVPixelFormat)destFormat, 1);
  54.   pCF->height = pCC->height;
  55.   pCF->width = pCC->width;
  56.   pCF->format = destFormat;
  57.  
  58.   // Conversion Context Creation Depends On Conversion Source So Delay Allocation Until Reading Frame
  59.   pConC = nullptr;
  60. }
  61.  
  62. clVideo::~clVideo()
  63. {
  64.   av_packet_free(&pP);
  65.   av_frame_free(&pF);
  66.   av_freep(&pCF->data);
  67.   av_frame_free(&pCF);
  68.   avcodec_free_context(&pCC);
  69.   if (pConC) sws_freeContext(pConC);
  70.   avformat_close_input(&pFC);
  71. }
  72.  
  73. bool clVideo::Frame(clImage *pFrame)
  74. {
  75.   bool foundVideoFrame = false;
  76.   while (!foundVideoFrame && av_read_frame(pFC, pP) >= 0)
  77.   {
  78.     if (pP->stream_index == video_stream_index)
  79.     {
  80.       if (pFrame)
  81.       {
  82.         int ret = avcodec_send_packet(pCC, pP);
  83.         if (ret < 0) return false;
  84.  
  85.         ret = avcodec_receive_frame(pCC, pF);
  86.         if (ret < 0) return false;
  87.  
  88.         if (!pConC)
  89.         {
  90.           pConC = sws_getContext(pCC->width, pCC->height, (AVPixelFormat)pF->format, pCC->width, pCC->height,
  91.             (AVPixelFormat)destFormat, SWS_BILINEAR, nullptr, nullptr, nullptr);
  92.         }
  93.  
  94.         sws_scale(pConC, pF->data, pF->linesize, 0, pCC->height, pCF->data, pCF->linesize);
  95.         *pFrame = clImage((ui32 *)pCF->data[0], v2I(pCF->width, pCF->height));
  96.       }
  97.       foundVideoFrame = true;
  98.     }
  99.     av_packet_unref(pP);
  100.   }
  101.   return foundVideoFrame;
  102. }
  103.  
  104. bool clVideo::Seek(float position)
  105. {
  106.   if (position < 0.0f || position > 1.0f)
  107.   {
  108.     printf("Error: Position must be between 0 and 1\n");
  109.     return false;
  110.   }
  111.  
  112.   int64_t duration = pFC->streams[video_stream_index]->duration;
  113.   int64_t seek_target = static_cast<int64_t>(duration * position);
  114.  
  115.   AVRational time_base = pFC->streams[video_stream_index]->time_base;
  116.   int64_t seek_target_in_stream_time_base = av_rescale_q(seek_target, AVRational{ 1, AV_TIME_BASE }, time_base);
  117.  
  118.   int ret = av_seek_frame(pFC, video_stream_index, seek_target_in_stream_time_base, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY);
  119.   if (ret < 0)
  120.   {
  121.     char errbuf[AV_ERROR_MAX_STRING_SIZE];
  122.     av_strerror(ret, errbuf, sizeof(errbuf));
  123.     printf("Error: Seeking failed with error code %d, details: %s\n", ret, errbuf);
  124.     return false;
  125.   }
  126.  
  127.   avcodec_flush_buffers(pCC);
  128.   clSleep(50);
  129.   //av_packet_unref(pP);
  130.  
  131.   return true;
  132. }
  133.  
  134. v2I clVideo::Res() { return v2I(pCC->width, pCC->height); }
  135.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement