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
Hide 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
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
DXVA2 and D3D11 hardware accelerated decoding now supports the new hwaccel API,
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
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
)
{
const
AVPixFmtDescriptor
*
desc
;
size_t
offsets
[
4
];
int
i
;
/* make sure we are noisy about decoders returning invalid cropping data */
if
(
frame
->
crop_left
>=
INT_MAX
-
frame
->
crop_right
||
frame
->
crop_top
>=
INT_MAX
-
frame
->
crop_bottom
||
...
...
@@ -504,57 +468,8 @@ static int apply_cropping(AVCodecContext *avctx, AVFrame *frame)
if
(
!
avctx
->
apply_cropping
)
return
0
;
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
(
!
(
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
;
return
av_frame_apply_cropping
(
frame
,
avctx
->
flags
&
AV_CODEC_FLAG_UNALIGNED
?
AV_FRAME_CROP_UNALIGNED
:
0
);
}
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)
}
}
}
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,
*/
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 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 56
#define LIBAVUTIL_VERSION_MINOR
2
#define LIBAVUTIL_VERSION_MINOR
3
#define LIBAVUTIL_VERSION_MICRO 0
#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