0
我使用FFmpeg的2.7寫一個示例應用程序,將做到以下幾點:與FFmpeg的尋求使舊框架的新包的時間戳
- 從給定的.mov文件讀取視頻數據包
- 解碼視頻10秒後尋找指定位置並繼續10秒
- 解碼所有視頻數據包在搜索之前和之後並將其寫入目標文件。
在這個過程中,我也將所有接收到的視頻幀轉儲到原始圖像文件中,使用原始數據包的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的?這在更高版本中得到修復嗎?有什麼我做錯了嗎?任何線索將不勝感激。
這對我有用。非常感謝。 –