Fetch the repository succeeded.
This action will force synchronization from 视频开发王纲/CGFileTranscode, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
// Transcode.cpp : 定义控制台应用程序的入口点。
//
/* Copyright [c] 2016-2026 By Gang.Wang Allrights Reserved
this file shows how to compress video. Any questions, you
can join QQ group for help, QQ
Group number:127903734.
*/
#include "stdafx.h"
#include "pch.h"
#include <string>
#include <iostream>
#include <thread>
#include <memory>
#include <iostream>
#include<fstream>
#include <Winsock2.h>
#include <condition_variable>
#include <concurrent_queue.h>
using namespace std;
AVFormatContext * context = nullptr;
AVFormatContext* outputContext;
int64_t lastPts = 0;
int64_t lastDts = 0;
int64_t lastFrameRealtime = 0;
int64_t firstPts = AV_NOPTS_VALUE;
int64_t startTime = 0;
AVCodecContext* outPutEncContext = NULL;
AVCodecContext *decoderContext = NULL;
#define SrcWidth 1920
#define SrcHeight 1080
#define DstWidth 640
#define DstHeight 480
struct SwsContext* pSwsContext;
AVFilterGraph * filter_graph = nullptr;
AVFilterContext *buffersink_ctx = nullptr;;
AVFilterContext *buffersrc_ctx = nullptr;;
int64_t packetCount = 0;
int interrupt_cb(void *ctx)
{
return 0;
}
string GetLocalIpAddress()
{
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(wVersionRequested, &wsaData) != 0)
return "";
char local[255] = {0};
gethostname(local, sizeof(local));
hostent* ph = gethostbyname(local);
if (ph == NULL)
return "";
in_addr addr;
memcpy(&addr, ph->h_addr_list[0], sizeof(in_addr)); // 这里仅获取第一个ip
string localIP;
localIP.assign(inet_ntoa(addr));
WSACleanup();
return localIP;
}
void Init()
{
av_register_all();
avfilter_register_all();
avformat_network_init();
avdevice_register_all();
av_log_set_level(AV_LOG_ERROR);
}
int OpenInput(char *fileName)
{
context = avformat_alloc_context();
context->interrupt_callback.callback = interrupt_cb;
AVDictionary *format_opts = nullptr;
int ret = avformat_open_input(&context, fileName, nullptr, &format_opts);
if(ret < 0)
{
return ret;
}
ret = avformat_find_stream_info(context,nullptr);
av_dump_format(context, 0, fileName, 0);
if(ret >= 0)
{
std::cout <<"open input stream successfully" << endl;
}
return ret;
}
shared_ptr<AVPacket> ReadPacketFromSource()
{
std::shared_ptr<AVPacket> packet(static_cast<AVPacket*>(av_malloc(sizeof(AVPacket))), [&](AVPacket *p) { av_packet_free(&p); av_freep(&p); });
av_init_packet(packet.get());
int ret = av_read_frame(context, packet.get());
if(ret >= 0)
{
return packet;
}
else
{
return nullptr;
}
}
int OpenOutput(char *fileName)
{
int ret = 0;
ret = avformat_alloc_output_context2(&outputContext, nullptr, "mpegts", fileName);
if(ret < 0)
{
goto Error;
}
ret = avio_open2(&outputContext->pb, fileName, AVIO_FLAG_READ_WRITE,nullptr, nullptr);
if(ret < 0)
{
goto Error;
}
for(int i = 0; i < context->nb_streams; i++)
{
AVStream * stream = avformat_new_stream(outputContext, outPutEncContext->codec);
stream->codec = outPutEncContext;
if(ret < 0)
{
goto Error;
}
}
av_dump_format(outputContext, 0, fileName, 1);
ret = avformat_write_header(outputContext, nullptr);
if(ret < 0)
{
goto Error;
}
if(ret >= 0)
cout <<"open output stream successfully" << endl;
return ret ;
Error:
if(outputContext)
{
avformat_close_input(&outputContext);
}
return ret ;
}
void CloseInput()
{
if(context != nullptr)
{
avformat_close_input(&context);
}
}
void CloseOutput()
{
if(outputContext != nullptr)
{
for(int i = 0 ; i < outputContext->nb_streams; i++)
{
AVCodecContext *codecContext = outputContext->streams[i]->codec;
avcodec_close(codecContext);
}
avformat_close_input(&outputContext);
}
}
int InitEncoderCodec( int iWidth, int iHeight)
{
AVCodec * pH264Codec = avcodec_find_encoder(AV_CODEC_ID_H264);
if(NULL == pH264Codec)
{
printf("%s", "avcodec_find_encoder failed");
return -1;
}
outPutEncContext = avcodec_alloc_context3(pH264Codec);
outPutEncContext->gop_size = 30;
outPutEncContext->has_b_frames = 0;
outPutEncContext->max_b_frames = 0;
outPutEncContext->codec_id = pH264Codec->id;
outPutEncContext->time_base.num =context->streams[0]->codec->time_base.num;
outPutEncContext->time_base.den = context->streams[0]->codec->time_base.den;
outPutEncContext->pix_fmt = *pH264Codec->pix_fmts;
outPutEncContext->width = iWidth;
outPutEncContext->height = iHeight;
AVDictionary *options = nullptr;
outPutEncContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
int ret = avcodec_open2(outPutEncContext, pH264Codec, &options);
if (ret < 0)
{
printf("%s", "open codec failed");
return ret;
}
return 1;
}
int InitDecodeCodec(AVCodecID codecId)
{
auto codec = avcodec_find_decoder(codecId);
if(!codec)
{
return -1;
}
decoderContext = context->streams[0]->codec;
if (!decoderContext) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}
if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
decoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
int ret = avcodec_open2(decoderContext, codec, NULL);
return ret;
}
bool DecodeVideo(AVPacket* packet, AVFrame* frame)
{
int gotFrame = 0;
auto hr = avcodec_decode_video2(decoderContext, frame, &gotFrame, packet);
if(hr >= 0 && gotFrame != 0)
{
return true;
}
return false;
}
int InitFilter(AVCodecContext * codecContext)
{
char args[512];
int ret = 0;
AVFilter *buffersrc = avfilter_get_by_name("buffer");
AVFilter *buffersink = avfilter_get_by_name("buffersink");
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
string filters_descr ="scale=640:480";
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P};
filter_graph = avfilter_graph_alloc();
if (!outputs || !inputs || !filter_graph) {
ret = AVERROR(ENOMEM);
goto end;
}
/* buffer video source: the decoded frames from the decoder will be inserted here. */
sprintf_s(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
codecContext->width, codecContext->height, codecContext->pix_fmt,
codecContext->time_base.num, codecContext->time_base.den,
codecContext->sample_aspect_ratio.num, codecContext->sample_aspect_ratio.den);
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
args, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
goto end;
}
/* buffer video sink: to terminate the filter chain. */
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
NULL, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
goto end;
}
ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
AV_PIX_FMT_YUV420P, AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
goto end;
}
/* Endpoints for the filter graph. */
outputs->name = av_strdup("in");
outputs->filter_ctx = buffersrc_ctx;
outputs->pad_idx = 0;
outputs->next = NULL;
inputs->name = av_strdup("out");
inputs->filter_ctx = buffersink_ctx;
inputs->pad_idx = 0;
inputs->next = NULL;
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr.c_str(),
&inputs, &outputs, NULL)) < 0)
goto end;
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
goto end;
return ret;
end:
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);
return ret;
}
int _tmain(int argc, _TCHAR* argv[])
{
string fileInput = "D:\\test1.ts";
string fileOutput = "D:\\TranscodedFile.ts";
Init();
if(OpenInput((char *)fileInput.c_str()) < 0)
{
cout << "Open file Input failed!" << endl;
this_thread::sleep_for(chrono::seconds(10));
return 0;
}
int ret = InitDecodeCodec(context->streams[0]->codecpar->codec_id);
if(ret <0)
{
cout << "InitDecodeCodec failed!" << endl;
this_thread::sleep_for(chrono::seconds(10));
return 0;
}
ret = InitEncoderCodec(DstWidth,DstHeight);
if(ret < 0)
{
cout << "open eccoder failed ret is " << ret<<endl;
cout << "InitEncoderCodec failed!" << endl;
this_thread::sleep_for(chrono::seconds(10));
return 0;
}
ret = InitFilter(outPutEncContext);
if(OpenOutput((char *)fileOutput.c_str()) < 0)
{
cout << "Open file Output failed!" << endl;
this_thread::sleep_for(chrono::seconds(10));
return 0;
}
auto pSrcFrame = av_frame_alloc();
auto filterFrame = av_frame_alloc();
int got_output = 0;
int64_t timeRecord = 0;
int64_t firstPacketTime = 0;
int64_t outLastTime = av_gettime();
int64_t inLastTime = av_gettime();
int64_t videoCount = 0;
while(true)
{
outLastTime = av_gettime();
auto packet = ReadPacketFromSource();
if(packet)
{
if(timeRecord == 0)
{
firstPacketTime = av_gettime();
timeRecord++;
}
if(DecodeVideo(packet.get(),pSrcFrame))
{
if (av_buffersrc_add_frame_flags(buffersrc_ctx, pSrcFrame, AV_BUFFERSRC_FLAG_KEEP_REF) >= 0)
{
if (av_buffersink_get_frame(buffersink_ctx, filterFrame) >= 0)
{
AVPacket *pTmpPkt = (AVPacket *)av_malloc(sizeof(AVPacket));
av_init_packet(pTmpPkt);
pTmpPkt->data = NULL;
pTmpPkt->size = 0;
ret = avcodec_encode_video2(outPutEncContext, pTmpPkt, filterFrame, &got_output);
if (ret >= 0 && got_output)
{
pTmpPkt->pts = pTmpPkt->dts = 3600 * packetCount++;
int ret = av_write_frame(outputContext, pTmpPkt);
av_packet_unref(pTmpPkt);
}
}
}
}
}
else break;
}
CloseInput();
CloseOutput();
std::cout <<"Transcode file end!" << endl;
this_thread::sleep_for(chrono::hours(10));
return 0;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。