我正在使用 FFmpeg 2.7 编写一个示例应用程序来执行以下操作:
在此过程中,我还将所有收到的视频帧转储到原始图像文件中,使用原始数据包的PTS作为文件名。我注意到即使在搜索发生之后(通过时间戳的跳转来指出),搜索之后的前几帧包含新的时间戳,但是旧的帧(即,我没有搜索就会收到的帧)。
These images illustrate the problem.
以下是我正在使用的代码片段:
int SeekAndTranscode::_TranscodePacket(AVPacket &packet, AVFrame *frame)
{
if(packet.stream_index == _videoStreamIndex)
{
int status = avcodec_decode_video2(&_videoDecContext, frame, &gotFrame, &packet);
if (status < 0)
{
fprintf(stderr, "\nError decoding video frame\n");
exit(1);
}
if (gotFrame)
{
if (frame->width != _width || frame->height != _height ||
frame->format != _pixelFormat)
{
return -1;
}
vector<uint8_t> rgbData;
rgbData.resize(_width * _height * 4);
uint8_t *rgbSrc[3]= {&rgbData[0], NULL, NULL};
int rgbStride[3]={4 * _width, 0, 0};
sws_scale(_csc, frame->data, frame->linesize, 0, _height, rgbSrc, rgbStride);
int64_t pts = packet.pts * AV_TIME_BASE / _videoDecContext.time_base.den;
FILE *file;
stringstream filename;
filename << "C:\\Bipul\\" << pts << ".raw";
file = fopen(filename.str().c_str(), "wb");
fwrite(&rgbData[0], 1, rgbData.size(), file);
fclose(file);
fwrite(&rgbData[0], 1, rgbData.size(), _videoOutputFile);
}
}
return decodedSize;
}
void SeekAndTranscode::TranscodeIntoFile()
{
AVFrame* frame = NULL;
AVPacket packet;
int videoSeeks = 0;
int frameCount = 0;
int framerate = 24;
try
{
frame = av_frame_alloc();
if (!frame)
{
fprintf(stderr, "\nCould not allocate frame for decoding\n");
exit(1);
}
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
while (av_read_frame(_formatContext, &packet) >= 0)
{
if(packet.stream_index == _videoStreamIndex)
{
frameCount++;
if(frameCount % (10*framerate) == 0)
{
if(videoSeeks == 1)
break;
av_seek_frame(_formatContext, -1, _seekPosition * AV_TIME_BASE, 0);
videoSeeks++;
continue;
}
}
AVPacket originalPacket = packet;
do
{
int status = _TranscodePacket(packet, frame);
if (status < 0)
break;
packet.data += status;
packet.size -= status;
} while (packet.size > 0);
av_packet_unref(&originalPacket);
}
if (frame)
{
av_frame_free(&frame);
}
swr_free(&_resampler);
}
catch(const exception& e)
{
fprintf(stderr, "\n%s\n", e.what());
exit(1);
}
}
这是这个版本的FFmpeg的已知问题吗?这是否已在以后的版本中修复?有什么我做错了吗?任何线索都将受到赞赏。
答案 0 :(得分:0)
在继续从流中读取更多帧之前,您需要刷新自己的缓冲区并在内部刷新ffmpegs缓冲区。
avcodec_flush_buffers(myAVCodecContext); // do this for all your streams that are opened