Следующий код работает отлично, пока я перемещаю только прямоугольник обрезки, однако как только я меняю его размер, я больше не получаю кадры из своего фильтра (av_buffersink_get_frame возвращает -11). Это безумие, даже после изменения размера, если он в конечном итоге изменится на исходный размер, через который пройдет кадр, то он снова перестанет предоставлять кадры.
Кто-нибудь знает? что я делаю не так?
Моя настройка фильтра (обратите внимание на комбинацию обрезки и масштабирования, она должна (я думаю?) масштабировать все, что я обрезаю, до размера размер выходного видео):
// buffer source -> buffer sink setup
auto args = std::format("video_size={}x{}:pix_fmt={}:time_base={}/{}:pixel_aspect={}/{}",
inputCodecContext->width, inputCodecContext->height, (int)inputCodecContext->pix_fmt,
inputCodecContext->pkt_timebase.num, inputCodecContext->pkt_timebase.den,
inputCodecContext->sample_aspect_ratio.num, inputCodecContext->sample_aspect_ratio.den);
AVFilterContext* buffersrc_ctx = nullptr, * buffersink_ctx = nullptr;
check_av_result(avfilter_graph_create_filter(&buffersrc_ctx, bufferSource, "in",
args.c_str(), nullptr, &*filterGraph));
check_av_result(avfilter_graph_create_filter(&buffersink_ctx, bufferSink, "out",
nullptr, nullptr, &*filterGraph));
check_av_result(av_opt_set_bin(buffersink_ctx, "pix_fmts",
(uint8_t*)&outputCodecContext->pix_fmt, sizeof(outputCodecContext->pix_fmt), AV_OPT_SEARCH_CHILDREN));
// filter command setup
auto filterSpec = std::format("crop,scale={}:{},setsar=1:1", outputCodecContext->width, outputCodecContext->height);
check_av_result(avfilter_graph_parse_ptr(&*filterGraph, filterSpec.c_str(), &filterInputs, &filterOutputs, nullptr));
check_av_result(avfilter_graph_config(&*filterGraph, nullptr));
Обрезка кадра:
check_av_result(avfilter_graph_send_command(&*filterGraph, "crop", "x", std::to_string(cropRectangle.CenterX() - cropRectangle.Width() / 2).c_str(), nullptr, 0, 0));
check_av_result(avfilter_graph_send_command(&*filterGraph, "crop", "y", std::to_string(cropRectangle.CenterY() - cropRectangle.Height() / 2).c_str(), nullptr, 0, 0));
check_av_result(avfilter_graph_send_command(&*filterGraph, "crop", "w", std::to_string(cropRectangle.Width()).c_str(), nullptr, 0, 0));
check_av_result(avfilter_graph_send_command(&*filterGraph, "crop", "h", std::to_string(cropRectangle.Height()).c_str(), nullptr, 0, 0));
// push the decoded frame into the filter graph
check_av_result(av_buffersrc_add_frame_flags(buffersrc_ctx, &*inputFrame, 0));
// pull filtered frames from the filter graph
while (1)
{
ret = av_buffersink_get_frame(buffersink_ctx, &*filteredFrame);
if (ret < 0)
{
// if no more frames, rewrite the code to 0 to show it as normal completion
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
ret = 0;
break;
}
// write the filtered frame to the output file
// [...]
}
Я также установил размер выходного видео перед созданием файла, и он выполняется так, как ожидалось:
outputCodecContext->width = (int)output.PixelSize().Width;
outputCodecContext->height = (int)output.PixelSize().Height;
Подробнее здесь: https://stackoverflow.com/questions/783 ... p-size-cha
Динамический код обрезки, масштабирования и кодирования ffmpeg, кажется, ломается при изменении размера обрезки. ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение