Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
b8773e44
Commit
b8773e44
authored
May 26, 2011
by
Martin Lambers
Committed by
Michael Niedermayer
May 27, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libdc1394: choose best video mode and rate based on camera capabilities.
parent
ea7e318f
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
162 additions
and
80 deletions
+162
-80
libdc1394.c
libavdevice/libdc1394.c
+162
-80
No files found.
libavdevice/libdc1394.c
View file @
b8773e44
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
* IIDC1394 grab interface (uses libdc1394 and libraw1394)
* IIDC1394 grab interface (uses libdc1394 and libraw1394)
* Copyright (c) 2004 Roman Shaposhnik
* Copyright (c) 2004 Roman Shaposhnik
* Copyright (c) 2008 Alessandro Sappia
* Copyright (c) 2008 Alessandro Sappia
* Copyright (c) 2011 Martin Lambers
*
*
* This file is part of FFmpeg.
* This file is part of FFmpeg.
*
*
...
@@ -25,6 +26,9 @@
...
@@ -25,6 +26,9 @@
#include "libavutil/opt.h"
#include "libavutil/opt.h"
#include "avdevice.h"
#include "avdevice.h"
#include <stdlib.h>
#include <string.h>
#include <dc1394/dc1394.h>
#include <dc1394/dc1394.h>
#undef free
#undef free
...
@@ -40,16 +44,21 @@ typedef struct dc1394_data {
...
@@ -40,16 +44,21 @@ typedef struct dc1394_data {
AVPacket
packet
;
AVPacket
packet
;
}
dc1394_data
;
}
dc1394_data
;
struct
dc1394_frame_format
{
/* The list of color codings that we support.
int
width
;
* We assume big endian for the dc1394 16bit modes: libdc1394 never sets the
int
height
;
* flag little_endian in dc1394video_frame_t. */
enum
PixelFormat
pix_fmt
;
struct
dc1394_color_coding
{
int
frame_size_id
;
int
pix_fmt
;
}
dc1394_frame_formats
[]
=
{
int
score
;
{
320
,
240
,
PIX_FMT_UYVY422
,
DC1394_VIDEO_MODE_320x240_YUV422
},
uint32_t
coding
;
{
640
,
480
,
PIX_FMT_UYYVYY411
,
DC1394_VIDEO_MODE_640x480_YUV411
},
}
dc1394_color_codings
[]
=
{
{
640
,
480
,
PIX_FMT_UYVY422
,
DC1394_VIDEO_MODE_640x480_YUV422
},
{
PIX_FMT_GRAY16BE
,
1000
,
DC1394_COLOR_CODING_MONO16
},
{
0
,
0
,
0
,
0
}
/* gotta be the last one */
{
PIX_FMT_RGB48BE
,
1100
,
DC1394_COLOR_CODING_RGB16
},
{
PIX_FMT_GRAY8
,
1200
,
DC1394_COLOR_CODING_MONO8
},
{
PIX_FMT_RGB24
,
1300
,
DC1394_COLOR_CODING_RGB8
},
{
PIX_FMT_UYYVYY411
,
1400
,
DC1394_COLOR_CODING_YUV411
},
{
PIX_FMT_UYVY422
,
1500
,
DC1394_COLOR_CODING_YUV422
},
{
PIX_FMT_NONE
,
0
,
0
}
/* gotta be the last one */
};
};
struct
dc1394_frame_rate
{
struct
dc1394_frame_rate
{
...
@@ -68,9 +77,6 @@ struct dc1394_frame_rate {
...
@@ -68,9 +77,6 @@ struct dc1394_frame_rate {
};
};
static
const
AVOption
options
[]
=
{
static
const
AVOption
options
[]
=
{
#if HAVE_LIBDC1394_1
{
"channel"
,
""
,
offsetof
(
dc1394_data
,
channel
),
FF_OPT_TYPE_INT
,
{.
dbl
=
0
},
0
,
INT_MAX
,
AV_OPT_FLAG_DECODING_PARAM
},
#endif
{
NULL
},
{
NULL
},
};
};
...
@@ -81,73 +87,22 @@ static const AVClass libdc1394_class = {
...
@@ -81,73 +87,22 @@ static const AVClass libdc1394_class = {
.
version
=
LIBAVUTIL_VERSION_INT
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
};
static
inline
int
dc1394_read_common
(
AVFormatContext
*
c
,
AVFormatParameters
*
ap
,
struct
dc1394_frame_format
**
select_fmt
,
struct
dc1394_frame_rate
**
select_fps
)
{
dc1394_data
*
dc1394
=
c
->
priv_data
;
AVStream
*
vst
;
struct
dc1394_frame_format
*
fmt
;
struct
dc1394_frame_rate
*
fps
;
enum
PixelFormat
pix_fmt
=
ap
->
pix_fmt
==
PIX_FMT_NONE
?
PIX_FMT_UYVY422
:
ap
->
pix_fmt
;
/* defaults */
int
width
=
!
ap
->
width
?
320
:
ap
->
width
;
int
height
=
!
ap
->
height
?
240
:
ap
->
height
;
int
frame_rate
=
!
ap
->
time_base
.
num
?
30000
:
av_rescale
(
1000
,
ap
->
time_base
.
den
,
ap
->
time_base
.
num
);
for
(
fmt
=
dc1394_frame_formats
;
fmt
->
width
;
fmt
++
)
if
(
fmt
->
pix_fmt
==
pix_fmt
&&
fmt
->
width
==
width
&&
fmt
->
height
==
height
)
break
;
for
(
fps
=
dc1394_frame_rates
;
fps
->
frame_rate
;
fps
++
)
if
(
fps
->
frame_rate
==
frame_rate
)
break
;
if
(
!
fps
->
frame_rate
||
!
fmt
->
width
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"Can't find matching camera format for %s, %dx%d@%d:1000fps
\n
"
,
avcodec_get_pix_fmt_name
(
pix_fmt
),
width
,
height
,
frame_rate
);
goto
out
;
}
/* create a video stream */
vst
=
av_new_stream
(
c
,
0
);
if
(
!
vst
)
goto
out
;
av_set_pts_info
(
vst
,
64
,
1
,
1000
);
vst
->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
vst
->
codec
->
codec_id
=
CODEC_ID_RAWVIDEO
;
vst
->
codec
->
time_base
.
den
=
fps
->
frame_rate
;
vst
->
codec
->
time_base
.
num
=
1000
;
vst
->
codec
->
width
=
fmt
->
width
;
vst
->
codec
->
height
=
fmt
->
height
;
vst
->
codec
->
pix_fmt
=
fmt
->
pix_fmt
;
/* packet init */
av_init_packet
(
&
dc1394
->
packet
);
dc1394
->
packet
.
size
=
avpicture_get_size
(
fmt
->
pix_fmt
,
fmt
->
width
,
fmt
->
height
);
dc1394
->
packet
.
stream_index
=
vst
->
index
;
dc1394
->
packet
.
flags
|=
AV_PKT_FLAG_KEY
;
dc1394
->
current_frame
=
0
;
dc1394
->
fps
=
fps
->
frame_rate
;
vst
->
codec
->
bit_rate
=
av_rescale
(
dc1394
->
packet
.
size
*
8
,
fps
->
frame_rate
,
1000
);
*
select_fps
=
fps
;
*
select_fmt
=
fmt
;
return
0
;
out:
return
-
1
;
}
static
int
dc1394_read_header
(
AVFormatContext
*
c
,
AVFormatParameters
*
ap
)
static
int
dc1394_read_header
(
AVFormatContext
*
c
,
AVFormatParameters
*
ap
)
{
{
dc1394_data
*
dc1394
=
c
->
priv_data
;
dc1394_data
*
dc1394
=
c
->
priv_data
;
AVStream
*
vst
;
const
struct
dc1394_color_coding
*
cc
;
const
struct
dc1394_frame_rate
*
fr
;
dc1394camera_list_t
*
list
;
dc1394camera_list_t
*
list
;
int
res
,
i
;
dc1394video_modes_t
video_modes
;
struct
dc1394_frame_format
*
fmt
=
NULL
;
dc1394video_mode_t
video_mode
;
struct
dc1394_frame_rate
*
fps
=
NULL
;
dc1394framerates_t
frame_rates
;
dc1394framerate_t
frame_rate
;
if
(
dc1394_read_common
(
c
,
ap
,
&
fmt
,
&
fps
)
!=
0
)
uint32_t
dc1394_width
,
dc1394_height
,
dc1394_color_coding
;
return
-
1
;
int
rate
,
best_rate
;
int
score
,
max_score
;
int
final_width
,
final_height
,
final_pix_fmt
,
final_frame_rate
;
int
res
,
i
,
j
;
/* Now let us prep the hardware. */
/* Now let us prep the hardware. */
dc1394
->
d
=
dc1394_new
();
dc1394
->
d
=
dc1394_new
();
...
@@ -166,6 +121,133 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap)
...
@@ -166,6 +121,133 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap)
/* Freeing list of cameras */
/* Freeing list of cameras */
dc1394_camera_free_list
(
list
);
dc1394_camera_free_list
(
list
);
/* Get the list of video modes supported by the camera. */
res
=
dc1394_video_get_supported_modes
(
dc1394
->
camera
,
&
video_modes
);
if
(
res
!=
DC1394_SUCCESS
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"Could not get video formats.
\n
"
);
goto
out_camera
;
}
/* Choose the best mode. */
rate
=
(
ap
->
time_base
.
num
?
av_rescale
(
1000
,
ap
->
time_base
.
den
,
ap
->
time_base
.
num
)
:
-
1
);
max_score
=
-
1
;
for
(
i
=
0
;
i
<
video_modes
.
num
;
i
++
)
{
if
(
video_modes
.
modes
[
i
]
==
DC1394_VIDEO_MODE_EXIF
||
(
video_modes
.
modes
[
i
]
>=
DC1394_VIDEO_MODE_FORMAT7_MIN
&&
video_modes
.
modes
[
i
]
<=
DC1394_VIDEO_MODE_FORMAT7_MAX
))
{
/* These modes are currently not supported as they would require
* much more work. For the remaining modes, the functions
* dc1394_get_image_size_from_video_mode and
* dc1394_get_color_coding_from_video_mode do not need to query the
* camera, and thus cannot fail. */
continue
;
}
dc1394_get_color_coding_from_video_mode
(
NULL
,
video_modes
.
modes
[
i
],
&
dc1394_color_coding
);
for
(
cc
=
dc1394_color_codings
;
cc
->
pix_fmt
!=
PIX_FMT_NONE
;
cc
++
)
if
(
cc
->
coding
==
dc1394_color_coding
)
break
;
if
(
cc
->
pix_fmt
==
PIX_FMT_NONE
)
{
/* We currently cannot handle this color coding. */
continue
;
}
/* Here we know that the mode is supported. Get its frame size and the list
* of frame rates supported by the camera for this mode. This list is sorted
* in ascending order according to libdc1394 example programs. */
dc1394_get_image_size_from_video_mode
(
NULL
,
video_modes
.
modes
[
i
],
&
dc1394_width
,
&
dc1394_height
);
res
=
dc1394_video_get_supported_framerates
(
dc1394
->
camera
,
video_modes
.
modes
[
i
],
&
frame_rates
);
if
(
res
!=
DC1394_SUCCESS
||
frame_rates
.
num
==
0
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"Cannot get frame rates for video mode.
\n
"
);
goto
out_camera
;
}
/* Choose the best frame rate. */
best_rate
=
-
1
;
for
(
j
=
0
;
j
<
frame_rates
.
num
;
j
++
)
{
for
(
fr
=
dc1394_frame_rates
;
fr
->
frame_rate
;
fr
++
)
{
if
(
fr
->
frame_rate_id
==
frame_rates
.
framerates
[
j
])
{
break
;
}
}
if
(
!
fr
->
frame_rate
)
{
/* This frame rate is not supported. */
continue
;
}
best_rate
=
fr
->
frame_rate
;
frame_rate
=
fr
->
frame_rate_id
;
if
(
ap
->
time_base
.
num
&&
rate
==
fr
->
frame_rate
)
{
/* This is the requested frame rate. */
break
;
}
}
if
(
best_rate
==
-
1
)
{
/* No supported rate found. */
continue
;
}
/* Here we know that both the mode and the rate are supported. Compute score. */
if
(
ap
->
width
&&
ap
->
height
&&
(
dc1394_width
==
ap
->
width
&&
dc1394_height
==
ap
->
height
))
{
score
=
110000
;
}
else
{
score
=
dc1394_width
*
10
;
// 1600 - 16000
}
if
(
ap
->
pix_fmt
==
cc
->
pix_fmt
)
{
score
+=
90000
;
}
else
{
score
+=
cc
->
score
;
// 1000 - 1500
}
if
(
ap
->
time_base
.
num
&&
rate
==
best_rate
)
{
score
+=
70000
;
}
else
{
score
+=
best_rate
/
1000
;
// 1 - 240
}
if
(
score
>
max_score
)
{
video_mode
=
video_modes
.
modes
[
i
];
final_width
=
dc1394_width
;
final_height
=
dc1394_height
;
final_pix_fmt
=
cc
->
pix_fmt
;
final_frame_rate
=
best_rate
;
max_score
=
score
;
}
}
if
(
max_score
==
-
1
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"No suitable video mode / frame rate available.
\n
"
);
goto
out_camera
;
}
if
(
ap
->
width
&&
ap
->
height
&&
!
(
ap
->
width
==
final_width
&&
ap
->
height
==
final_height
))
{
av_log
(
c
,
AV_LOG_WARNING
,
"Requested frame size is not available, using fallback.
\n
"
);
}
if
(
ap
->
pix_fmt
!=
PIX_FMT_NONE
&&
ap
->
pix_fmt
!=
final_pix_fmt
)
{
av_log
(
c
,
AV_LOG_WARNING
,
"Requested pixel format is not supported, using fallback.
\n
"
);
}
if
(
ap
->
time_base
.
num
&&
rate
!=
final_frame_rate
)
{
av_log
(
c
,
AV_LOG_WARNING
,
"Requested frame rate is not available, using fallback.
\n
"
);
}
/* create a video stream */
vst
=
av_new_stream
(
c
,
0
);
if
(
!
vst
)
goto
out_camera
;
av_set_pts_info
(
vst
,
64
,
1
,
1000
);
vst
->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
vst
->
codec
->
codec_id
=
CODEC_ID_RAWVIDEO
;
vst
->
codec
->
time_base
.
den
=
final_frame_rate
;
vst
->
codec
->
time_base
.
num
=
1000
;
vst
->
codec
->
width
=
final_width
;
vst
->
codec
->
height
=
final_height
;
vst
->
codec
->
pix_fmt
=
final_pix_fmt
;
/* packet init */
av_init_packet
(
&
dc1394
->
packet
);
dc1394
->
packet
.
size
=
avpicture_get_size
(
final_pix_fmt
,
final_width
,
final_height
);
dc1394
->
packet
.
stream_index
=
vst
->
index
;
dc1394
->
packet
.
flags
|=
AV_PKT_FLAG_KEY
;
dc1394
->
current_frame
=
0
;
dc1394
->
fps
=
final_frame_rate
;
vst
->
codec
->
bit_rate
=
av_rescale
(
dc1394
->
packet
.
size
*
8
,
final_frame_rate
,
1000
);
/* Select MAX Speed possible from the cam */
/* Select MAX Speed possible from the cam */
if
(
dc1394
->
camera
->
bmode_capable
>
0
)
{
if
(
dc1394
->
camera
->
bmode_capable
>
0
)
{
dc1394_video_set_operation_mode
(
dc1394
->
camera
,
DC1394_OPERATION_MODE_1394B
);
dc1394_video_set_operation_mode
(
dc1394
->
camera
,
DC1394_OPERATION_MODE_1394B
);
...
@@ -182,13 +264,13 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap)
...
@@ -182,13 +264,13 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap)
goto
out_camera
;
goto
out_camera
;
}
}
if
(
dc1394_video_set_mode
(
dc1394
->
camera
,
fmt
->
frame_size_id
)
!=
DC1394_SUCCESS
)
{
if
(
dc1394_video_set_mode
(
dc1394
->
camera
,
video_mode
)
!=
DC1394_SUCCESS
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"Couldn't set video format
\n
"
);
av_log
(
c
,
AV_LOG_ERROR
,
"Couldn't set video format
\n
"
);
goto
out_camera
;
goto
out_camera
;
}
}
if
(
dc1394_video_set_framerate
(
dc1394
->
camera
,
fps
->
frame_rate_id
)
!=
DC1394_SUCCESS
)
{
if
(
dc1394_video_set_framerate
(
dc1394
->
camera
,
frame_rate
)
!=
DC1394_SUCCESS
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"Could
n't set framerate %d
\n
"
,
fps
->
frame_rate
);
av_log
(
c
,
AV_LOG_ERROR
,
"Could
not set framerate %d.
\n
"
,
final_
frame_rate
);
goto
out_camera
;
goto
out_camera
;
}
}
if
(
dc1394_capture_setup
(
dc1394
->
camera
,
10
,
DC1394_CAPTURE_FLAGS_DEFAULT
)
!=
DC1394_SUCCESS
)
{
if
(
dc1394_capture_setup
(
dc1394
->
camera
,
10
,
DC1394_CAPTURE_FLAGS_DEFAULT
)
!=
DC1394_SUCCESS
)
{
...
@@ -256,6 +338,6 @@ AVInputFormat ff_libdc1394_demuxer = {
...
@@ -256,6 +338,6 @@ AVInputFormat ff_libdc1394_demuxer = {
.
read_header
=
dc1394_read_header
,
.
read_header
=
dc1394_read_header
,
.
read_packet
=
dc1394_read_packet
,
.
read_packet
=
dc1394_read_packet
,
.
read_close
=
dc1394_close
,
.
read_close
=
dc1394_close
,
.
flags
=
AVFMT_NOFILE
.
flags
=
AVFMT_NOFILE
,
.
priv_class
=
&
libdc1394_class
,
.
priv_class
=
&
libdc1394_class
,
};
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment