|
|
|
@ -20,6 +20,9 @@ |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include "libavformat/avformat.h" |
|
|
|
|
#include "libavutil/log.h" |
|
|
|
|
#include "libavutil/opt.h" |
|
|
|
|
#include "libavutil/parseutils.h" |
|
|
|
|
#include <windows.h> |
|
|
|
|
#include <vfw.h> |
|
|
|
|
|
|
|
|
@ -34,12 +37,14 @@ |
|
|
|
|
/* End of missing MinGW defines */ |
|
|
|
|
|
|
|
|
|
struct vfw_ctx { |
|
|
|
|
const AVClass *class; |
|
|
|
|
HWND hwnd; |
|
|
|
|
HANDLE mutex; |
|
|
|
|
HANDLE event; |
|
|
|
|
AVPacketList *pktl; |
|
|
|
|
unsigned int curbufsize; |
|
|
|
|
unsigned int frame_num; |
|
|
|
|
char *video_size; /**< A string describing video size, set by a private option. */ |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static enum PixelFormat vfw_pixfmt(DWORD biCompression, WORD biBitCount) |
|
|
|
@ -230,6 +235,8 @@ static int vfw_read_close(AVFormatContext *s) |
|
|
|
|
pktl = next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
av_freep(&ctx->video_size); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -244,8 +251,6 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
CAPTUREPARMS cparms; |
|
|
|
|
DWORD biCompression; |
|
|
|
|
WORD biBitCount; |
|
|
|
|
int width; |
|
|
|
|
int height; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
if (!strcmp(s->filename, "list")) { |
|
|
|
@ -318,10 +323,20 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
|
|
|
|
|
dump_bih(s, &bi->bmiHeader); |
|
|
|
|
|
|
|
|
|
width = ap->width ? ap->width : bi->bmiHeader.biWidth ; |
|
|
|
|
height = ap->height ? ap->height : bi->bmiHeader.biHeight; |
|
|
|
|
bi->bmiHeader.biWidth = width ; |
|
|
|
|
bi->bmiHeader.biHeight = height; |
|
|
|
|
|
|
|
|
|
if (ctx->video_size) { |
|
|
|
|
ret = av_parse_video_size(&bi->bmiHeader.biWidth, &bi->bmiHeader.biHeight, ctx->video_size); |
|
|
|
|
if (ret < 0) { |
|
|
|
|
av_log(s, AV_LOG_ERROR, "Couldn't parse video size.\n"); |
|
|
|
|
goto fail_bi; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#if FF_API_FORMAT_PARAMETERS |
|
|
|
|
if (ap->width > 0) |
|
|
|
|
bi->bmiHeader.biWidth = ap->width; |
|
|
|
|
if (ap->height > 0) |
|
|
|
|
bi->bmiHeader.biHeight = ap->height; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (0) { |
|
|
|
|
/* For testing yet unsupported compressions
|
|
|
|
@ -370,8 +385,8 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
codec = st->codec; |
|
|
|
|
codec->time_base = ap->time_base; |
|
|
|
|
codec->codec_type = AVMEDIA_TYPE_VIDEO; |
|
|
|
|
codec->width = width; |
|
|
|
|
codec->height = height; |
|
|
|
|
codec->width = bi->bmiHeader.biWidth; |
|
|
|
|
codec->height = bi->bmiHeader.biHeight; |
|
|
|
|
codec->pix_fmt = vfw_pixfmt(biCompression, biBitCount); |
|
|
|
|
if(codec->pix_fmt == PIX_FMT_NONE) { |
|
|
|
|
codec->codec_id = vfw_codecid(biCompression); |
|
|
|
@ -452,6 +467,20 @@ static int vfw_read_packet(AVFormatContext *s, AVPacket *pkt) |
|
|
|
|
return pkt->size; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define OFFSET(x) offsetof(struct vfw_ctx, x) |
|
|
|
|
#define DEC AV_OPT_FLAG_DECODING_PARAM |
|
|
|
|
static const AVOption options[] = { |
|
|
|
|
{ "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, |
|
|
|
|
{ NULL }, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static const AVClass vfw_class = { |
|
|
|
|
.class_name = "VFW indev", |
|
|
|
|
.item_name = av_default_item_name, |
|
|
|
|
.option = options, |
|
|
|
|
.version = LIBAVUTIL_VERSION_INT, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
AVInputFormat ff_vfwcap_demuxer = { |
|
|
|
|
"vfwcap", |
|
|
|
|
NULL_IF_CONFIG_SMALL("VFW video capture"), |
|
|
|
@ -461,4 +490,5 @@ AVInputFormat ff_vfwcap_demuxer = { |
|
|
|
|
vfw_read_packet, |
|
|
|
|
vfw_read_close, |
|
|
|
|
.flags = AVFMT_NOFILE, |
|
|
|
|
.priv_class = &vfw_class, |
|
|
|
|
}; |
|
|
|
|