Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
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
Show 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 @@
* IIDC1394 grab interface (uses libdc1394 and libraw1394)
* Copyright (c) 2004 Roman Shaposhnik
* Copyright (c) 2008 Alessandro Sappia
* Copyright (c) 2011 Martin Lambers
*
* This file is part of FFmpeg.
*
...
...
@@ -25,6 +26,9 @@
#include "libavutil/opt.h"
#include "avdevice.h"
#include <stdlib.h>
#include <string.h>
#include <dc1394/dc1394.h>
#undef free
...
...
@@ -40,16 +44,21 @@ typedef struct dc1394_data {
AVPacket
packet
;
}
dc1394_data
;
struct
dc1394_frame_format
{
int
width
;
int
height
;
enum
PixelFormat
pix_fmt
;
int
frame_size_id
;
}
dc1394_frame_formats
[]
=
{
{
320
,
240
,
PIX_FMT_UYVY422
,
DC1394_VIDEO_MODE_320x240_YUV422
},
{
640
,
480
,
PIX_FMT_UYYVYY411
,
DC1394_VIDEO_MODE_640x480_YUV411
},
{
640
,
480
,
PIX_FMT_UYVY422
,
DC1394_VIDEO_MODE_640x480_YUV422
},
{
0
,
0
,
0
,
0
}
/* gotta be the last one */
/* The list of color codings that we support.
* We assume big endian for the dc1394 16bit modes: libdc1394 never sets the
* flag little_endian in dc1394video_frame_t. */
struct
dc1394_color_coding
{
int
pix_fmt
;
int
score
;
uint32_t
coding
;
}
dc1394_color_codings
[]
=
{
{
PIX_FMT_GRAY16BE
,
1000
,
DC1394_COLOR_CODING_MONO16
},
{
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
{
...
...
@@ -68,9 +77,6 @@ struct dc1394_frame_rate {
};
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
},
};
...
...
@@ -81,73 +87,22 @@ static const AVClass libdc1394_class = {
.
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
)
{
dc1394_data
*
dc1394
=
c
->
priv_data
;
AVStream
*
vst
;
const
struct
dc1394_color_coding
*
cc
;
const
struct
dc1394_frame_rate
*
fr
;
dc1394camera_list_t
*
list
;
int
res
,
i
;
struct
dc1394_frame_format
*
fmt
=
NULL
;
struct
dc1394_frame_rate
*
fps
=
NULL
;
if
(
dc1394_read_common
(
c
,
ap
,
&
fmt
,
&
fps
)
!=
0
)
return
-
1
;
dc1394video_modes_t
video_modes
;
dc1394video_mode_t
video_mode
;
dc1394framerates_t
frame_rates
;
dc1394framerate_t
frame_rate
;
uint32_t
dc1394_width
,
dc1394_height
,
dc1394_color_coding
;
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. */
dc1394
->
d
=
dc1394_new
();
...
...
@@ -166,6 +121,133 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap)
/* Freeing list of cameras */
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 */
if
(
dc1394
->
camera
->
bmode_capable
>
0
)
{
dc1394_video_set_operation_mode
(
dc1394
->
camera
,
DC1394_OPERATION_MODE_1394B
);
...
...
@@ -182,13 +264,13 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap)
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
"
);
goto
out_camera
;
}
if
(
dc1394_video_set_framerate
(
dc1394
->
camera
,
fps
->
frame_rate_id
)
!=
DC1394_SUCCESS
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"Could
n't set framerate %d
\n
"
,
fps
->
frame_rate
);
if
(
dc1394_video_set_framerate
(
dc1394
->
camera
,
frame_rate
)
!=
DC1394_SUCCESS
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"Could
not set framerate %d.
\n
"
,
final_
frame_rate
);
goto
out_camera
;
}
if
(
dc1394_capture_setup
(
dc1394
->
camera
,
10
,
DC1394_CAPTURE_FLAGS_DEFAULT
)
!=
DC1394_SUCCESS
)
{
...
...
@@ -256,6 +338,6 @@ AVInputFormat ff_libdc1394_demuxer = {
.
read_header
=
dc1394_read_header
,
.
read_packet
=
dc1394_read_packet
,
.
read_close
=
dc1394_close
,
.
flags
=
AVFMT_NOFILE
.
flags
=
AVFMT_NOFILE
,
.
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