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

Reply via email to