| @@ -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, | |||
| }; | |||