void FfmpegMuxer::flushVideoQueue(uint64_t startTimestamp){
FrameNode videoNode;
Log::write("flush Video queue , startTimeStamp = %d\n", startTimestamp);
if(demuxer->beChunkMode2()) {
return;
}
while(demuxer->getVideoFrame(videoNode, startTimestamp)){
//if(demuxer->getVideoFrame(videoNode, startTimestamp)){
//decode video frame.
//fprintf(demuxer->fp4showsquence, "Video: timestamp = %d\n", videoNode.startStamp);
AVPacket packet;
packet.data = videoNode.buffer;
packet.size = videoNode.len;
int pts = videoNode.pts;
//int timeStamp = videoNode.startStamp;
AVFrame *pFrame = NULL;
pFrame=avcodec_alloc_frame();
int frameFinished = 0;
int ret = 0;
AVCodecContext *pCodecCtx = demuxer->getCodecContext();
int width,height;
demuxer->getVideoFrameWH(width, height);
ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,
&packet);
free(videoNode.buffer);
if(ret < 0){
Log::write("error: avcodec_decode_video() failed.\n");
if(pFrame){
av_free(pFrame);
}
continue;
}
if(frameFinished == 0){
Log::write("error: need next frame to finish decode.\n");
if(pFrame){
av_free(pFrame);
}
continue;
}
generatePreview(pFrame, width, height);
if(pFrame){
av_free(pFrame);
}
//writeVideoFrame(outContext, videoStream, yuvdata);
writeVideoFrame2(outContext, videoStream, yuvdata, pts);
}
}
void FfmpegMuxer::generatePreview(AVFrame* pFrame, int width, int height)
{memset(yuvdata, 0, 1024 * 1024);
int hw = (width+1)/2;
int hh = (height+1)/2;
for (int y = 0; y < height; y++)
memcpy(&yuvdata[width*y], &pFrame->data[0][pFrame->linesize[0]*y], width);
for (int y = 0; y < hh; y++) {
memcpy(&yuvdata[width*height + hw*y], &pFrame->data[1][pFrame->linesize[1]*y], hw);
memcpy(&yuvdata[width*height + hw*hh + hw*y], &pFrame->data[2][pFrame->linesize[2]*y], hw);
}
if(!hasPreview){
addPreview(yuvdata, width, height);
}
}