| @@ -20,6 +20,9 @@ | |||||
| */ | */ | ||||
| #include "libavformat/avformat.h" | #include "libavformat/avformat.h" | ||||
| #include "libavutil/log.h" | |||||
| #include "libavutil/opt.h" | |||||
| #include "libavutil/parseutils.h" | |||||
| #include <windows.h> | #include <windows.h> | ||||
| #include <vfw.h> | #include <vfw.h> | ||||
| @@ -34,12 +37,14 @@ | |||||
| /* End of missing MinGW defines */ | /* End of missing MinGW defines */ | ||||
| struct vfw_ctx { | struct vfw_ctx { | ||||
| const AVClass *class; | |||||
| HWND hwnd; | HWND hwnd; | ||||
| HANDLE mutex; | HANDLE mutex; | ||||
| HANDLE event; | HANDLE event; | ||||
| AVPacketList *pktl; | AVPacketList *pktl; | ||||
| unsigned int curbufsize; | unsigned int curbufsize; | ||||
| unsigned int frame_num; | 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) | static enum PixelFormat vfw_pixfmt(DWORD biCompression, WORD biBitCount) | ||||
| @@ -230,6 +235,8 @@ static int vfw_read_close(AVFormatContext *s) | |||||
| pktl = next; | pktl = next; | ||||
| } | } | ||||
| av_freep(&ctx->video_size); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -244,8 +251,6 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| CAPTUREPARMS cparms; | CAPTUREPARMS cparms; | ||||
| DWORD biCompression; | DWORD biCompression; | ||||
| WORD biBitCount; | WORD biBitCount; | ||||
| int width; | |||||
| int height; | |||||
| int ret; | int ret; | ||||
| if (!strcmp(s->filename, "list")) { | if (!strcmp(s->filename, "list")) { | ||||
| @@ -318,10 +323,20 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| dump_bih(s, &bi->bmiHeader); | 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) { | if (0) { | ||||
| /* For testing yet unsupported compressions | /* For testing yet unsupported compressions | ||||
| @@ -370,8 +385,8 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| codec = st->codec; | codec = st->codec; | ||||
| codec->time_base = ap->time_base; | codec->time_base = ap->time_base; | ||||
| codec->codec_type = AVMEDIA_TYPE_VIDEO; | 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); | codec->pix_fmt = vfw_pixfmt(biCompression, biBitCount); | ||||
| if(codec->pix_fmt == PIX_FMT_NONE) { | if(codec->pix_fmt == PIX_FMT_NONE) { | ||||
| codec->codec_id = vfw_codecid(biCompression); | codec->codec_id = vfw_codecid(biCompression); | ||||
| @@ -452,6 +467,20 @@ static int vfw_read_packet(AVFormatContext *s, AVPacket *pkt) | |||||
| return pkt->size; | 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 = { | AVInputFormat ff_vfwcap_demuxer = { | ||||
| "vfwcap", | "vfwcap", | ||||
| NULL_IF_CONFIG_SMALL("VFW video capture"), | NULL_IF_CONFIG_SMALL("VFW video capture"), | ||||
| @@ -461,4 +490,5 @@ AVInputFormat ff_vfwcap_demuxer = { | |||||
| vfw_read_packet, | vfw_read_packet, | ||||
| vfw_read_close, | vfw_read_close, | ||||
| .flags = AVFMT_NOFILE, | .flags = AVFMT_NOFILE, | ||||
| .priv_class = &vfw_class, | |||||
| }; | }; | ||||