DTS
解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据
PTS
显示时间戳这个时间戳用来告诉播放器该在什么时候显示这一帧的数据
dts 解码参考时间,pts是预览参考时间,
在没有B帧的情况下,pts=dts
在有B帧的情况下 同一帧才可能带有不同的dts 和pts
要等到下一帧才能解码,但是显示时间在前面
//记一些重要函数
//转换时间基
AVFormatContext *inputContext=nullptr;
AVFormatContext *outputContext;
void av_packet_ts(AVPacket *pkt,AVRational src_tb,AVRational dst_tb)
{
if(pkt->pts!=AV_NOPTS_VALUE)
pkt->pts=av_rescale_q(pkt->pts,src_tb,dst_tb);
if(pkt->dts!=AV_NOPTS_VALUE)
pkt->dts=av_rescale_q(pkt->dts,src_tb,dst_tb);
if(pkt->duration>0)
pkt->duration=av_rescale_q(pkt->duration,src_tb,dst_tb);
}
int WritePacket(AVPacket *packet)
{
auto inputStream=inputContext->stream[packet->stream_index];
auto outputStream=outputContext->stream[packet->stream_index];
avpacket_rescale_ts(packet.get(),inputStream->time_base,outputStream->time_base);
av_interleaved_write_frame(outputContext,packet.get());
}
//packet 就是裸流PES 有时间戳
av_init_packet(packet.get());
int ret=av_read_frame(inputContext,packet.get());
if(ret>=0)
{
return packet;
}
int Openinput(string inputUrl)
{
inputContext=avformat_alloc_context();
int ret=avformat_open_input(&inputContext,inputUrl.c_str,nullptr,nullptr);
if(ret<0)
{
av_log(NULL,AV_LOG_ERROR,"Input file open input failed\n");
}
ret=avformat_find_stream_info(inputContext,nullptr);
if(ret<0)
{
av_log(NULL,AV_LOG_ERROR,"Find input file stream inform failed\n");
}
else
{
av_log(NULL,AV_LOG_FATAL,"open input file%s success\n",inputUrl.c_str());
}
retrun ret;
}
int OpenOutput(string outUrl)
{
int ret=avformat_alloc_output_context2(&outputContext,nullptr,"mpegts",outUrl.c_str());
if(ret<0)
{
av_log(NULL,AV_LOG_ERROR,"open output context failed\n");
goto Error;
}
ret=avio_open2(&outputContext->pb,outUrl.c_str(),AVIO_FLAG_READ_WRITE,nullptr,nullptr);
if(ret<0)
{
av_log(NULL,AV_LOG_ERROR,"open avio failed");
goto Error;
}
for(int i=0;inb_streams;i++)
{
AVStream *stream=avformat_naw_stream(outputContext->stream[i]->codec->codec);
ret=avcodec_copy_context(stream->codec,inputContext->stream[i]->codec);
if(ret<0)
{
av_log(NULL,AV_LOG_ERROR,"copy codec context failed\n");
goto Error;
}
ret=avformat_write_header(outputContext,nullptr);
if(ret<0)
{
av_log(NULL,AV_LOG_ERROR,"format write head failed");
goto Error;
}
av_log(NULL,AV_LOG_FATAL,"open output file success%s\n",outYrl.c_ctr);
return ret;
Error:
if(outputContext)
{
for(int i=0;inb_streams;i++)
{
avcodec_close(outputContext->stream[i]->codec);
}
avformat_close_input(&outputContext);
}
return ret;
}