Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "clVideo.h"
- extern "C"
- {
- #include "libavformat/avformat.h"
- #include "libavcodec/avcodec.h"
- #include "libswscale/swscale.h"
- #include "libavutil/imgutils.h"
- #include "clThreading.h"
- }
- #pragma comment(lib, "Secur32.lib")
- #pragma comment(lib, "Bcrypt.lib")
- #pragma comment(lib, "Ws2_32.lib")
- #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/swresample.lib")
- #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/avformat.lib")
- #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/avfilter.lib")
- #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/avdevice.lib")
- #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/avcodec.lib")
- #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/swscale.lib")
- #pragma comment(lib, "../../CommonLib/3rdParty/ffmpeg/lib/avutil.lib")
- clVideo::clVideo(clPath mediaFile, bool swapRedAndBlue)
- {
- destFormat = swapRedAndBlue ? AV_PIX_FMT_RGBA : AV_PIX_FMT_BGRA;
- av_register_all();
- pFC = avformat_alloc_context();
- if (avformat_open_input(&pFC, mediaFile.Path().c_str(), nullptr, nullptr) != 0) clRelFail("Unable to open video");
- // Identify Video Stream
- avformat_find_stream_info(pFC, nullptr);
- video_stream_index = -1;
- for (int i = 0; i < (int)pFC->nb_streams; ++i)
- if (pFC->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
- {
- video_stream_index = i;
- break;
- }
- AVCodecParameters *codecpar = pFC->streams[video_stream_index]->codecpar;
- AVCodec *pCodec = avcodec_find_decoder(codecpar->codec_id);
- pCC = avcodec_alloc_context3(pCodec);
- avcodec_parameters_to_context(pCC, codecpar);
- avcodec_open2(pCC, pCodec, nullptr);
- // Allocate Frame Buffer
- pF = av_frame_alloc();
- pP = av_packet_alloc();
- // Allocate RGBA frame
- pCF = av_frame_alloc();
- av_image_alloc(pCF->data, pCF->linesize, pCC->width, pCC->height, (AVPixelFormat)destFormat, 1);
- pCF->height = pCC->height;
- pCF->width = pCC->width;
- pCF->format = destFormat;
- // Conversion Context Creation Depends On Conversion Source So Delay Allocation Until Reading Frame
- pConC = nullptr;
- }
- clVideo::~clVideo()
- {
- av_packet_free(&pP);
- av_frame_free(&pF);
- av_freep(&pCF->data);
- av_frame_free(&pCF);
- avcodec_free_context(&pCC);
- if (pConC) sws_freeContext(pConC);
- avformat_close_input(&pFC);
- }
- bool clVideo::Frame(clImage *pFrame)
- {
- bool foundVideoFrame = false;
- while (!foundVideoFrame && av_read_frame(pFC, pP) >= 0)
- {
- if (pP->stream_index == video_stream_index)
- {
- if (pFrame)
- {
- int ret = avcodec_send_packet(pCC, pP);
- if (ret < 0) return false;
- ret = avcodec_receive_frame(pCC, pF);
- if (ret < 0) return false;
- if (!pConC)
- {
- pConC = sws_getContext(pCC->width, pCC->height, (AVPixelFormat)pF->format, pCC->width, pCC->height,
- (AVPixelFormat)destFormat, SWS_BILINEAR, nullptr, nullptr, nullptr);
- }
- sws_scale(pConC, pF->data, pF->linesize, 0, pCC->height, pCF->data, pCF->linesize);
- *pFrame = clImage((ui32 *)pCF->data[0], v2I(pCF->width, pCF->height));
- }
- foundVideoFrame = true;
- }
- av_packet_unref(pP);
- }
- return foundVideoFrame;
- }
- bool clVideo::Seek(float position)
- {
- if (position < 0.0f || position > 1.0f)
- {
- printf("Error: Position must be between 0 and 1\n");
- return false;
- }
- int64_t duration = pFC->streams[video_stream_index]->duration;
- int64_t seek_target = static_cast<int64_t>(duration * position);
- AVRational time_base = pFC->streams[video_stream_index]->time_base;
- int64_t seek_target_in_stream_time_base = av_rescale_q(seek_target, AVRational{ 1, AV_TIME_BASE }, time_base);
- int ret = av_seek_frame(pFC, video_stream_index, seek_target_in_stream_time_base, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY);
- if (ret < 0)
- {
- char errbuf[AV_ERROR_MAX_STRING_SIZE];
- av_strerror(ret, errbuf, sizeof(errbuf));
- printf("Error: Seeking failed with error code %d, details: %s\n", ret, errbuf);
- return false;
- }
- avcodec_flush_buffers(pCC);
- clSleep(50);
- //av_packet_unref(pP);
- return true;
- }
- v2I clVideo::Res() { return v2I(pCC->width, pCC->height); }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement