AVFrame имеет отрицательный размер строки

Я использую libav (2.7 построен для MSVC), чтобы открыть камеру с помощью dshow:

input_format = av_find_input_format("dshow");
avformat_open_input(format_context, "video=Integrated Camera", input_format, 0);

Когда я открываю видеопоток, это «сырое видео» (в соответствии с его длинным именем) в формате AV_PIX_FMT_BGR24. Мне нужно иметь кадры в AV_PIX_FMT_RGB24, поэтому я делаю SwsContext следующим образом:

sws_context = sws_getContext(codec_context->width, codec_context->height, codec_context->pix_fmt,
codec_context->width, codec_context->height, AV_PIX_FMT_RGB24,
SWS_BICUBIC, 0, 0, 0);
av_picture = new AVPicture();
avpicture_alloc(av_picture, AV_PIX_FMT_RGB24, codec_context->width, codec_context->height);

Затем у меня есть циклический таймер для чтения кадров и декодирования в AVFrame, который затем передается в sws_scale.

while(av_read_frame(format_context, &packet) >= 0)
{
if(packet.stream_index == stream_index)
{
av_frame = 0;
av_frame = av_frame_alloc();

avcodec_decode_video2(codec_context, av_frame, &frame_finished, &packet);
if(frame_finished)
{
sws_scale(sws_context, (const uint8_t * const *)av_frame->data, av_frame->linesize,
0, codec_context->height, av_picture->data, av_picture->linesize);
av_free_packet(&packet);
return;
}
}
av_free_packet(&packet);
}

После этого я буду использовать av_picture в своем приложении, однако sws_scale зависает и вылетает. Глядя на все данные, которые я получаю в sws_scale, для меня нет ничего странного, кроме linesize для av_frame. av_frame->linsize[0] == -1920 (размеры линий 1 и 2 равны 0, как и ожидалось для BGR24). Поскольку ширина моей рамки равна 640, я ожидал бы 1920, но отрицательный знак кажется очень странным. Я попытался перевернуть знак, но это не помогает. Я должен отметить, что он не падает каждый раз (при некоторых запусках он сначала проходит несколько кадров).

Почему размер линии будет отрицательным? Это что-то значит или просто облажалось?

2

Решение

Стандартное упорядочение строк RGB в Windows для растровых изображений и видео — снизу вверх (AFAIR — это только относительно новые API, такие как WIC и Direct2D, где линии переупорядочены естественным образом). Порядок линий сверху вниз обозначается отрицательной высотой и в основном встречается редко. В этом порядке строк нет ничего плохого: указатель на «первый пиксель» указывает на крайний левый пиксель последней строки, а затем вы перемещаетесь между строками с отрицательным смещением. libswscale справляется с этим нормально.

Разве отрицательный размер линии не будет соответствовать отрицательному значению biWidth (которое они не обсуждают), а не отрицательному значению biHeight (которое они делают)?

Нет, соглашение таково: если biHeight отрицательно, то это минус количество строк и порядок строк меняется на противоположный. biWidth всегда положительно (biWidth несет ответственность за перенос другого расширения: оно может быть увеличено до указанного нестандартного расширенного шага в случае заполнения справа от изображения полезной нагрузки).

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]