Hello,
I've been trying to write part of a larger application that receives frames,
then encodes and records them to disk. However, I've been having issue with the
timing of the output files. The output files are commonly half of the duration
that they should be, almost as if the duration information that I attach the
packets isn't having an effect and the packets are being placed immediately one
after another. Is there something I'm forgetting in my code? (Write frame
function source included below)
Thank you
Source does include some additional scaling and conversion. I've removed
extraneous debugging snippets
Source:
TrdMediaWriter::ERROR_CODE TrdMediaWriter::convertAndWrite(const TrdFrame&
_frame, double _currTimeInMovie)
{
ERROR_CODE error = ERROR_CODE_NONE;
mWriteMutex.lock();
int avError = 0;
AVPacket packet;
av_init_packet(&packet);
if (packet.pts > 0 && mLastPtsWritten == packet.pts)
{
error = ERROR_WARNING_SAME_PTS;
}
if (error == ERROR_CODE_NONE)
{
////////////////////////////////////////////////////////////////////
double startTime = TrdTimeUtils::getTickTime();
TrdFrame frameToBeWritten = _frame;
if (mWatermark.isReady())
{
TrdFrameUtils::copyFrame(_frame, mWatermarkFrame);
mWatermark.updateFrame(mWatermarkFrame, TrdWatermark::LOCATIONS_LOWER_RIGHT,
10, 10);
frameToBeWritten = mWatermarkFrame;
}
if (mWriteParams.mUseIppConversions)
{
IppiSize size = { 0 };
size.width = frameToBeWritten.getWidth();
size.height = frameToBeWritten.getHeight();
Ipp8u* bufferYUV[3] = { nullptr };
bufferYUV[0] = (Ipp8u*)mFrameYUV;
bufferYUV[1] = (Ipp8u*)(mFrameYUV + (frameToBeWritten.getWidth() *
frameToBeWritten.getHeight()));
bufferYUV[2] = (Ipp8u*)(mFrameYUV + (frameToBeWritten.getWidth() *
frameToBeWritten.getHeight()) + ((frameToBeWritten.getWidth() *
frameToBeWritten.getHeight()) / 4));
/////////////////////////////////////////////////////////////////////////
int pDst[3] = { size.width, size.width / 2, size.width / 2 };
IPPCALL(ippiRGBToYCbCr420_8u_C3P3R) ((Ipp8u*)frameToBeWritten.getFrame(),
size.width * 3, bufferYUV, pDst, size);
/////////////////////////////////////////////////////////////////////////
avpicture_fill((AVPicture*)mAVFramePicture, (uint8_t*)mFrameYUV,
PIX_FMT_YUV420P, frameToBeWritten.getWidth(), frameToBeWritten.getHeight());
}
else
{
avpicture_fill((AVPicture*)mAVFrameRGB, (uint8_t*)frameToBeWritten.getFrame(),
PIX_FMT_RGB24, frameToBeWritten.getWidth(), frameToBeWritten.getHeight());
sws_scale(mSwsConversionContext, mAVFrameRGB->data, mAVFrameRGB->linesize, 0,
mAVStream->codec->height, mAVFramePicture->data, mAVFramePicture->linesize);
}
double endTime = TrdTimeUtils::getTickTime();
////////////////////////////////////////////////////////////////////
int got_packet;
packet.data = *mAVFramePicture->data;
packet.size = avpicture_get_size(PIX_FMT_YUV420P, frameToBeWritten.getWidth(),
frameToBeWritten.getHeight());
mAVFramePicture->format = PIX_FMT_YUV420P;
mAVFramePicture->height = frameToBeWritten.getHeight();
mAVFramePicture->width = frameToBeWritten.getWidth();
double diffTime = _currTimeInMovie - 0.0;
// Find the frame number for presentation --> diffTime * fps;
int64_t calculatedPts = (unsigned long)((diffTime *
(double)mAVStream->time_base.den) / (double)mAVStream->time_base.num);
int enc_error = avcodec_encode_video2(mAVStream->codec, &packet,
mAVFramePicture, &got_packet);
if (enc_error >= 0 && got_packet != 0)
{
if (mAVStream->codec->coded_frame->key_frame)
{
packet.flags |= AV_PKT_FLAG_KEY;
}
packet.stream_index = mAVStream->index;
packet.pts = calculatedPts;
av_packet_rescale_ts(&packet, mAVStream->codec->time_base,
mAVStream->time_base);
packet.duration = ((diffTime - mLastTimeWritten) *
(double)mAVStream->time_base.den) / ((double)mAVStream->time_base.num);
mLastPtsWritten = packet.pts;
mLastTimeWritten = _currTimeInMovie;
avError = av_interleaved_write_frame(mAVFormatContext, &packet);
mRecordLogFrameCount++;
if (avError != 0)
{
error = ERROR_CODES_FILE_WRITE_FAILED;
}
} // end of -- if (bytesToWrite > 0)
else
{
error = ERROR_CODES_ENCODING_FAILED;
}
} // end of -- if (error == ERROR_CODE_NONE)
av_free_packet(&packet);
mWriteMutex.unlock();
return (error);
} // end of -- ERROR_CODE TrdMediaWriter::convertAndWrite(const TrdFrame&
_frame, double _beginTime, double _currTimeInMovie)
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user