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
47399ccd
Commit
47399ccd
authored
Jul 22, 2017
by
wm4
Committed by
Anton Khirnov
Jul 26, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavc, lavu: move frame cropping to a convenience function
Signed-off-by:
Anton Khirnov
<
anton@khirnov.net
>
parent
80e919b1
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
140 additions
and
88 deletions
+140
-88
APIchanges
doc/APIchanges
+3
-0
decode.c
libavcodec/decode.c
+2
-87
frame.c
libavutil/frame.c
+100
-0
frame.h
libavutil/frame.h
+34
-0
version.h
libavutil/version.h
+1
-1
No files found.
doc/APIchanges
View file @
47399ccd
...
@@ -13,6 +13,9 @@ libavutil: 2017-03-23
...
@@ -13,6 +13,9 @@ libavutil: 2017-03-23
API changes, most recent first:
API changes, most recent first:
2017-xx-xx - xxxxxxx - lavu 56.3.0 - frame.h
Add av_frame_apply_cropping().
2017-xx-xx - xxxxxxx - lavc 58.4.0 - avcodec.h
2017-xx-xx - xxxxxxx - lavc 58.4.0 - avcodec.h
DXVA2 and D3D11 hardware accelerated decoding now supports the new hwaccel API,
DXVA2 and D3D11 hardware accelerated decoding now supports the new hwaccel API,
which can create the decoder context and allocate hardware frame automatically.
which can create the decoder context and allocate hardware frame automatically.
...
...
libavcodec/decode.c
View file @
47399ccd
...
@@ -446,44 +446,8 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke
...
@@ -446,44 +446,8 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke
return
0
;
return
0
;
}
}
static
int
calc_cropping_offsets
(
size_t
offsets
[
4
],
const
AVFrame
*
frame
,
const
AVPixFmtDescriptor
*
desc
)
{
int
i
,
j
;
for
(
i
=
0
;
frame
->
data
[
i
];
i
++
)
{
const
AVComponentDescriptor
*
comp
=
NULL
;
int
shift_x
=
(
i
==
1
||
i
==
2
)
?
desc
->
log2_chroma_w
:
0
;
int
shift_y
=
(
i
==
1
||
i
==
2
)
?
desc
->
log2_chroma_h
:
0
;
if
(
desc
->
flags
&
(
AV_PIX_FMT_FLAG_PAL
|
AV_PIX_FMT_FLAG_PSEUDOPAL
)
&&
i
==
1
)
{
offsets
[
i
]
=
0
;
break
;
}
/* find any component descriptor for this plane */
for
(
j
=
0
;
j
<
desc
->
nb_components
;
j
++
)
{
if
(
desc
->
comp
[
j
].
plane
==
i
)
{
comp
=
&
desc
->
comp
[
j
];
break
;
}
}
if
(
!
comp
)
return
AVERROR_BUG
;
offsets
[
i
]
=
(
frame
->
crop_top
>>
shift_y
)
*
frame
->
linesize
[
i
]
+
(
frame
->
crop_left
>>
shift_x
)
*
comp
->
step
;
}
return
0
;
}
static
int
apply_cropping
(
AVCodecContext
*
avctx
,
AVFrame
*
frame
)
static
int
apply_cropping
(
AVCodecContext
*
avctx
,
AVFrame
*
frame
)
{
{
const
AVPixFmtDescriptor
*
desc
;
size_t
offsets
[
4
];
int
i
;
/* make sure we are noisy about decoders returning invalid cropping data */
/* make sure we are noisy about decoders returning invalid cropping data */
if
(
frame
->
crop_left
>=
INT_MAX
-
frame
->
crop_right
||
if
(
frame
->
crop_left
>=
INT_MAX
-
frame
->
crop_right
||
frame
->
crop_top
>=
INT_MAX
-
frame
->
crop_bottom
||
frame
->
crop_top
>=
INT_MAX
-
frame
->
crop_bottom
||
...
@@ -504,57 +468,8 @@ static int apply_cropping(AVCodecContext *avctx, AVFrame *frame)
...
@@ -504,57 +468,8 @@ static int apply_cropping(AVCodecContext *avctx, AVFrame *frame)
if
(
!
avctx
->
apply_cropping
)
if
(
!
avctx
->
apply_cropping
)
return
0
;
return
0
;
desc
=
av_pix_fmt_desc_get
(
frame
->
format
);
return
av_frame_apply_cropping
(
frame
,
avctx
->
flags
&
AV_CODEC_FLAG_UNALIGNED
?
if
(
!
desc
)
AV_FRAME_CROP_UNALIGNED
:
0
);
return
AVERROR_BUG
;
/* Apply just the right/bottom cropping for hwaccel formats. Bitstream
* formats cannot be easily handled here either (and corresponding decoders
* should not export any cropping anyway), so do the same for those as well.
* */
if
(
desc
->
flags
&
(
AV_PIX_FMT_FLAG_BITSTREAM
|
AV_PIX_FMT_FLAG_HWACCEL
))
{
frame
->
width
-=
frame
->
crop_right
;
frame
->
height
-=
frame
->
crop_bottom
;
frame
->
crop_right
=
0
;
frame
->
crop_bottom
=
0
;
return
0
;
}
/* calculate the offsets for each plane */
calc_cropping_offsets
(
offsets
,
frame
,
desc
);
/* adjust the offsets to avoid breaking alignment */
if
(
!
(
avctx
->
flags
&
AV_CODEC_FLAG_UNALIGNED
))
{
int
log2_crop_align
=
frame
->
crop_left
?
av_ctz
(
frame
->
crop_left
)
:
INT_MAX
;
int
min_log2_align
=
INT_MAX
;
for
(
i
=
0
;
frame
->
data
[
i
];
i
++
)
{
int
log2_align
=
offsets
[
i
]
?
av_ctz
(
offsets
[
i
])
:
INT_MAX
;
min_log2_align
=
FFMIN
(
log2_align
,
min_log2_align
);
}
/* we assume, and it should always be true, that the data alignment is
* related to the cropping alignment by a constant power-of-2 factor */
if
(
log2_crop_align
<
min_log2_align
)
return
AVERROR_BUG
;
if
(
min_log2_align
<
5
)
{
frame
->
crop_left
&=
~
((
1
<<
(
5
+
log2_crop_align
-
min_log2_align
))
-
1
);
calc_cropping_offsets
(
offsets
,
frame
,
desc
);
}
}
for
(
i
=
0
;
frame
->
data
[
i
];
i
++
)
frame
->
data
[
i
]
+=
offsets
[
i
];
frame
->
width
-=
(
frame
->
crop_left
+
frame
->
crop_right
);
frame
->
height
-=
(
frame
->
crop_top
+
frame
->
crop_bottom
);
frame
->
crop_left
=
0
;
frame
->
crop_right
=
0
;
frame
->
crop_top
=
0
;
frame
->
crop_bottom
=
0
;
return
0
;
}
}
int
attribute_align_arg
avcodec_receive_frame
(
AVCodecContext
*
avctx
,
AVFrame
*
frame
)
int
attribute_align_arg
avcodec_receive_frame
(
AVCodecContext
*
avctx
,
AVFrame
*
frame
)
...
...
libavutil/frame.c
View file @
47399ccd
...
@@ -596,3 +596,103 @@ void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
...
@@ -596,3 +596,103 @@ void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
}
}
}
}
}
}
static
int
calc_cropping_offsets
(
size_t
offsets
[
4
],
const
AVFrame
*
frame
,
const
AVPixFmtDescriptor
*
desc
)
{
int
i
,
j
;
for
(
i
=
0
;
frame
->
data
[
i
];
i
++
)
{
const
AVComponentDescriptor
*
comp
=
NULL
;
int
shift_x
=
(
i
==
1
||
i
==
2
)
?
desc
->
log2_chroma_w
:
0
;
int
shift_y
=
(
i
==
1
||
i
==
2
)
?
desc
->
log2_chroma_h
:
0
;
if
(
desc
->
flags
&
(
AV_PIX_FMT_FLAG_PAL
|
AV_PIX_FMT_FLAG_PSEUDOPAL
)
&&
i
==
1
)
{
offsets
[
i
]
=
0
;
break
;
}
/* find any component descriptor for this plane */
for
(
j
=
0
;
j
<
desc
->
nb_components
;
j
++
)
{
if
(
desc
->
comp
[
j
].
plane
==
i
)
{
comp
=
&
desc
->
comp
[
j
];
break
;
}
}
if
(
!
comp
)
return
AVERROR_BUG
;
offsets
[
i
]
=
(
frame
->
crop_top
>>
shift_y
)
*
frame
->
linesize
[
i
]
+
(
frame
->
crop_left
>>
shift_x
)
*
comp
->
step
;
}
return
0
;
}
int
av_frame_apply_cropping
(
AVFrame
*
frame
,
int
flags
)
{
const
AVPixFmtDescriptor
*
desc
;
size_t
offsets
[
4
];
int
i
;
if
(
!
(
frame
->
width
>
0
&&
frame
->
height
>
0
))
return
AVERROR
(
EINVAL
);
if
(
frame
->
crop_left
>=
INT_MAX
-
frame
->
crop_right
||
frame
->
crop_top
>=
INT_MAX
-
frame
->
crop_bottom
||
(
frame
->
crop_left
+
frame
->
crop_right
)
>=
frame
->
width
||
(
frame
->
crop_top
+
frame
->
crop_bottom
)
>=
frame
->
height
)
return
AVERROR
(
ERANGE
);
desc
=
av_pix_fmt_desc_get
(
frame
->
format
);
if
(
!
desc
)
return
AVERROR_BUG
;
/* Apply just the right/bottom cropping for hwaccel formats. Bitstream
* formats cannot be easily handled here either (and corresponding decoders
* should not export any cropping anyway), so do the same for those as well.
* */
if
(
desc
->
flags
&
(
AV_PIX_FMT_FLAG_BITSTREAM
|
AV_PIX_FMT_FLAG_HWACCEL
))
{
frame
->
width
-=
frame
->
crop_right
;
frame
->
height
-=
frame
->
crop_bottom
;
frame
->
crop_right
=
0
;
frame
->
crop_bottom
=
0
;
return
0
;
}
/* calculate the offsets for each plane */
calc_cropping_offsets
(
offsets
,
frame
,
desc
);
/* adjust the offsets to avoid breaking alignment */
if
(
!
(
flags
&
AV_FRAME_CROP_UNALIGNED
))
{
int
log2_crop_align
=
frame
->
crop_left
?
av_ctz
(
frame
->
crop_left
)
:
INT_MAX
;
int
min_log2_align
=
INT_MAX
;
for
(
i
=
0
;
frame
->
data
[
i
];
i
++
)
{
int
log2_align
=
offsets
[
i
]
?
av_ctz
(
offsets
[
i
])
:
INT_MAX
;
min_log2_align
=
FFMIN
(
log2_align
,
min_log2_align
);
}
/* we assume, and it should always be true, that the data alignment is
* related to the cropping alignment by a constant power-of-2 factor */
if
(
log2_crop_align
<
min_log2_align
)
return
AVERROR_BUG
;
if
(
min_log2_align
<
5
)
{
frame
->
crop_left
&=
~
((
1
<<
(
5
+
log2_crop_align
-
min_log2_align
))
-
1
);
calc_cropping_offsets
(
offsets
,
frame
,
desc
);
}
}
for
(
i
=
0
;
frame
->
data
[
i
];
i
++
)
frame
->
data
[
i
]
+=
offsets
[
i
];
frame
->
width
-=
(
frame
->
crop_left
+
frame
->
crop_right
);
frame
->
height
-=
(
frame
->
crop_top
+
frame
->
crop_bottom
);
frame
->
crop_left
=
0
;
frame
->
crop_right
=
0
;
frame
->
crop_top
=
0
;
frame
->
crop_bottom
=
0
;
return
0
;
}
libavutil/frame.h
View file @
47399ccd
...
@@ -580,6 +580,40 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
...
@@ -580,6 +580,40 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
*/
*/
void
av_frame_remove_side_data
(
AVFrame
*
frame
,
enum
AVFrameSideDataType
type
);
void
av_frame_remove_side_data
(
AVFrame
*
frame
,
enum
AVFrameSideDataType
type
);
/**
* Flags for frame cropping.
*/
enum
{
/**
* Apply the maximum possible cropping, even if it requires setting the
* AVFrame.data[] entries to unaligned pointers. Passing unaligned data
* to Libav API is generally not allowed, and causes undefined behavior
* (such as crashes). You can pass unaligned data only to Libav APIs that
* are explicitly documented to accept it. Use this flag only if you
* absolutely know what you are doing.
*/
AV_FRAME_CROP_UNALIGNED
=
1
<<
0
,
};
/**
* Crop the given video AVFrame according to its crop_left/crop_top/crop_right/
* crop_bottom fields. If cropping is successful, the function will adjust the
* data pointers and the width/height fields, and set the crop fields to 0.
*
* In all cases, the cropping boundaries will be rounded to the inherent
* alignment of the pixel format. In some cases, such as for opaque hwaccel
* formats, the left/top cropping is ignored. The crop fields are set to 0 even
* if the cropping was rounded or ignored.
*
* @param frame the frame which should be cropped
* @param flags Some combination of AV_FRAME_CROP_* flags, or 0.
*
* @return >= 0 on success, a negative AVERROR on error. If the cropping fields
* were invalid, AVERROR(ERANGE) is returned, and nothing is changed.
*/
int
av_frame_apply_cropping
(
AVFrame
*
frame
,
int
flags
);
/**
/**
* @}
* @}
*/
*/
...
...
libavutil/version.h
View file @
47399ccd
...
@@ -54,7 +54,7 @@
...
@@ -54,7 +54,7 @@
*/
*/
#define LIBAVUTIL_VERSION_MAJOR 56
#define LIBAVUTIL_VERSION_MAJOR 56
#define LIBAVUTIL_VERSION_MINOR
2
#define LIBAVUTIL_VERSION_MINOR
3
#define LIBAVUTIL_VERSION_MICRO 0
#define LIBAVUTIL_VERSION_MICRO 0
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
...
...
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