introduce -video_size
if not provided use the first size available
---
libavdevice/avfoundation_dec.m | 66 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/libavdevice/avfoundation_dec.m b/libavdevice/avfoundation_dec.m
index 7c0212a..ce04f33 100644
--- a/libavdevice/avfoundation_dec.m
+++ b/libavdevice/avfoundation_dec.m
@@ -30,6 +30,7 @@
#include "libavformat/internal.h"
#include "libavutil/time.h"
#include "libavutil/mathematics.h"
+#include "libavutil/parseutils.h"
#include "avdevice.h"
@@ -93,8 +94,10 @@ typedef struct AVFoundationCaptureContext {
int list_devices;
int list_formats;
char* pixel_format;
+ char *video_size; /* String describing video size */
int video_stream_index;
+ int width, height;
int64_t first_pts;
int frames_captured;
@@ -121,6 +124,7 @@ static const AVOption options[] = {
{ "video", "Show only the video devices", OFFSET(list_devices),
AV_OPT_TYPE_CONST, {.i64 = VIDEO_DEVICES }, 0, INT_MAX, DEC, "list_devices" },
{ "list_formats", "List available formats and exit", OFFSET(list_formats),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, DEC, "list_formats" },
{ "pixel_format", "Preferred pixel format", OFFSET(pixel_format),
AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC},
+ { "video_size", "A string describing frame size, such as 640x480 or
hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
{ NULL },
};
@@ -226,6 +230,51 @@ static void unlock_frames(AVFoundationCaptureContext* ctx)
@end
+/**
+ * Configure the video device.
+ */
+static bool configure_video_device(AVFormatContext *s, AVCaptureDevice
*video_device)
+{
+ AVFoundationCaptureContext *ctx = s->priv_data;
+ AVCaptureDeviceFormat* selected_format = nil;
+
+ for (AVCaptureDeviceFormat* format in [video_device formats]) {
+ CMFormatDescriptionRef formatDescription;
+ CMVideoDimensions dimensions;
+
+ formatDescription = (CMFormatDescriptionRef) format.formatDescription;
+ dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
+
+ if ((ctx->width == 0 && ctx->height == 0) ||
+ (dimensions.width == ctx->width && dimensions.height ==
ctx->height)) {
+
+ av_log(s, AV_LOG_INFO, "Video size (%dx%d) supported\n",
+ dimensions.width, dimensions.height);
+ ctx->width = dimensions.width;
+ ctx->height = dimensions.height;
+ selected_format = format;
+ break;
+ }
+ }
+
+ if (!selected_format) {
+ av_log(s, AV_LOG_ERROR, "Selected video size (%dx%d) is not supported
by the device\n",
+ ctx->width, ctx->height);
+ return false;
+ } else {
+ av_log(s, AV_LOG_INFO, "Setting video size to %dx%d\n",
+ ctx->width, ctx->height);
+ }
+
+ if ([video_device lockForConfiguration:NULL] == YES) {
+ [video_device setActiveFormat:selected_format];
+ } else {
+ av_log(s, AV_LOG_ERROR, "Could not lock device for configuration");
+ return false;
+ }
+ return true;
+}
+
static int setup_stream(AVFormatContext *s, AVCaptureDevice *device)
{
av_log(s, AV_LOG_INFO, "Setting up stream for device %s\n", [[device
uniqueID] UTF8String]);
@@ -236,6 +285,12 @@ static int setup_stream(AVFormatContext *s,
AVCaptureDevice *device)
AVCaptureSession *session = (__bridge AVCaptureSession*)ctx->session;
input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
+
+ if (!configure_video_device(s, device)) {
+ av_log(s, AV_LOG_ERROR, "device configuration failed\n");
+ return AVERROR(EINVAL);
+ }
+
// add the input devices
if (!input) {
av_log(s, AV_LOG_ERROR, "%s\n",
@@ -456,13 +511,16 @@ static int setup_streams(AVFormatContext *s)
}
if (ret < 0) {
- av_log(s, AV_LOG_ERROR, "No device could be added");
+ av_log(s, AV_LOG_ERROR, "No device could be added\n");
return ret;
}
av_log(s, AV_LOG_INFO, "Starting session!\n");
[(__bridge AVCaptureSession*)ctx->session startRunning];
+ // Session is started, unlock device
+ [device unlockForConfiguration];
+
av_log(s, AV_LOG_INFO, "Checking video config\n");
if (get_video_config(s)) {
destroy_context(ctx);
@@ -491,6 +549,12 @@ static int avfoundation_read_header(AVFormatContext *s)
}
}
+ if (ctx->video_size &&
+ (av_parse_video_size(&ctx->width, &ctx->height, ctx->video_size)) < 0)
{
+ av_log(s, AV_LOG_ERROR, "Could not parse video size '%s'.\n",
+ ctx->video_size);
+ return AVERROR(EINVAL);
+ }
return setup_streams(s);
}
--
2.6.2
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel