Advertisement
Guest User

Untitled

a guest
Sep 5th, 2024
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.72 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <windows.h>
  4. #include <stdint.h>
  5.  
  6. extern "C" {
  7. #include <libavcodec/avcodec.h>
  8. #include <libavformat/avformat.h>
  9. #include <libswscale/swscale.h>
  10. #include <libavutil/opt.h>
  11. #include <libavutil/imgutils.h>
  12. #include <libavutil/error.h>
  13. }
  14.  
  15.  
  16. void printFFmpegError(int errNum) {
  17.     char errbuf[AV_ERROR_MAX_STRING_SIZE];
  18.     av_strerror(errNum, errbuf, AV_ERROR_MAX_STRING_SIZE);
  19.     std::cerr << "FFmpeg error: " << errbuf << std::endl;
  20. }
  21.  
  22. // Funktion für die Aufnahme eines Screenshots
  23. std::vector<uint8_t> captureScreenshot(int& width, int& height) {
  24.     HDC hScreenDC = GetDC(NULL);  // Desktop DC
  25.     HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
  26.     width = GetSystemMetrics(SM_CXSCREEN);
  27.     height = GetSystemMetrics(SM_CYSCREEN);
  28.     HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
  29.     HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);
  30.  
  31.     BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
  32.  
  33.     BITMAPINFOHEADER bi = {0};
  34.     bi.biSize = sizeof(BITMAPINFOHEADER);
  35.     bi.biWidth = width;
  36.     bi.biHeight = -height;  // Negative to avoid flipping the image
  37.     bi.biPlanes = 1;
  38.     bi.biBitCount = 24;
  39.     bi.biCompression = BI_RGB;
  40.  
  41.     std::vector<uint8_t> buffer(width * height * 3);  // RGB buffer
  42.     GetDIBits(hMemoryDC, hBitmap, 0, height, buffer.data(), (BITMAPINFO*)&bi, DIB_RGB_COLORS);
  43.  
  44.     SelectObject(hMemoryDC, hOldBitmap);
  45.     DeleteObject(hBitmap);
  46.     DeleteDC(hMemoryDC);
  47.     ReleaseDC(NULL, hScreenDC);
  48.  
  49.     return buffer;
  50. }
  51.  
  52.  
  53. std::vector<uint8_t> compressWithH264(const std::vector<uint8_t>& rgbData, int width, int height) {
  54.     std::vector<uint8_t> compressedData;
  55.  
  56.     const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264);  // Hier const verwenden
  57.     if (!codec) {
  58.         std::cerr << "Codec not found!" << std::endl;
  59.         return compressedData;
  60.     }
  61.  
  62.     AVCodecContext* codecCtx = avcodec_alloc_context3(codec);
  63.     if (!codecCtx) {
  64.         std::cerr << "Could not allocate video codec context!" << std::endl;
  65.         return compressedData;
  66.     }
  67.  
  68.     codecCtx->bit_rate = 400000;
  69.     codecCtx->width = width;
  70.     codecCtx->height = height;
  71.     codecCtx->time_base = (AVRational){1, 25};
  72.     codecCtx->framerate = (AVRational){25, 1};
  73.     codecCtx->gop_size = 10;
  74.     codecCtx->max_b_frames = 1;
  75.     codecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
  76.  
  77.     if (avcodec_open2(codecCtx, codec, NULL) < 0) {
  78.         std::cerr << "Could not open codec!" << std::endl;
  79.         avcodec_free_context(&codecCtx);
  80.         return compressedData;
  81.     }
  82.  
  83.     AVFrame* frame = av_frame_alloc();
  84.     frame->format = AV_PIX_FMT_YUV420P;
  85.     frame->width = width;
  86.     frame->height = height;
  87.  
  88.     if (av_image_alloc(frame->data, frame->linesize, width, height, AV_PIX_FMT_YUV420P, 32) < 0) {
  89.         std::cerr << "Could not allocate raw picture buffer!" << std::endl;
  90.         av_frame_free(&frame);
  91.         avcodec_free_context(&codecCtx);
  92.         return compressedData;
  93.     }
  94.  
  95.     SwsContext* swsCtx = sws_getContext(width, height, AV_PIX_FMT_RGB24, width, height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);
  96.  
  97.     const uint8_t* inData[1] = { rgbData.data() };
  98.     int inLinesize[1] = { 3 * width };
  99.  
  100.     sws_scale(swsCtx, inData, inLinesize, 0, height, frame->data, frame->linesize);
  101.  
  102.     frame->pts = 0;
  103.  
  104.     AVPacket* pkt = av_packet_alloc();
  105.     if (!pkt) {
  106.         std::cerr << "Could not allocate AVPacket!" << std::endl;
  107.         sws_freeContext(swsCtx);
  108.         av_frame_free(&frame);
  109.         avcodec_free_context(&codecCtx);
  110.         return compressedData;
  111.     }
  112.  
  113.     if (avcodec_send_frame(codecCtx, frame) < 0) {
  114.         std::cerr << "Error sending frame for encoding!" << std::endl;
  115.     }
  116.  
  117.     if (avcodec_receive_packet(codecCtx, pkt) == 0) {
  118.         compressedData.assign(pkt->data, pkt->data + pkt->size);
  119.     } else {
  120.         std::cerr << "Error receiving packet!" << std::endl;
  121.     }
  122.  
  123.     av_packet_free(&pkt);
  124.     av_freep(&frame->data[0]);
  125.     av_frame_free(&frame);
  126.     sws_freeContext(swsCtx);
  127.     avcodec_free_context(&codecCtx);
  128.  
  129.     return compressedData;
  130. }
  131.  
  132. int main() {
  133.     int width, height;
  134.     std::vector<uint8_t> screenshot = captureScreenshot(width, height);
  135.     if (screenshot.empty()) {
  136.         std::cerr << "Failed to capture screenshot!" << std::endl;
  137.         return -1;
  138.     }
  139.  
  140.     std::vector<uint8_t> compressedData = compressWithH264(screenshot, width, height);
  141.     if (compressedData.empty()) {
  142.         std::cerr << "Failed to compress screenshot!" << std::endl;
  143.         return -1;
  144.     }
  145.  
  146.     std::cout << "Screenshot captured and compressed. Size: " << compressedData.size() << " bytes." << std::endl;
  147.  
  148.     return 0;
  149. }
  150.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement