After research, the FFMPEG SDK has two places to control the timestamp of writing when writing video. One is AvPacket and the other is AvFrame. When calling avcodec_encode_video, you need to pass the object pointer of AvFrame, that is, pass a frame of uncompressed video for compression processing. AvFrame contains a parameter of pts. This parameter is the timestamp of the current frame when it is restored during playback. There are also pts in AvPacket, as well as dts. Speaking of this, you must explain the three video compression frames I, P, and B. An I frame is a key frame and does not depend on other video frames. A P frame is a forward predicted frame, which depends only on the previous video frame, and a B frame is a bidirectionally predicted video frame, which depends on the front and rear video frames. Since the B frame exists, because it is bidirectional, it is necessary to know the details of the previous video frame and the following video frame to know what image the B frame should ultimately render. The two parameters pts and dts are used to control the order of display and decoding of video frames.
Pts is the order in which frames are displayed.
Dts is the order in which frames are read for decoding.
If no B frame exists, dts and pts are the same. On the contrary, it is not the same. For a detailed introduction to this, you can refer to the principle of mpeg.
Let's talk about the value of pts and dts contained in AvPacket.
What pts and dts need to set is the order in which video frames are decoded and displayed. Add one for each additional frame, not the timestamp of the video being played.
However, it has been proved that the video decoded by rmvb is sometimes not a fixed frame rate, but a variable frame rate. Thus, if each frame is compressed, the scheme of adding pts and dts is to cause the audio and video to be out of sync.
Solve the audio and video out of sync method:lTImeStamp is the timestamp of the current video frame obtained by directshow.
M_llframe_index is the number of frames that have been compressed so far.
First, av_rescale calculates the video frame of the timestamp that the current compression process has to process. If the timestamp has not reached the timestamp of the video frame currently provided by the directshow, the frame is discarded.
Otherwise, the compression operation is performed. And set the pts and dts of AVPacket. It is assumed here that the B frame does not exist.
Because the video is played at the fixed playback frame rate we set in the future playback, it is necessary to compare the video frame timestamp calculated according to the set playback frame rate with the timestamp of the current video frame provided by directshow. Is there a need to implement a strategy to delay playback? If you need to delay playback, increase pts by 2 steps, otherwise play at normal speed, set to 1.dts.
__int64 x = av_rescale(m_llframe_index, AV_TIME_BASE*(int64_t)c-"TIme_base.num,c-"TIme_base.den);
If( x "lTimeStamp )
{
Return TRUE;
}
m_pVideoFrame2-"pts = lTimeStamp;
m_pVideoFrame2-"pict_type = 0;
Int out_size = avcodec_encode_video( c, m_pvideo_outbuf, video_outbuf_size,m_pVideoFrame2 );
/* if zero size, it means the image was buffered */
If (out_size 0)
{
AVPacket pkt;
Av_init_packet(&pkt);
If( x "lTimeStamp )
{
Pkt.pts = pkt.dts = m_llframe_index;
Pkt.duration = 0;
}
Else
{
Pkt.duration = (lTimeStamp - x)*c-"time_base.den/1000000 + 1;
Pkt.pts = m_llframe_index;
Pkt.dts = pkt.pts;
M_llframe_index += pkt.duration;
}
//pkt.pts = lTimeStamp * (__int64)frame_rate.den / 1000;
If( c-"coded_frame && c-"coded_frame-"key_frame )
{
Pkt.flags |= PKT_FLAG_KEY;
}
Pkt.stream_index= m_pVideoStream-"index;
Pkt.data= m_pvideo_outbuf;
Pkt.size= out_size;
/* write the compressed frame in the media file */
Ret = av_interleaved_write_frame( m_pAvFormatContext, &pkt );
}
Else
{
Ret = 0;
}
Cbd Vape Products Oem,D8 Vape Pen Oem,Cbd Disposable Vape Pen Oem,China Cbd Vape Products Oem
Shenzhen MASON VAP Technology Co., Ltd. , https://www.e-cigarettefactory.com