I am using libav (2.7 built for MSVC) to open a camera using dshow:
input_format = av_find_input_format("dshow");
avformat_open_input(format_context, "video=Integrated Camera", input_format, 0);
When I open the video stream it is "raw video" (according to its long_name
) in the format AV_PIX_FMT_BGR24
. I need to have frames in AV_PIX_FMT_RGB24
so I make a SwsContext as follows:
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);
I then have a looping timer to read frames and decode into a AVFrame which is then passed off to 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);
}
After this point I would use av_picture
in my application, however sws_scale
hangs and crashes. Looking at all the data I am getting going into sws_scale
nothing looks odd to me except the linesize for av_frame
. av_frame->linesize[0] == -1920
(linesize[1]
and linesize[2]
are 0 as expected for BGR24
). As the width of my frame is 640 I would expect 1920 but the negative sign seems very odd. I have tried flipping the sign but it does not help. I should note that it does not crash every time (some runs it makes it through a few frames first).
Why would the linesize be negative? Does it mean something or is it just screwed up somehow?