Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMate Sebok <smfinc.org@gmail.com>2015-04-22 19:38:38 +0300
committerMichael Niedermayer <michaelni@gmx.at>2015-04-22 21:12:36 +0300
commit4d98015dcf6562b5822a96f024ac8c94b95203a6 (patch)
treeccdf417deec93a4ceff5dda011de923c5b1a69f6 /libavdevice/dshow.c
parent53ff9a4ec9ce1ab4ff2ab92479b885260ff5cf4c (diff)
dshow: add capture device save and load
Signed-off-by: Mate Sebok <smfinc.org@gmail.com> Reviewed-by: Roger Pack <rogerdpack2@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavdevice/dshow.c')
-rw-r--r--libavdevice/dshow.c97
1 files changed, 94 insertions, 3 deletions
diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index d03670e36f..62249785cb 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -27,6 +27,8 @@
#include "libavformat/riff.h"
#include "avdevice.h"
#include "libavcodec/raw.h"
+#include "objidl.h"
+#include "shlwapi.h"
static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
@@ -728,12 +730,46 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
ICaptureGraphBuilder2 *graph_builder2 = NULL;
int ret = AVERROR(EIO);
int r;
+ IStream *ifile_stream = NULL;
+ IStream *ofile_stream = NULL;
+ IPersistStream *pers_stream = NULL;
const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
- if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter)) < 0) {
- ret = r;
- goto error;
+
+ if ( ((ctx->audio_filter_load_file) && (strlen(ctx->audio_filter_load_file)>0) && (sourcetype == AudioSourceDevice)) ||
+ ((ctx->video_filter_load_file) && (strlen(ctx->video_filter_load_file)>0) && (sourcetype == VideoSourceDevice)) ) {
+ HRESULT hr;
+ char *filename = NULL;
+
+ if (sourcetype == AudioSourceDevice)
+ filename = ctx->audio_filter_load_file;
+ else
+ filename = ctx->video_filter_load_file;
+
+ hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_READ, &ifile_stream);
+ if (S_OK != hr) {
+ av_log(avctx, AV_LOG_ERROR, "Could not open capture filter description file.\n");
+ goto error;
+ }
+
+ hr = OleLoadFromStream(ifile_stream, &IID_IBaseFilter, (void **) &device_filter);
+ if (hr != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not load capture filter from file.\n");
+ goto error;
+ }
+
+ if (sourcetype == AudioSourceDevice)
+ av_log(avctx, AV_LOG_INFO, "Audio-");
+ else
+ av_log(avctx, AV_LOG_INFO, "Video-");
+ av_log(avctx, AV_LOG_INFO, "Capture filter loaded successfully from file \"%s\".\n", filename);
+ } else {
+
+ if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter)) < 0) {
+ ret = r;
+ goto error;
+ }
}
ctx->device_filter [devtype] = device_filter;
@@ -758,6 +794,48 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
}
ctx->capture_filter[devtype] = capture_filter;
+ if ( ((ctx->audio_filter_save_file) && (strlen(ctx->audio_filter_save_file)>0) && (sourcetype == AudioSourceDevice)) ||
+ ((ctx->video_filter_save_file) && (strlen(ctx->video_filter_save_file)>0) && (sourcetype == VideoSourceDevice)) ) {
+
+ HRESULT hr;
+ char *filename = NULL;
+
+ if (sourcetype == AudioSourceDevice)
+ filename = ctx->audio_filter_save_file;
+ else
+ filename = ctx->video_filter_save_file;
+
+ hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_CREATE | STGM_READWRITE, &ofile_stream);
+ if (S_OK != hr) {
+ av_log(avctx, AV_LOG_ERROR, "Could not create capture filter description file.\n");
+ goto error;
+ }
+
+ hr = IBaseFilter_QueryInterface(device_filter, &IID_IPersistStream, (void **) &pers_stream);
+ if (hr != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Query for IPersistStream failed.\n");
+ goto error;
+ }
+
+ hr = OleSaveToStream(pers_stream, ofile_stream);
+ if (hr != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not save capture filter \n");
+ goto error;
+ }
+
+ hr = IStream_Commit(ofile_stream, STGC_DEFAULT);
+ if (S_OK != hr) {
+ av_log(avctx, AV_LOG_ERROR, "Could not commit capture filter data to file.\n");
+ goto error;
+ }
+
+ if (sourcetype == AudioSourceDevice)
+ av_log(avctx, AV_LOG_INFO, "Audio-");
+ else
+ av_log(avctx, AV_LOG_INFO, "Video-");
+ av_log(avctx, AV_LOG_INFO, "Capture filter saved successfully to file \"%s\".\n", filename);
+ }
+
r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
filter_name[devtype]);
if (r != S_OK) {
@@ -802,6 +880,15 @@ error:
if (graph_builder2 != NULL)
ICaptureGraphBuilder2_Release(graph_builder2);
+ if (pers_stream)
+ IPersistStream_Release(pers_stream);
+
+ if (ifile_stream)
+ IStream_Release(ifile_stream);
+
+ if (ofile_stream)
+ IStream_Release(ofile_stream);
+
return ret;
}
@@ -1211,6 +1298,10 @@ static const AVOption options[] = {
{ "show_analog_tv_tuner_audio_dialog", "display property dialog for analog tuner audio filter", OFFSET(show_analog_tv_tuner_audio_dialog), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC, "show_analog_tv_tuner_dialog" },
{ "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "show_analog_tv_tuner_audio_dialog" },
{ "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "show_analog_tv_tuner_audio_dialog" },
+ { "audio_device_load", "load audio capture filter device (and properties) from file", OFFSET(audio_filter_load_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "audio_device_save", "save audio capture filter device (and properties) to file", OFFSET(audio_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "video_device_load", "load video capture filter device (and properties) from file", OFFSET(video_filter_load_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "video_device_save", "save video capture filter device (and properties) to file", OFFSET(video_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
{ NULL },
};