【发布时间】:2017-08-17 15:56:22
【问题描述】:
我正在使用 FFmpeg 2.7 编写一个示例应用程序,该应用程序将执行以下操作:
- 从给定的 .mov 文件中读取视频数据包
- 在解码视频 10 秒后寻找指定位置,然后再继续 10 秒
- 在搜索之前和之后解码所有视频数据包并将它们写入目标文件。
在此过程中,我还将接收到的所有视频帧转储到原始图像文件中,使用原始数据包的 PTS 作为文件名。我注意到,即使在搜索发生之后(由时间戳中的跳转注意到),搜索后的前几帧包含新的时间戳,但旧帧(即我会在没有搜索的情况下收到的帧)。
These images illustrate the problem.
以下是我正在使用的代码的 sn-p:
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 是否存在已知问题?这在以后的版本中修复了吗?有什么我做错了吗?任何线索将不胜感激。
【问题讨论】: