Advertisement
Guest User

video.cpp

a guest
Jun 12th, 2019
465
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.28 KB | None | 0 0
  1. #include <../../../../FPExternalClasses/Classes/FFmpeg/ffmpegvideoplay.h>
  2.  
  3. #include "cocostudio/CocoStudio.h"
  4. #include "ui/CocosGUI.h"
  5. #include "../../../../FPExternalClasses/Classes/videoplay.h"
  6. #include <mutex>
  7. #include "iostream"
  8. #include <cocos2d.h>
  9. #include "../../../../FPExternalClasses/Classes/global.h"
  10. #include "../../../../FPExternalClasses/Classes/globalevents.h"
  11. #include "../../../../FPExternalClasses/Classes/videomanager.h";
  12.  
  13.  
  14.  
  15. #include <mutex>
  16.  
  17.  
  18. unsigned int video::totalVideoPlayers = 0;
  19.  
  20.  
  21. bool isAlt = false;
  22.  
  23.  
  24. video::video(std::string path, cocos2d::Sprite* origin) {
  25.     totalVideoPlayers++;
  26.     this->infilename = path;
  27.    
  28.     if (origin) {
  29.         holdersprite = origin; //save the guy
  30.         transfer = true;
  31.         org_rotation =           origin->getRotation();
  32.         org_scaleX =             origin->getScaleX();
  33.         org_scaleY =             origin->getScaleY();
  34.         org_anchor =             origin->getAnchorPoint();
  35.         org_pos =                origin->getPosition();
  36.         org_size =               origin->getContentSize();
  37.         org_opacity =            origin->getOpacity();
  38.         wasVisible =             origin->isVisible();
  39.         org_blend =              origin->getBlendFunc();
  40.         org_zorder =             origin->getZOrder();
  41.     }
  42.  
  43.     this->video_init();
  44. }
  45.  
  46.  
  47. video::~video() {
  48.  
  49.     freeData();
  50.  
  51. }
  52.  
  53.  
  54. void video::video_init() {
  55.  
  56.     //get mat?
  57.     //or draw vertices?
  58.  
  59.     //try first standard way?
  60.     //draw vertices?
  61.  
  62.  
  63.  
  64.     // build and compile our shader zprogram
  65.     // ------------------------------------
  66. /// ourShader = new Shader("4.2.texture.vs", "4.2.texture.fs");
  67.  
  68.     // load and create a texture
  69.     // -------------------------
  70.  
  71.     // texture 1
  72.     // ---------
  73.     glGenTextures(1, &texture1);
  74.     glBindTexture(GL_TEXTURE_2D, texture1);
  75.     // set the texture wrapping parameters
  76.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);  // set texture wrapping to GL_REPEAT (default wrapping method)
  77.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  78.     // set texture filtering parameters
  79.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //GL_LINEAR);
  80.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //GL_LINEAR);
  81.     // load image, create texture and generate mipmaps
  82.  
  83.  
  84.     // tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
  85.     // -------------------------------------------------------------------------------------------
  86. /// ourShader->use(); // don't forget to activate/use the shader before setting uniforms!
  87.                      // either set it manually like so:
  88. /// glUniform1i(glGetUniformLocation(ourShader->ID, "texture1"), 0);
  89.     // or set it via the texture class
  90.  
  91.  
  92.  
  93.  
  94.     //we already have DECLARED contexts
  95.     //we need to fill them up boi
  96.  
  97. #pragma warning(disable : 4996)
  98.     av_register_all(); //will register only the ones we need next time around
  99.  
  100.     avformat_open_input(&format_contex, infilename.c_str(), NULL, NULL);
  101.     avformat_find_stream_info(format_contex, NULL);
  102.  
  103.     // get video stream index
  104.     for (int i = 0; i < format_contex->nb_streams; i++) {
  105.         //FIND STREAM THAT IS VIDEO TYPE!
  106.         if (format_contex->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { //kinda pointless step
  107.             VideoStreamIndex = i;
  108.             break;
  109.         }
  110.     }
  111.     //  av_dump_format(format_contex, VideoStreamIndex, infilename, false);
  112.  
  113.     codec_contex = avcodec_alloc_context3(NULL);
  114.  
  115.     avcodec_parameters_to_context(codec_contex, format_contex->streams[VideoStreamIndex]->codecpar);
  116.  
  117.     Codec = avcodec_find_decoder(codec_contex->codec_id);
  118.  
  119.     avcodec_open2(codec_contex, Codec, NULL);
  120.  
  121.     ///pkt = av_packet_alloc();
  122.     ///av_init_packet(pkt);
  123.  
  124.     ///oframe = av_frame_alloc();
  125.  
  126.     //fin = fopen(infilename, "rb");
  127.  
  128.     this->width = codec_contex->width;
  129.     this->height = codec_contex->height;
  130.  
  131.     if (this->height == 0 || this->width == 0) {
  132.         //SOMETHING WENT WRONG
  133.         int breakpoint = 12;
  134.     }
  135.  
  136.     //allocate buffer
  137.     //buffer = (uint8_t*)calloc(3 * width * height, sizeof(uint8_t));
  138.  
  139.  
  140.     //That's all i think!
  141.     //now just get dem frames
  142. /// glAttachShader(ourShader->ID, GL_VERTEX_SHADER);
  143. /// glAttachShader(ourShader->ID, GL_FRAGMENT_SHADER);
  144.  
  145.     //global::global_pending_futures.push_back(std::async(std::launch::async, [] {
  146.  
  147.     //global::global_pending_futures.push_back(std::async(std::launch::async, [this] {
  148.     //  this->decodeLoop();
  149.     //}));
  150.  
  151.     //auto GlobalSize = Director::getInstance()->getWinSize();
  152.     cocos2d::Size contentSize = cocos2d::Size(width, height);
  153.     if (transfer) {
  154.  
  155.         this->setContentSize(org_size);
  156.  
  157.         contentSize = org_size;//cocos2d::Size(width, height);
  158.  
  159.         this->setAnchorPoint(org_anchor);
  160.         this->setPosition(org_pos);
  161.  
  162.         this->setScaleX(org_scaleX);
  163.         this->setScaleY(org_scaleY);
  164.  
  165.         this->setRotation(org_rotation);
  166.         this->setOpacity(org_opacity);
  167.         this->setVisible(wasVisible);
  168.     }
  169.  
  170.     buf1.frame = av_frame_alloc();
  171.     buf2.frame = av_frame_alloc();
  172.     //buf3.frame = av_frame_alloc();
  173.  
  174.     buf1.pdata = (uint8_t*)malloc(3 * (width*height));
  175.     buf2.pdata = (uint8_t*)malloc(3 * (width*height));
  176.     //buf3.pdata = (uint8_t*)malloc(3 * (width*height));
  177.  
  178.     buf1.pkt = av_packet_alloc();
  179.     buf2.pkt = av_packet_alloc();
  180.     //buf3.pkt = av_packet_alloc();
  181.  
  182.     buf1.name = "buffer 1";
  183.     buf2.name = "buffer 2";
  184.     //buf3.name = "buffer 3";
  185.  
  186.    
  187.     glGenBuffers(2, pboids);
  188.  
  189.     buf1.pboid = pboids[0];
  190.     buf2.pboid = pboids[1];
  191.  
  192.     size_t size = 3 * (width*height);
  193.  
  194.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf1.pboid);
  195.     glBufferData(GL_PIXEL_UNPACK_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
  196.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf2.pboid);
  197.     glBufferData(GL_PIXEL_UNPACK_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
  198.  
  199.  
  200.     GLenum err;
  201.     while ((err = glGetError()) != GL_NO_ERROR)
  202.     {
  203.         //Process/log the error.
  204.     }
  205.  
  206.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  207.  
  208.  
  209.     decodeLoop();
  210.  
  211.     ///unsigned char *
  212.     video::frameData* dataEna = getData();///vid.getCurrentRBGConvertedFrame();
  213.  
  214.     Texture2D *texture = new Texture2D();
  215.  
  216.     if (dataEna) {
  217.         if (dataEna->pdata) {
  218.             texture->initWithData(dataEna->pdata, sizeof(dataEna->pdata),
  219.                 cocos2d::Texture2D::PixelFormat::RGB888, width, height, contentSize);
  220.         }
  221.     }
  222.     else {
  223.         global::AppendToLog("ERROR! Couldn't create video!", true);
  224.         return;
  225.     }
  226.  
  227.     _texture = texture;
  228.     //texture->_ID
  229.  
  230.     initWithTexture(texture);
  231.  
  232.     this->freeData();
  233.  
  234.     if (transfer) {
  235.  
  236.         this->setContentSize(org_size);
  237.  
  238.         contentSize = org_size;//cocos2d::Size(width, height);
  239.  
  240.         this->setAnchorPoint(org_anchor);
  241.         this->setPosition(org_pos);
  242.  
  243.         this->setScaleX(org_scaleX);
  244.         this->setScaleY(org_scaleY);
  245.  
  246.         this->setRotation(org_rotation);
  247.         this->setOpacity(org_opacity);
  248.         this->setVisible(wasVisible);
  249.         this->_blendFunc = org_blend;
  250.         this->setZOrder(org_zorder);
  251.     }
  252.  
  253.  
  254.  
  255.  
  256.     ///buffer = (uint8_t*)malloc(3 * (width*height));///(width*height));
  257.  
  258.  
  259.  
  260.  
  261.  
  262.     ///std::thread t2([this] {
  263.     global::global_pending_futures.push_back(std::async(std::launch::async, [=] {
  264.         while (true) {
  265.             if (isPlaying) {
  266.                 this->decodeLoop();
  267.                 ///std::this_thread::sleep_for(std::chrono::milliseconds(3));
  268.             }
  269.             else {
  270.                 std::this_thread::sleep_for(std::chrono::milliseconds(3));
  271.             }
  272.         }
  273.         /// });
  274.     }));
  275.  
  276.  
  277. }
  278.  
  279.  
  280. void video::decodeLoop() { //this should loop in a separate thread
  281.     frameData* buff = nullptr;
  282.     if (buf1.needsRefill) {
  283.     /// buf1.bufferLock.lock();
  284.         buff = &buf1;
  285.         buf1.needsRefill = false;
  286.         firstBuff = true;
  287.     }
  288.     else if (buf2.needsRefill) {
  289.         ///buf2.bufferLock.lock();
  290.         buff = &buf2;
  291.         buf2.needsRefill = false;
  292.         firstBuff = false;
  293.     }
  294.  
  295.     if (buff == nullptr) {
  296.         std::this_thread::sleep_for(std::chrono::milliseconds(1));
  297.         return;//error? //wait?
  298.     }
  299.  
  300.     //pack pixel buffer?
  301.  
  302.     if (getNextFrame(buff)) {
  303.         getCurrentRBGConvertedFrame(buff);
  304.     }
  305.     else {
  306.         loopedTimes++;
  307.         if (loopedTimes >= repeatTimes) {
  308.             stop();
  309.         }
  310.         else {
  311.             restartVideoPlay(&buf1);//restart both
  312.             restartVideoPlay(&buf2);
  313.             if (getNextFrame(buff)) {
  314.                 getCurrentRBGConvertedFrame(buff);
  315.             }
  316.         }
  317.     }
  318.     ///glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buff->pboid);
  319.     ///glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * (width*height), buff->pdata, GL_DYNAMIC_DRAW);
  320.  
  321. /// buff->bufferLock.unlock();
  322.  
  323.     return;
  324. }
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331. void video::actualDraw() { //meant for cocos implementation
  332.     ///return;
  333.     if (this->isVisible()) {
  334.         if (this->getOpacity() > 0) {
  335.            
  336.            
  337.             //since we do flip flop method, we can check for loops here
  338.             if (isPlaying) {
  339.                 if (loopedTimes >= repeatTimes) { //ignore -1 because comparing unsgined to singed
  340.                     this->stop();
  341.                 }
  342.             }
  343.  
  344.  
  345.             if (isPlaying) {
  346.                 this->setVisible(true);
  347.  
  348.                 ///pxDataMtx.lock();
  349.  
  350.                 if (!display) { //skip frame
  351.                     ///this->getNextFrame();
  352.                     display = true;
  353.                 }
  354.                 else if (display) {
  355.                     display = false;
  356.  
  357.                     auto buff = this->getData();
  358.                    
  359.                     width = this->getWidth();
  360.                     height = this->getHeight();
  361.                     if (buff) {
  362.                         ///buff->bufferLock.lock();
  363.                         if (buff->pdata) {
  364.  
  365.                             glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buff->pboid);
  366.                             glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * (width*height), buff->pdata, GL_DYNAMIC_DRAW);
  367.  
  368.  
  369.                             glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, 0);///buff->pdata);
  370.                             //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
  371.                             //glGenerateMipmap(GL_TEXTURE_2D);
  372.                             glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  373.                         }
  374.  
  375.                         buff->needsRefill = true;
  376.                         ///buff->bufferLock.unlock();
  377.                     }
  378.  
  379.  
  380.  
  381.  
  382.  
  383.                     //std::this_thread::sleep_for(std::chrono::milliseconds(14));
  384.  
  385.                     ///this->freeData();
  386.  
  387.                     // bind textures on corresponding texture units
  388.  
  389.                     //glActiveTexture(GL_TEXTURE0);
  390.                     glBindTexture(GL_TEXTURE_2D, texture1);
  391.  
  392.  
  393.                 }
  394.  
  395.                 //glActiveTexture(GL_TEXTURE1);
  396.                 //glBindTexture(GL_TEXTURE_2D, texture2);
  397.  
  398.                 // render container
  399.                 //ourShader.use();
  400.  
  401.                 //  glDetachShader(ourShader->ID, GL_VERTEX_SHADER);
  402.                 //  glDetachShader(ourShader->ID, GL_FRAGMENT_SHADER);
  403.                 ///pxDataMtx.unlock();
  404.  
  405.             }
  406.             else { this->setVisible(false); }
  407.         }
  408.     }
  409. }
  410.  
  411.  
  412. void video::draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t flags){
  413.     if(!_customCommand){
  414.         _customCommand = new cocos2d::CustomCommand();
  415.     }
  416.  
  417.     Sprite::draw(renderer, transform, flags);
  418.     _customCommand->init(_globalZOrder);
  419.     _customCommand->func = CC_CALLBACK_0(video::actualDraw, this);
  420.     cocos2d::Director::getInstance()->getRenderer()->addCommand(_customCommand);
  421.    
  422. }
  423.  
  424.  
  425.  
  426.  
  427.  
  428. unsigned char* video::getNextFrame(frameData* fd) {
  429.  
  430.     //if (isAlt) { isAlt = false; return NULL; }
  431.     //else { isAlt = true; }
  432.     //outputs pixel data but also updates oframe so we can fill cframe
  433.     framecount++;
  434.     //std::cout << std::to_string(framecount) << std::endl;
  435.     // read an encoded packet from file
  436.     int ret = av_read_frame(format_contex, fd->pkt);
  437.  
  438.     if (ret < 0)
  439.     {
  440.         //if cannot read frame, seek to start
  441.  
  442.         if (repeat) {
  443.             av_packet_unref(fd->pkt);
  444.             return nullptr;
  445.             //ret = av_read_frame(format_contex, pkt); //we already do that in restart()
  446.         }
  447.         else {
  448.             //av_log(NULL, AV_LOG_ERROR, "cannot read frame");
  449.             av_packet_unref(fd->pkt);
  450.             return nullptr;
  451.         }
  452.     }
  453.     // if packet data is video data then send it to decoder
  454.     if (fd->pkt->stream_index == VideoStreamIndex) {
  455.         //decode
  456.         fd->frame = decode(codec_contex, fd->frame, fd->pkt);
  457.     }
  458.  
  459.     // release packet buffers to be allocated again
  460.     av_packet_unref(fd->pkt);
  461.  
  462.     //std::this_thread::sleep_for(std::chrono::milliseconds(2));
  463.  
  464.     return (unsigned char*)fd->frame->data[0];
  465.  
  466.     //flush decoder
  467.     //decode(codec_ctx, frame, NULL);
  468. }
  469.  
  470.  
  471. //only internally resets video, doesn't output frame!
  472. void video::restartVideoPlay(video::frameData* buff) {
  473.     ///return;
  474.     av_seek_frame(format_contex, buff->pkt->stream_index, 0, AVSEEK_FLAG_BACKWARD);
  475.     ///av_read_frame(format_contex, buff->pkt);
  476.     framecount = 0;
  477.     codec_contex->frame_number = 0;
  478.     ///loopedTimes++;
  479. }
  480.  
  481.  
  482. AVFrame* video::decode(AVCodecContext* cc, AVFrame* frame, AVPacket* pack) {
  483.  
  484.     int ret;
  485.  
  486.     //send packet to decoder
  487.     ret = avcodec_send_packet(cc, pack);
  488.     if (ret < 0) {
  489.         //fprintf(stderr, "Error sending a packet for decoding\n");
  490.         //exit(1);
  491.     }
  492.     while (ret >= 0) {
  493.         // receive frame from decoder
  494.         // we may receive multiple frames or we may consume all data from decoder, then return to main loop
  495.         ret = avcodec_receive_frame(cc, frame);
  496.         if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
  497.             av_packet_unref(pack);
  498.             return frame;
  499.         }
  500.         else if (ret < 0) {
  501.             // something wrong, quit program
  502.             fprintf(stderr, "Error during decoding\n");
  503.             exit(1);
  504.         }
  505.         //printf("outputing frame %3d\n", cc->frame_number);
  506.         fflush(stdout);
  507.  
  508.         av_packet_unref(pack);
  509.         return frame;
  510.     }
  511.  
  512. }
  513.  
  514.  
  515. /*
  516.  
  517. void YUVImage::yuv2rgb(uint8_t yValue, uint8_t uValue, uint8_t vValue,
  518. uint8_t *r, uint8_t *g, uint8_t *b) const {
  519. int rTmp = yValue + (1.370705 * (vValue-128));
  520. int gTmp = yValue - (0.698001 * (vValue-128)) - (0.337633 * (uValue-128));
  521. int bTmp = yValue + (1.732446 * (uValue-128));
  522. *r = clamp(rTmp, 0, 255);
  523. *g = clamp(gTmp, 0, 255);
  524. *b = clamp(bTmp, 0, 255);
  525. }
  526.  
  527. */
  528.  
  529.  
  530.  
  531. unsigned char* video::getCurrentRBGConvertedFrame(frameData* fd) {
  532.  
  533.     SwsContext *sws_ctx = sws_getContext(width, height,
  534.         codec_contex->pix_fmt, width, height,
  535.         AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL //BICUBIC is nicer color?
  536.     );
  537.  
  538.     uint8_t *rgb24[1];
  539.  
  540.     //buffer should only be allocated ONCE
  541.     ///buffer = (uint8_t*)malloc(3 * (width*height));//(uint8_t*)calloc(3 * width * height, sizeof(uint8_t));
  542.     //memset(buffer, NULL, sizeof(buffer));
  543.  
  544.     //buffer = prgb24;
  545.     rgb24[0] = { fd->pdata };
  546.  
  547.     int rgb24_stride[1] = { 3 * width }; //same as linesize supposedly
  548.  
  549.     sws_scale(sws_ctx, fd->frame->data, fd->frame->linesize, 0, height, rgb24, rgb24_stride);
  550.  
  551.     sws_freeContext(sws_ctx);
  552.  
  553.     return fd->pdata;
  554. }
  555.  
  556.  
  557. void video::freeData() {
  558.     return;
  559.     if (codec_contex) {
  560.         //avcodec_free_context(&codec_contex);levi
  561.     }
  562.     //return;
  563.  
  564.     if (buffer) {
  565.         ///free(buffer);
  566.         ///buffer = NULL;
  567.     }
  568.     if (oframe) {
  569.         //av_frame_free(&oframe);
  570.         av_frame_unref(oframe);
  571.         //av_frame_free(&oframe);
  572.     }
  573.     if (cframe) {
  574.         //av_frame_free(&cframe);
  575.         av_frame_unref(cframe);
  576.     }
  577.     if (pkt) {
  578.         av_packet_unref(pkt);
  579.         //av_free_packet(pkt);
  580.     }
  581.  
  582. }
  583.  
  584. void video::stop() { //will make actual stop
  585.     isPlaying = false;
  586.  
  587.     restartVideoPlay(&buf1);
  588.     restartVideoPlay(&buf2);
  589.  
  590.     freeData();
  591.  
  592.     this->setVisible(false);
  593.     this->holdersprite->setVisible(false);
  594.  
  595.     if (hideWithEvent != "") {
  596.         cocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread([this] {
  597.             globalevents::fireCustomEvent(hideWithEvent);
  598.         });
  599.     }
  600. }
  601.  
  602.  
  603.  
  604. void video::play() {
  605.     if (isPlaying) { return; }
  606.     isPlaying = true;
  607.     if (showWithEvent != "") {
  608.         cocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread([this] {
  609.             globalevents::fireCustomEvent(showWithEvent);
  610.         });
  611.     }
  612.  
  613.     //opengl data here
  614.     //no opengl data here!
  615.  
  616.     this->setVisible(true);
  617.  
  618.     this->holdersprite->setVisible(false);
  619.  
  620. }
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628. void video::pause() {
  629.     isPlaying = false;
  630. }
  631.  
  632. void video::setRepeats(int reps) {
  633.     if (reps == 999) {
  634.         repeatTimes = -1; //forever
  635.     }
  636.     else if (reps == 0) {
  637.         repeatTimes = 1;
  638.     }
  639.     else {
  640.         repeatTimes = reps;
  641.     }
  642.  
  643. }
  644.  
  645.  
  646.  
  647. ///unsigned char*
  648. video::frameData* video::getData() {
  649.     if (firstBuff) {
  650.         if (buf1.needsRefill == false) {
  651.             ///firstBuff = false;
  652.             return &buf1;///.pdata;
  653.         }
  654.     }
  655.     else { //if false
  656.         if (buf2.needsRefill == false) {
  657.             ///firstBuff = true;
  658.             return &buf2;///.pdata;
  659.         }
  660.     }
  661.     return nullptr;
  662. }
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.  
  682. #ifdef SAMPLENOTDEFINED
  683.  
  684. Step 1. RGB - YUV conversion.----------------------------
  685.  
  686. // Create YUV buffer
  687. m_bufferSize = avpicture_get_size(PIX_FMT_YUV420P, width, height);
  688. avPictureInfo_ = avcodec_alloc_frame();
  689. m_buffer = (uint8_t *)av_malloc(m_bufferSize);
  690.  
  691. avpicture_fill((AVPicture*)avPictureInfo_, m_buffer, PIX_FMT_YUV420P,
  692.     width, height);
  693.  
  694. // Then fill it with  RGB data
  695. struct SwsContext *img_convert_ctx = sws_getContext(m_width, m_height,
  696.     PIX_FMT_RGB24,
  697.     m_width,
  698.     m_height, PIX_FMT_YUV420P, SWS_BICUBIC,
  699.     NULL, NULL, NULL);
  700.  
  701. if (img_convert_ctx == NULL) {
  702.     return NULL;
  703. }
  704.  
  705. uint8_t * srcData[4] = { m_buffer, 0, 0, 0 };
  706. int srcLineSize[4] = { m_width * 3 * sizeof(uint8_t), 0, 0, 0 };
  707. sws_scale(img_convert_ctx, srcData, srcLineSize, 0,
  708.     m_height, yuvImage->avPictureInfo_->data,
  709.     yuvImage->avPictureInfo_->linesize);
  710.  
  711. free(img_convert_ctx);
  712.  
  713. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement