extern "C"{
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libavutil/time.h"
};
#include <iostream>
void printErr(int errNum);
static double r2d(AVRational r){
return (r.num == 0 || r.den == 0) ? 0.0 : (double)r.num / (double)r.den;
}
int main(){
avformat_network_init();
AVFormatContext *inContext = NULL;
char *inFile = "001.mp4";
int ret = avformat_open_input(&inContext, inFile, 0, 0);
if(ret != 0){
printErr(ret);
return -1;
}
std::cout<<"avformat_open_input success"<<std::endl;
ret = avformat_find_stream_info(inContext, 0);
if(ret != 0){
printErr(ret);
return -1;
}
std::cout<<"avformat_find_stream_info success"<<std::endl;
av_dump_format(inContext, 0, inFile, 0);
AVFormatContext *outContext;
char *outFile = "rtmp://192.168.206.131:10088/live";
ret = avformat_alloc_output_context2(&outContext, 0, "flv", outFile);
if(outContext == 0){
printErr(ret);
return -1;
}
std::cout<<"avformat_alloc_output_context2 success"<<std::endl;
for(int i = 0; i < inContext->nb_streams; i++){
AVStream *outStream = avformat_new_stream(outContext, NULL);
if(outStream == NULL){
printErr(-1);
return -1;
}
ret = avcodec_parameters_copy(outStream->codecpar, inContext->streams[i]->codecpar);
if(ret < 0){
printErr(ret);
return -1;
}
outStream->codecpar->codec_tag = 0;
}
av_dump_format(outContext, 0, outFile, 1);
ret = avio_open(&outContext->pb, outFile, AVIO_FLAG_WRITE);
if(ret != 0){
printErr(ret);
return -1;
}
std::cout<<"avio_open success"<<std::endl;
ret = avformat_write_header(outContext, NULL);
if(ret < 0){
printErr(ret);
return -1;
}
std::cout<<"avformat_write_header success"<<std::endl;
AVPacket avpkt;
long long startTime = av_gettime();
while(1){
ret = av_read_frame(inContext, &avpkt);
if(ret != 0){
break;
}
std::cout << avpkt.pts << std::endl;
AVRational inTime = inContext->streams[avpkt.stream_index]->time_base;
AVRational outTime = outContext->streams[avpkt.stream_index]->time_base;
avpkt.pts = av_rescale_q_rnd(avpkt.pts, inTime, outTime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
avpkt.dts = av_rescale_q_rnd(avpkt.dts, inTime, outTime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
avpkt.duration = av_rescale_q_rnd(avpkt.duration, inTime, outTime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
avpkt.pos = -1;
if(inContext->streams[avpkt.stream_index]->codecpar->codec_type = AVMEDIA_TYPE_VIDEO){
AVRational tb = inContext->streams[avpkt.stream_index]->time_base;
long long nowTime = av_gettime() - startTime;
long long dtsTime = avpkt.dts * (1000 * 1000 * r2d(tb));
if(dtsTime > nowTime){
av_usleep(dtsTime - nowTime);
}
}
ret = av_interleaved_write_frame(outContext, &avpkt);
if(ret < 0){
printErr(ret);
return -1;
}
av_packet_unref(&avpkt);
}
system("pause");
return 0;
}
void printErr(int errNum){
char errBuf[1024] = {0};
av_strerror(errNum, errBuf, sizeof(errBuf));
system("pause");
}